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;
5260   int          int_data;
5261   int          rc;
5262   char         str_data[50];
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_LONGLONG,
7616                        "", "", "", 10, 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_default()8426 static void test_list_fields_default()
8427 {
8428   int rc, i;
8429   myheader("test_list_fields_default");
8430 
8431   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
8432   myquery(rc);
8433 
8434   rc= mysql_query(mysql,
8435                   "CREATE TABLE t1 ("
8436                   " i1 INT NOT NULL DEFAULT 0,"
8437                   " i3 BIGINT UNSIGNED NOT NULL DEFAULT 0xFFFFFFFFFFFFFFFF,"
8438                   " s1 VARCHAR(10) CHARACTER SET latin1 NOT NULL DEFAULT 's1def',"
8439                   " d1 DECIMAL(31,1) NOT NULL DEFAULT 111111111122222222223333333333.9,"
8440                   " t1 DATETIME(6) NOT NULL DEFAULT '2001-01-01 10:20:30.123456',"
8441                   " e1 ENUM('a','b') NOT NULL DEFAULT 'a'"
8442                   ")");
8443   myquery(rc);
8444 
8445   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1");
8446   myquery(rc);
8447 
8448   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
8449   myquery(rc);
8450 
8451   /*
8452     Checking that mysql_list_fields() returns the same result
8453     for a TABLE and a VIEW on the same table.
8454   */
8455   for (i= 0; i < 2; i++)
8456   {
8457     const char *table_name= i == 0 ? "t1" : "v1";
8458     MYSQL_RES *result= mysql_list_fields(mysql, table_name, NULL);
8459     mytest(result);
8460 
8461     rc= my_process_result_set(result);
8462     DIE_UNLESS(rc == 0);
8463 
8464     verify_prepare_field(result, 0, "i1", "i1", MYSQL_TYPE_LONG,
8465                          table_name, table_name, current_db,
8466                          11, "0");
8467 
8468     verify_prepare_field(result, 1, "i3", "i3", MYSQL_TYPE_LONGLONG,
8469                          table_name, table_name, current_db,
8470                          20, "18446744073709551615");
8471 
8472     verify_prepare_field(result, 2, "s1", "s1", MYSQL_TYPE_VAR_STRING,
8473                          table_name, table_name, current_db,
8474                          10, "s1def");
8475 
8476     verify_prepare_field(result, 3, "d1", "d1", MYSQL_TYPE_NEWDECIMAL,
8477                          table_name, table_name, current_db,
8478                          33, "111111111122222222223333333333.9");
8479 
8480     verify_prepare_field(result, 4, "t1", "t1", MYSQL_TYPE_DATETIME,
8481                          table_name, table_name, current_db,
8482                          26, "2001-01-01 10:20:30.123456");
8483 
8484     verify_prepare_field(result, 5, "e1", "e1", MYSQL_TYPE_STRING,
8485                          table_name, table_name, current_db,
8486                          1, "a");
8487 
8488     mysql_free_result(result);
8489   }
8490 
8491   myquery(mysql_query(mysql, "DROP VIEW v1"));
8492   myquery(mysql_query(mysql, "DROP TABLE t1"));
8493 }
8494 
8495 
test_bug19671()8496 static void test_bug19671()
8497 {
8498   MYSQL_RES *result;
8499   int rc;
8500   myheader("test_bug19671");
8501 
8502   mysql_query(mysql, "set sql_mode=''");
8503   rc= mysql_query(mysql, "drop table if exists t1");
8504   myquery(rc);
8505 
8506   rc= mysql_query(mysql, "drop view if exists v1");
8507   myquery(rc);
8508 
8509   rc= mysql_query(mysql, "create table t1(f1 int)");
8510   myquery(rc);
8511 
8512   rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
8513   myquery(rc);
8514 
8515   result= mysql_list_fields(mysql, "v1", NULL);
8516   mytest(result);
8517 
8518   rc= my_process_result_set(result);
8519   DIE_UNLESS(rc == 0);
8520 
8521   verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
8522                        "v1", "v1", current_db, 11, "0");
8523 
8524   mysql_free_result(result);
8525   myquery(mysql_query(mysql, "drop view v1"));
8526   myquery(mysql_query(mysql, "drop table t1"));
8527 }
8528 
8529 
8530 /* Test a memory ovverun bug */
8531 
test_mem_overun()8532 static void test_mem_overun()
8533 {
8534   char       buffer[10000], field[10];
8535   MYSQL_STMT *stmt;
8536   MYSQL_RES  *field_res;
8537   int        rc, length;
8538   unsigned   i;
8539 
8540   myheader("test_mem_overun");
8541 
8542   /*
8543     Test a memory ovverun bug when a table had 1000 fields with
8544     a row of data
8545   */
8546   rc= mysql_query(mysql, "drop table if exists t_mem_overun");
8547   myquery(rc);
8548 
8549   strxmov(buffer, "create table t_mem_overun(", NullS);
8550   for (i= 0; i < 1000; i++)
8551   {
8552     sprintf(field, "c%u int", i);
8553     strxmov(buffer, buffer, field, ", ", NullS);
8554   }
8555   length= strlen(buffer);
8556   buffer[length-2]= ')';
8557   buffer[--length]= '\0';
8558 
8559   rc= mysql_real_query(mysql, buffer, length);
8560   myquery(rc);
8561 
8562   strxmov(buffer, "insert into t_mem_overun values(", NullS);
8563   for (i= 0; i < 1000; i++)
8564   {
8565     strxmov(buffer, buffer, "1, ", NullS);
8566   }
8567   length= strlen(buffer);
8568   buffer[length-2]= ')';
8569   buffer[--length]= '\0';
8570 
8571   rc= mysql_real_query(mysql, buffer, length);
8572   myquery(rc);
8573 
8574   rc= mysql_query(mysql, "select * from t_mem_overun");
8575   myquery(rc);
8576 
8577   rc= my_process_result(mysql);
8578   DIE_UNLESS(rc == 1);
8579 
8580   stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun");
8581   check_stmt(stmt);
8582 
8583   rc= mysql_stmt_execute(stmt);
8584   check_execute(stmt, rc);
8585 
8586   field_res= mysql_stmt_result_metadata(stmt);
8587   mytest(field_res);
8588 
8589   if (!opt_silent)
8590     fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
8591   DIE_UNLESS( 1000 == mysql_num_fields(field_res));
8592 
8593   rc= mysql_stmt_store_result(stmt);
8594   check_execute(stmt, rc);
8595 
8596   rc= mysql_stmt_fetch(stmt);
8597   check_execute(stmt, rc);
8598 
8599   rc= mysql_stmt_fetch(stmt);
8600   DIE_UNLESS(rc == MYSQL_NO_DATA);
8601 
8602   mysql_free_result(field_res);
8603 
8604   mysql_stmt_close(stmt);
8605 }
8606 
8607 
8608 /* Test mysql_stmt_free_result() */
8609 
test_free_result()8610 static void test_free_result()
8611 {
8612   MYSQL_STMT *stmt;
8613   MYSQL_BIND my_bind[1];
8614   char       c2[5];
8615   ulong      bl1, l2;
8616   int        rc, c1, bc1;
8617 
8618   myheader("test_free_result");
8619 
8620   rc= mysql_query(mysql, "drop table if exists test_free_result");
8621   myquery(rc);
8622 
8623   rc= mysql_query(mysql, "create table test_free_result("
8624                          "c1 int primary key auto_increment)");
8625   myquery(rc);
8626 
8627   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8628   myquery(rc);
8629 
8630   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8631   check_stmt(stmt);
8632 
8633   bzero((char*) my_bind, sizeof(my_bind));
8634   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8635   my_bind[0].buffer= (void *)&bc1;
8636   my_bind[0].length= &bl1;
8637 
8638   rc= mysql_stmt_execute(stmt);
8639   check_execute(stmt, rc);
8640 
8641   rc= mysql_stmt_bind_result(stmt, my_bind);
8642   check_execute(stmt, rc);
8643 
8644   rc= mysql_stmt_fetch(stmt);
8645   check_execute(stmt, rc);
8646 
8647   c2[0]= '\0'; l2= 0;
8648   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8649   my_bind[0].buffer= (void *)c2;
8650   my_bind[0].buffer_length= 7;
8651   my_bind[0].is_null= 0;
8652   my_bind[0].length= &l2;
8653 
8654   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8655   check_execute(stmt, rc);
8656   if (!opt_silent)
8657     fprintf(stdout, "\n col 0: %s(%ld)", c2, l2);
8658   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8659 
8660   rc= mysql_stmt_fetch(stmt);
8661   check_execute(stmt, rc);
8662 
8663   c1= 0, l2= 0;
8664   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8665   my_bind[0].buffer= (void *)&c1;
8666   my_bind[0].buffer_length= 0;
8667   my_bind[0].is_null= 0;
8668   my_bind[0].length= &l2;
8669 
8670   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8671   check_execute(stmt, rc);
8672   if (!opt_silent)
8673     fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8674   DIE_UNLESS(c1 == 2 && l2 == 4);
8675 
8676   rc= mysql_query(mysql, "drop table test_free_result");
8677   myquery_r(rc); /* error should be, COMMANDS OUT OF SYNC */
8678 
8679   rc= mysql_stmt_free_result(stmt);
8680   check_execute(stmt, rc);
8681 
8682   rc= mysql_query(mysql, "drop table test_free_result");
8683   myquery(rc);  /* should be successful */
8684 
8685   mysql_stmt_close(stmt);
8686 }
8687 
8688 
8689 /* Test mysql_stmt_store_result() */
8690 
test_free_store_result()8691 static void test_free_store_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_store_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(c1 int primary key auto_increment)");
8705   myquery(rc);
8706 
8707   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8708   myquery(rc);
8709 
8710   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8711   check_stmt(stmt);
8712 
8713   bzero((char*) my_bind, sizeof(my_bind));
8714   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8715   my_bind[0].buffer= (void *)&bc1;
8716   my_bind[0].buffer_length= 0;
8717   my_bind[0].is_null= 0;
8718   my_bind[0].length= &bl1;
8719 
8720   rc= mysql_stmt_execute(stmt);
8721   check_execute(stmt, rc);
8722 
8723   rc= mysql_stmt_bind_result(stmt, my_bind);
8724   check_execute(stmt, rc);
8725 
8726   rc= mysql_stmt_store_result(stmt);
8727   check_execute(stmt, rc);
8728 
8729   rc= mysql_stmt_fetch(stmt);
8730   check_execute(stmt, rc);
8731 
8732   c2[0]= '\0'; l2= 0;
8733   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8734   my_bind[0].buffer= (void *)c2;
8735   my_bind[0].buffer_length= 7;
8736   my_bind[0].is_null= 0;
8737   my_bind[0].length= &l2;
8738 
8739   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8740   check_execute(stmt, rc);
8741   if (!opt_silent)
8742     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8743   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8744 
8745   rc= mysql_stmt_fetch(stmt);
8746   check_execute(stmt, rc);
8747 
8748   c1= 0, l2= 0;
8749   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8750   my_bind[0].buffer= (void *)&c1;
8751   my_bind[0].buffer_length= 0;
8752   my_bind[0].is_null= 0;
8753   my_bind[0].length= &l2;
8754 
8755   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8756   check_execute(stmt, rc);
8757   if (!opt_silent)
8758     fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8759   DIE_UNLESS(c1 == 2 && l2 == 4);
8760 
8761   rc= mysql_stmt_free_result(stmt);
8762   check_execute(stmt, rc);
8763 
8764   rc= mysql_query(mysql, "drop table test_free_result");
8765   myquery(rc);
8766 
8767   mysql_stmt_close(stmt);
8768 }
8769 
8770 
8771 /* Test SQLmode */
8772 
test_sqlmode()8773 static void test_sqlmode()
8774 {
8775   MYSQL_STMT *stmt;
8776   MYSQL_BIND my_bind[2];
8777   char       c1[5], c2[5];
8778   int        rc;
8779   char query[MAX_TEST_QUERY_LENGTH];
8780 
8781   myheader("test_sqlmode");
8782 
8783   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping");
8784   myquery(rc);
8785 
8786   rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))");
8787   myquery(rc);
8788 
8789   /* PIPES_AS_CONCAT */
8790   strmov(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
8791   if (!opt_silent)
8792     fprintf(stdout, "\n With %s", query);
8793   rc= mysql_query(mysql, query);
8794   myquery(rc);
8795 
8796   strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8797   if (!opt_silent)
8798     fprintf(stdout, "\n  query: %s", query);
8799   stmt= mysql_simple_prepare(mysql, query);
8800   check_stmt(stmt);
8801 
8802   if (!opt_silent)
8803     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8804 
8805   /*
8806     We need to bzero bind structure because mysql_stmt_bind_param checks all
8807     its members.
8808   */
8809   bzero((char*) my_bind, sizeof(my_bind));
8810 
8811   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8812   my_bind[0].buffer= (void *)c1;
8813   my_bind[0].buffer_length= 2;
8814 
8815   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8816   my_bind[1].buffer= (void *)c2;
8817   my_bind[1].buffer_length= 3;
8818 
8819   rc= mysql_stmt_bind_param(stmt, my_bind);
8820   check_execute(stmt, rc);
8821 
8822   strmov(c1, "My"); strmov(c2, "SQL");
8823   rc= mysql_stmt_execute(stmt);
8824   check_execute(stmt, rc);
8825   mysql_stmt_close(stmt);
8826 
8827   verify_col_data("test_piping", "name", "MySQL");
8828 
8829   rc= mysql_query(mysql, "DELETE FROM test_piping");
8830   myquery(rc);
8831 
8832   strmov(query, "SELECT connection_id    ()");
8833   if (!opt_silent)
8834     fprintf(stdout, "\n  query: %s", query);
8835   stmt= mysql_simple_prepare(mysql, query);
8836   check_stmt(stmt);
8837   mysql_stmt_close(stmt);
8838 
8839   /* ANSI */
8840   strmov(query, "SET SQL_MODE= \"ANSI\"");
8841   if (!opt_silent)
8842     fprintf(stdout, "\n With %s", query);
8843   rc= mysql_query(mysql, query);
8844   myquery(rc);
8845 
8846   strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8847   if (!opt_silent)
8848     fprintf(stdout, "\n  query: %s", query);
8849   stmt= mysql_simple_prepare(mysql, query);
8850   check_stmt(stmt);
8851   if (!opt_silent)
8852     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8853 
8854   rc= mysql_stmt_bind_param(stmt, my_bind);
8855   check_execute(stmt, rc);
8856 
8857   strmov(c1, "My"); strmov(c2, "SQL");
8858   rc= mysql_stmt_execute(stmt);
8859   check_execute(stmt, rc);
8860 
8861   mysql_stmt_close(stmt);
8862   verify_col_data("test_piping", "name", "MySQL");
8863 
8864   /* ANSI mode spaces ... */
8865   strmov(query, "SELECT connection_id    ()");
8866   if (!opt_silent)
8867     fprintf(stdout, "\n  query: %s", query);
8868   stmt= mysql_simple_prepare(mysql, query);
8869   check_stmt(stmt);
8870 
8871   rc= mysql_stmt_execute(stmt);
8872   check_execute(stmt, rc);
8873 
8874   rc= mysql_stmt_fetch(stmt);
8875   check_execute(stmt, rc);
8876 
8877   rc= mysql_stmt_fetch(stmt);
8878   DIE_UNLESS(rc == MYSQL_NO_DATA);
8879   if (!opt_silent)
8880     fprintf(stdout, "\n  returned 1 row\n");
8881 
8882   mysql_stmt_close(stmt);
8883 
8884   /* IGNORE SPACE MODE */
8885   strmov(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
8886   if (!opt_silent)
8887     fprintf(stdout, "\n With %s", query);
8888   rc= mysql_query(mysql, query);
8889   myquery(rc);
8890 
8891   strmov(query, "SELECT connection_id    ()");
8892   if (!opt_silent)
8893     fprintf(stdout, "\n  query: %s", query);
8894   stmt= mysql_simple_prepare(mysql, query);
8895   check_stmt(stmt);
8896 
8897   rc= mysql_stmt_execute(stmt);
8898   check_execute(stmt, rc);
8899 
8900   rc= mysql_stmt_fetch(stmt);
8901   check_execute(stmt, rc);
8902 
8903   rc= mysql_stmt_fetch(stmt);
8904   DIE_UNLESS(rc == MYSQL_NO_DATA);
8905   if (!opt_silent)
8906     fprintf(stdout, "\n  returned 1 row");
8907 
8908   mysql_stmt_close(stmt);
8909 }
8910 
8911 
8912 /* Test for timestamp handling */
8913 
test_ts()8914 static void test_ts()
8915 {
8916   MYSQL_STMT *stmt;
8917   MYSQL_BIND my_bind[6];
8918   MYSQL_TIME ts;
8919   MYSQL_RES  *prep_res;
8920   char       strts[30];
8921   ulong      length;
8922   int        rc, field_count;
8923   char       name;
8924   char query[MAX_TEST_QUERY_LENGTH];
8925   const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
8926                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS TIME)",
8927                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
8928   myheader("test_ts");
8929 
8930   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts");
8931   myquery(rc);
8932 
8933   rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)");
8934   myquery(rc);
8935 
8936   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)");
8937   check_stmt(stmt);
8938 
8939   ts.year= 2003;
8940   ts.month= 07;
8941   ts.day= 12;
8942   ts.hour= 21;
8943   ts.minute= 07;
8944   ts.second= 46;
8945   ts.second_part= 0;
8946   length= (long)(strmov(strts, "2003-07-12 21:07:46") - strts);
8947 
8948   /*
8949     We need to bzero bind structure because mysql_stmt_bind_param checks all
8950     its members.
8951   */
8952   bzero((char*) my_bind, sizeof(my_bind));
8953 
8954   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
8955   my_bind[0].buffer= (void *)&ts;
8956   my_bind[0].buffer_length= sizeof(ts);
8957 
8958   my_bind[2]= my_bind[1]= my_bind[0];
8959 
8960   my_bind[3].buffer_type= MYSQL_TYPE_STRING;
8961   my_bind[3].buffer= (void *)strts;
8962   my_bind[3].buffer_length= sizeof(strts);
8963   my_bind[3].length= &length;
8964 
8965   my_bind[5]= my_bind[4]= my_bind[3];
8966 
8967   rc= mysql_stmt_bind_param(stmt, my_bind);
8968   check_execute(stmt, rc);
8969 
8970   rc= mysql_stmt_execute(stmt);
8971   check_execute(stmt, rc);
8972 
8973   mysql_stmt_close(stmt);
8974 
8975   verify_col_data("test_ts", "a", "2003-07-12");
8976   verify_col_data("test_ts", "b", "21:07:46");
8977   verify_col_data("test_ts", "c", "2003-07-12 21:07:46");
8978 
8979   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts");
8980   check_stmt(stmt);
8981 
8982   prep_res= mysql_stmt_result_metadata(stmt);
8983   mytest(prep_res);
8984 
8985   rc= mysql_stmt_execute(stmt);
8986   check_execute(stmt, rc);
8987 
8988   rc= my_process_stmt_result(stmt);
8989   DIE_UNLESS(rc == 2);
8990   field_count= mysql_num_fields(prep_res);
8991 
8992   mysql_free_result(prep_res);
8993   mysql_stmt_close(stmt);
8994 
8995   for (name= 'a'; field_count--; name++)
8996   {
8997     int row_count= 0;
8998 
8999     sprintf(query, queries[field_count], name);
9000 
9001     if (!opt_silent)
9002       fprintf(stdout, "\n  %s", query);
9003     stmt= mysql_simple_prepare(mysql, query);
9004     check_stmt(stmt);
9005 
9006     rc= mysql_stmt_bind_param(stmt, my_bind);
9007     check_execute(stmt, rc);
9008 
9009     rc= mysql_stmt_execute(stmt);
9010     check_execute(stmt, rc);
9011 
9012     while (mysql_stmt_fetch(stmt) == 0)
9013       row_count++;
9014 
9015     if (!opt_silent)
9016       fprintf(stdout, "\n   returned '%d' rows", row_count);
9017     DIE_UNLESS(row_count == 2);
9018     mysql_stmt_close(stmt);
9019   }
9020 }
9021 
9022 
9023 /* Test for bug #1500. */
9024 
test_bug1500()9025 static void test_bug1500()
9026 {
9027   MYSQL_STMT *stmt;
9028   MYSQL_BIND my_bind[3];
9029   int        rc;
9030   int32 int_data[3]= {2, 3, 4};
9031   const char *data;
9032 
9033   myheader("test_bug1500");
9034 
9035   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
9036   myquery(rc);
9037 
9038   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (i INT)");
9039   myquery(rc);
9040 
9041   rc= mysql_query(mysql, "INSERT INTO test_bg1500 VALUES (1), (2)");
9042   myquery(rc);
9043 
9044   rc= mysql_commit(mysql);
9045   myquery(rc);
9046 
9047   stmt= mysql_simple_prepare(mysql, "SELECT i FROM test_bg1500 WHERE i IN (?, ?, ?)");
9048   check_stmt(stmt);
9049   verify_param_count(stmt, 3);
9050 
9051   /*
9052     We need to bzero bind structure because mysql_stmt_bind_param checks all
9053     its members.
9054   */
9055   bzero((char*) my_bind, sizeof(my_bind));
9056 
9057   my_bind[0].buffer= (void *)int_data;
9058   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9059   my_bind[2]= my_bind[1]= my_bind[0];
9060   my_bind[1].buffer= (void *)(int_data + 1);
9061   my_bind[2].buffer= (void *)(int_data + 2);
9062 
9063   rc= mysql_stmt_bind_param(stmt, my_bind);
9064   check_execute(stmt, rc);
9065 
9066   rc= mysql_stmt_execute(stmt);
9067   check_execute(stmt, rc);
9068 
9069   rc= my_process_stmt_result(stmt);
9070   DIE_UNLESS(rc == 1);
9071 
9072   mysql_stmt_close(stmt);
9073 
9074   rc= mysql_query(mysql, "DROP TABLE test_bg1500");
9075   myquery(rc);
9076 
9077   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM");
9078   myquery(rc);
9079 
9080   rc= mysql_query(mysql,
9081         "INSERT INTO test_bg1500 VALUES ('Gravedigger'), ('Greed'), ('Hollow Dogs')");
9082   myquery(rc);
9083 
9084   rc= mysql_commit(mysql);
9085   myquery(rc);
9086 
9087   stmt= mysql_simple_prepare(mysql,
9088           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)");
9089   check_stmt(stmt);
9090 
9091   verify_param_count(stmt, 1);
9092 
9093   data= "Dogs";
9094   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9095   my_bind[0].buffer= (void *) data;
9096   my_bind[0].buffer_length= strlen(data);
9097   my_bind[0].is_null= 0;
9098   my_bind[0].length= 0;
9099 
9100   rc= mysql_stmt_bind_param(stmt, my_bind);
9101   check_execute(stmt, rc);
9102 
9103   rc= mysql_stmt_execute(stmt);
9104   check_execute(stmt, rc);
9105 
9106   rc= my_process_stmt_result(stmt);
9107   DIE_UNLESS(rc == 1);
9108 
9109   mysql_stmt_close(stmt);
9110 
9111   /* This should work too */
9112   stmt= mysql_simple_prepare(mysql,
9113           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?, 'digger'))");
9114   check_stmt(stmt);
9115 
9116   verify_param_count(stmt, 1);
9117 
9118   data= "Grave";
9119   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9120   my_bind[0].buffer= (void *) data;
9121   my_bind[0].buffer_length= strlen(data);
9122 
9123   rc= mysql_stmt_bind_param(stmt, my_bind);
9124   check_execute(stmt, rc);
9125 
9126   rc= mysql_stmt_execute(stmt);
9127   check_execute(stmt, rc);
9128 
9129   rc= my_process_stmt_result(stmt);
9130   DIE_UNLESS(rc == 1);
9131 
9132   mysql_stmt_close(stmt);
9133 }
9134 
9135 
test_bug1946()9136 static void test_bug1946()
9137 {
9138   MYSQL_STMT *stmt;
9139   int rc;
9140   const char *query= "INSERT INTO prepare_command VALUES (?)";
9141 
9142   myheader("test_bug1946");
9143 
9144   rc= mysql_query(mysql, "DROP TABLE IF EXISTS prepare_command");
9145   myquery(rc);
9146 
9147   rc= mysql_query(mysql, "CREATE TABLE prepare_command(ID INT)");
9148   myquery(rc);
9149 
9150   stmt= mysql_simple_prepare(mysql, query);
9151   check_stmt(stmt);
9152   rc= mysql_real_query(mysql, query, strlen(query));
9153   DIE_UNLESS(rc != 0);
9154   if (!opt_silent)
9155     fprintf(stdout, "Got error (as expected):\n");
9156   myerror(NULL);
9157 
9158   mysql_stmt_close(stmt);
9159   rc= mysql_query(mysql, "DROP TABLE prepare_command");
9160 }
9161 
9162 
test_parse_error_and_bad_length()9163 static void test_parse_error_and_bad_length()
9164 {
9165   MYSQL_STMT *stmt;
9166   int rc;
9167 
9168   /* check that we get 4 syntax errors over the 4 calls */
9169   myheader("test_parse_error_and_bad_length");
9170 
9171   rc= mysql_query(mysql, "SHOW DATABAAAA");
9172   DIE_UNLESS(rc);
9173   if (!opt_silent)
9174     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9175   rc= mysql_real_query(mysql, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAAA"));
9176   DIE_UNLESS(rc);
9177   if (!opt_silent)
9178     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9179 
9180   stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA");
9181   DIE_UNLESS(!stmt);
9182   if (!opt_silent)
9183     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9184   stmt= mysql_stmt_init(mysql);
9185   DIE_UNLESS(stmt);
9186   rc= mysql_stmt_prepare(stmt, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAA"));
9187   DIE_UNLESS(rc != 0);
9188   if (!opt_silent)
9189     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
9190   mysql_stmt_close(stmt);
9191 }
9192 
9193 
test_bug2247()9194 static void test_bug2247()
9195 {
9196   MYSQL_STMT *stmt;
9197   MYSQL_RES *res;
9198   int rc;
9199   int i;
9200   const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)";
9201   const char *insert= "INSERT INTO bug2247 VALUES (NULL)";
9202   const char *SELECT= "SELECT id FROM bug2247";
9203   const char *update= "UPDATE bug2247 SET id=id+10";
9204   const char *drop= "DROP TABLE IF EXISTS bug2247";
9205   ulonglong exp_count;
9206   enum { NUM_ROWS= 5 };
9207 
9208   myheader("test_bug2247");
9209 
9210   if (!opt_silent)
9211     fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
9212                   "mysql_query ... ");
9213   /* create table and insert few rows */
9214   rc= mysql_query(mysql, drop);
9215   myquery(rc);
9216 
9217   rc= mysql_query(mysql, create);
9218   myquery(rc);
9219 
9220   stmt= mysql_simple_prepare(mysql, insert);
9221   check_stmt(stmt);
9222   for (i= 0; i < NUM_ROWS; ++i)
9223   {
9224     rc= mysql_stmt_execute(stmt);
9225     check_execute(stmt, rc);
9226   }
9227   exp_count= mysql_stmt_affected_rows(stmt);
9228   DIE_UNLESS(exp_count == 1);
9229 
9230   rc= mysql_query(mysql, SELECT);
9231   myquery(rc);
9232   /*
9233     mysql_store_result overwrites mysql->affected_rows. Check that
9234     mysql_stmt_affected_rows() returns the same value, whereas
9235     mysql_affected_rows() value is correct.
9236   */
9237   res= mysql_store_result(mysql);
9238   mytest(res);
9239 
9240   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9241   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9242 
9243   rc= mysql_query(mysql, update);
9244   myquery(rc);
9245   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9246   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9247 
9248   mysql_free_result(res);
9249   mysql_stmt_close(stmt);
9250 
9251   /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */
9252   stmt= mysql_simple_prepare(mysql, SELECT);
9253   check_stmt(stmt);
9254 
9255   rc= mysql_stmt_execute(stmt);
9256   check_execute(stmt, rc);
9257   rc= mysql_stmt_store_result(stmt);
9258   check_execute(stmt, rc);
9259   exp_count= mysql_stmt_affected_rows(stmt);
9260   DIE_UNLESS(exp_count == NUM_ROWS);
9261 
9262   rc= mysql_query(mysql, insert);
9263   myquery(rc);
9264   DIE_UNLESS(mysql_affected_rows(mysql) == 1);
9265   DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count);
9266 
9267   mysql_stmt_close(stmt);
9268   if (!opt_silent)
9269     fprintf(stdout, "OK");
9270 }
9271 
9272 
test_subqueries()9273 static void test_subqueries()
9274 {
9275   MYSQL_STMT *stmt;
9276   int rc, i;
9277   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";
9278 
9279   myheader("test_subqueries");
9280 
9281   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9282   myquery(rc);
9283 
9284   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9285   myquery(rc);
9286 
9287   rc= mysql_query(mysql,
9288                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9289   myquery(rc);
9290 
9291   rc= mysql_query(mysql, "create table t2 select * from t1;");
9292   myquery(rc);
9293 
9294   stmt= mysql_simple_prepare(mysql, query);
9295   check_stmt(stmt);
9296   for (i= 0; i < 3; i++)
9297   {
9298     rc= mysql_stmt_execute(stmt);
9299     check_execute(stmt, rc);
9300     rc= my_process_stmt_result(stmt);
9301     DIE_UNLESS(rc == 5);
9302   }
9303   mysql_stmt_close(stmt);
9304 
9305   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9306   myquery(rc);
9307 }
9308 
9309 
test_bad_union()9310 static void test_bad_union()
9311 {
9312   MYSQL_STMT *stmt;
9313   const char *query= "SELECT 1, 2 union SELECT 1";
9314 
9315   myheader("test_bad_union");
9316 
9317   stmt= mysql_simple_prepare(mysql, query);
9318   DIE_UNLESS(stmt == 0);
9319   myerror(NULL);
9320 }
9321 
9322 
test_distinct()9323 static void test_distinct()
9324 {
9325   MYSQL_STMT *stmt;
9326   int rc, i;
9327   const char *query=
9328     "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a";
9329 
9330   myheader("test_distinct");
9331 
9332   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9333   myquery(rc);
9334 
9335   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9336   myquery(rc);
9337 
9338   rc= mysql_query(mysql,
9339                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), \
9340 (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);");
9341   myquery(rc);
9342 
9343   for (i= 0; i < 3; i++)
9344   {
9345     stmt= mysql_simple_prepare(mysql, query);
9346     check_stmt(stmt);
9347     rc= mysql_stmt_execute(stmt);
9348     check_execute(stmt, rc);
9349     rc= my_process_stmt_result(stmt);
9350     DIE_UNLESS(rc == 5);
9351     mysql_stmt_close(stmt);
9352   }
9353 
9354   rc= mysql_query(mysql, "DROP TABLE t1");
9355   myquery(rc);
9356 }
9357 
9358 
9359 /*
9360   Test for bug#2248 "mysql_fetch without prior mysql_stmt_execute hangs"
9361 */
9362 
test_bug2248()9363 static void test_bug2248()
9364 {
9365   MYSQL_STMT *stmt;
9366   int rc;
9367   const char *query1= "SELECT DATABASE()";
9368   const char *query2= "INSERT INTO test_bug2248 VALUES (10)";
9369 
9370   myheader("test_bug2248");
9371 
9372   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248");
9373   myquery(rc);
9374 
9375   rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)");
9376   myquery(rc);
9377 
9378   stmt= mysql_simple_prepare(mysql, query1);
9379   check_stmt(stmt);
9380 
9381   /* This should not hang */
9382   rc= mysql_stmt_fetch(stmt);
9383   check_execute_r(stmt, rc);
9384 
9385   /* And this too */
9386   rc= mysql_stmt_store_result(stmt);
9387   check_execute_r(stmt, rc);
9388 
9389   mysql_stmt_close(stmt);
9390 
9391   stmt= mysql_simple_prepare(mysql, query2);
9392   check_stmt(stmt);
9393 
9394   rc= mysql_stmt_execute(stmt);
9395   check_execute(stmt, rc);
9396 
9397   /* This too should not hang but should return proper error */
9398   rc= mysql_stmt_fetch(stmt);
9399   DIE_UNLESS(rc == 1);
9400 
9401   /* This too should not hang but should not bark */
9402   rc= mysql_stmt_store_result(stmt);
9403   check_execute(stmt, rc);
9404 
9405   /* This should return proper error */
9406   rc= mysql_stmt_fetch(stmt);
9407   check_execute_r(stmt, rc);
9408   DIE_UNLESS(rc == 1);
9409 
9410   mysql_stmt_close(stmt);
9411 
9412   rc= mysql_query(mysql, "DROP TABLE test_bug2248");
9413   myquery(rc);
9414 }
9415 
9416 
test_subqueries_ref()9417 static void test_subqueries_ref()
9418 {
9419   MYSQL_STMT *stmt;
9420   int rc, i;
9421   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)";
9422 
9423   myheader("test_subqueries_ref");
9424 
9425   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9426   myquery(rc);
9427 
9428   rc= mysql_query(mysql, "CREATE TABLE t1 (a int);");
9429   myquery(rc);
9430 
9431   rc= mysql_query(mysql,
9432                   "insert into t1 values (1), (2), (3), (4), (5);");
9433   myquery(rc);
9434 
9435   stmt= mysql_simple_prepare(mysql, query);
9436   check_stmt(stmt);
9437   for (i= 0; i < 3; i++)
9438   {
9439     rc= mysql_stmt_execute(stmt);
9440     check_execute(stmt, rc);
9441     rc= my_process_stmt_result(stmt);
9442     DIE_UNLESS(rc == 1);
9443   }
9444   mysql_stmt_close(stmt);
9445 
9446   rc= mysql_query(mysql, "DROP TABLE t1");
9447   myquery(rc);
9448 }
9449 
9450 
test_union()9451 static void test_union()
9452 {
9453   MYSQL_STMT *stmt;
9454   int rc;
9455 
9456   myheader("test_union");
9457 
9458   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9459   myquery(rc);
9460 
9461   rc= mysql_query(mysql,
9462                   "CREATE TABLE t1 "
9463                   "(id INTEGER NOT NULL PRIMARY KEY, "
9464                   " name VARCHAR(20) NOT NULL)");
9465   myquery(rc);
9466   rc= mysql_query(mysql,
9467                   "INSERT INTO t1 (id, name) VALUES "
9468                   "(2, 'Ja'), (3, 'Ede'), "
9469                   "(4, 'Haag'), (5, 'Kabul'), "
9470                   "(6, 'Almere'), (7, 'Utrecht'), "
9471                   "(8, 'Qandahar'), (9, 'Amsterdam'), "
9472                   "(10, 'Amersfoort'), (11, 'Constantine')");
9473   myquery(rc);
9474   rc= mysql_query(mysql,
9475                   "CREATE TABLE t2 "
9476                   "(id INTEGER NOT NULL PRIMARY KEY, "
9477                   " name VARCHAR(20) NOT NULL)");
9478   myquery(rc);
9479   rc= mysql_query(mysql,
9480                   "INSERT INTO t2 (id, name) VALUES "
9481                   "(4, 'Guam'), (5, 'Aruba'), "
9482                   "(6, 'Angola'), (7, 'Albania'), "
9483                   "(8, 'Anguilla'), (9, 'Argentina'), "
9484                   "(10, 'Azerbaijan'), (11, 'Afghanistan'), "
9485                   "(12, 'Burkina Faso'), (13, 'Faroe Islands')");
9486   myquery(rc);
9487 
9488   stmt= mysql_simple_prepare(mysql,
9489                              "SELECT t1.name FROM t1 UNION "
9490                              "SELECT t2.name FROM t2");
9491   check_stmt(stmt);
9492 
9493   rc= mysql_stmt_execute(stmt);
9494   check_execute(stmt, rc);
9495   rc= my_process_stmt_result(stmt);
9496   DIE_UNLESS(rc == 20);
9497   mysql_stmt_close(stmt);
9498 
9499   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9500   myquery(rc);
9501 }
9502 
9503 
test_bug3117()9504 static void test_bug3117()
9505 {
9506   MYSQL_STMT *stmt;
9507   MYSQL_BIND buffer;
9508   longlong lii;
9509   ulong length;
9510   my_bool is_null;
9511   int rc;
9512 
9513   myheader("test_bug3117");
9514 
9515   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9516   myquery(rc);
9517 
9518   rc= mysql_query(mysql, "CREATE TABLE t1 (id int auto_increment primary key)");
9519   myquery(rc);
9520 
9521   stmt= mysql_simple_prepare(mysql, "SELECT LAST_INSERT_ID()");
9522   check_stmt(stmt);
9523 
9524   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9525   myquery(rc);
9526 
9527   rc= mysql_stmt_execute(stmt);
9528   check_execute(stmt, rc);
9529 
9530   bzero((char*) &buffer, sizeof(buffer));
9531   buffer.buffer_type= MYSQL_TYPE_LONGLONG;
9532   buffer.buffer_length= sizeof(lii);
9533   buffer.buffer= (void *)&lii;
9534   buffer.length= &length;
9535   buffer.is_null= &is_null;
9536 
9537   rc= mysql_stmt_bind_result(stmt, &buffer);
9538   check_execute(stmt, rc);
9539 
9540   rc= mysql_stmt_store_result(stmt);
9541   check_execute(stmt, rc);
9542 
9543   rc= mysql_stmt_fetch(stmt);
9544   check_execute(stmt, rc);
9545 
9546   DIE_UNLESS(is_null == 0 && lii == 1);
9547   if (!opt_silent)
9548     fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
9549 
9550   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9551   myquery(rc);
9552 
9553   rc= mysql_stmt_execute(stmt);
9554   check_execute(stmt, rc);
9555 
9556   rc= mysql_stmt_fetch(stmt);
9557   check_execute(stmt, rc);
9558 
9559   DIE_UNLESS(is_null == 0 && lii == 2);
9560   if (!opt_silent)
9561     fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
9562 
9563   mysql_stmt_close(stmt);
9564 
9565   rc= mysql_query(mysql, "DROP TABLE t1");
9566   myquery(rc);
9567 }
9568 
9569 
test_join()9570 static void test_join()
9571 {
9572   MYSQL_STMT *stmt;
9573   int rc, i, j;
9574   const char *query[]= {"SELECT * FROM t2 join t1 on (t1.a=t2.a)",
9575                         "SELECT * FROM t2 natural join t1",
9576                         "SELECT * FROM t2 join t1 using(a)",
9577                         "SELECT * FROM t2 left join t1 on(t1.a=t2.a)",
9578                         "SELECT * FROM t2 natural left join t1",
9579                         "SELECT * FROM t2 left join t1 using(a)",
9580                         "SELECT * FROM t2 right join t1 on(t1.a=t2.a)",
9581                         "SELECT * FROM t2 natural right join t1",
9582                         "SELECT * FROM t2 right join t1 using(a)"};
9583 
9584   myheader("test_join");
9585 
9586   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9587   myquery(rc);
9588 
9589   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9590   myquery(rc);
9591 
9592   rc= mysql_query(mysql,
9593                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9594   myquery(rc);
9595 
9596   rc= mysql_query(mysql, "CREATE TABLE t2 (a int , c int);");
9597   myquery(rc);
9598 
9599   rc= mysql_query(mysql,
9600                   "insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9601   myquery(rc);
9602 
9603   for (j= 0; j < 9; j++)
9604   {
9605     stmt= mysql_simple_prepare(mysql, query[j]);
9606     check_stmt(stmt);
9607     for (i= 0; i < 3; i++)
9608     {
9609       rc= mysql_stmt_execute(stmt);
9610       check_execute(stmt, rc);
9611       rc= my_process_stmt_result(stmt);
9612       DIE_UNLESS(rc == 5);
9613     }
9614     mysql_stmt_close(stmt);
9615   }
9616 
9617   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9618   myquery(rc);
9619 }
9620 
9621 
test_selecttmp()9622 static void test_selecttmp()
9623 {
9624   MYSQL_STMT *stmt;
9625   int rc, i;
9626   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";
9627 
9628   myheader("test_select_tmp");
9629 
9630   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3");
9631   myquery(rc);
9632 
9633   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9634   myquery(rc);
9635 
9636   rc= mysql_query(mysql, "create table t2 (a int, b int);");
9637   myquery(rc);
9638 
9639   rc= mysql_query(mysql, "create table t3 (a int, b int);");
9640   myquery(rc);
9641 
9642   rc= mysql_query(mysql,
9643                   "insert into t1 values (0, 100), (1, 2), (1, 3), (2, 2), (2, 7), \
9644 (2, -1), (3, 10);");
9645   myquery(rc);
9646   rc= mysql_query(mysql,
9647                   "insert into t2 values (0, 0), (1, 1), (2, 1), (3, 1), (4, 1);");
9648   myquery(rc);
9649   rc= mysql_query(mysql,
9650                   "insert into t3 values (3, 3), (2, 2), (1, 1);");
9651   myquery(rc);
9652 
9653   stmt= mysql_simple_prepare(mysql, query);
9654   check_stmt(stmt);
9655   for (i= 0; i < 3; i++)
9656   {
9657     rc= mysql_stmt_execute(stmt);
9658     check_execute(stmt, rc);
9659     rc= my_process_stmt_result(stmt);
9660     DIE_UNLESS(rc == 3);
9661   }
9662   mysql_stmt_close(stmt);
9663 
9664   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3");
9665   myquery(rc);
9666 }
9667 
9668 
test_create_drop()9669 static void test_create_drop()
9670 {
9671   MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select;
9672   char *query;
9673   int rc, i;
9674   myheader("test_table_manipulation");
9675 
9676   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9677   myquery(rc);
9678 
9679   rc= mysql_query(mysql, "create table t2 (a int);");
9680   myquery(rc);
9681 
9682   rc= mysql_query(mysql, "create table t1 (a int);");
9683   myquery(rc);
9684 
9685   rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);");
9686   myquery(rc);
9687 
9688   query= (char*)"create table t1 (a int)";
9689   stmt_create= mysql_simple_prepare(mysql, query);
9690   check_stmt(stmt_create);
9691 
9692   query= (char*)"drop table t1";
9693   stmt_drop= mysql_simple_prepare(mysql, query);
9694   check_stmt(stmt_drop);
9695 
9696   query= (char*)"select a in (select a from t2) from t1";
9697   stmt_select= mysql_simple_prepare(mysql, query);
9698   check_stmt(stmt_select);
9699 
9700   rc= mysql_query(mysql, "DROP TABLE t1");
9701   myquery(rc);
9702 
9703   query= (char*)"create table t1 select a from t2";
9704   stmt_create_select= mysql_simple_prepare(mysql, query);
9705   check_stmt(stmt_create_select);
9706 
9707   for (i= 0; i < 3; i++)
9708   {
9709     rc= mysql_stmt_execute(stmt_create);
9710     check_execute(stmt_create, rc);
9711     if (!opt_silent)
9712       fprintf(stdout, "created %i\n", i);
9713 
9714     rc= mysql_stmt_execute(stmt_select);
9715     check_execute(stmt_select, rc);
9716     rc= my_process_stmt_result(stmt_select);
9717     DIE_UNLESS(rc == 0);
9718 
9719     rc= mysql_stmt_execute(stmt_drop);
9720     check_execute(stmt_drop, rc);
9721     if (!opt_silent)
9722       fprintf(stdout, "dropped %i\n", i);
9723 
9724     rc= mysql_stmt_execute(stmt_create_select);
9725     check_execute(stmt_create, rc);
9726     if (!opt_silent)
9727       fprintf(stdout, "created select %i\n", i);
9728 
9729     rc= mysql_stmt_execute(stmt_select);
9730     check_execute(stmt_select, rc);
9731     rc= my_process_stmt_result(stmt_select);
9732     DIE_UNLESS(rc == 3);
9733 
9734     rc= mysql_stmt_execute(stmt_drop);
9735     check_execute(stmt_drop, rc);
9736     if (!opt_silent)
9737       fprintf(stdout, "dropped %i\n", i);
9738   }
9739 
9740   mysql_stmt_close(stmt_create);
9741   mysql_stmt_close(stmt_drop);
9742   mysql_stmt_close(stmt_select);
9743   mysql_stmt_close(stmt_create_select);
9744 
9745   rc= mysql_query(mysql, "DROP TABLE t2");
9746   myquery(rc);
9747 }
9748 
9749 
test_rename()9750 static void test_rename()
9751 {
9752   MYSQL_STMT *stmt;
9753   const char *query= "rename table t1 to t2, t3 to t4";
9754   int rc;
9755   myheader("test_table_rename");
9756 
9757   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
9758   myquery(rc);
9759 
9760   stmt= mysql_simple_prepare(mysql, query);
9761   check_stmt(stmt);
9762 
9763   rc= mysql_query(mysql, "create table t1 (a int)");
9764   myquery(rc);
9765 
9766   rc= mysql_stmt_execute(stmt);
9767   check_execute_r(stmt, rc);
9768   if (!opt_silent)
9769     fprintf(stdout, "rename without t3\n");
9770 
9771   rc= mysql_query(mysql, "create table t3 (a int)");
9772   myquery(rc);
9773 
9774   rc= mysql_stmt_execute(stmt);
9775   check_execute(stmt, rc);
9776   if (!opt_silent)
9777     fprintf(stdout, "rename with t3\n");
9778 
9779   rc= mysql_stmt_execute(stmt);
9780   check_execute_r(stmt, rc);
9781   if (!opt_silent)
9782     fprintf(stdout, "rename renamed\n");
9783 
9784   rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3");
9785   myquery(rc);
9786 
9787   rc= mysql_stmt_execute(stmt);
9788   check_execute(stmt, rc);
9789   if (!opt_silent)
9790     fprintf(stdout, "rename reverted\n");
9791 
9792   mysql_stmt_close(stmt);
9793 
9794   rc= mysql_query(mysql, "DROP TABLE t2, t4");
9795   myquery(rc);
9796 }
9797 
9798 
test_do_set()9799 static void test_do_set()
9800 {
9801   MYSQL_STMT *stmt_do, *stmt_set;
9802   char *query;
9803   int rc, i;
9804   myheader("test_do_set");
9805 
9806   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9807   myquery(rc);
9808 
9809   rc= mysql_query(mysql, "create table t1 (a int)");
9810   myquery(rc);
9811 
9812   query= (char*)"do @var:=(1 in (select * from t1))";
9813   stmt_do= mysql_simple_prepare(mysql, query);
9814   check_stmt(stmt_do);
9815 
9816   query= (char*)"set @var=(1 in (select * from t1))";
9817   stmt_set= mysql_simple_prepare(mysql, query);
9818   check_stmt(stmt_set);
9819 
9820   for (i= 0; i < 3; i++)
9821   {
9822     rc= mysql_stmt_execute(stmt_do);
9823     check_execute(stmt_do, rc);
9824     if (!opt_silent)
9825       fprintf(stdout, "do %i\n", i);
9826     rc= mysql_stmt_execute(stmt_set);
9827     check_execute(stmt_set, rc);
9828     if (!opt_silent)
9829       fprintf(stdout, "set %i\n", i);
9830   }
9831 
9832   mysql_stmt_close(stmt_do);
9833   mysql_stmt_close(stmt_set);
9834 }
9835 
9836 
test_multi()9837 static void test_multi()
9838 {
9839   MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2;
9840   char *query;
9841   MYSQL_BIND my_bind[1];
9842   int rc, i;
9843   int32 param= 1;
9844   ulong length= 1;
9845   myheader("test_multi");
9846 
9847   /*
9848     We need to bzero bind structure because mysql_stmt_bind_param checks all
9849     its members.
9850   */
9851   bzero((char*) my_bind, sizeof(my_bind));
9852 
9853   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9854   my_bind[0].buffer= (void *)&param;
9855   my_bind[0].length= &length;
9856 
9857   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9858   myquery(rc);
9859 
9860   rc= mysql_query(mysql, "create table t1 (a int, b int)");
9861   myquery(rc);
9862 
9863   rc= mysql_query(mysql, "create table t2 (a int, b int)");
9864   myquery(rc);
9865 
9866   rc= mysql_query(mysql, "insert into t1 values (3, 3), (2, 2), (1, 1)");
9867   myquery(rc);
9868 
9869   rc= mysql_query(mysql, "insert into t2 values (3, 3), (2, 2), (1, 1)");
9870   myquery(rc);
9871 
9872   query= (char*)"delete t1, t2 from t1, t2 where t1.a=t2.a and t1.b=10";
9873   stmt_delete= mysql_simple_prepare(mysql, query);
9874   check_stmt(stmt_delete);
9875 
9876   query= (char*)"update t1, t2 set t1.b=10, t2.b=10 where t1.a=t2.a and t1.b=?";
9877   stmt_update= mysql_simple_prepare(mysql, query);
9878   check_stmt(stmt_update);
9879 
9880   query= (char*)"select * from t1";
9881   stmt_select1= mysql_simple_prepare(mysql, query);
9882   check_stmt(stmt_select1);
9883 
9884   query= (char*)"select * from t2";
9885   stmt_select2= mysql_simple_prepare(mysql, query);
9886   check_stmt(stmt_select2);
9887 
9888   for(i= 0; i < 3; i++)
9889   {
9890     rc= mysql_stmt_bind_param(stmt_update, my_bind);
9891     check_execute(stmt_update, rc);
9892 
9893     rc= mysql_stmt_execute(stmt_update);
9894     check_execute(stmt_update, rc);
9895     if (!opt_silent)
9896       fprintf(stdout, "update %ld\n", (long) param);
9897 
9898     rc= mysql_stmt_execute(stmt_delete);
9899     check_execute(stmt_delete, rc);
9900     if (!opt_silent)
9901       fprintf(stdout, "delete %ld\n", (long) param);
9902 
9903     rc= mysql_stmt_execute(stmt_select1);
9904     check_execute(stmt_select1, rc);
9905     rc= my_process_stmt_result(stmt_select1);
9906     DIE_UNLESS(rc == 3-param);
9907 
9908     rc= mysql_stmt_execute(stmt_select2);
9909     check_execute(stmt_select2, rc);
9910     rc= my_process_stmt_result(stmt_select2);
9911     DIE_UNLESS(rc == 3-param);
9912 
9913     param++;
9914   }
9915 
9916   mysql_stmt_close(stmt_delete);
9917   mysql_stmt_close(stmt_update);
9918   mysql_stmt_close(stmt_select1);
9919   mysql_stmt_close(stmt_select2);
9920   rc= mysql_query(mysql, "drop table t1, t2");
9921   myquery(rc);
9922 }
9923 
9924 
test_insert_select()9925 static void test_insert_select()
9926 {
9927   MYSQL_STMT *stmt_insert, *stmt_select;
9928   char *query;
9929   int rc;
9930   uint i;
9931   myheader("test_insert_select");
9932 
9933   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9934   myquery(rc);
9935 
9936   rc= mysql_query(mysql, "create table t1 (a int)");
9937   myquery(rc);
9938 
9939   rc= mysql_query(mysql, "create table t2 (a int)");
9940   myquery(rc);
9941 
9942   rc= mysql_query(mysql, "insert into t2 values (1)");
9943   myquery(rc);
9944 
9945   query= (char*)"insert into t1 select a from t2";
9946   stmt_insert= mysql_simple_prepare(mysql, query);
9947   check_stmt(stmt_insert);
9948 
9949   query= (char*)"select * from t1";
9950   stmt_select= mysql_simple_prepare(mysql, query);
9951   check_stmt(stmt_select);
9952 
9953   for(i= 0; i < 3; i++)
9954   {
9955     rc= mysql_stmt_execute(stmt_insert);
9956     check_execute(stmt_insert, rc);
9957     if (!opt_silent)
9958       fprintf(stdout, "insert %u\n", i);
9959 
9960     rc= mysql_stmt_execute(stmt_select);
9961     check_execute(stmt_select, rc);
9962     rc= my_process_stmt_result(stmt_select);
9963     DIE_UNLESS(rc == (int)(i+1));
9964   }
9965 
9966   mysql_stmt_close(stmt_insert);
9967   mysql_stmt_close(stmt_select);
9968   rc= mysql_query(mysql, "drop table t1, t2");
9969   myquery(rc);
9970 }
9971 
9972 
test_bind_nagative()9973 static void test_bind_nagative()
9974 {
9975   MYSQL_STMT *stmt_insert;
9976   char *query;
9977   int rc;
9978   MYSQL_BIND      my_bind[1];
9979   int32           my_val= 0;
9980   ulong           my_length= 0L;
9981   my_bool         my_null= FALSE;
9982   myheader("test_insert_select");
9983 
9984   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9985   myquery(rc);
9986 
9987   rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)");
9988   myquery(rc);
9989 
9990   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)");
9991   myquery(rc);
9992 
9993   query= (char*)"INSERT INTO t1 VALUES (?)";
9994   stmt_insert= mysql_simple_prepare(mysql, query);
9995   check_stmt(stmt_insert);
9996 
9997   /* bind parameters */
9998   bzero((char*) my_bind, sizeof(my_bind));
9999 
10000   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10001   my_bind[0].buffer= (void *)&my_val;
10002   my_bind[0].length= &my_length;
10003   my_bind[0].is_null= (char*)&my_null;
10004 
10005   rc= mysql_stmt_bind_param(stmt_insert, my_bind);
10006   check_execute(stmt_insert, rc);
10007 
10008   my_val= -1;
10009   rc= mysql_stmt_execute(stmt_insert);
10010   check_execute(stmt_insert, rc);
10011 
10012   mysql_stmt_close(stmt_insert);
10013   rc= mysql_query(mysql, "drop table t1");
10014   myquery(rc);
10015 }
10016 
10017 
test_derived()10018 static void test_derived()
10019 {
10020   MYSQL_STMT *stmt;
10021   int rc, i;
10022   MYSQL_BIND      my_bind[1];
10023   int32           my_val= 0;
10024   ulong           my_length= 0L;
10025   my_bool         my_null= FALSE;
10026   const char *query=
10027     "select count(1) from (select f.id from t1 f where f.id=?) as x";
10028 
10029   myheader("test_derived");
10030 
10031   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10032   myquery(rc);
10033 
10034   rc= mysql_query(mysql, "create table t1 (id  int(8), primary key (id)) \
10035 ENGINE=InnoDB DEFAULT CHARSET=utf8");
10036   myquery(rc);
10037 
10038   rc= mysql_query(mysql, "insert into t1 values (1)");
10039   myquery(rc);
10040 
10041   stmt= mysql_simple_prepare(mysql, query);
10042   check_stmt(stmt);
10043   /*
10044     We need to bzero bind structure because mysql_stmt_bind_param checks all
10045     its members.
10046   */
10047   bzero((char*) my_bind, sizeof(my_bind));
10048 
10049   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10050   my_bind[0].buffer= (void *)&my_val;
10051   my_bind[0].length= &my_length;
10052   my_bind[0].is_null= (char*)&my_null;
10053   my_val= 1;
10054   rc= mysql_stmt_bind_param(stmt, my_bind);
10055   check_execute(stmt, rc);
10056 
10057   for (i= 0; i < 3; i++)
10058   {
10059     rc= mysql_stmt_execute(stmt);
10060     check_execute(stmt, rc);
10061     rc= my_process_stmt_result(stmt);
10062     DIE_UNLESS(rc == 1);
10063   }
10064   mysql_stmt_close(stmt);
10065 
10066   rc= mysql_query(mysql, "DROP TABLE t1");
10067   myquery(rc);
10068 }
10069 
10070 
test_xjoin()10071 static void test_xjoin()
10072 {
10073   MYSQL_STMT *stmt;
10074   int rc, i;
10075   const char *query=
10076     "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";
10077 
10078   myheader("test_xjoin");
10079 
10080   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
10081   myquery(rc);
10082 
10083   rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10084   myquery(rc);
10085 
10086   rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10087   myquery(rc);
10088 
10089   rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
10090   myquery(rc);
10091 
10092   rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10093   myquery(rc);
10094 
10095   rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)");
10096   myquery(rc);
10097 
10098   rc= mysql_query(mysql, "insert into t1 values (1, 1, 'aaa'), (2, null, 'bbb')");
10099   myquery(rc);
10100 
10101   rc= mysql_query(mysql, "insert into t2 values (1, 2, 'ccc')");
10102   myquery(rc);
10103 
10104   rc= mysql_query(mysql, "insert into t4 values (1, 'Name1'), (2, null)");
10105   myquery(rc);
10106 
10107   stmt= mysql_simple_prepare(mysql, query);
10108   check_stmt(stmt);
10109 
10110   for (i= 0; i < 3; i++)
10111   {
10112     rc= mysql_stmt_execute(stmt);
10113     check_execute(stmt, rc);
10114     rc= my_process_stmt_result(stmt);
10115     DIE_UNLESS(rc == 1);
10116   }
10117   mysql_stmt_close(stmt);
10118 
10119   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3, t4");
10120   myquery(rc);
10121 }
10122 
10123 
test_bug3035()10124 static void test_bug3035()
10125 {
10126   MYSQL_STMT *stmt;
10127   int rc;
10128   MYSQL_BIND bind_array[12], *my_bind= bind_array, *bind_end= my_bind + 12;
10129   int8 int8_val;
10130   uint8 uint8_val;
10131   int16 int16_val;
10132   uint16 uint16_val;
10133   int32 int32_val;
10134   uint32 uint32_val;
10135   longlong int64_val;
10136   ulonglong uint64_val;
10137   double double_val, udouble_val, double_tmp;
10138   char longlong_as_string[22], ulonglong_as_string[22];
10139 
10140   /* mins and maxes */
10141   const int8 int8_min= -128;
10142   const int8 int8_max= 127;
10143   const uint8 uint8_min= 0;
10144   const uint8 uint8_max= 255;
10145 
10146   const int16 int16_min= -32768;
10147   const int16 int16_max= 32767;
10148   const uint16 uint16_min= 0;
10149   const uint16 uint16_max= 65535;
10150 
10151   const int32 int32_max= 2147483647L;
10152   const int32 int32_min= -int32_max - 1;
10153   const uint32 uint32_min= 0;
10154   const uint32 uint32_max= 4294967295U;
10155 
10156   /* it might not work okay everyplace */
10157   const longlong int64_max= 9223372036854775807LL;
10158   const longlong int64_min= -int64_max - 1;
10159 
10160   const ulonglong uint64_min= 0U;
10161   const ulonglong uint64_max= 18446744073709551615ULL;
10162 
10163   const char *stmt_text;
10164 
10165   myheader("test_bug3035");
10166 
10167   stmt_text= "DROP TABLE IF EXISTS t1";
10168   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10169   myquery(rc);
10170 
10171   stmt_text= "CREATE TABLE t1 (i8 TINYINT, ui8 TINYINT UNSIGNED, "
10172                               "i16 SMALLINT, ui16 SMALLINT UNSIGNED, "
10173                               "i32 INT, ui32 INT UNSIGNED, "
10174                               "i64 BIGINT, ui64 BIGINT UNSIGNED, "
10175                               "id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT)";
10176   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10177   myquery(rc);
10178 
10179   bzero((char*) bind_array, sizeof(bind_array));
10180 
10181   for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10182     my_bind->error= &my_bind->error_value;
10183 
10184   bind_array[0].buffer_type= MYSQL_TYPE_TINY;
10185   bind_array[0].buffer= (void *) &int8_val;
10186 
10187   bind_array[1].buffer_type= MYSQL_TYPE_TINY;
10188   bind_array[1].buffer= (void *) &uint8_val;
10189   bind_array[1].is_unsigned= 1;
10190 
10191   bind_array[2].buffer_type= MYSQL_TYPE_SHORT;
10192   bind_array[2].buffer= (void *) &int16_val;
10193 
10194   bind_array[3].buffer_type= MYSQL_TYPE_SHORT;
10195   bind_array[3].buffer= (void *) &uint16_val;
10196   bind_array[3].is_unsigned= 1;
10197 
10198   bind_array[4].buffer_type= MYSQL_TYPE_LONG;
10199   bind_array[4].buffer= (void *) &int32_val;
10200 
10201   bind_array[5].buffer_type= MYSQL_TYPE_LONG;
10202   bind_array[5].buffer= (void *) &uint32_val;
10203   bind_array[5].is_unsigned= 1;
10204 
10205   bind_array[6].buffer_type= MYSQL_TYPE_LONGLONG;
10206   bind_array[6].buffer= (void *) &int64_val;
10207 
10208   bind_array[7].buffer_type= MYSQL_TYPE_LONGLONG;
10209   bind_array[7].buffer= (void *) &uint64_val;
10210   bind_array[7].is_unsigned= 1;
10211 
10212   stmt= mysql_stmt_init(mysql);
10213   check_stmt(stmt);
10214 
10215   stmt_text= "INSERT INTO t1 (i8, ui8, i16, ui16, i32, ui32, i64, ui64) "
10216                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
10217   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10218   check_execute(stmt, rc);
10219 
10220   mysql_stmt_bind_param(stmt, bind_array);
10221 
10222   int8_val= int8_min;
10223   uint8_val= uint8_min;
10224   int16_val= int16_min;
10225   uint16_val= uint16_min;
10226   int32_val= int32_min;
10227   uint32_val= uint32_min;
10228   int64_val= int64_min;
10229   uint64_val= uint64_min;
10230 
10231   rc= mysql_stmt_execute(stmt);
10232   check_execute(stmt, rc);
10233 
10234   int8_val= int8_max;
10235   uint8_val= uint8_max;
10236   int16_val= int16_max;
10237   uint16_val= uint16_max;
10238   int32_val= int32_max;
10239   uint32_val= uint32_max;
10240   int64_val= int64_max;
10241   uint64_val= uint64_max;
10242 
10243   rc= mysql_stmt_execute(stmt);
10244   check_execute(stmt, rc);
10245 
10246   stmt_text= "SELECT i8, ui8, i16, ui16, i32, ui32, i64, ui64, ui64, "
10247              "cast(ui64 as signed), ui64, cast(ui64 as signed)"
10248              "FROM t1 ORDER BY id ASC";
10249 
10250   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10251   check_execute(stmt, rc);
10252 
10253   rc= mysql_stmt_execute(stmt);
10254   check_execute(stmt, rc);
10255 
10256   bind_array[8].buffer_type= MYSQL_TYPE_DOUBLE;
10257   bind_array[8].buffer= (void *) &udouble_val;
10258 
10259   bind_array[9].buffer_type= MYSQL_TYPE_DOUBLE;
10260   bind_array[9].buffer= (void *) &double_val;
10261 
10262   bind_array[10].buffer_type= MYSQL_TYPE_STRING;
10263   bind_array[10].buffer= (void *) &ulonglong_as_string;
10264   bind_array[10].buffer_length= sizeof(ulonglong_as_string);
10265 
10266   bind_array[11].buffer_type= MYSQL_TYPE_STRING;
10267   bind_array[11].buffer= (void *) &longlong_as_string;
10268   bind_array[11].buffer_length= sizeof(longlong_as_string);
10269 
10270   mysql_stmt_bind_result(stmt, bind_array);
10271 
10272   rc= mysql_stmt_fetch(stmt);
10273   check_execute(stmt, rc);
10274 
10275   DIE_UNLESS(int8_val == int8_min);
10276   DIE_UNLESS(uint8_val == uint8_min);
10277   DIE_UNLESS(int16_val == int16_min);
10278   DIE_UNLESS(uint16_val == uint16_min);
10279   DIE_UNLESS(int32_val == int32_min);
10280   DIE_UNLESS(uint32_val == uint32_min);
10281   DIE_UNLESS(int64_val == int64_min);
10282   DIE_UNLESS(uint64_val == uint64_min);
10283   DIE_UNLESS(double_val == (longlong) uint64_min);
10284   double_tmp= ulonglong2double(uint64_val);
10285   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10286   DIE_UNLESS(!strcmp(longlong_as_string, "0"));
10287   DIE_UNLESS(!strcmp(ulonglong_as_string, "0"));
10288 
10289   rc= mysql_stmt_fetch(stmt);
10290 
10291   if (!opt_silent)
10292   {
10293     printf("Truncation mask: ");
10294     for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10295       printf("%d", (int) my_bind->error_value);
10296     printf("\n");
10297   }
10298   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0);
10299 
10300   DIE_UNLESS(int8_val == int8_max);
10301   DIE_UNLESS(uint8_val == uint8_max);
10302   DIE_UNLESS(int16_val == int16_max);
10303   DIE_UNLESS(uint16_val == uint16_max);
10304   DIE_UNLESS(int32_val == int32_max);
10305   DIE_UNLESS(uint32_val == uint32_max);
10306   DIE_UNLESS(int64_val == int64_max);
10307   DIE_UNLESS(uint64_val == uint64_max);
10308   DIE_UNLESS(double_val == (longlong) uint64_val);
10309   double_tmp= ulonglong2double(uint64_val);
10310   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10311   DIE_UNLESS(!strcmp(longlong_as_string, "-1"));
10312   DIE_UNLESS(!strcmp(ulonglong_as_string, "18446744073709551615"));
10313 
10314   rc= mysql_stmt_fetch(stmt);
10315   DIE_UNLESS(rc == MYSQL_NO_DATA);
10316 
10317   mysql_stmt_close(stmt);
10318 
10319   stmt_text= "DROP TABLE t1";
10320   mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10321 }
10322 
10323 
test_union2()10324 static void test_union2()
10325 {
10326   MYSQL_STMT *stmt;
10327   int rc, i;
10328 
10329   myheader("test_union2");
10330 
10331   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10332   myquery(rc);
10333 
10334   rc= mysql_query(mysql, "CREATE TABLE t1(col1 INT, \
10335                                          col2 VARCHAR(40),      \
10336                                          col3 SMALLINT, \
10337                                          col4 TIMESTAMP)");
10338   myquery(rc);
10339 
10340   stmt= mysql_simple_prepare(mysql,
10341                              "select col1 FROM t1 where col1=1 union distinct "
10342                              "select col1 FROM t1 where col1=2");
10343   check_stmt(stmt);
10344 
10345   for (i= 0; i < 3; i++)
10346   {
10347     rc= mysql_stmt_execute(stmt);
10348     check_execute(stmt, rc);
10349     rc= my_process_stmt_result(stmt);
10350     DIE_UNLESS(rc == 0);
10351   }
10352 
10353   mysql_stmt_close(stmt);
10354 
10355   rc= mysql_query(mysql, "DROP TABLE t1");
10356   myquery(rc);
10357 }
10358 
10359 
10360 /*
10361   This tests for various mysql_stmt_send_long_data bugs described in #1664
10362 */
10363 
test_bug1664()10364 static void test_bug1664()
10365 {
10366     MYSQL_STMT *stmt;
10367     int        rc, int_data;
10368     const char *data;
10369     const char *str_data= "Simple string";
10370     MYSQL_BIND my_bind[2];
10371     const char *query= "INSERT INTO test_long_data(col2, col1) VALUES(?, ?)";
10372 
10373     myheader("test_bug1664");
10374 
10375     rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
10376     myquery(rc);
10377 
10378     rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, col2 long varchar)");
10379     myquery(rc);
10380 
10381     stmt= mysql_stmt_init(mysql);
10382     check_stmt(stmt);
10383     rc= mysql_stmt_prepare(stmt, query, strlen(query));
10384     check_execute(stmt, rc);
10385 
10386     verify_param_count(stmt, 2);
10387 
10388     bzero((char*) my_bind, sizeof(my_bind));
10389 
10390     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10391     my_bind[0].buffer= (void *)str_data;
10392     my_bind[0].buffer_length= strlen(str_data);
10393 
10394     my_bind[1].buffer= (void *)&int_data;
10395     my_bind[1].buffer_type= MYSQL_TYPE_LONG;
10396 
10397     rc= mysql_stmt_bind_param(stmt, my_bind);
10398     check_execute(stmt, rc);
10399 
10400     int_data= 1;
10401 
10402     /*
10403       Let us supply empty long_data. This should work and should
10404       not break following execution.
10405     */
10406     data= "";
10407     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10408     check_execute(stmt, rc);
10409 
10410     rc= mysql_stmt_execute(stmt);
10411     check_execute(stmt, rc);
10412 
10413     verify_col_data("test_long_data", "col1", "1");
10414     verify_col_data("test_long_data", "col2", "");
10415 
10416     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10417     myquery(rc);
10418 
10419     /* This should pass OK */
10420     data= (char *)"Data";
10421     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10422     check_execute(stmt, rc);
10423 
10424     rc= mysql_stmt_execute(stmt);
10425     check_execute(stmt, rc);
10426 
10427     verify_col_data("test_long_data", "col1", "1");
10428     verify_col_data("test_long_data", "col2", "Data");
10429 
10430     /* clean up */
10431     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10432     myquery(rc);
10433 
10434     /*
10435       Now we are changing int parameter and don't do anything
10436       with first parameter. Second mysql_stmt_execute() should run
10437       OK treating this first parameter as string parameter.
10438     */
10439 
10440     int_data= 2;
10441     /* execute */
10442     rc= mysql_stmt_execute(stmt);
10443     check_execute(stmt, rc);
10444 
10445     verify_col_data("test_long_data", "col1", "2");
10446     verify_col_data("test_long_data", "col2", str_data);
10447 
10448     /* clean up */
10449     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10450     myquery(rc);
10451 
10452     /*
10453       Now we are sending other long data. It should not be
10454       concatened to previous.
10455     */
10456 
10457     data= (char *)"SomeOtherData";
10458     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10459     check_execute(stmt, rc);
10460 
10461     rc= mysql_stmt_execute(stmt);
10462     check_execute(stmt, rc);
10463 
10464     verify_col_data("test_long_data", "col1", "2");
10465     verify_col_data("test_long_data", "col2", "SomeOtherData");
10466 
10467     mysql_stmt_close(stmt);
10468 
10469     /* clean up */
10470     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10471     myquery(rc);
10472 
10473     /* Now let us test how mysql_stmt_reset works. */
10474     stmt= mysql_stmt_init(mysql);
10475     check_stmt(stmt);
10476     rc= mysql_stmt_prepare(stmt, query, strlen(query));
10477     check_execute(stmt, rc);
10478     rc= mysql_stmt_bind_param(stmt, my_bind);
10479     check_execute(stmt, rc);
10480 
10481     data= (char *)"SomeData";
10482     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10483     check_execute(stmt, rc);
10484 
10485     rc= mysql_stmt_reset(stmt);
10486     check_execute(stmt, rc);
10487 
10488     rc= mysql_stmt_execute(stmt);
10489     check_execute(stmt, rc);
10490 
10491     verify_col_data("test_long_data", "col1", "2");
10492     verify_col_data("test_long_data", "col2", str_data);
10493 
10494     mysql_stmt_close(stmt);
10495 
10496     /* Final clean up */
10497     rc= mysql_query(mysql, "DROP TABLE test_long_data");
10498     myquery(rc);
10499 }
10500 
10501 
test_order_param()10502 static void test_order_param()
10503 {
10504   MYSQL_STMT *stmt;
10505   int rc;
10506 
10507   myheader("test_order_param");
10508 
10509   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10510   myquery(rc);
10511 
10512   rc= mysql_query(mysql, "CREATE TABLE t1(a INT, b char(10))");
10513   myquery(rc);
10514 
10515   stmt= mysql_simple_prepare(mysql,
10516                              "select sum(a) + 200, 1 from t1 "
10517                              " union distinct "
10518                              "select sum(a) + 200, 1 from t1 group by b ");
10519   check_stmt(stmt);
10520   mysql_stmt_close(stmt);
10521 
10522   stmt= mysql_simple_prepare(mysql,
10523                              "select sum(a) + 200, ? from t1 group by b "
10524                              " union distinct "
10525                              "select sum(a) + 200, 1 from t1 group by b ");
10526   check_stmt(stmt);
10527   mysql_stmt_close(stmt);
10528 
10529   stmt= mysql_simple_prepare(mysql,
10530                              "select sum(a) + 200, ? from t1 "
10531                              " union distinct "
10532                              "select sum(a) + 200, 1 from t1 group by b ");
10533   check_stmt(stmt);
10534   mysql_stmt_close(stmt);
10535 
10536   rc= mysql_query(mysql, "DROP TABLE t1");
10537   myquery(rc);
10538 }
10539 
10540 
test_union_param()10541 static void test_union_param()
10542 {
10543   MYSQL_STMT *stmt;
10544   char *query;
10545   int rc, i;
10546   MYSQL_BIND      my_bind[2];
10547   char            my_val[4];
10548   ulong           my_length= 3L;
10549   my_bool         my_null= FALSE;
10550   myheader("test_union_param");
10551 
10552   strmov(my_val, "abc");
10553 
10554   query= (char*)"select ? as my_col union distinct select ?";
10555   stmt= mysql_simple_prepare(mysql, query);
10556   check_stmt(stmt);
10557 
10558   /*
10559     We need to bzero bind structure because mysql_stmt_bind_param checks all
10560     its members.
10561   */
10562   bzero((char*) my_bind, sizeof(my_bind));
10563 
10564   /* bind parameters */
10565   my_bind[0].buffer_type=    MYSQL_TYPE_STRING;
10566   my_bind[0].buffer=         (char*) &my_val;
10567   my_bind[0].buffer_length=  4;
10568   my_bind[0].length=         &my_length;
10569   my_bind[0].is_null=        (char*)&my_null;
10570   my_bind[1].buffer_type=    MYSQL_TYPE_STRING;
10571   my_bind[1].buffer=         (char*) &my_val;
10572   my_bind[1].buffer_length=  4;
10573   my_bind[1].length=         &my_length;
10574   my_bind[1].is_null=        (char*)&my_null;
10575 
10576   rc= mysql_stmt_bind_param(stmt, my_bind);
10577   check_execute(stmt, rc);
10578 
10579   for (i= 0; i < 3; i++)
10580   {
10581     rc= mysql_stmt_execute(stmt);
10582     check_execute(stmt, rc);
10583     rc= my_process_stmt_result(stmt);
10584     DIE_UNLESS(rc == 1);
10585   }
10586 
10587   mysql_stmt_close(stmt);
10588 }
10589 
10590 
test_ps_i18n()10591 static void test_ps_i18n()
10592 {
10593   MYSQL_STMT *stmt;
10594   int rc;
10595   const char *stmt_text;
10596   MYSQL_BIND bind_array[2];
10597 
10598   /* Represented as numbers to keep UTF8 tools from clobbering them. */
10599   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
10600   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
10601   char buf1[16], buf2[16];
10602   ulong buf1_len, buf2_len;
10603 
10604 
10605   myheader("test_ps_i18n");
10606 
10607   stmt_text= "DROP TABLE IF EXISTS t1";
10608   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10609   myquery(rc);
10610 
10611   /*
10612     Create table with binary columns, set session character set to cp1251,
10613     client character set to koi8, and make sure that there is conversion
10614     on insert and no conversion on select
10615   */
10616 
10617   stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
10618 
10619   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10620   myquery(rc);
10621 
10622   stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
10623                  "CHARACTER_SET_CONNECTION=cp1251, "
10624                  "CHARACTER_SET_RESULTS=koi8r";
10625 
10626   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10627   myquery(rc);
10628 
10629   bzero((char*) bind_array, sizeof(bind_array));
10630 
10631   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10632   bind_array[0].buffer= (void *) koi8;
10633   bind_array[0].buffer_length= strlen(koi8);
10634 
10635   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10636   bind_array[1].buffer= (void *) koi8;
10637   bind_array[1].buffer_length= strlen(koi8);
10638 
10639   stmt= mysql_stmt_init(mysql);
10640   check_stmt(stmt);
10641 
10642   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10643 
10644   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10645   check_execute(stmt, rc);
10646 
10647   mysql_stmt_bind_param(stmt, bind_array);
10648 
10649   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10650 
10651   rc= mysql_stmt_execute(stmt);
10652   check_execute(stmt, rc);
10653 
10654   stmt_text= "SELECT c1, c2 FROM t1";
10655 
10656   /* c1 and c2 are binary so no conversion will be done on select */
10657   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10658   check_execute(stmt, rc);
10659 
10660   rc= mysql_stmt_execute(stmt);
10661   check_execute(stmt, rc);
10662 
10663   bind_array[0].buffer= buf1;
10664   bind_array[0].buffer_length= sizeof(buf1);
10665   bind_array[0].length= &buf1_len;
10666 
10667   bind_array[1].buffer= buf2;
10668   bind_array[1].buffer_length= sizeof(buf2);
10669   bind_array[1].length= &buf2_len;
10670 
10671   mysql_stmt_bind_result(stmt, bind_array);
10672 
10673   rc= mysql_stmt_fetch(stmt);
10674   check_execute(stmt, rc);
10675 
10676   DIE_UNLESS(buf1_len == strlen(cp1251));
10677   DIE_UNLESS(buf2_len == strlen(cp1251));
10678   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
10679   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
10680 
10681   rc= mysql_stmt_fetch(stmt);
10682   DIE_UNLESS(rc == MYSQL_NO_DATA);
10683 
10684   stmt_text= "DROP TABLE IF EXISTS t1";
10685   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10686   myquery(rc);
10687 
10688   /*
10689     Now create table with two cp1251 columns, set client character
10690     set to koi8 and supply columns of one row as string and another as
10691     binary data. Binary data must not be converted on insert, and both
10692     columns must be converted to client character set on select.
10693   */
10694 
10695   stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
10696                               "c2 VARCHAR(255) CHARACTER SET cp1251)";
10697 
10698   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10699   myquery(rc);
10700 
10701   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10702 
10703   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10704   check_execute(stmt, rc);
10705 
10706   /* this data must be converted */
10707   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10708   bind_array[0].buffer= (void *) koi8;
10709   bind_array[0].buffer_length= strlen(koi8);
10710 
10711   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10712   bind_array[1].buffer= (void *) koi8;
10713   bind_array[1].buffer_length= strlen(koi8);
10714 
10715   mysql_stmt_bind_param(stmt, bind_array);
10716 
10717   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10718 
10719   rc= mysql_stmt_execute(stmt);
10720   check_execute(stmt, rc);
10721 
10722   /* this data must not be converted */
10723   bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
10724   bind_array[0].buffer= (void *) cp1251;
10725   bind_array[0].buffer_length= strlen(cp1251);
10726 
10727   bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
10728   bind_array[1].buffer= (void *) cp1251;
10729   bind_array[1].buffer_length= strlen(cp1251);
10730 
10731   mysql_stmt_bind_param(stmt, bind_array);
10732 
10733   mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251));
10734 
10735   rc= mysql_stmt_execute(stmt);
10736   check_execute(stmt, rc);
10737 
10738   /* Fetch data and verify that rows are in koi8 */
10739 
10740   stmt_text= "SELECT c1, c2 FROM t1";
10741 
10742   /* c1 and c2 are binary so no conversion will be done on select */
10743   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10744   check_execute(stmt, rc);
10745 
10746   rc= mysql_stmt_execute(stmt);
10747   check_execute(stmt, rc);
10748 
10749   bind_array[0].buffer= buf1;
10750   bind_array[0].buffer_length= sizeof(buf1);
10751   bind_array[0].length= &buf1_len;
10752 
10753   bind_array[1].buffer= buf2;
10754   bind_array[1].buffer_length= sizeof(buf2);
10755   bind_array[1].length= &buf2_len;
10756 
10757   mysql_stmt_bind_result(stmt, bind_array);
10758 
10759   while ((rc= mysql_stmt_fetch(stmt)) == 0)
10760   {
10761     DIE_UNLESS(buf1_len == strlen(koi8));
10762     DIE_UNLESS(buf2_len == strlen(koi8));
10763     DIE_UNLESS(!memcmp(buf1, koi8, buf1_len));
10764     DIE_UNLESS(!memcmp(buf2, koi8, buf1_len));
10765   }
10766   DIE_UNLESS(rc == MYSQL_NO_DATA);
10767   mysql_stmt_close(stmt);
10768 
10769   stmt_text= "DROP TABLE t1";
10770   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10771   myquery(rc);
10772   stmt_text= "SET NAMES DEFAULT";
10773   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10774   myquery(rc);
10775 }
10776 
10777 
test_bug3796()10778 static void test_bug3796()
10779 {
10780   MYSQL_STMT *stmt;
10781   MYSQL_BIND my_bind[1];
10782   const char *concat_arg0= "concat_with_";
10783   enum { OUT_BUFF_SIZE= 30 };
10784   char out_buff[OUT_BUFF_SIZE];
10785   char canonical_buff[OUT_BUFF_SIZE];
10786   ulong out_length;
10787   const char *stmt_text;
10788   int rc;
10789 
10790   myheader("test_bug3796");
10791 
10792   /* Create and fill test table */
10793   stmt_text= "DROP TABLE IF EXISTS t1";
10794   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10795   myquery(rc);
10796 
10797   stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))";
10798   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10799   myquery(rc);
10800 
10801   stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')";
10802   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10803   myquery(rc);
10804 
10805   /* Create statement handle and prepare it with select */
10806   stmt= mysql_stmt_init(mysql);
10807   stmt_text= "SELECT concat(?, b) FROM t1";
10808 
10809   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10810   check_execute(stmt, rc);
10811 
10812   /* Bind input buffers */
10813   bzero((char*) my_bind, sizeof(my_bind));
10814 
10815   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10816   my_bind[0].buffer= (void *) concat_arg0;
10817   my_bind[0].buffer_length= strlen(concat_arg0);
10818 
10819   mysql_stmt_bind_param(stmt, my_bind);
10820 
10821   /* Execute the select statement */
10822   rc= mysql_stmt_execute(stmt);
10823   check_execute(stmt, rc);
10824 
10825   my_bind[0].buffer= (void *) out_buff;
10826   my_bind[0].buffer_length= OUT_BUFF_SIZE;
10827   my_bind[0].length= &out_length;
10828 
10829   mysql_stmt_bind_result(stmt, my_bind);
10830 
10831   rc= mysql_stmt_fetch(stmt);
10832   if (!opt_silent)
10833     printf("Concat result: '%s'\n", out_buff);
10834   check_execute(stmt, rc);
10835   strmov(canonical_buff, concat_arg0);
10836   strcat(canonical_buff, "ONE");
10837   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10838          strncmp(out_buff, canonical_buff, out_length) == 0);
10839 
10840   rc= mysql_stmt_fetch(stmt);
10841   check_execute(stmt, rc);
10842   strmov(canonical_buff + strlen(concat_arg0), "TWO");
10843   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10844          strncmp(out_buff, canonical_buff, out_length) == 0);
10845   if (!opt_silent)
10846     printf("Concat result: '%s'\n", out_buff);
10847 
10848   rc= mysql_stmt_fetch(stmt);
10849   DIE_UNLESS(rc == MYSQL_NO_DATA);
10850 
10851   mysql_stmt_close(stmt);
10852 
10853   stmt_text= "DROP TABLE IF EXISTS t1";
10854   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10855   myquery(rc);
10856 }
10857 
10858 
test_bug4026()10859 static void test_bug4026()
10860 {
10861   MYSQL_STMT *stmt;
10862   MYSQL_BIND my_bind[2];
10863   MYSQL_TIME time_in, time_out;
10864   MYSQL_TIME datetime_in, datetime_out;
10865   const char *stmt_text;
10866   int rc;
10867 
10868   myheader("test_bug4026");
10869 
10870   /* Check that microseconds are inserted and selected successfully */
10871 
10872   /* Create a statement handle and prepare it with select */
10873   stmt= mysql_stmt_init(mysql);
10874   stmt_text= "SELECT ?, ?";
10875 
10876   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10877   check_execute(stmt, rc);
10878 
10879   /* Bind input buffers */
10880   bzero((char*) my_bind, sizeof(my_bind));
10881   bzero((char*) &time_in, sizeof(time_in));
10882   bzero((char*) &time_out, sizeof(time_out));
10883   bzero((char*) &datetime_in, sizeof(datetime_in));
10884   bzero((char*) &datetime_out, sizeof(datetime_out));
10885 
10886   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
10887   my_bind[0].buffer= (void *) &time_in;
10888   my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
10889   my_bind[1].buffer= (void *) &datetime_in;
10890 
10891   time_in.hour= 23;
10892   time_in.minute= 59;
10893   time_in.second= 59;
10894   time_in.second_part= 123456;
10895   /*
10896     This is not necessary, just to make DIE_UNLESS below work: this field
10897     is filled in when time is received from server
10898   */
10899   time_in.time_type= MYSQL_TIMESTAMP_TIME;
10900 
10901   datetime_in= time_in;
10902   datetime_in.year= 2003;
10903   datetime_in.month= 12;
10904   datetime_in.day= 31;
10905   datetime_in.time_type= MYSQL_TIMESTAMP_DATETIME;
10906 
10907   mysql_stmt_bind_param(stmt, my_bind);
10908 
10909   /* Execute the select statement */
10910   rc= mysql_stmt_execute(stmt);
10911   check_execute(stmt, rc);
10912 
10913   my_bind[0].buffer= (void *) &time_out;
10914   my_bind[1].buffer= (void *) &datetime_out;
10915 
10916   mysql_stmt_bind_result(stmt, my_bind);
10917 
10918   rc= mysql_stmt_fetch(stmt);
10919   DIE_UNLESS(rc == 0);
10920   if (!opt_silent)
10921   {
10922     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
10923            time_out.second_part);
10924     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
10925            datetime_out.day, datetime_out.hour,
10926            datetime_out.minute, datetime_out.second,
10927            datetime_out.second_part);
10928   }
10929   DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0);
10930   DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0);
10931   mysql_stmt_close(stmt);
10932 }
10933 
10934 
test_bug4079()10935 static void test_bug4079()
10936 {
10937   MYSQL_STMT *stmt;
10938   MYSQL_BIND my_bind[1];
10939   const char *stmt_text;
10940   uint32 res;
10941   int rc;
10942 
10943   myheader("test_bug4079");
10944 
10945   /* Create and fill table */
10946   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10947   mysql_query(mysql, "CREATE TABLE t1 (a int)");
10948   mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2)");
10949 
10950   /* Prepare erroneous statement */
10951   stmt= mysql_stmt_init(mysql);
10952   stmt_text= "SELECT 1 < (SELECT a FROM t1)";
10953 
10954   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10955   check_execute(stmt, rc);
10956 
10957   /* Execute the select statement */
10958   rc= mysql_stmt_execute(stmt);
10959   check_execute(stmt, rc);
10960 
10961   /* Bind input buffers */
10962   bzero((char*) my_bind, sizeof(my_bind));
10963 
10964   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10965   my_bind[0].buffer= (void *) &res;
10966 
10967   mysql_stmt_bind_result(stmt, my_bind);
10968 
10969   rc= mysql_stmt_fetch(stmt);
10970   DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA);
10971   if (!opt_silent)
10972     printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
10973            mysql_stmt_error(stmt));
10974   /* buggy version of libmysql hanged up here */
10975   mysql_stmt_close(stmt);
10976 }
10977 
10978 
test_bug4236()10979 static void test_bug4236()
10980 {
10981   MYSQL_STMT *stmt;
10982   const char *stmt_text;
10983   int rc;
10984   MYSQL_STMT backup;
10985 
10986   myheader("test_bug4236");
10987 
10988   stmt= mysql_stmt_init(mysql);
10989 
10990   /* mysql_stmt_execute() of statement with statement id= 0 crashed server */
10991   stmt_text= "SELECT 1";
10992   /* We need to prepare statement to pass by possible check in libmysql */
10993   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10994   check_execute(stmt, rc);
10995   /* Hack to check that server works OK if statement wasn't found */
10996   backup.stmt_id= stmt->stmt_id;
10997   stmt->stmt_id= 0;
10998   rc= mysql_stmt_execute(stmt);
10999   DIE_UNLESS(rc);
11000   /* Restore original statement id to be able to reprepare it */
11001   stmt->stmt_id= backup.stmt_id;
11002 
11003   mysql_stmt_close(stmt);
11004 }
11005 
11006 
test_bug4030()11007 static void test_bug4030()
11008 {
11009   MYSQL_STMT *stmt;
11010   MYSQL_BIND my_bind[3];
11011   MYSQL_TIME time_canonical, time_out;
11012   MYSQL_TIME date_canonical, date_out;
11013   MYSQL_TIME datetime_canonical, datetime_out;
11014   const char *stmt_text;
11015   int rc;
11016 
11017   myheader("test_bug4030");
11018 
11019   /* Check that microseconds are inserted and selected successfully */
11020 
11021   /* Execute a query with time values in prepared mode */
11022   stmt= mysql_stmt_init(mysql);
11023   stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
11024              "'2003-12-31 23:59:59.123456'";
11025   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11026   check_execute(stmt, rc);
11027   rc= mysql_stmt_execute(stmt);
11028   check_execute(stmt, rc);
11029 
11030   /* Bind output buffers */
11031   bzero((char*) my_bind, sizeof(my_bind));
11032   bzero((char*) &time_canonical, sizeof(time_canonical));
11033   bzero((char*) &time_out, sizeof(time_out));
11034   bzero((char*) &date_canonical, sizeof(date_canonical));
11035   bzero((char*) &date_out, sizeof(date_out));
11036   bzero((char*) &datetime_canonical, sizeof(datetime_canonical));
11037   bzero((char*) &datetime_out, sizeof(datetime_out));
11038 
11039   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
11040   my_bind[0].buffer= (void *) &time_out;
11041   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11042   my_bind[1].buffer= (void *) &date_out;
11043   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
11044   my_bind[2].buffer= (void *) &datetime_out;
11045 
11046   time_canonical.hour= 23;
11047   time_canonical.minute= 59;
11048   time_canonical.second= 59;
11049   time_canonical.second_part= 123456;
11050   time_canonical.time_type= MYSQL_TIMESTAMP_TIME;
11051 
11052   date_canonical.year= 2003;
11053   date_canonical.month= 12;
11054   date_canonical.day= 31;
11055   date_canonical.time_type= MYSQL_TIMESTAMP_DATE;
11056 
11057   datetime_canonical= time_canonical;
11058   datetime_canonical.year= 2003;
11059   datetime_canonical.month= 12;
11060   datetime_canonical.day= 31;
11061   datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME;
11062 
11063   mysql_stmt_bind_result(stmt, my_bind);
11064 
11065   rc= mysql_stmt_fetch(stmt);
11066   DIE_UNLESS(rc == 0);
11067   if (!opt_silent)
11068   {
11069     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
11070            time_out.second_part);
11071     printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
11072     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
11073            datetime_out.day, datetime_out.hour,
11074            datetime_out.minute, datetime_out.second,
11075            datetime_out.second_part);
11076   }
11077   DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
11078   DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
11079   DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
11080   mysql_stmt_close(stmt);
11081 }
11082 
test_view()11083 static void test_view()
11084 {
11085   MYSQL_STMT *stmt;
11086   int rc, i;
11087   MYSQL_BIND      my_bind[1];
11088   char            str_data[50];
11089   ulong           length = 0L;
11090   long            is_null = 0L;
11091   const char *query=
11092     "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
11093 
11094   myheader("test_view");
11095 
11096   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
11097   myquery(rc);
11098 
11099   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
11100   myquery(rc);
11101   rc= mysql_query(mysql,"CREATE TABLE t1 ("
11102                         " SERVERGRP varchar(20) NOT NULL default '', "
11103                         " DBINSTANCE varchar(20) NOT NULL default '', "
11104                         " PRIMARY KEY  (SERVERGRP)) "
11105                         " CHARSET=latin1 collate=latin1_bin");
11106   myquery(rc);
11107   rc= mysql_query(mysql,"CREATE TABLE t2 ("
11108                         " SERVERNAME varchar(20) NOT NULL, "
11109                         " SERVERGRP varchar(20) NOT NULL, "
11110                         " PRIMARY KEY (SERVERNAME)) "
11111                         " CHARSET=latin1 COLLATE latin1_bin");
11112   myquery(rc);
11113   rc= mysql_query(mysql,
11114                   "CREATE TABLE t3 ("
11115                   " SERVERGRP varchar(20) BINARY NOT NULL, "
11116                   " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
11117                   " ACTSTATE char(1) NOT NULL , "
11118                   " LOCAL_NAME varchar(30) NOT NULL, "
11119                   " CHG_DATE varchar(8) NOT NULL default '00000000', "
11120                   " CHG_TIME varchar(6) NOT NULL default '000000', "
11121                   " MXUSER varchar(12) NOT NULL default '', "
11122                   " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
11123                   " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
11124   myquery(rc);
11125   rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
11126                   " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
11127                   " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
11128                   " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
11129                   " ((T0002.SERVERGRP = T0001.SERVERGRP) and"
11130                   " (T0002.SERVERGRP = T0003.SERVERGRP)"
11131                   " and (T0003.MAPSTATE = _latin1'A') and"
11132                   " (T0003.ACTSTATE = _latin1' '))");
11133   myquery(rc);
11134 
11135   stmt= mysql_stmt_init(mysql);
11136   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11137   check_execute(stmt, rc);
11138 
11139   strmov(str_data, "TEST");
11140   bzero((char*) my_bind, sizeof(my_bind));
11141   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
11142   my_bind[0].buffer= (char *)&str_data;
11143   my_bind[0].buffer_length= 50;
11144   my_bind[0].length= &length;
11145   length= 4;
11146   my_bind[0].is_null= (char*)&is_null;
11147   rc= mysql_stmt_bind_param(stmt, my_bind);
11148   check_execute(stmt,rc);
11149 
11150   for (i= 0; i < 3; i++)
11151   {
11152     rc= mysql_stmt_execute(stmt);
11153     check_execute(stmt, rc);
11154     rc= my_process_stmt_result(stmt);
11155     DIE_UNLESS(1 == rc);
11156   }
11157   mysql_stmt_close(stmt);
11158 
11159   rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
11160   myquery(rc);
11161   rc= mysql_query(mysql, "DROP VIEW v1");
11162   myquery(rc);
11163 }
11164 
11165 
test_view_where()11166 static void test_view_where()
11167 {
11168   MYSQL_STMT *stmt;
11169   int rc, i;
11170   const char *query=
11171     "select v1.c,v2.c from v1, v2";
11172 
11173   myheader("test_view_where");
11174 
11175   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2");
11176   myquery(rc);
11177 
11178   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1");
11179   myquery(rc);
11180   rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)");
11181   myquery(rc);
11182   rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)");
11183   myquery(rc);
11184   rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3");
11185   myquery(rc);
11186   rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3");
11187   myquery(rc);
11188 
11189   stmt= mysql_stmt_init(mysql);
11190   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11191   check_execute(stmt, rc);
11192 
11193   for (i= 0; i < 3; i++)
11194   {
11195     rc= mysql_stmt_execute(stmt);
11196     check_execute(stmt, rc);
11197     rc= my_process_stmt_result(stmt);
11198     DIE_UNLESS(4 == rc);
11199   }
11200   mysql_stmt_close(stmt);
11201 
11202   rc= mysql_query(mysql, "DROP TABLE t1");
11203   myquery(rc);
11204   rc= mysql_query(mysql, "DROP VIEW v1, v2");
11205   myquery(rc);
11206 }
11207 
11208 
test_view_2where()11209 static void test_view_2where()
11210 {
11211   MYSQL_STMT *stmt;
11212   int rc, i;
11213   MYSQL_BIND      my_bind[8];
11214   char            parms[8][100];
11215   ulong           length[8];
11216   const char *query=
11217     "select relid, report, handle, log_group, username, variant, type, "
11218     "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
11219     "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
11220     "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";
11221 
11222   myheader("test_view_2where");
11223 
11224   rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
11225   myquery(rc);
11226   rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
11227   myquery(rc);
11228   rc= mysql_query(mysql,
11229                   "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
11230                   " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
11231                   " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
11232                   " USERNAME varchar(12) NOT NULL,"
11233                   " VARIANT varchar(12) NOT NULL,"
11234                   " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
11235                   " VERSION varchar(6) NOT NULL default '000000',"
11236                   " ERFDAT varchar(8) NOT NULL default '00000000',"
11237                   " ERFTIME varchar(6) NOT NULL default '000000',"
11238                   " ERFNAME varchar(12) NOT NULL,"
11239                   " AEDAT varchar(8) NOT NULL default '00000000',"
11240                   " AETIME varchar(6) NOT NULL default '000000',"
11241                   " AENAME varchar(12) NOT NULL,"
11242                   " DEPENDVARS varchar(10) NOT NULL,"
11243                   " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
11244                   " CLUSTD blob,"
11245                   " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
11246                                 "USERNAME, VARIANT, TYPE, SRTF2))"
11247                  " CHARSET=latin1 COLLATE latin1_bin");
11248   myquery(rc);
11249   rc= mysql_query(mysql,
11250                   "CREATE VIEW V_LTDX AS select T0001.MANDT AS "
11251                   " MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
11252                   " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
11253                   " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
11254                   " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
11255                   " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
11256                   " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
11257                   " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
11258                   " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
11259                   " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
11260   myquery(rc);
11261   bzero((char*) my_bind, sizeof(my_bind));
11262   for (i=0; i < 8; i++) {
11263     strmov(parms[i], "1");
11264     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11265     my_bind[i].buffer = (char *)&parms[i];
11266     my_bind[i].buffer_length = 100;
11267     my_bind[i].is_null = 0;
11268     my_bind[i].length = &length[i];
11269     length[i] = 1;
11270   }
11271   stmt= mysql_stmt_init(mysql);
11272   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11273   check_execute(stmt, rc);
11274 
11275   rc= mysql_stmt_bind_param(stmt, my_bind);
11276   check_execute(stmt,rc);
11277 
11278   rc= mysql_stmt_execute(stmt);
11279   check_execute(stmt, rc);
11280   rc= my_process_stmt_result(stmt);
11281   DIE_UNLESS(0 == rc);
11282 
11283   mysql_stmt_close(stmt);
11284 
11285   rc= mysql_query(mysql, "DROP VIEW V_LTDX");
11286   myquery(rc);
11287   rc= mysql_query(mysql, "DROP TABLE LTDX");
11288   myquery(rc);
11289 }
11290 
11291 
test_view_star()11292 static void test_view_star()
11293 {
11294   MYSQL_STMT *stmt;
11295   int rc, i;
11296   MYSQL_BIND      my_bind[8];
11297   char            parms[8][100];
11298   ulong           length[8];
11299   const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)";
11300 
11301   myheader("test_view_star");
11302 
11303   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1");
11304   myquery(rc);
11305   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1");
11306   myquery(rc);
11307   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
11308   myquery(rc);
11309   rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1");
11310   myquery(rc);
11311   bzero((char*) my_bind, sizeof(my_bind));
11312   for (i= 0; i < 2; i++) {
11313     sprintf((char *)&parms[i], "%d", i);
11314     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11315     my_bind[i].buffer = (char *)&parms[i];
11316     my_bind[i].buffer_length = 100;
11317     my_bind[i].is_null = 0;
11318     my_bind[i].length = &length[i];
11319     length[i] = 1;
11320   }
11321 
11322   stmt= mysql_stmt_init(mysql);
11323   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11324   check_execute(stmt, rc);
11325 
11326   rc= mysql_stmt_bind_param(stmt, my_bind);
11327   check_execute(stmt,rc);
11328 
11329   for (i= 0; i < 3; i++)
11330   {
11331     rc= mysql_stmt_execute(stmt);
11332     check_execute(stmt, rc);
11333     rc= my_process_stmt_result(stmt);
11334     DIE_UNLESS(0 == rc);
11335   }
11336 
11337   mysql_stmt_close(stmt);
11338 
11339   rc= mysql_query(mysql, "DROP TABLE t1");
11340   myquery(rc);
11341   rc= mysql_query(mysql, "DROP VIEW vt1");
11342   myquery(rc);
11343 }
11344 
11345 
test_view_insert()11346 static void test_view_insert()
11347 {
11348   MYSQL_STMT *insert_stmt, *select_stmt;
11349   int rc, i;
11350   MYSQL_BIND      my_bind[1];
11351   int             my_val = 0;
11352   ulong           my_length = 0L;
11353   long            my_null = 0L;
11354   const char *query=
11355     "insert into v1 values (?)";
11356 
11357   myheader("test_view_insert");
11358 
11359   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11360   myquery(rc);
11361   rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1");
11362   myquery(rc);
11363 
11364   rc= mysql_query(mysql,"create table t1 (a int, primary key (a))");
11365   myquery(rc);
11366 
11367   rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1");
11368   myquery(rc);
11369 
11370   insert_stmt= mysql_stmt_init(mysql);
11371   rc= mysql_stmt_prepare(insert_stmt, query, strlen(query));
11372   check_execute(insert_stmt, rc);
11373   query= "select * from t1";
11374   select_stmt= mysql_stmt_init(mysql);
11375   rc= mysql_stmt_prepare(select_stmt, query, strlen(query));
11376   check_execute(select_stmt, rc);
11377 
11378   bzero((char*) my_bind, sizeof(my_bind));
11379   my_bind[0].buffer_type = MYSQL_TYPE_LONG;
11380   my_bind[0].buffer = (char *)&my_val;
11381   my_bind[0].length = &my_length;
11382   my_bind[0].is_null = (char*)&my_null;
11383   rc= mysql_stmt_bind_param(insert_stmt, my_bind);
11384   check_execute(insert_stmt, rc);
11385 
11386   for (i= 0; i < 3; i++)
11387   {
11388     int rowcount= 0;
11389     my_val= i;
11390 
11391     rc= mysql_stmt_execute(insert_stmt);
11392     check_execute(insert_stmt, rc);
11393 
11394     rc= mysql_stmt_execute(select_stmt);
11395     check_execute(select_stmt, rc);
11396     rowcount= (int)my_process_stmt_result(select_stmt);
11397     DIE_UNLESS((i+1) == rowcount);
11398   }
11399   mysql_stmt_close(insert_stmt);
11400   mysql_stmt_close(select_stmt);
11401 
11402   rc= mysql_query(mysql, "DROP VIEW v1");
11403   myquery(rc);
11404   rc= mysql_query(mysql, "DROP TABLE t1");
11405   myquery(rc);
11406 }
11407 
11408 
test_left_join_view()11409 static void test_left_join_view()
11410 {
11411   MYSQL_STMT *stmt;
11412   int rc, i;
11413   const char *query=
11414     "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);";
11415 
11416   myheader("test_left_join_view");
11417 
11418   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11419   myquery(rc);
11420 
11421   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1");
11422   myquery(rc);
11423   rc= mysql_query(mysql,"CREATE TABLE t1 (a int)");
11424   myquery(rc);
11425   rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)");
11426   myquery(rc);
11427   rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1");
11428   myquery(rc);
11429   stmt= mysql_stmt_init(mysql);
11430   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11431   check_execute(stmt, rc);
11432 
11433   for (i= 0; i < 3; i++)
11434   {
11435     rc= mysql_stmt_execute(stmt);
11436     check_execute(stmt, rc);
11437     rc= my_process_stmt_result(stmt);
11438     DIE_UNLESS(3 == rc);
11439   }
11440   mysql_stmt_close(stmt);
11441 
11442   rc= mysql_query(mysql, "DROP VIEW v1");
11443   myquery(rc);
11444   rc= mysql_query(mysql, "DROP TABLE t1");
11445   myquery(rc);
11446 }
11447 
11448 
test_view_insert_fields()11449 static void test_view_insert_fields()
11450 {
11451   MYSQL_STMT	*stmt;
11452   char		parm[11][1000];
11453   ulong         l[11];
11454   int		rc, i;
11455   MYSQL_BIND	my_bind[11];
11456   const char    *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";
11457 
11458   myheader("test_view_insert_fields");
11459 
11460   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
11461   myquery(rc);
11462   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
11463   myquery(rc);
11464   rc= mysql_query(mysql,
11465                   "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
11466                   "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
11467                   "K4N4 varchar(4) NOT NULL default '0000',"
11468                   "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
11469                   "F3N5 varchar(5) NOT NULL default '00000',"
11470                   "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
11471                   "F6N4 varchar(4) NOT NULL default '0000',"
11472                   "F7F8 double NOT NULL default '0',"
11473                   "F8F8 double NOT NULL default '0',"
11474                   "F9D8 decimal(8,2) NOT NULL default '0.00',"
11475                   "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
11476                   "CHARSET=latin1 COLLATE latin1_bin");
11477   myquery(rc);
11478   rc= mysql_query(mysql,
11479                   "CREATE VIEW v1 AS select sql_no_cache "
11480                   " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
11481                   " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
11482                   " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
11483                   " from t1 T0001");
11484 
11485   bzero((char*) my_bind, sizeof(my_bind));
11486   for (i= 0; i < 11; i++)
11487   {
11488     l[i]= 20;
11489     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
11490     my_bind[i].is_null= 0;
11491     my_bind[i].buffer= (char *)&parm[i];
11492 
11493     strmov(parm[i], "1");
11494     my_bind[i].buffer_length= 2;
11495     my_bind[i].length= &l[i];
11496   }
11497   stmt= mysql_stmt_init(mysql);
11498   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11499   check_execute(stmt, rc);
11500   rc= mysql_stmt_bind_param(stmt, my_bind);
11501   check_execute(stmt, rc);
11502 
11503   rc= mysql_stmt_execute(stmt);
11504   check_execute(stmt, rc);
11505   mysql_stmt_close(stmt);
11506 
11507   query= "select * from t1";
11508   stmt= mysql_stmt_init(mysql);
11509   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11510   check_execute(stmt, rc);
11511   rc= mysql_stmt_execute(stmt);
11512   check_execute(stmt, rc);
11513   rc= my_process_stmt_result(stmt);
11514   DIE_UNLESS(1 == rc);
11515 
11516   mysql_stmt_close(stmt);
11517   rc= mysql_query(mysql, "DROP VIEW v1");
11518   myquery(rc);
11519   rc= mysql_query(mysql, "DROP TABLE t1");
11520   myquery(rc);
11521 
11522 }
11523 
test_bug5126()11524 static void test_bug5126()
11525 {
11526   MYSQL_STMT *stmt;
11527   MYSQL_BIND my_bind[2];
11528   int32 c1, c2;
11529   const char *stmt_text;
11530   int rc;
11531 
11532   myheader("test_bug5126");
11533 
11534   stmt_text= "DROP TABLE IF EXISTS t1";
11535   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11536   myquery(rc);
11537 
11538   stmt_text= "CREATE TABLE t1 (a mediumint, b int)";
11539   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11540   myquery(rc);
11541 
11542   stmt_text= "INSERT INTO t1 VALUES (8386608, 1)";
11543   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11544   myquery(rc);
11545 
11546   stmt= mysql_stmt_init(mysql);
11547   stmt_text= "SELECT a, b FROM t1";
11548   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11549   check_execute(stmt, rc);
11550   rc= mysql_stmt_execute(stmt);
11551   check_execute(stmt, rc);
11552 
11553   /* Bind output buffers */
11554   bzero((char*) my_bind, sizeof(my_bind));
11555 
11556   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11557   my_bind[0].buffer= &c1;
11558   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
11559   my_bind[1].buffer= &c2;
11560 
11561   mysql_stmt_bind_result(stmt, my_bind);
11562 
11563   rc= mysql_stmt_fetch(stmt);
11564   DIE_UNLESS(rc == 0);
11565   DIE_UNLESS(c1 == 8386608 && c2 == 1);
11566   if (!opt_silent)
11567     printf("%ld, %ld\n", (long) c1, (long) c2);
11568   mysql_stmt_close(stmt);
11569 }
11570 
11571 
test_bug4231()11572 static void test_bug4231()
11573 {
11574   MYSQL_STMT *stmt;
11575   MYSQL_BIND my_bind[2];
11576   MYSQL_TIME tm[2];
11577   const char *stmt_text;
11578   int rc;
11579 
11580   myheader("test_bug4231");
11581 
11582   stmt_text= "DROP TABLE IF EXISTS t1";
11583   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11584   myquery(rc);
11585 
11586   stmt_text= "CREATE TABLE t1 (a int)";
11587   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11588   myquery(rc);
11589 
11590   stmt_text= "INSERT INTO t1 VALUES (1)";
11591   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11592   myquery(rc);
11593 
11594   stmt= mysql_stmt_init(mysql);
11595   stmt_text= "SELECT a FROM t1 WHERE ? = ?";
11596   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11597   check_execute(stmt, rc);
11598 
11599   /* Bind input buffers */
11600   bzero((char*) my_bind, sizeof(my_bind));
11601   bzero((char*) tm, sizeof(tm));
11602 
11603   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
11604   my_bind[0].buffer= &tm[0];
11605   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11606   my_bind[1].buffer= &tm[1];
11607 
11608   mysql_stmt_bind_param(stmt, my_bind);
11609   check_execute(stmt, rc);
11610 
11611   /*
11612     First set server-side params to some non-zero non-equal values:
11613     then we will check that they are not used when client sends
11614     new (zero) times.
11615   */
11616   tm[0].time_type = MYSQL_TIMESTAMP_DATE;
11617   tm[0].year = 2000;
11618   tm[0].month = 1;
11619   tm[0].day = 1;
11620   tm[1]= tm[0];
11621   --tm[1].year;                                 /* tm[0] != tm[1] */
11622 
11623   rc= mysql_stmt_execute(stmt);
11624   check_execute(stmt, rc);
11625 
11626   rc= mysql_stmt_fetch(stmt);
11627 
11628   /* binds are unequal, no rows should be returned */
11629   DIE_UNLESS(rc == MYSQL_NO_DATA);
11630 
11631   /* Set one of the dates to zero */
11632   tm[0].year= tm[0].month= tm[0].day= 0;
11633   tm[1]= tm[0];
11634   mysql_stmt_execute(stmt);
11635   rc= mysql_stmt_fetch(stmt);
11636   DIE_UNLESS(rc == 0);
11637 
11638   mysql_stmt_close(stmt);
11639   stmt_text= "DROP TABLE t1";
11640   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11641   myquery(rc);
11642 }
11643 
11644 
test_bug5399()11645 static void test_bug5399()
11646 {
11647   /*
11648     Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
11649     statement id hash in the server uses binary collation.
11650   */
11651 #define NUM_OF_USED_STMT 97
11652   MYSQL_STMT *stmt_list[NUM_OF_USED_STMT];
11653   MYSQL_STMT **stmt;
11654   MYSQL_BIND my_bind[1];
11655   char buff[600];
11656   int rc;
11657   int32 no;
11658 
11659   myheader("test_bug5399");
11660 
11661   bzero((char*) my_bind, sizeof(my_bind));
11662   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11663   my_bind[0].buffer= &no;
11664 
11665   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11666   {
11667     sprintf(buff, "select %d", (int) (stmt - stmt_list));
11668     *stmt= mysql_stmt_init(mysql);
11669     rc= mysql_stmt_prepare(*stmt, buff, strlen(buff));
11670     check_execute(*stmt, rc);
11671     mysql_stmt_bind_result(*stmt, my_bind);
11672   }
11673   if (!opt_silent)
11674     printf("%d statements prepared.\n", NUM_OF_USED_STMT);
11675 
11676   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11677   {
11678     rc= mysql_stmt_execute(*stmt);
11679     check_execute(*stmt, rc);
11680     rc= mysql_stmt_store_result(*stmt);
11681     check_execute(*stmt, rc);
11682     rc= mysql_stmt_fetch(*stmt);
11683     DIE_UNLESS(rc == 0);
11684     DIE_UNLESS((int32) (stmt - stmt_list) == no);
11685   }
11686 
11687   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11688     mysql_stmt_close(*stmt);
11689 #undef NUM_OF_USED_STMT
11690 }
11691 
11692 
test_bug5194()11693 static void test_bug5194()
11694 {
11695   MYSQL_STMT *stmt;
11696   MYSQL_BIND *my_bind;
11697   char *query;
11698   char *param_str;
11699   int param_str_length;
11700   const char *stmt_text;
11701   int rc;
11702   float float_array[250] =
11703   {
11704     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11705     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11706     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11707     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11708     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11709     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11710     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11711     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11712     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11713     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11714     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11715     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11716     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11717     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11718     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11719     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11720     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11721     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11722     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11723     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11724     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11725     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11726     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11727     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11728     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25
11729   };
11730   float *fa_ptr= float_array;
11731   /* Number of columns per row */
11732   const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array);
11733   /* Number of rows per bulk insert to start with */
11734   const int MIN_ROWS_PER_INSERT= 262;
11735   /* Max number of rows per bulk insert to end with */
11736   const int MAX_ROWS_PER_INSERT= 300;
11737   const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT;
11738   const char *query_template= "insert into t1 values %s";
11739   const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */
11740   const int uint16_max= 65535;
11741   int nrows, i;
11742 
11743   myheader("test_bug5194");
11744 
11745   stmt_text= "drop table if exists t1";
11746   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11747 
11748   stmt_text= "create table if not exists t1"
11749    "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, "
11750    "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, "
11751    "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, "
11752    "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, "
11753    "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, "
11754    "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, "
11755    "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, "
11756    "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, "
11757    "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, "
11758    "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, "
11759    "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, "
11760    "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, "
11761    "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, "
11762    "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, "
11763    "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, "
11764    "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, "
11765    "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, "
11766    "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, "
11767    "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, "
11768    "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, "
11769    "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, "
11770    "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, "
11771    "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, "
11772    "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, "
11773    "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, "
11774    "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, "
11775    "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, "
11776    "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, "
11777    "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, "
11778    "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, "
11779    "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, "
11780    "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, "
11781    "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, "
11782    "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, "
11783    "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, "
11784    "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, "
11785    "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, "
11786    "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, "
11787    "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, "
11788    "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, "
11789    "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, "
11790    "c247 float, c248 float, c249 float, c250 float)";
11791   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11792   myquery(rc);
11793 
11794   my_bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11795   query= (char*) malloc(strlen(query_template) +
11796                         MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
11797   param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
11798 
11799   if (my_bind == 0 || query == 0 || param_str == 0)
11800   {
11801     fprintf(stderr, "Can't allocate enough memory for query structs\n");
11802     if (my_bind)
11803       free(my_bind);
11804     if (query)
11805       free(query);
11806     if (param_str)
11807       free(param_str);
11808     return;
11809   }
11810 
11811   stmt= mysql_stmt_init(mysql);
11812 
11813   /* setup a template for one row of parameters */
11814   sprintf(param_str, "(");
11815   for (i= 1; i < COLUMN_COUNT; ++i)
11816     strcat(param_str, "?, ");
11817   strcat(param_str, "?)");
11818   param_str_length= strlen(param_str);
11819 
11820   /* setup bind array */
11821   bzero((char*) my_bind, MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11822   for (i= 0; i < MAX_PARAM_COUNT; ++i)
11823   {
11824     my_bind[i].buffer_type= MYSQL_TYPE_FLOAT;
11825     my_bind[i].buffer= fa_ptr;
11826     if (++fa_ptr == float_array + COLUMN_COUNT)
11827       fa_ptr= float_array;
11828   }
11829 
11830   /*
11831     Test each number of rows per bulk insert, so that we can see where
11832     MySQL fails.
11833   */
11834   for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows)
11835   {
11836     char *query_ptr;
11837     /* Create statement text for current number of rows */
11838     sprintf(query, query_template, param_str);
11839     query_ptr= query + strlen(query);
11840     for (i= 1; i < nrows; ++i)
11841     {
11842       memcpy(query_ptr, ", ", 2);
11843       query_ptr+= 2;
11844       memcpy(query_ptr, param_str, param_str_length);
11845       query_ptr+= param_str_length;
11846     }
11847     *query_ptr= '\0';
11848 
11849     rc= mysql_stmt_prepare(stmt, query, (ulong)(query_ptr - query));
11850     if (rc && nrows * COLUMN_COUNT > uint16_max)
11851     {
11852       if (!opt_silent)
11853         printf("Failed to prepare a statement with %d placeholders "
11854                "(as expected).\n", nrows * COLUMN_COUNT);
11855       break;
11856     }
11857     else
11858       check_execute(stmt, rc);
11859 
11860     if (!opt_silent)
11861       printf("Insert: query length= %d, row count= %d, param count= %lu\n",
11862              (int) strlen(query), nrows, mysql_stmt_param_count(stmt));
11863 
11864     /* bind the parameter array and execute the query */
11865     rc= mysql_stmt_bind_param(stmt, my_bind);
11866     check_execute(stmt, rc);
11867 
11868     rc= mysql_stmt_execute(stmt);
11869     check_execute(stmt, rc);
11870     mysql_stmt_reset(stmt);
11871   }
11872 
11873   mysql_stmt_close(stmt);
11874   free(my_bind);
11875   free(query);
11876   free(param_str);
11877   stmt_text= "drop table t1";
11878   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11879   myquery(rc);
11880 }
11881 
11882 
test_bug5315()11883 static void test_bug5315()
11884 {
11885   MYSQL_STMT *stmt;
11886   const char *stmt_text;
11887   int rc;
11888 
11889   myheader("test_bug5315");
11890 
11891   stmt_text= "SELECT 1";
11892   stmt= mysql_stmt_init(mysql);
11893   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11894   DIE_UNLESS(rc == 0);
11895   if (!opt_silent)
11896     printf("Executing mysql_change_user\n");
11897   mysql_change_user(mysql, opt_user, opt_password, current_db);
11898   if (!opt_silent)
11899     printf("Executing mysql_stmt_execute\n");
11900   rc= mysql_stmt_execute(stmt);
11901   DIE_UNLESS(rc != 0);
11902   if (rc)
11903   {
11904     if (!opt_silent)
11905       printf("Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
11906   }
11907   /* check that connection is OK */
11908   if (!opt_silent)
11909     printf("Executing mysql_stmt_close\n");
11910   mysql_stmt_close(stmt);
11911   if (!opt_silent)
11912     printf("Executing mysql_stmt_init\n");
11913   stmt= mysql_stmt_init(mysql);
11914   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11915   DIE_UNLESS(rc == 0);
11916   rc= mysql_stmt_execute(stmt);
11917   DIE_UNLESS(rc == 0);
11918   mysql_stmt_close(stmt);
11919 }
11920 
11921 
test_bug6049()11922 static void test_bug6049()
11923 {
11924   MYSQL_STMT *stmt;
11925   MYSQL_BIND my_bind[1];
11926   MYSQL_RES *res;
11927   MYSQL_ROW row;
11928   const char *stmt_text;
11929   char buffer[30];
11930   ulong length;
11931   int rc;
11932 
11933   myheader("test_bug6049");
11934 
11935   stmt_text= "SELECT MAKETIME(-25, 12, 12)";
11936 
11937   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11938   myquery(rc);
11939   res= mysql_store_result(mysql);
11940   row= mysql_fetch_row(res);
11941 
11942   stmt= mysql_stmt_init(mysql);
11943   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11944   check_execute(stmt, rc);
11945   rc= mysql_stmt_execute(stmt);
11946   check_execute(stmt, rc);
11947 
11948   bzero((char*) my_bind, sizeof(my_bind));
11949   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
11950   my_bind[0].buffer         = &buffer;
11951   my_bind[0].buffer_length  = sizeof(buffer);
11952   my_bind[0].length         = &length;
11953 
11954   mysql_stmt_bind_result(stmt, my_bind);
11955   rc= mysql_stmt_fetch(stmt);
11956   DIE_UNLESS(rc == 0);
11957 
11958   if (!opt_silent)
11959   {
11960     printf("Result from query: %s\n", row[0]);
11961     printf("Result from prepared statement: %s\n", (char*) buffer);
11962   }
11963 
11964   DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);
11965 
11966   mysql_free_result(res);
11967   mysql_stmt_close(stmt);
11968 }
11969 
11970 
test_bug6058()11971 static void test_bug6058()
11972 {
11973   MYSQL_STMT *stmt;
11974   MYSQL_BIND my_bind[1];
11975   MYSQL_RES *res;
11976   MYSQL_ROW row;
11977   const char *stmt_text;
11978   char buffer[30];
11979   ulong length;
11980   int rc;
11981 
11982   myheader("test_bug6058");
11983 
11984   rc= mysql_query(mysql, "SET SQL_MODE=''");
11985   myquery(rc);
11986 
11987   stmt_text= "SELECT CAST('0000-00-00' AS DATE)";
11988 
11989   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11990   myquery(rc);
11991   res= mysql_store_result(mysql);
11992   row= mysql_fetch_row(res);
11993 
11994   stmt= mysql_stmt_init(mysql);
11995   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11996   check_execute(stmt, rc);
11997   rc= mysql_stmt_execute(stmt);
11998   check_execute(stmt, rc);
11999 
12000   bzero((char*) my_bind, sizeof(my_bind));
12001   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
12002   my_bind[0].buffer         = &buffer;
12003   my_bind[0].buffer_length  = sizeof(buffer);
12004   my_bind[0].length         = &length;
12005 
12006   mysql_stmt_bind_result(stmt, my_bind);
12007   rc= mysql_stmt_fetch(stmt);
12008   DIE_UNLESS(rc == 0);
12009 
12010   if (!opt_silent)
12011   {
12012     printf("Result from query: %s\n", row[0]);
12013     printf("Result from prepared statement: %s\n", buffer);
12014   }
12015 
12016   DIE_UNLESS(strcmp(row[0], buffer) == 0);
12017 
12018   mysql_free_result(res);
12019   mysql_stmt_close(stmt);
12020 }
12021 
12022 
test_bug6059()12023 static void test_bug6059()
12024 {
12025   MYSQL_STMT *stmt;
12026   const char *stmt_text;
12027 
12028   myheader("test_bug6059");
12029 
12030   stmt_text= "SELECT 'foo' INTO OUTFILE 'x.3'";
12031 
12032   stmt= mysql_stmt_init(mysql);
12033   (void) mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12034   DIE_UNLESS(mysql_stmt_field_count(stmt) == 0);
12035   mysql_stmt_close(stmt);
12036 }
12037 
12038 
test_bug6046()12039 static void test_bug6046()
12040 {
12041   MYSQL_STMT *stmt;
12042   const char *stmt_text;
12043   int rc;
12044   short b= 1;
12045   MYSQL_BIND my_bind[1];
12046 
12047   myheader("test_bug6046");
12048 
12049   stmt_text= "DROP TABLE IF EXISTS t1";
12050   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12051   myquery(rc);
12052   stmt_text= "CREATE TABLE t1 (a int, b int)";
12053   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12054   myquery(rc);
12055   stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)";
12056   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12057   myquery(rc);
12058 
12059   stmt= mysql_stmt_init(mysql);
12060 
12061   stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 "
12062              "WHERE t1.b > ? ORDER BY t1.a";
12063 
12064   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12065   check_execute(stmt, rc);
12066 
12067   b= 1;
12068   bzero((char*) my_bind, sizeof(my_bind));
12069   my_bind[0].buffer= &b;
12070   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
12071 
12072   mysql_stmt_bind_param(stmt, my_bind);
12073 
12074   rc= mysql_stmt_execute(stmt);
12075   check_execute(stmt, rc);
12076   mysql_stmt_store_result(stmt);
12077 
12078   rc= mysql_stmt_execute(stmt);
12079   check_execute(stmt, rc);
12080 
12081   mysql_stmt_close(stmt);
12082 }
12083 
12084 
12085 
test_basic_cursors()12086 static void test_basic_cursors()
12087 {
12088   const char *basic_tables[]=
12089   {
12090     "DROP TABLE IF EXISTS t1, t2",
12091 
12092     "CREATE TABLE t1 "
12093     "(id INTEGER NOT NULL PRIMARY KEY, "
12094     " name VARCHAR(20) NOT NULL)",
12095 
12096     "INSERT INTO t1 (id, name) VALUES "
12097     "  (2, 'Ja'), (3, 'Ede'), "
12098     "  (4, 'Haag'), (5, 'Kabul'), "
12099     "  (6, 'Almere'), (7, 'Utrecht'), "
12100     "  (8, 'Qandahar'), (9, 'Amsterdam'), "
12101     "  (10, 'Amersfoort'), (11, 'Constantine')",
12102 
12103     "CREATE TABLE t2 "
12104     "(id INTEGER NOT NULL PRIMARY KEY, "
12105     " name VARCHAR(20) NOT NULL)",
12106 
12107     "INSERT INTO t2 (id, name) VALUES "
12108     "  (4, 'Guam'), (5, 'Aruba'), "
12109     "  (6, 'Angola'), (7, 'Albania'), "
12110     "  (8, 'Anguilla'), (9, 'Argentina'), "
12111     "  (10, 'Azerbaijan'), (11, 'Afghanistan'), "
12112     "  (12, 'Burkina Faso'), (13, 'Faroe Islands')"
12113   };
12114   const char *queries[]=
12115   {
12116     "SELECT * FROM t1",
12117     "SELECT * FROM t2"
12118   };
12119 
12120   DBUG_ENTER("test_basic_cursors");
12121   myheader("test_basic_cursors");
12122 
12123   fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
12124 
12125   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12126   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12127   DBUG_VOID_RETURN;
12128 }
12129 
12130 
test_cursors_with_union()12131 static void test_cursors_with_union()
12132 {
12133   const char *queries[]=
12134   {
12135     "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2",
12136     "SELECT t1.id FROM t1 WHERE t1.id < 5"
12137   };
12138   myheader("test_cursors_with_union");
12139   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12140   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12141 }
12142 
12143 
test_cursors_with_procedure()12144 static void test_cursors_with_procedure()
12145 {
12146   const char *queries[]=
12147   {
12148     "SELECT * FROM t1 procedure analyse()"
12149   };
12150   myheader("test_cursors_with_procedure");
12151   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12152   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12153 }
12154 
12155 
12156 /*
12157   Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
12158   should not crash server and should not hang in case of errors.
12159 
12160   Since those functions can't be seen in modern API (unless client library
12161   was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro.
12162 */
test_bug6081()12163 static void test_bug6081()
12164 {
12165   int rc;
12166   myheader("test_bug6081");
12167 
12168   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12169                      (ulong)strlen(current_db), 0);
12170   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12171   {
12172     myerror(NULL);                                   /* purecov: inspected */
12173     die(__FILE__, __LINE__, "COM_DROP_DB failed");   /* purecov: inspected */
12174   }
12175   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12176                      (ulong)strlen(current_db), 0);
12177   myquery_r(rc);
12178   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12179                      (ulong)strlen(current_db), 0);
12180   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12181   {
12182     myerror(NULL);                                   /* purecov: inspected */
12183     die(__FILE__, __LINE__, "COM_CREATE_DB failed"); /* purecov: inspected */
12184   }
12185   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12186                      (ulong)strlen(current_db), 0);
12187   myquery_r(rc);
12188   rc= mysql_select_db(mysql, current_db);
12189   myquery(rc);
12190 }
12191 
12192 
test_bug6096()12193 static void test_bug6096()
12194 {
12195   MYSQL_STMT *stmt;
12196   MYSQL_RES *query_result, *stmt_metadata;
12197   const char *stmt_text;
12198   MYSQL_BIND my_bind[12];
12199   MYSQL_FIELD *query_field_list, *stmt_field_list;
12200   ulong query_field_count, stmt_field_count;
12201   int rc;
12202   my_bool update_max_length= TRUE;
12203   uint i;
12204 
12205   myheader("test_bug6096");
12206 
12207   stmt_text= "drop table if exists t1";
12208   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12209   myquery(rc);
12210 
12211   mysql_query(mysql, "set sql_mode=''");
12212   stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, "
12213                              " c_mediumint mediumint, c_int int, "
12214                              " c_bigint bigint, c_float float, "
12215                              " c_double double, c_varchar varchar(20), "
12216                              " c_char char(20), c_time time, c_date date, "
12217                              " c_datetime datetime)";
12218   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12219   myquery(rc);
12220   stmt_text= "insert into t1  values (-100, -20000, 30000000, 4, 8, 1.0, "
12221                                      "2.0, 'abc', 'def', now(), now(), now())";
12222   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12223   myquery(rc);
12224 
12225   stmt_text= "select * from t1";
12226 
12227   /* Run select in prepared and non-prepared mode and compare metadata */
12228   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12229   myquery(rc);
12230   query_result= mysql_store_result(mysql);
12231   query_field_list= mysql_fetch_fields(query_result);
12232   query_field_count= mysql_num_fields(query_result);
12233 
12234   stmt= mysql_stmt_init(mysql);
12235   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12236   check_execute(stmt, rc);
12237   rc= mysql_stmt_execute(stmt);
12238   check_execute(stmt, rc);
12239   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
12240                       (void*) &update_max_length);
12241   mysql_stmt_store_result(stmt);
12242   stmt_metadata= mysql_stmt_result_metadata(stmt);
12243   stmt_field_list= mysql_fetch_fields(stmt_metadata);
12244   stmt_field_count= mysql_num_fields(stmt_metadata);
12245   DIE_UNLESS(stmt_field_count == query_field_count);
12246 
12247   /* Print out and check the metadata */
12248 
12249   if (!opt_silent)
12250   {
12251     printf(" ------------------------------------------------------------\n");
12252     printf("             |                     Metadata \n");
12253     printf(" ------------------------------------------------------------\n");
12254     printf("             |         Query          |   Prepared statement \n");
12255     printf(" ------------------------------------------------------------\n");
12256     printf(" field name  |  length   | max_length |  length   |  max_length\n");
12257     printf(" ------------------------------------------------------------\n");
12258 
12259     for (i= 0; i < query_field_count; ++i)
12260     {
12261       MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
12262       printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
12263              f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
12264       DIE_UNLESS(f1->length == f2->length);
12265     }
12266     printf(" ---------------------------------------------------------------\n");
12267   }
12268 
12269   /* Bind and fetch the data */
12270 
12271   bzero((char*) my_bind, sizeof(my_bind));
12272   for (i= 0; i < stmt_field_count; ++i)
12273   {
12274     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
12275     my_bind[i].buffer_length= stmt_field_list[i].max_length + 1;
12276     my_bind[i].buffer= malloc(my_bind[i].buffer_length);
12277   }
12278   mysql_stmt_bind_result(stmt, my_bind);
12279   rc= mysql_stmt_fetch(stmt);
12280   check_execute(stmt, rc);
12281   rc= mysql_stmt_fetch(stmt);
12282   DIE_UNLESS(rc == MYSQL_NO_DATA);
12283 
12284   /* Clean up */
12285 
12286   for (i= 0; i < stmt_field_count; ++i)
12287     free(my_bind[i].buffer);
12288   mysql_stmt_close(stmt);
12289   mysql_free_result(query_result);
12290   mysql_free_result(stmt_metadata);
12291   stmt_text= "drop table t1";
12292   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12293   myquery(rc);
12294 }
12295 
12296 
12297 /*
12298   Test of basic checks that are performed in server for components
12299   of MYSQL_TIME parameters.
12300 */
12301 
test_datetime_ranges()12302 static void test_datetime_ranges()
12303 {
12304   const char *stmt_text;
12305   int rc, i;
12306   MYSQL_STMT *stmt;
12307   MYSQL_BIND my_bind[6];
12308   MYSQL_TIME tm[6];
12309 
12310   myheader("test_datetime_ranges");
12311 
12312   stmt_text= "drop table if exists t1";
12313   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12314   myquery(rc);
12315 
12316   stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
12317                               "hour datetime, min datetime, sec datetime)";
12318   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12319   myquery(rc);
12320 
12321   stmt= mysql_simple_prepare(mysql,
12322                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
12323   check_stmt(stmt);
12324   verify_param_count(stmt, 6);
12325 
12326   bzero((char*) my_bind, sizeof(my_bind));
12327   for (i= 0; i < 6; i++)
12328   {
12329     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12330     my_bind[i].buffer= &tm[i];
12331   }
12332   rc= mysql_stmt_bind_param(stmt, my_bind);
12333   check_execute(stmt, rc);
12334 
12335   tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
12336   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12337   tm[0].second_part= 0; tm[0].neg= 0;
12338 
12339   tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12340   tm[0].year= 10000;  tm[1].month= 13; tm[2].day= 32;
12341   tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;
12342 
12343   rc= mysql_stmt_execute(stmt);
12344   check_execute(stmt, rc);
12345   my_process_warnings(mysql, 6);
12346 
12347   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12348   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12349   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12350   verify_col_data("t1", "hour", "0000-00-00 00:00:00");
12351   verify_col_data("t1", "min", "0000-00-00 00:00:00");
12352   verify_col_data("t1", "sec", "0000-00-00 00:00:00");
12353 
12354   mysql_stmt_close(stmt);
12355 
12356   stmt_text= "delete from t1";
12357   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12358   myquery(rc);
12359 
12360   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
12361                                     "VALUES (?, ?, ?)");
12362   check_stmt(stmt);
12363   verify_param_count(stmt, 3);
12364 
12365   /*
12366     We reuse contents of bind and tm arrays left from previous part of test.
12367   */
12368   for (i= 0; i < 3; i++)
12369     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12370 
12371   rc= mysql_stmt_bind_param(stmt, my_bind);
12372   check_execute(stmt, rc);
12373 
12374   rc= mysql_stmt_execute(stmt);
12375   check_execute(stmt, rc);
12376   my_process_warnings(mysql, 3);
12377 
12378   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12379   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12380   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12381 
12382   mysql_stmt_close(stmt);
12383 
12384   stmt_text= "drop table t1";
12385   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12386   myquery(rc);
12387 
12388   stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
12389   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12390   myquery(rc);
12391 
12392   stmt= mysql_simple_prepare(mysql,
12393                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
12394   check_stmt(stmt);
12395   verify_param_count(stmt, 5);
12396 
12397   /*
12398     Again we reuse what we can from previous part of test.
12399   */
12400   for (i= 0; i < 5; i++)
12401     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12402 
12403   rc= mysql_stmt_bind_param(stmt, my_bind);
12404   check_execute(stmt, rc);
12405 
12406   tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
12407   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12408   tm[0].second_part= 0; tm[0].neg= 0;
12409 
12410   tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12411   tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;
12412 
12413   rc= mysql_stmt_execute(stmt);
12414   check_execute(stmt, rc);
12415   my_process_warnings(mysql, 2);
12416 
12417   verify_col_data("t1", "day_ovfl", "838:59:59");
12418   verify_col_data("t1", "day", "828:30:30");
12419   verify_col_data("t1", "hour", "270:30:30");
12420   verify_col_data("t1", "min", "00:00:00");
12421   verify_col_data("t1", "sec", "00:00:00");
12422 
12423   mysql_stmt_close(stmt);
12424 
12425   stmt_text= "drop table t1";
12426   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12427   myquery(rc);
12428 }
12429 
12430 
12431 /*
12432   This test is used in:
12433   mysql-test/suite/binlog/binlog_stm_datetime_ranges_mdev15289.test
12434 */
test_datetime_ranges_mdev15289()12435 static void test_datetime_ranges_mdev15289()
12436 {
12437   const char *stmt_text;
12438   int rc, i;
12439   MYSQL_STMT *stmt;
12440   MYSQL_BIND my_bind[4];
12441   MYSQL_TIME tm[4];
12442 
12443   myheader("test_datetime_ranges_mdev15289");
12444 
12445   stmt_text= "SET sql_mode=''";
12446   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12447   myquery(rc);
12448 
12449   stmt_text= "create or replace table t1 "
12450              "(t time, d date, dt datetime,ts timestamp)";
12451   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12452   myquery(rc);
12453 
12454   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?, ?, ?, ?)");
12455   check_stmt(stmt);
12456   verify_param_count(stmt, 4);
12457 
12458   /*** Testing DATETIME ***/
12459   bzero((char*) my_bind, sizeof(my_bind));
12460   for (i= 0; i < 4; i++)
12461   {
12462     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12463     my_bind[i].buffer= &tm[i];
12464   }
12465   rc= mysql_stmt_bind_param(stmt, my_bind);
12466   check_execute(stmt, rc);
12467 
12468   /* Notice bad year */
12469   tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2;
12470   tm[0].hour= 03; tm[0].minute= 04; tm[0].second= 05;
12471   tm[0].second_part= 0; tm[0].neg= 0;
12472   tm[0].time_type= MYSQL_TIMESTAMP_DATETIME;
12473   tm[3]= tm[2]= tm[1]= tm[0];
12474 
12475   rc= mysql_stmt_execute(stmt);
12476   check_execute(stmt, rc);
12477   my_process_warnings(mysql, 4);
12478 
12479   verify_col_data("t1", "t", "00:00:00");
12480   verify_col_data("t1", "d", "0000-00-00");
12481   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12482   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12483 
12484   /*** Testing DATE ***/
12485   bzero((char*) my_bind, sizeof(my_bind));
12486   for (i= 0; i < 4; i++)
12487   {
12488     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12489     my_bind[i].buffer= &tm[i];
12490   }
12491   rc= mysql_stmt_bind_param(stmt, my_bind);
12492   check_execute(stmt, rc);
12493 
12494   /* Notice bad year */
12495   tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2;
12496   tm[0].hour= 00; tm[0].minute= 00; tm[0].second= 00;
12497   tm[0].second_part= 0; tm[0].neg= 0;
12498   tm[0].time_type= MYSQL_TIMESTAMP_DATE;
12499   tm[3]= tm[2]= tm[1]= tm[0];
12500 
12501   rc= mysql_stmt_execute(stmt);
12502   check_execute(stmt, rc);
12503   my_process_warnings(mysql, 4);
12504 
12505   verify_col_data("t1", "t", "00:00:00");
12506   verify_col_data("t1", "d", "0000-00-00");
12507   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12508   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12509 
12510   /*** Testing TIME ***/
12511   bzero((char*) my_bind, sizeof(my_bind));
12512   for (i= 0; i < 4; i++)
12513   {
12514     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12515     my_bind[i].buffer= &tm[i];
12516   }
12517   rc= mysql_stmt_bind_param(stmt, my_bind);
12518   check_execute(stmt, rc);
12519 
12520   /* Notice bad hour */
12521   tm[0].year= 0; tm[0].month= 0; tm[0].day= 0;
12522   tm[0].hour= 100; tm[0].minute= 64; tm[0].second= 05;
12523   tm[0].second_part= 0; tm[0].neg= 0;
12524   tm[0].time_type= MYSQL_TIMESTAMP_TIME;
12525   tm[3]= tm[2]= tm[1]= tm[0];
12526 
12527   rc= mysql_stmt_execute(stmt);
12528   check_execute(stmt, rc);
12529   my_process_warnings(mysql, 4);
12530 
12531   verify_col_data("t1", "t", "00:00:00");
12532   verify_col_data("t1", "d", "0000-00-00");
12533   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12534   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12535 
12536   mysql_stmt_close(stmt);
12537 
12538   stmt_text= "drop table t1";
12539   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12540   myquery(rc);
12541 }
12542 
12543 
test_bug4172()12544 static void test_bug4172()
12545 {
12546   MYSQL_STMT *stmt;
12547   MYSQL_BIND my_bind[3];
12548   const char *stmt_text;
12549   MYSQL_RES *res;
12550   MYSQL_ROW row;
12551   int rc;
12552   char f[100], d[100], e[100];
12553   ulong f_len, d_len, e_len;
12554 
12555   myheader("test_bug4172");
12556 
12557   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
12558   mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))");
12559   mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, "
12560                                             "123456.1234)");
12561 
12562   stmt= mysql_stmt_init(mysql);
12563   stmt_text= "SELECT f, d, e FROM t1";
12564 
12565   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12566   check_execute(stmt, rc);
12567   rc= mysql_stmt_execute(stmt);
12568   check_execute(stmt, rc);
12569 
12570   bzero((char*) my_bind, sizeof(my_bind));
12571   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12572   my_bind[0].buffer= f;
12573   my_bind[0].buffer_length= sizeof(f);
12574   my_bind[0].length= &f_len;
12575   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
12576   my_bind[1].buffer= d;
12577   my_bind[1].buffer_length= sizeof(d);
12578   my_bind[1].length= &d_len;
12579   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
12580   my_bind[2].buffer= e;
12581   my_bind[2].buffer_length= sizeof(e);
12582   my_bind[2].length= &e_len;
12583 
12584   mysql_stmt_bind_result(stmt, my_bind);
12585 
12586   mysql_stmt_store_result(stmt);
12587   rc= mysql_stmt_fetch(stmt);
12588   check_execute(stmt, rc);
12589 
12590   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12591   myquery(rc);
12592   res= mysql_store_result(mysql);
12593   row= mysql_fetch_row(res);
12594 
12595   if (!opt_silent)
12596   {
12597     printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n",
12598            f, d, e);
12599     printf("Text protocol:   float=%s, double=%s, decimal(10,4)=%s\n",
12600            row[0], row[1], row[2]);
12601   }
12602   DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]));
12603 
12604   mysql_free_result(res);
12605   mysql_stmt_close(stmt);
12606 }
12607 
12608 
test_conversion()12609 static void test_conversion()
12610 {
12611   MYSQL_STMT *stmt;
12612   const char *stmt_text;
12613   int rc;
12614   MYSQL_BIND my_bind[1];
12615   uchar buff[4];
12616   ulong length;
12617 
12618   myheader("test_conversion");
12619 
12620   stmt_text= "DROP TABLE IF EXISTS t1";
12621   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12622   myquery(rc);
12623   stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
12624   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12625   myquery(rc);
12626   stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
12627              " character_set_results=latin1";
12628   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12629   myquery(rc);
12630 
12631   stmt= mysql_stmt_init(mysql);
12632 
12633   stmt_text= "INSERT INTO t1 (a) VALUES (?)";
12634   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12635   check_execute(stmt, rc);
12636 
12637   bzero((char*) my_bind, sizeof(my_bind));
12638   my_bind[0].buffer= (char*) buff;
12639   my_bind[0].length= &length;
12640   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12641 
12642   mysql_stmt_bind_param(stmt, my_bind);
12643 
12644   buff[0]= (uchar) 0xC3;
12645   buff[1]= (uchar) 0xA0;
12646   length= 2;
12647 
12648   rc= mysql_stmt_execute(stmt);
12649   check_execute(stmt, rc);
12650 
12651   stmt_text= "SELECT a FROM t1";
12652   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12653   check_execute(stmt, rc);
12654   rc= mysql_stmt_execute(stmt);
12655   check_execute(stmt, rc);
12656 
12657   my_bind[0].buffer_length= sizeof(buff);
12658   mysql_stmt_bind_result(stmt, my_bind);
12659 
12660   rc= mysql_stmt_fetch(stmt);
12661   DIE_UNLESS(rc == 0);
12662   DIE_UNLESS(length == 1);
12663   DIE_UNLESS(buff[0] == 0xE0);
12664   rc= mysql_stmt_fetch(stmt);
12665   DIE_UNLESS(rc == MYSQL_NO_DATA);
12666 
12667   mysql_stmt_close(stmt);
12668   stmt_text= "DROP TABLE t1";
12669   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12670   myquery(rc);
12671   stmt_text= "SET NAMES DEFAULT";
12672   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12673   myquery(rc);
12674 }
12675 
test_rewind(void)12676 static void test_rewind(void)
12677 {
12678   MYSQL_STMT *stmt;
12679   MYSQL_BIND my_bind;
12680   int rc = 0;
12681   const char *stmt_text;
12682   long unsigned int length=4, Data=0;
12683   my_bool isnull=0;
12684 
12685   myheader("test_rewind");
12686 
12687   stmt_text= "CREATE TABLE t1 (a int)";
12688   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12689   myquery(rc);
12690   stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)";
12691   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12692   myquery(rc);
12693 
12694   stmt= mysql_stmt_init(mysql);
12695 
12696   stmt_text= "SELECT * FROM t1";
12697   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12698   check_execute(stmt, rc);
12699 
12700   bzero((char*) &my_bind, sizeof(MYSQL_BIND));
12701   my_bind.buffer_type= MYSQL_TYPE_LONG;
12702   my_bind.buffer= (void *)&Data; /* this buffer won't be altered */
12703   my_bind.length= &length;
12704   my_bind.is_null= &isnull;
12705 
12706   rc= mysql_stmt_execute(stmt);
12707   check_execute(stmt, rc);
12708 
12709   rc= mysql_stmt_store_result(stmt);
12710   DIE_UNLESS(rc == 0);
12711 
12712   rc= mysql_stmt_bind_result(stmt, &my_bind);
12713   DIE_UNLESS(rc == 0);
12714 
12715   /* retreive all result sets till we are at the end */
12716   while(!mysql_stmt_fetch(stmt))
12717     if (!opt_silent)
12718       printf("fetched result:%ld\n", Data);
12719 
12720   DIE_UNLESS(rc != MYSQL_NO_DATA);
12721 
12722   /* seek to the first row */
12723   mysql_stmt_data_seek(stmt, 0);
12724 
12725   /* now we should be able to fetch the results again */
12726   /* but mysql_stmt_fetch returns MYSQL_NO_DATA */
12727   while(!(rc= mysql_stmt_fetch(stmt)))
12728     if (!opt_silent)
12729       printf("fetched result after seek:%ld\n", Data);
12730 
12731   DIE_UNLESS(rc == MYSQL_NO_DATA);
12732 
12733   stmt_text= "DROP TABLE t1";
12734   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12735   myquery(rc);
12736   rc= mysql_stmt_free_result(stmt);
12737   rc= mysql_stmt_close(stmt);
12738 }
12739 
12740 
test_truncation()12741 static void test_truncation()
12742 {
12743   MYSQL_STMT *stmt;
12744   const char *stmt_text;
12745   int rc;
12746   uint bind_count;
12747   MYSQL_BIND *bind_array, *my_bind;
12748 
12749   myheader("test_truncation");
12750 
12751   /* Prepare the test table */
12752   rc= mysql_query(mysql, "drop table if exists t1");
12753   myquery(rc);
12754 
12755   stmt_text= "create table t1 ("
12756              "i8 tinyint, ui8 tinyint unsigned, "
12757              "i16 smallint, i16_1 smallint, "
12758              "ui16 smallint unsigned, i32 int, i32_1 int, "
12759              "d double, d_1 double, ch char(30), ch_1 char(30), "
12760              "tx text, tx_1 text, ch_2 char(30) "
12761              ")";
12762   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12763   myquery(rc);
12764 
12765   {
12766     const char insert_text[]=
12767              "insert into t1 VALUES ("
12768              "-10, "                            /* i8 */
12769              "200, "                            /* ui8 */
12770              "32000, "                          /* i16 */
12771              "-32767, "                         /* i16_1 */
12772              "64000, "                          /* ui16 */
12773              "1073741824, "                     /* i32 */
12774              "1073741825, "                     /* i32_1 */
12775              "123.456, "                        /* d */
12776              "-12345678910, "                   /* d_1 */
12777              "'111111111111111111111111111111',"/* ch */
12778              "'abcdef', "                       /* ch_1 */
12779              "'12345 	      ', "              /* tx */
12780              "'12345.67 	      ', "      /* tx_1 */
12781              "'12345.67abc'"                    /* ch_2 */
12782              ")";
12783     rc= mysql_real_query(mysql, insert_text, strlen(insert_text));
12784     myquery(rc);
12785   }
12786 
12787   stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, "
12788              "       i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, "
12789              "       d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, "
12790              "       tx_1 c17, ch_2 c18 "
12791              "from t1";
12792 
12793   stmt= mysql_stmt_init(mysql);
12794   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12795   check_execute(stmt, rc);
12796   rc= mysql_stmt_execute(stmt);
12797   check_execute(stmt, rc);
12798   bind_count= (uint) mysql_stmt_field_count(stmt);
12799 
12800   /*************** Fill in the bind structure and bind it **************/
12801   bind_array= malloc(sizeof(MYSQL_BIND) * bind_count);
12802   bzero((char*) bind_array, sizeof(MYSQL_BIND) * bind_count);
12803   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12804     my_bind->error= &my_bind->error_value;
12805   my_bind= bind_array;
12806 
12807   my_bind->buffer= malloc(sizeof(uint8));
12808   my_bind->buffer_type= MYSQL_TYPE_TINY;
12809   my_bind->is_unsigned= TRUE;
12810 
12811   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12812   my_bind->buffer= malloc(sizeof(uint32));
12813   my_bind->buffer_type= MYSQL_TYPE_LONG;
12814   my_bind->is_unsigned= TRUE;
12815 
12816   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12817   my_bind->buffer= malloc(sizeof(int8));
12818   my_bind->buffer_type= MYSQL_TYPE_TINY;
12819 
12820   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12821   my_bind->buffer= malloc(sizeof(uint16));
12822   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12823   my_bind->is_unsigned= TRUE;
12824 
12825   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12826   my_bind->buffer= malloc(sizeof(int16));
12827   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12828 
12829   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12830   my_bind->buffer= malloc(sizeof(uint16));
12831   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12832   my_bind->is_unsigned= TRUE;
12833 
12834   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12835   my_bind->buffer= malloc(sizeof(int8));
12836   my_bind->buffer_type= MYSQL_TYPE_TINY;
12837   my_bind->is_unsigned= TRUE;
12838 
12839   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12840   my_bind->buffer= malloc(sizeof(float));
12841   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12842 
12843   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12844   my_bind->buffer= malloc(sizeof(float));
12845   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12846 
12847   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12848   my_bind->buffer= malloc(sizeof(double));
12849   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12850 
12851   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12852   my_bind->buffer= malloc(sizeof(longlong));
12853   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12854 
12855   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12856   my_bind->buffer= malloc(sizeof(ulonglong));
12857   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12858   my_bind->is_unsigned= TRUE;
12859 
12860   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12861   my_bind->buffer= malloc(sizeof(longlong));
12862   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12863 
12864   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12865   my_bind->buffer= malloc(sizeof(longlong));
12866   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12867 
12868   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12869   my_bind->buffer= malloc(sizeof(longlong));
12870   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12871 
12872   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12873   my_bind->buffer= malloc(sizeof(longlong));
12874   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12875 
12876   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12877   my_bind->buffer= malloc(sizeof(double));
12878   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12879 
12880   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12881   my_bind->buffer= malloc(sizeof(double));
12882   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12883 
12884   rc= mysql_stmt_bind_result(stmt, bind_array);
12885   check_execute(stmt, rc);
12886   rc= mysql_stmt_fetch(stmt);
12887   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12888 
12889   /*************** Verify truncation results ***************************/
12890   my_bind= bind_array;
12891 
12892   /* signed tiny -> tiny */
12893   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == -10);
12894 
12895   /* signed tiny -> uint32 */
12896   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12897   DIE_UNLESS(*my_bind->error && * (int32*) my_bind->buffer == -10);
12898 
12899   /* unsigned tiny -> tiny */
12900   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12901   DIE_UNLESS(*my_bind->error && * (uint8*) my_bind->buffer == 200);
12902 
12903   /* short -> ushort */
12904   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12905   DIE_UNLESS(*my_bind->error && * (int16*) my_bind->buffer == -32767);
12906 
12907   /* ushort -> short */
12908   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12909   DIE_UNLESS(*my_bind->error && * (uint16*) my_bind->buffer == 64000);
12910 
12911   /* short -> ushort (no truncation, data is in the range of target type) */
12912   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12913   DIE_UNLESS(! *my_bind->error && * (uint16*) my_bind->buffer == 32000);
12914 
12915   /* ushort -> utiny */
12916   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12917   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == 0);
12918 
12919   /* int -> float: no truncation, the number is a power of two */
12920   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12921   DIE_UNLESS(! *my_bind->error && * (float*) my_bind->buffer == 1073741824);
12922 
12923   /* int -> float: truncation, not enough bits in float */
12924   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12925   DIE_UNLESS(*my_bind->error);
12926 
12927   /* int -> double: no truncation */
12928   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12929   DIE_UNLESS(! *my_bind->error && * (double*) my_bind->buffer == 1073741825);
12930 
12931   /* double -> longlong: fractional part is lost */
12932   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12933 
12934   /* double -> ulonglong, negative fp number to unsigned integer */
12935   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12936   /* Value in the buffer is not defined: don't test it */
12937   DIE_UNLESS(*my_bind->error);
12938 
12939   /* double -> longlong, negative fp number to signed integer: no loss */
12940   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12941   DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == -12345678910LL);
12942 
12943   /* big numeric string -> number */
12944   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12945   DIE_UNLESS(*my_bind->error);
12946 
12947   /* junk string -> number */
12948   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12949   DIE_UNLESS(*my_bind->error && *(longlong*) my_bind->buffer == 0);
12950 
12951   /* string with trailing spaces -> number */
12952   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12953   DIE_UNLESS(! *my_bind->error && *(longlong*) my_bind->buffer == 12345);
12954 
12955   /* string with trailing spaces -> double */
12956   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12957   DIE_UNLESS(! *my_bind->error && *(double*) my_bind->buffer == 12345.67);
12958 
12959   /* string with trailing junk -> double */
12960   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12961   /*
12962     XXX: There must be a truncation error: but it's not the way the server
12963     behaves, so let's leave it for now.
12964   */
12965   DIE_UNLESS(*(double*) my_bind->buffer == 12345.67);
12966   /*
12967     TODO: string -> double,  double -> time, double -> string (truncation
12968           errors are not supported here yet)
12969           longlong -> time/date/datetime
12970           date -> time, date -> timestamp, date -> number
12971           time -> string, time -> date, time -> timestamp,
12972           number -> date string -> date
12973   */
12974   /*************** Cleanup *********************************************/
12975 
12976   mysql_stmt_close(stmt);
12977 
12978   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12979     free(my_bind->buffer);
12980   free(bind_array);
12981 
12982   rc= mysql_query(mysql, "drop table t1");
12983   myquery(rc);
12984 }
12985 
test_truncation_option()12986 static void test_truncation_option()
12987 {
12988   MYSQL_STMT *stmt;
12989   const char *stmt_text;
12990   int rc;
12991   uint8 buf;
12992   my_bool option= 0;
12993   my_bool error;
12994   MYSQL_BIND my_bind;
12995 
12996   myheader("test_truncation_option");
12997 
12998   /* Prepare the test table */
12999   stmt_text= "select -1";
13000 
13001   stmt= mysql_stmt_init(mysql);
13002   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13003   check_execute(stmt, rc);
13004   rc= mysql_stmt_execute(stmt);
13005   check_execute(stmt, rc);
13006 
13007   bzero((char*) &my_bind, sizeof(my_bind));
13008 
13009   my_bind.buffer= (void*) &buf;
13010   my_bind.buffer_type= MYSQL_TYPE_TINY;
13011   my_bind.is_unsigned= TRUE;
13012   my_bind.error= &error;
13013 
13014   rc= mysql_stmt_bind_result(stmt, &my_bind);
13015   check_execute(stmt, rc);
13016   rc= mysql_stmt_fetch(stmt);
13017   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
13018   DIE_UNLESS(error);
13019   rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
13020   myquery(rc);
13021   /* need to rebind for the new setting to take effect */
13022   rc= mysql_stmt_bind_result(stmt, &my_bind);
13023   check_execute(stmt, rc);
13024   rc= mysql_stmt_execute(stmt);
13025   check_execute(stmt, rc);
13026   rc= mysql_stmt_fetch(stmt);
13027   check_execute(stmt, rc);
13028   /* The only change is rc - error pointers are still filled in */
13029   DIE_UNLESS(error == 1);
13030   /* restore back the defaults */
13031   option= 1;
13032   mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
13033 
13034   mysql_stmt_close(stmt);
13035 }
13036 
13037 
13038 /* Bug#6761 - mysql_list_fields doesn't work */
13039 
test_bug6761(void)13040 static void test_bug6761(void)
13041 {
13042   const char *stmt_text;
13043   MYSQL_RES *res;
13044   int rc;
13045   myheader("test_bug6761");
13046 
13047   stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
13048   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13049   myquery(rc);
13050 
13051   res= mysql_list_fields(mysql, "t1", "%");
13052   DIE_UNLESS(res && mysql_num_fields(res) == 3);
13053   mysql_free_result(res);
13054 
13055   stmt_text= "DROP TABLE t1";
13056   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13057   myquery(rc);
13058 }
13059 
13060 
13061 /* Bug#8330 - mysql_stmt_execute crashes (libmysql) */
13062 
test_bug8330()13063 static void test_bug8330()
13064 {
13065   const char *stmt_text;
13066   MYSQL_STMT *stmt[2];
13067   int i, rc;
13068   const char *query= "select a,b from t1 where a=?";
13069   MYSQL_BIND my_bind[2];
13070   long lval[2];
13071 
13072   myheader("test_bug8330");
13073 
13074   stmt_text= "drop table if exists t1";
13075   /* in case some previos test failed */
13076   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13077   myquery(rc);
13078   stmt_text= "create table t1 (a int, b int)";
13079   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13080   myquery(rc);
13081 
13082   bzero((char*) my_bind, sizeof(my_bind));
13083   for (i=0; i < 2; i++)
13084   {
13085     stmt[i]= mysql_stmt_init(mysql);
13086     rc= mysql_stmt_prepare(stmt[i], query, strlen(query));
13087     check_execute(stmt[i], rc);
13088 
13089     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
13090     my_bind[i].buffer= (void*) &lval[i];
13091     my_bind[i].is_null= 0;
13092     mysql_stmt_bind_param(stmt[i], &my_bind[i]);
13093   }
13094 
13095   rc= mysql_stmt_execute(stmt[0]);
13096   check_execute(stmt[0], rc);
13097 
13098   rc= mysql_stmt_execute(stmt[1]);
13099   DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
13100   rc= mysql_stmt_execute(stmt[0]);
13101   check_execute(stmt[0], rc);
13102 
13103   mysql_stmt_close(stmt[0]);
13104   mysql_stmt_close(stmt[1]);
13105 
13106   stmt_text= "drop table t1";
13107   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13108   myquery(rc);
13109 }
13110 
13111 
13112 /* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */
13113 
test_bug7990()13114 static void test_bug7990()
13115 {
13116   MYSQL_STMT *stmt;
13117   int rc;
13118   myheader("test_bug7990");
13119 
13120   stmt= mysql_stmt_init(mysql);
13121   rc= mysql_stmt_prepare(stmt, "foo", 3);
13122   /*
13123     XXX: the fact that we store errno both in STMT and in
13124     MYSQL is not documented and is subject to change in 5.0
13125   */
13126   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql));
13127   mysql_stmt_close(stmt);
13128   DIE_UNLESS(!mysql_errno(mysql));
13129 }
13130 
13131 /*
13132   Bug #15518 - Reusing a stmt that has failed during prepare
13133   does not clear error
13134 */
13135 
test_bug15518()13136 static void test_bug15518()
13137 {
13138   MYSQL_STMT *stmt;
13139   MYSQL* mysql1;
13140   int rc;
13141   myheader("test_bug15518");
13142 
13143   mysql1= mysql_client_init(NULL);
13144 
13145   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13146                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13147                           CLIENT_MULTI_STATEMENTS))
13148   {
13149     fprintf(stderr, "Failed to connect to the database\n");
13150     DIE_UNLESS(0);
13151   }
13152 
13153   stmt= mysql_stmt_init(mysql1);
13154 
13155   /*
13156     The prepare of foo should fail with errno 1064 since
13157     it's not a valid query
13158   */
13159   rc= mysql_stmt_prepare(stmt, "foo", 3);
13160   if (!opt_silent)
13161     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13162             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13163   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13164 
13165   /*
13166     Use the same stmt and reprepare with another query that
13167     suceeds
13168   */
13169   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13170   if (!opt_silent)
13171     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13172             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13173   DIE_UNLESS(!rc || mysql_stmt_errno(stmt) || mysql_errno(mysql1));
13174 
13175   mysql_stmt_close(stmt);
13176   DIE_UNLESS(!mysql_errno(mysql1));
13177 
13178   /*
13179     part2, when connection to server has been closed
13180     after first prepare
13181   */
13182   stmt= mysql_stmt_init(mysql1);
13183   rc= mysql_stmt_prepare(stmt, "foo", 3);
13184   if (!opt_silent)
13185     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13186             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13187   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13188 
13189   /* Close connection to server */
13190   mysql_close(mysql1);
13191 
13192   /*
13193     Use the same stmt and reprepare with another query that
13194     suceeds. The prepare should fail with error 2013 since
13195     connection to server has been closed.
13196   */
13197   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13198   if (!opt_silent)
13199     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d\n",
13200             rc, mysql_stmt_errno(stmt));
13201   DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13202 
13203   mysql_stmt_close(stmt);
13204 }
13205 
13206 
disable_query_logs()13207 static void disable_query_logs()
13208 {
13209   int rc;
13210   rc= mysql_query(mysql, "set @@global.general_log=off");
13211   myquery(rc);
13212   rc= mysql_query(mysql, "set @@global.slow_query_log=off");
13213   myquery(rc);
13214 }
13215 
13216 
enable_query_logs(int truncate)13217 static void enable_query_logs(int truncate)
13218 {
13219   int rc;
13220 
13221   rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
13222   myquery(rc);
13223 
13224   rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log");
13225   myquery(rc);
13226 
13227   rc= mysql_query(mysql, "set @@global.general_log=on");
13228   myquery(rc);
13229 
13230   rc= mysql_query(mysql, "set @@global.slow_query_log=on");
13231   myquery(rc);
13232 
13233 
13234   if (truncate)
13235   {
13236     rc= mysql_query(mysql, "truncate mysql.general_log");
13237     myquery(rc);
13238 
13239     rc= mysql_query(mysql, "truncate mysql.slow_log");
13240     myquery(rc);
13241   }
13242 }
13243 
13244 
restore_query_logs()13245 static void restore_query_logs()
13246 {
13247   int rc;
13248   rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
13249   myquery(rc);
13250 
13251   rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log");
13252   myquery(rc);
13253 }
13254 
13255 
test_view_sp_list_fields()13256 static void test_view_sp_list_fields()
13257 {
13258   int		rc;
13259   MYSQL_RES     *res;
13260 
13261   myheader("test_view_sp_list_fields");
13262 
13263   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
13264   myquery(rc);
13265   rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
13266   myquery(rc);
13267   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
13268   myquery(rc);
13269   rc= mysql_query(mysql, "create function f1 () returns int return 5");
13270   myquery(rc);
13271   rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
13272   myquery(rc);
13273   rc= mysql_query(mysql, "create table t2 (s1 int);");
13274   myquery(rc);
13275   rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
13276 count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
13277 from t2);");
13278   myquery(rc);
13279   res= mysql_list_fields(mysql, "v1", NullS);
13280   DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0);
13281   rc= mysql_query(mysql, "DROP FUNCTION f1");
13282   myquery(rc);
13283   rc= mysql_query(mysql, "DROP VIEW v1");
13284   myquery(rc);
13285   rc= mysql_query(mysql, "DROP TABLE t1, t2");
13286   mysql_free_result(res);
13287   myquery(rc);
13288 
13289 }
13290 
13291 
13292 /*
13293  Test mysql_real_escape_string() with gbk charset
13294 
13295  The important part is that 0x27 (') is the second-byte in a invalid
13296  two-byte GBK character here. But 0xbf5c is a valid GBK character, so
13297  it needs to be escaped as 0x5cbf27
13298 */
13299 #define TEST_BUG8378_IN  "\xef\xbb\xbf\x27\xbf\x10"
13300 #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
13301 
test_bug8378()13302 static void test_bug8378()
13303 {
13304 #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
13305   MYSQL *lmysql;
13306   char out[9]; /* strlen(TEST_BUG8378)*2+1 */
13307   char buf[256];
13308   int len, rc;
13309 
13310   myheader("test_bug8378");
13311 
13312   if (!opt_silent)
13313     fprintf(stdout, "\n Establishing a test connection ...");
13314   if (!(lmysql= mysql_client_init(NULL)))
13315   {
13316     myerror("mysql_client_init() failed");
13317     exit(1);
13318   }
13319   if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
13320   {
13321     myerror("mysql_options() failed");
13322     exit(1);
13323   }
13324   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
13325                            opt_password, current_db, opt_port,
13326                            opt_unix_socket, 0)))
13327   {
13328     myerror("connection failed");
13329     exit(1);
13330   }
13331   if (!opt_silent)
13332     fprintf(stdout, "OK");
13333 
13334   rc= mysql_query(lmysql, "SET SQL_MODE=''");
13335   myquery(rc);
13336 
13337   len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4);
13338 
13339   /* No escaping should have actually happened. */
13340   DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
13341 
13342   sprintf(buf, "SELECT '%s'", out);
13343 
13344   rc=mysql_real_query(lmysql, buf, strlen(buf));
13345   myquery(rc);
13346 
13347   mysql_close(lmysql);
13348 #endif
13349 }
13350 
13351 
test_bug8722()13352 static void test_bug8722()
13353 {
13354   MYSQL_STMT *stmt;
13355   int rc;
13356   const char *stmt_text;
13357 
13358   myheader("test_bug8722");
13359   /* Prepare test data */
13360   stmt_text= "drop table if exists t1, v1";
13361   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13362   myquery(rc);
13363   stmt_text= "CREATE TABLE t1 (c1 varchar(10), c2 varchar(10), c3 varchar(10),"
13364                              " c4 varchar(10), c5 varchar(10), c6 varchar(10),"
13365                              " c7 varchar(10), c8 varchar(10), c9 varchar(10),"
13366                              "c10 varchar(10))";
13367   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13368   myquery(rc);
13369   stmt_text= "INSERT INTO t1 VALUES (1,2,3,4,5,6,7,8,9,10)";
13370   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13371   myquery(rc);
13372   stmt_text= "CREATE VIEW v1 AS SELECT * FROM t1";
13373   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13374   myquery(rc);
13375   /* Note: if you uncomment following block everything works fine */
13376 /*
13377   rc= mysql_query(mysql, "sellect * from v1");
13378   myquery(rc);
13379   mysql_free_result(mysql_store_result(mysql));
13380 */
13381 
13382   stmt= mysql_stmt_init(mysql);
13383   stmt_text= "select * from v1";
13384   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13385   check_execute(stmt, rc);
13386   mysql_stmt_close(stmt);
13387   stmt_text= "drop table if exists t1, v1";
13388   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13389   myquery(rc);
13390 }
13391 
13392 
open_cursor(const char * query)13393 MYSQL_STMT *open_cursor(const char *query)
13394 {
13395   int rc;
13396   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
13397 
13398   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
13399   rc= mysql_stmt_prepare(stmt, query, strlen(query));
13400   check_execute(stmt, rc);
13401 
13402   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13403   return stmt;
13404 }
13405 
13406 
test_bug8880()13407 static void test_bug8880()
13408 {
13409   MYSQL_STMT *stmt_list[2], **stmt;
13410   MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
13411   int rc;
13412 
13413   myheader("test_bug8880");
13414 
13415   mysql_query(mysql, "drop table if exists t1");
13416   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13417   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13418   myquery(rc);                                  /* one check is enough */
13419   /*
13420     when inserting 2 rows everything works well
13421     mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
13422   */
13423   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13424     *stmt= open_cursor("select a from t1");
13425   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13426   {
13427     rc= mysql_stmt_execute(*stmt);
13428     check_execute(*stmt, rc);
13429   }
13430   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13431     mysql_stmt_close(*stmt);
13432 }
13433 
13434 /*
13435   Test executing a query with prepared statements while query cache is active
13436 */
13437 
test_open_cursor_prepared_statement_query_cache()13438 static void test_open_cursor_prepared_statement_query_cache()
13439 {
13440   MYSQL_STMT *stmt;
13441   int rc;
13442   MYSQL_RES *result;
13443 
13444   myheader("test_open_cursor_prepared_statement_query_cache");
13445   if (! is_query_cache_available())
13446   {
13447     fprintf(stdout, "Skipping test_open_cursor_prepared_statement_query_cache: Query cache not available.\n");
13448     return;
13449   }
13450 
13451   rc= mysql_query(mysql,
13452                   "set @save_query_cache_type="
13453                   "@@global.query_cache_type,"
13454                   "@save_query_cache_size="
13455                   "@@global.query_cache_size");
13456   myquery(rc);
13457   rc= mysql_query(mysql, "set global query_cache_type=ON");
13458   myquery(rc);
13459   rc= mysql_query(mysql, "set local query_cache_type=ON");
13460   myquery(rc);
13461   rc= mysql_query(mysql, "set global query_cache_size=1000000");
13462   myquery(rc);
13463 
13464   mysql_query(mysql, "drop table if exists t1");
13465   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13466   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13467   myquery(rc);                                  /* one check is enough */
13468 
13469   /* Store query in query cache */
13470   rc= mysql_query(mysql, "SELECT * FROM t1");
13471   myquery(rc);
13472   result= mysql_store_result(mysql);
13473   mytest(result);
13474   (void) my_process_result_set(result);
13475   mysql_free_result(result);
13476 
13477   /* Test using a cursor */
13478   stmt= open_cursor("select a from t1");
13479   rc= mysql_stmt_execute(stmt);
13480   check_execute(stmt, rc);
13481   mysql_stmt_close(stmt);
13482 
13483   rc= mysql_query(mysql, "set global query_cache_type=@save_query_cache_type");
13484   myquery(rc);
13485   rc= mysql_query(mysql, "set global query_cache_size=@save_query_cache_size");
13486   myquery(rc);
13487 }
13488 
13489 
test_bug9159()13490 static void test_bug9159()
13491 {
13492   MYSQL_STMT *stmt;
13493   int rc;
13494   const char *stmt_text= "select a, b from t1";
13495   const unsigned long type= CURSOR_TYPE_READ_ONLY;
13496 
13497   myheader("test_bug9159");
13498 
13499   mysql_query(mysql, "drop table if exists t1");
13500   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13501   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13502   myquery(rc);
13503 
13504   stmt= mysql_stmt_init(mysql);
13505   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13506   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
13507 
13508   mysql_stmt_execute(stmt);
13509   mysql_stmt_close(stmt);
13510   rc= mysql_query(mysql, "drop table if exists t1");
13511   myquery(rc);
13512 }
13513 
13514 
13515 /* Crash when opening a cursor to a query with DISTICNT and no key */
13516 
test_bug9520()13517 static void test_bug9520()
13518 {
13519   MYSQL_STMT *stmt;
13520   MYSQL_BIND my_bind[1];
13521   char a[6];
13522   ulong a_len;
13523   int rc, row_count= 0;
13524 
13525   myheader("test_bug9520");
13526 
13527   mysql_query(mysql, "drop table if exists t1");
13528   mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
13529                      " primary key (a, b, c))");
13530   rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
13531                   " ('a', 'b', 'c'), ('k', 'l', 'm')");
13532   myquery(rc);
13533 
13534   stmt= open_cursor("select distinct b from t1");
13535 
13536   /*
13537     Not crashes with:
13538     stmt= open_cursor("select distinct a from t1");
13539   */
13540 
13541   rc= mysql_stmt_execute(stmt);
13542   check_execute(stmt, rc);
13543 
13544   bzero((char*) my_bind, sizeof(my_bind));
13545   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13546   my_bind[0].buffer= (char*) a;
13547   my_bind[0].buffer_length= sizeof(a);
13548   my_bind[0].length= &a_len;
13549 
13550   mysql_stmt_bind_result(stmt, my_bind);
13551 
13552   while (!(rc= mysql_stmt_fetch(stmt)))
13553     row_count++;
13554 
13555   DIE_UNLESS(rc == MYSQL_NO_DATA);
13556 
13557   if (!opt_silent)
13558     printf("Fetched %d rows\n", row_count);
13559   DBUG_ASSERT(row_count == 3);
13560 
13561   mysql_stmt_close(stmt);
13562 
13563   rc= mysql_query(mysql, "drop table t1");
13564   myquery(rc);
13565 }
13566 
13567 
13568 /*
13569   We can't have more than one cursor open for a prepared statement.
13570   Test re-executions of a PS with cursor; mysql_stmt_reset must close
13571   the cursor attached to the statement, if there is one.
13572 */
13573 
test_bug9478()13574 static void test_bug9478()
13575 {
13576   MYSQL_STMT *stmt;
13577   MYSQL_BIND my_bind[1];
13578   char a[6];
13579   ulong a_len;
13580   int rc, i;
13581   DBUG_ENTER("test_bug9478");
13582 
13583   myheader("test_bug9478");
13584 
13585   mysql_query(mysql, "drop table if exists t1");
13586   mysql_query(mysql, "create table t1 (id integer not null primary key, "
13587                      " name varchar(20) not null)");
13588   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13589                          " (1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13590   myquery(rc);
13591 
13592   stmt= open_cursor("select name from t1 where id=2");
13593 
13594   bzero((char*) my_bind, sizeof(my_bind));
13595   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13596   my_bind[0].buffer= (char*) a;
13597   my_bind[0].buffer_length= sizeof(a);
13598   my_bind[0].length= &a_len;
13599   mysql_stmt_bind_result(stmt, my_bind);
13600 
13601   for (i= 0; i < 5; i++)
13602   {
13603     rc= mysql_stmt_execute(stmt);
13604     check_execute(stmt, rc);
13605     rc= mysql_stmt_fetch(stmt);
13606     check_execute(stmt, rc);
13607     if (!opt_silent && i == 0)
13608       printf("Fetched row: %s\n", a);
13609 
13610     /*
13611       The query above is a one-row result set. Therefore, there is no
13612       cursor associated with it, as the server won't bother with opening
13613       a cursor for a one-row result set. The first row was read from the
13614       server in the fetch above. But there is eof packet pending in the
13615       network. mysql_stmt_execute will flush the packet and successfully
13616       execute the statement.
13617     */
13618 
13619     rc= mysql_stmt_execute(stmt);
13620     check_execute(stmt, rc);
13621 
13622     rc= mysql_stmt_fetch(stmt);
13623     check_execute(stmt, rc);
13624     if (!opt_silent && i == 0)
13625       printf("Fetched row: %s\n", a);
13626     rc= mysql_stmt_fetch(stmt);
13627     DIE_UNLESS(rc == MYSQL_NO_DATA);
13628 
13629     {
13630       char buff[8];
13631       /* Fill in the fetch packet */
13632       int4store(buff, stmt->stmt_id);
13633       buff[4]= 1;                               /* prefetch rows */
13634       rc= mysql_stmt_fetch(stmt);
13635       DIE_UNLESS(rc);
13636       if (!opt_silent && i == 0)
13637         printf("Got error (as expected): %s\n", mysql_error(mysql));
13638     }
13639 
13640     rc= mysql_stmt_execute(stmt);
13641     check_execute(stmt, rc);
13642 
13643     rc= mysql_stmt_fetch(stmt);
13644     check_execute(stmt, rc);
13645     if (!opt_silent && i == 0)
13646       printf("Fetched row: %s\n", a);
13647 
13648     rc= mysql_stmt_reset(stmt);
13649     check_execute(stmt, rc);
13650     rc= mysql_stmt_fetch(stmt);
13651     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13652     if (!opt_silent && i == 0)
13653       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13654   }
13655   rc= mysql_stmt_close(stmt);
13656   DIE_UNLESS(rc == 0);
13657 
13658   /* Test the case with a server side cursor */
13659   stmt= open_cursor("select name from t1");
13660 
13661   mysql_stmt_bind_result(stmt, my_bind);
13662 
13663   for (i= 0; i < 5; i++)
13664   {
13665     DBUG_PRINT("loop",("i: %d", i));
13666     rc= mysql_stmt_execute(stmt);
13667     check_execute(stmt, rc);
13668     rc= mysql_stmt_fetch(stmt);
13669     check_execute(stmt, rc);
13670     if (!opt_silent && i == 0)
13671       printf("Fetched row: %s\n", a);
13672     rc= mysql_stmt_execute(stmt);
13673     check_execute(stmt, rc);
13674 
13675     while (! (rc= mysql_stmt_fetch(stmt)))
13676     {
13677       if (!opt_silent && i == 0)
13678         printf("Fetched row: %s\n", a);
13679     }
13680     DIE_UNLESS(rc == MYSQL_NO_DATA);
13681 
13682     rc= mysql_stmt_execute(stmt);
13683     check_execute(stmt, rc);
13684 
13685     rc= mysql_stmt_fetch(stmt);
13686     check_execute(stmt, rc);
13687     if (!opt_silent && i == 0)
13688       printf("Fetched row: %s\n", a);
13689 
13690     rc= mysql_stmt_reset(stmt);
13691     check_execute(stmt, rc);
13692     rc= mysql_stmt_fetch(stmt);
13693     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13694     if (!opt_silent && i == 0)
13695       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13696   }
13697 
13698   rc= mysql_stmt_close(stmt);
13699   DIE_UNLESS(rc == 0);
13700 
13701   rc= mysql_query(mysql, "drop table t1");
13702   myquery(rc);
13703   DBUG_VOID_RETURN;
13704 }
13705 
13706 
13707 /*
13708   Error message is returned for unsupported features.
13709   Test also cursors with non-default PREFETCH_ROWS
13710 */
13711 
test_bug9643()13712 static void test_bug9643()
13713 {
13714   MYSQL_STMT *stmt;
13715   MYSQL_BIND my_bind[1];
13716   int32 a;
13717   int rc;
13718   const char *stmt_text;
13719   int num_rows= 0;
13720   ulong type;
13721   ulong prefetch_rows= 5;
13722 
13723   myheader("test_bug9643");
13724 
13725   mysql_query(mysql, "drop table if exists t1");
13726   mysql_query(mysql, "create table t1 (id integer not null primary key)");
13727   rc= mysql_query(mysql, "insert into t1 (id) values "
13728                          " (1), (2), (3), (4), (5), (6), (7), (8), (9)");
13729   myquery(rc);
13730 
13731   stmt= mysql_stmt_init(mysql);
13732   /* Not implemented in 5.0 */
13733   type= (ulong) CURSOR_TYPE_SCROLLABLE;
13734   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13735   DIE_UNLESS(rc);
13736   if (! opt_silent)
13737     printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13738 
13739   type= (ulong) CURSOR_TYPE_READ_ONLY;
13740   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13741   check_execute(stmt, rc);
13742   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
13743                           (void*) &prefetch_rows);
13744   check_execute(stmt, rc);
13745   stmt_text= "select * from t1";
13746   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13747   check_execute(stmt, rc);
13748 
13749   bzero((char*) my_bind, sizeof(my_bind));
13750   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13751   my_bind[0].buffer= (void*) &a;
13752   my_bind[0].buffer_length= sizeof(a);
13753   mysql_stmt_bind_result(stmt, my_bind);
13754 
13755   rc= mysql_stmt_execute(stmt);
13756   check_execute(stmt, rc);
13757 
13758   while ((rc= mysql_stmt_fetch(stmt)) == 0)
13759     ++num_rows;
13760   DIE_UNLESS(num_rows == 9);
13761 
13762   rc= mysql_stmt_close(stmt);
13763   DIE_UNLESS(rc == 0);
13764 
13765   rc= mysql_query(mysql, "drop table t1");
13766   myquery(rc);
13767 }
13768 
13769 /*
13770   Bug#11111: fetch from view returns wrong data
13771 */
13772 
test_bug11111()13773 static void test_bug11111()
13774 {
13775   MYSQL_STMT    *stmt;
13776   MYSQL_BIND    my_bind[2];
13777   char          buf[2][20];
13778   ulong         len[2];
13779   int i;
13780   int rc;
13781   const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
13782 
13783   myheader("test_bug11111");
13784 
13785   rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
13786   myquery(rc);
13787   rc= mysql_query(mysql, "drop view if exists t1, t2, v1");
13788   myquery(rc);
13789   rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)");
13790   myquery(rc);
13791   rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)");
13792   myquery(rc);
13793   rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1");
13794   myquery(rc);
13795   rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)");
13796   myquery(rc);
13797   rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
13798   myquery(rc);
13799 
13800   stmt= mysql_stmt_init(mysql);
13801 
13802   mysql_stmt_prepare(stmt, query, strlen(query));
13803   mysql_stmt_execute(stmt);
13804 
13805   bzero((char*) my_bind, sizeof(my_bind));
13806   for (i=0; i < 2; i++)
13807   {
13808     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
13809     my_bind[i].buffer= (uchar* *)&buf[i];
13810     my_bind[i].buffer_length= 20;
13811     my_bind[i].length= &len[i];
13812   }
13813 
13814   rc= mysql_stmt_bind_result(stmt, my_bind);
13815   check_execute(stmt, rc);
13816 
13817   rc= mysql_stmt_fetch(stmt);
13818   check_execute(stmt, rc);
13819   if (!opt_silent)
13820     printf("return: %s", buf[1]);
13821   DIE_UNLESS(!strcmp(buf[1],"1"));
13822   mysql_stmt_close(stmt);
13823   rc= mysql_query(mysql, "drop view v1");
13824   myquery(rc);
13825   rc= mysql_query(mysql, "drop table t1, t2");
13826   myquery(rc);
13827 }
13828 
13829 /*
13830   Check that proper cleanups are done for prepared statement when
13831   fetching thorugh a cursor.
13832 */
13833 
test_bug10729()13834 static void test_bug10729()
13835 {
13836   MYSQL_STMT *stmt;
13837   MYSQL_BIND my_bind[1];
13838   char a[21];
13839   int rc;
13840   const char *stmt_text;
13841   int i= 0;
13842   const char *name_array[3]= { "aaa", "bbb", "ccc" };
13843   ulong type;
13844 
13845   myheader("test_bug10729");
13846 
13847   mysql_query(mysql, "drop table if exists t1");
13848   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13849                                       "name VARCHAR(20) NOT NULL)");
13850   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13851                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13852   myquery(rc);
13853 
13854   stmt= mysql_stmt_init(mysql);
13855 
13856   type= (ulong) CURSOR_TYPE_READ_ONLY;
13857   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13858   check_execute(stmt, rc);
13859   stmt_text= "select name from t1";
13860   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13861   check_execute(stmt, rc);
13862 
13863   bzero((char*) my_bind, sizeof(my_bind));
13864   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13865   my_bind[0].buffer= (void*) a;
13866   my_bind[0].buffer_length= sizeof(a);
13867   mysql_stmt_bind_result(stmt, my_bind);
13868 
13869   for (i= 0; i < 3; i++)
13870   {
13871     int row_no= 0;
13872     rc= mysql_stmt_execute(stmt);
13873     check_execute(stmt, rc);
13874     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13875     {
13876       DIE_UNLESS(strcmp(a, name_array[row_no]) == 0);
13877       if (!opt_silent)
13878         printf("%d: %s\n", row_no, a);
13879       ++row_no;
13880     }
13881     DIE_UNLESS(rc == MYSQL_NO_DATA);
13882   }
13883   rc= mysql_stmt_close(stmt);
13884   DIE_UNLESS(rc == 0);
13885 
13886   rc= mysql_query(mysql, "drop table t1");
13887   myquery(rc);
13888 }
13889 
13890 
13891 /*
13892   Check that mysql_next_result works properly in case when one of
13893   the statements used in a multi-statement query is erroneous
13894 */
13895 
test_bug9992()13896 static void test_bug9992()
13897 {
13898   MYSQL *mysql1;
13899   MYSQL_RES* res ;
13900   int   rc;
13901 
13902   myheader("test_bug9992");
13903 
13904   if (!opt_silent)
13905     printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
13906 
13907   mysql1= mysql_client_init(NULL);
13908 
13909   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13910                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13911                           CLIENT_MULTI_STATEMENTS))
13912   {
13913     fprintf(stderr, "Failed to connect to the database\n");
13914     DIE_UNLESS(0);
13915   }
13916 
13917 
13918   /* Sic: SHOW DATABASE is incorrect syntax. */
13919   rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;");
13920 
13921   if (rc)
13922   {
13923     fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1));
13924     DIE_UNLESS(0);
13925   }
13926 
13927   if (!opt_silent)
13928     printf("Testing mysql_store_result/mysql_next_result..\n");
13929 
13930   res= mysql_store_result(mysql1);
13931   DIE_UNLESS(res);
13932   mysql_free_result(res);
13933   rc= mysql_next_result(mysql1);
13934   DIE_UNLESS(rc == 1);                         /* Got errors, as expected */
13935 
13936   if (!opt_silent)
13937     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
13938             mysql_errno(mysql1), mysql_error(mysql1));
13939 
13940   mysql_close(mysql1);
13941 }
13942 
13943 /* Bug#10736: cursors and subqueries, memroot management */
13944 
test_bug10736()13945 static void test_bug10736()
13946 {
13947   MYSQL_STMT *stmt;
13948   MYSQL_BIND my_bind[1];
13949   char a[21];
13950   int rc;
13951   const char *stmt_text;
13952   int i= 0;
13953   ulong type;
13954 
13955   myheader("test_bug10736");
13956 
13957   mysql_query(mysql, "drop table if exists t1");
13958   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13959                                       "name VARCHAR(20) NOT NULL)");
13960   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13961                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13962   myquery(rc);
13963 
13964   stmt= mysql_stmt_init(mysql);
13965 
13966   type= (ulong) CURSOR_TYPE_READ_ONLY;
13967   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13968   check_execute(stmt, rc);
13969   stmt_text= "select name from t1 where name=(select name from t1 where id=2)";
13970   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13971   check_execute(stmt, rc);
13972 
13973   bzero((char*) my_bind, sizeof(my_bind));
13974   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13975   my_bind[0].buffer= (void*) a;
13976   my_bind[0].buffer_length= sizeof(a);
13977   mysql_stmt_bind_result(stmt, my_bind);
13978 
13979   for (i= 0; i < 3; i++)
13980   {
13981     int row_no= 0;
13982     rc= mysql_stmt_execute(stmt);
13983     check_execute(stmt, rc);
13984     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13985     {
13986       if (!opt_silent)
13987         printf("%d: %s\n", row_no, a);
13988       ++row_no;
13989     }
13990     DIE_UNLESS(rc == MYSQL_NO_DATA);
13991   }
13992   rc= mysql_stmt_close(stmt);
13993   DIE_UNLESS(rc == 0);
13994 
13995   rc= mysql_query(mysql, "drop table t1");
13996   myquery(rc);
13997 }
13998 
13999 /* Bug#10794: cursors, packets out of order */
14000 
test_bug10794()14001 static void test_bug10794()
14002 {
14003   MYSQL_STMT *stmt, *stmt1;
14004   MYSQL_BIND my_bind[2];
14005   char a[21];
14006   int id_val;
14007   ulong a_len;
14008   int rc;
14009   const char *stmt_text;
14010   int i= 0;
14011   ulong type;
14012 
14013   myheader("test_bug10794");
14014 
14015   mysql_query(mysql, "drop table if exists t1");
14016   mysql_query(mysql, "create table t1 (id integer not null primary key,"
14017                                       "name varchar(20) not null)");
14018   stmt= mysql_stmt_init(mysql);
14019   stmt_text= "insert into t1 (id, name) values (?, ?)";
14020   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14021   check_execute(stmt, rc);
14022   bzero((char*) my_bind, sizeof(my_bind));
14023   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14024   my_bind[0].buffer= (void*) &id_val;
14025   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14026   my_bind[1].buffer= (void*) a;
14027   my_bind[1].length= &a_len;
14028   rc= mysql_stmt_bind_param(stmt, my_bind);
14029   check_execute(stmt, rc);
14030   for (i= 0; i < 42; i++)
14031   {
14032     id_val= (i+1)*10;
14033     sprintf(a, "a%d", i);
14034     a_len= strlen(a); /* safety against broken sprintf */
14035     rc= mysql_stmt_execute(stmt);
14036     check_execute(stmt, rc);
14037   }
14038   stmt_text= "select name from t1";
14039   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14040   type= (ulong) CURSOR_TYPE_READ_ONLY;
14041   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14042   stmt1= mysql_stmt_init(mysql);
14043   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14044   bzero((char*) my_bind, sizeof(my_bind));
14045   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14046   my_bind[0].buffer= (void*) a;
14047   my_bind[0].buffer_length= sizeof(a);
14048   my_bind[0].length= &a_len;
14049   rc= mysql_stmt_bind_result(stmt, my_bind);
14050   check_execute(stmt, rc);
14051   rc= mysql_stmt_execute(stmt);
14052   check_execute(stmt, rc);
14053   rc= mysql_stmt_fetch(stmt);
14054   check_execute(stmt, rc);
14055   if (!opt_silent)
14056     printf("Fetched row from stmt: %s\n", a);
14057   /* Don't optimize: an attribute of the original test case */
14058   mysql_stmt_free_result(stmt);
14059   mysql_stmt_reset(stmt);
14060   stmt_text= "select name from t1 where id=10";
14061   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14062   check_execute(stmt1, rc);
14063   rc= mysql_stmt_bind_result(stmt1, my_bind);
14064   check_execute(stmt1, rc);
14065   rc= mysql_stmt_execute(stmt1);
14066   while (1)
14067   {
14068     rc= mysql_stmt_fetch(stmt1);
14069     if (rc == MYSQL_NO_DATA)
14070     {
14071       if (!opt_silent)
14072         printf("End of data in stmt1\n");
14073       break;
14074     }
14075     check_execute(stmt1, rc);
14076     if (!opt_silent)
14077       printf("Fetched row from stmt1: %s\n", a);
14078   }
14079   mysql_stmt_close(stmt);
14080   mysql_stmt_close(stmt1);
14081 
14082   rc= mysql_query(mysql, "drop table t1");
14083   myquery(rc);
14084 }
14085 
14086 
14087 /* Bug#11172: cursors, crash on a fetch from a datetime column */
14088 
test_bug11172()14089 static void test_bug11172()
14090 {
14091   MYSQL_STMT *stmt;
14092   MYSQL_BIND bind_in[1], bind_out[2];
14093   MYSQL_TIME hired;
14094   int rc;
14095   const char *stmt_text;
14096   int i= 0, id;
14097   ulong type;
14098 
14099   myheader("test_bug11172");
14100 
14101   mysql_query(mysql, "drop table if exists t1");
14102   mysql_query(mysql, "create table t1 (id integer not null primary key,"
14103                                       "hired date not null)");
14104   rc= mysql_query(mysql,
14105                   "insert into t1 (id, hired) values (1, '1933-08-24'), "
14106                   "(2, '1965-01-01'), (3, '1949-08-17'), (4, '1945-07-07'), "
14107                   "(5, '1941-05-15'), (6, '1978-09-15'), (7, '1936-03-28')");
14108   myquery(rc);
14109   stmt= mysql_stmt_init(mysql);
14110   stmt_text= "SELECT id, hired FROM t1 WHERE hired=?";
14111   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14112   check_execute(stmt, rc);
14113 
14114   type= (ulong) CURSOR_TYPE_READ_ONLY;
14115   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14116 
14117   bzero((char*) bind_in, sizeof(bind_in));
14118   bzero((char*) bind_out, sizeof(bind_out));
14119   bzero((char*) &hired, sizeof(hired));
14120   hired.year= 1965;
14121   hired.month= 1;
14122   hired.day= 1;
14123   bind_in[0].buffer_type= MYSQL_TYPE_DATE;
14124   bind_in[0].buffer= (void*) &hired;
14125   bind_in[0].buffer_length= sizeof(hired);
14126   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
14127   bind_out[0].buffer= (void*) &id;
14128   bind_out[1]= bind_in[0];
14129 
14130   for (i= 0; i < 3; i++)
14131   {
14132     rc= mysql_stmt_bind_param(stmt, bind_in);
14133     check_execute(stmt, rc);
14134     rc= mysql_stmt_bind_result(stmt, bind_out);
14135     check_execute(stmt, rc);
14136     rc= mysql_stmt_execute(stmt);
14137     check_execute(stmt, rc);
14138     while ((rc= mysql_stmt_fetch(stmt)) == 0)
14139     {
14140       if (!opt_silent)
14141         printf("fetched data %d:%d-%d-%d\n", id,
14142                hired.year, hired.month, hired.day);
14143     }
14144     DIE_UNLESS(rc == MYSQL_NO_DATA);
14145     if (!mysql_stmt_free_result(stmt))
14146       mysql_stmt_reset(stmt);
14147   }
14148   mysql_stmt_close(stmt);
14149   mysql_rollback(mysql);
14150   mysql_rollback(mysql);
14151 
14152   rc= mysql_query(mysql, "drop table t1");
14153   myquery(rc);
14154 }
14155 
14156 
14157 /* Bug#11656: cursors, crash on a fetch from a query with distinct. */
14158 
test_bug11656()14159 static void test_bug11656()
14160 {
14161   MYSQL_STMT *stmt;
14162   MYSQL_BIND my_bind[2];
14163   int rc;
14164   const char *stmt_text;
14165   char buf[2][20];
14166   int i= 0;
14167   ulong type;
14168 
14169   myheader("test_bug11656");
14170 
14171   mysql_query(mysql, "drop table if exists t1");
14172 
14173   rc= mysql_query(mysql, "create table t1 ("
14174                   "server varchar(40) not null, "
14175                   "test_kind varchar(1) not null, "
14176                   "test_id varchar(30) not null , "
14177                   "primary key (server,test_kind,test_id))");
14178   myquery(rc);
14179 
14180   stmt_text= "select distinct test_kind, test_id from t1 "
14181              "where server in (?, ?)";
14182   stmt= mysql_stmt_init(mysql);
14183   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14184   check_execute(stmt, rc);
14185   type= (ulong) CURSOR_TYPE_READ_ONLY;
14186   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14187 
14188   bzero((char*) my_bind, sizeof(my_bind));
14189   strmov(buf[0], "pcint502_MY2");
14190   strmov(buf[1], "*");
14191   for (i=0; i < 2; i++)
14192   {
14193     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
14194     my_bind[i].buffer= (uchar* *)&buf[i];
14195     my_bind[i].buffer_length= strlen(buf[i]);
14196   }
14197   mysql_stmt_bind_param(stmt, my_bind);
14198 
14199   rc= mysql_stmt_execute(stmt);
14200   check_execute(stmt, rc);
14201 
14202   rc= mysql_stmt_fetch(stmt);
14203   DIE_UNLESS(rc == MYSQL_NO_DATA);
14204 
14205   mysql_stmt_close(stmt);
14206   rc= mysql_query(mysql, "drop table t1");
14207   myquery(rc);
14208 }
14209 
14210 
14211 /*
14212   Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
14213   and mysql_real_escape_string() does the right thing as a result.
14214 */
14215 
test_bug10214()14216 static void test_bug10214()
14217 {
14218   int   len;
14219   char  out[8];
14220 
14221   myheader("test_bug10214");
14222 
14223   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
14224 
14225   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14226   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14227 
14228   mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
14229   DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
14230 
14231   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14232   DIE_UNLESS(memcmp(out, "a''b\\c", len) == 0);
14233 
14234   mysql_query(mysql, "set sql_mode=''");
14235 }
14236 
test_client_character_set()14237 static void test_client_character_set()
14238 {
14239   MY_CHARSET_INFO cs;
14240   char *csname= (char*) "utf8";
14241   char *csdefault= (char*)mysql_character_set_name(mysql);
14242   int rc;
14243 
14244   myheader("test_client_character_set");
14245 
14246   rc= mysql_set_character_set(mysql, csname);
14247   DIE_UNLESS(rc == 0);
14248 
14249   mysql_get_character_set_info(mysql, &cs);
14250   DIE_UNLESS(!strcmp(cs.csname, "utf8"));
14251   DIE_UNLESS(!strcmp(cs.name, "utf8_general_ci"));
14252   /* Restore the default character set */
14253   rc= mysql_set_character_set(mysql, csdefault);
14254   myquery(rc);
14255 }
14256 
14257 /* Test correct max length for MEDIUMTEXT and LONGTEXT columns */
14258 
test_bug9735()14259 static void test_bug9735()
14260 {
14261   MYSQL_RES *res;
14262   int rc;
14263 
14264   myheader("test_bug9735");
14265 
14266   rc= mysql_query(mysql, "drop table if exists t1");
14267   myquery(rc);
14268   rc= mysql_query(mysql, "create table t1 (a mediumtext, b longtext) "
14269                          "character set latin1");
14270   myquery(rc);
14271   rc= mysql_query(mysql, "select * from t1");
14272   myquery(rc);
14273   res= mysql_store_result(mysql);
14274   verify_prepare_field(res, 0, "a", "a", MYSQL_TYPE_BLOB,
14275                        "t1", "t1", current_db, (1U << 24)-1, 0);
14276   verify_prepare_field(res, 1, "b", "b", MYSQL_TYPE_BLOB,
14277                        "t1", "t1", current_db, ~0U, 0);
14278   mysql_free_result(res);
14279   rc= mysql_query(mysql, "drop table t1");
14280   myquery(rc);
14281 }
14282 
14283 
14284 /* Bug#11183 "mysql_stmt_reset() doesn't reset information about error" */
14285 
test_bug11183()14286 static void test_bug11183()
14287 {
14288   int rc;
14289   MYSQL_STMT *stmt;
14290   char bug_statement[]= "insert into t1 values (1)";
14291 
14292   myheader("test_bug11183");
14293 
14294   mysql_query(mysql, "drop table t1 if exists");
14295   mysql_query(mysql, "create table t1 (a int)");
14296 
14297   stmt= mysql_stmt_init(mysql);
14298   DIE_UNLESS(stmt != 0);
14299 
14300   rc= mysql_stmt_prepare(stmt, bug_statement, strlen(bug_statement));
14301   check_execute(stmt, rc);
14302 
14303   rc= mysql_query(mysql, "drop table t1");
14304   myquery(rc);
14305 
14306   /* Trying to execute statement that should fail on execute stage */
14307   rc= mysql_stmt_execute(stmt);
14308   DIE_UNLESS(rc);
14309 
14310   mysql_stmt_reset(stmt);
14311   DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14312 
14313   mysql_query(mysql, "create table t1 (a int)");
14314 
14315   /* Trying to execute statement that should pass ok */
14316   if (mysql_stmt_execute(stmt))
14317   {
14318     mysql_stmt_reset(stmt);
14319     DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14320   }
14321 
14322   mysql_stmt_close(stmt);
14323 
14324   rc= mysql_query(mysql, "drop table t1");
14325   myquery(rc);
14326 }
14327 
test_bug11037()14328 static void test_bug11037()
14329 {
14330   MYSQL_STMT *stmt;
14331   int rc;
14332   const char *stmt_text;
14333 
14334   myheader("test_bug11037");
14335 
14336   mysql_query(mysql, "drop table if exists t1");
14337 
14338   rc= mysql_query(mysql, "create table t1 (id int not null)");
14339   myquery(rc);
14340 
14341   rc= mysql_query(mysql, "insert into t1 values (1)");
14342   myquery(rc);
14343 
14344   stmt_text= "select id FROM t1";
14345   stmt= mysql_stmt_init(mysql);
14346   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14347 
14348   /* expected error */
14349   rc = mysql_stmt_fetch(stmt);
14350   DIE_UNLESS(rc==1);
14351   if (!opt_silent)
14352     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
14353             mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
14354 
14355   rc= mysql_stmt_execute(stmt);
14356   check_execute(stmt, rc);
14357 
14358   rc= mysql_stmt_fetch(stmt);
14359   DIE_UNLESS(rc==0);
14360 
14361   rc= mysql_stmt_fetch(stmt);
14362   DIE_UNLESS(rc==MYSQL_NO_DATA);
14363 
14364   rc= mysql_stmt_fetch(stmt);
14365   DIE_UNLESS(rc==MYSQL_NO_DATA);
14366 
14367   mysql_stmt_close(stmt);
14368   rc= mysql_query(mysql, "drop table t1");
14369   myquery(rc);
14370 }
14371 
14372 /* Bug#10760: cursors, crash in a fetch after rollback. */
14373 
test_bug10760()14374 static void test_bug10760()
14375 {
14376   MYSQL_STMT *stmt;
14377   MYSQL_BIND my_bind[1];
14378   int rc;
14379   const char *stmt_text;
14380   char id_buf[20];
14381   ulong id_len;
14382   int i= 0;
14383   ulong type;
14384 
14385   myheader("test_bug10760");
14386 
14387   mysql_query(mysql, "drop table if exists t1, t2");
14388 
14389   /* create tables */
14390   rc= mysql_query(mysql, "create table t1 (id integer not null primary key)"
14391                          " engine=MyISAM");
14392   myquery(rc);
14393   for (; i < 42; ++i)
14394   {
14395     char buf[100];
14396     sprintf(buf, "insert into t1 (id) values (%d)", i+1);
14397     rc= mysql_query(mysql, buf);
14398     myquery(rc);
14399   }
14400   mysql_autocommit(mysql, FALSE);
14401   /* create statement */
14402   stmt= mysql_stmt_init(mysql);
14403   type= (ulong) CURSOR_TYPE_READ_ONLY;
14404   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14405 
14406   /*
14407     1: check that a deadlock within the same connection
14408     is resolved and an error is returned. The deadlock is modelled
14409     as follows:
14410     con1: open cursor for select * from t1;
14411     con1: insert into t1 (id) values (1)
14412   */
14413   stmt_text= "select id from t1 order by 1";
14414   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14415   check_execute(stmt, rc);
14416   rc= mysql_stmt_execute(stmt);
14417   check_execute(stmt, rc);
14418   rc= mysql_query(mysql, "update t1 set id=id+100");
14419   /*
14420     If cursors are not materialized, the update will return an error;
14421     we mainly test that it won't deadlock.
14422   */
14423   if (rc && !opt_silent)
14424     printf("Got error (as expected): %s\n", mysql_error(mysql));
14425   /*
14426     2: check that MyISAM tables used in cursors survive
14427     COMMIT/ROLLBACK.
14428   */
14429   rc= mysql_rollback(mysql);                  /* should not close the cursor */
14430   myquery(rc);
14431   rc= mysql_stmt_fetch(stmt);
14432   check_execute(stmt, rc);
14433 
14434   /*
14435     3: check that cursors to InnoDB tables are closed (for now) by
14436     COMMIT/ROLLBACK.
14437   */
14438   if (! have_innodb)
14439   {
14440     if (!opt_silent)
14441       printf("Testing that cursors are closed at COMMIT/ROLLBACK requires "
14442              "InnoDB.\n");
14443   }
14444   else
14445   {
14446     stmt_text= "select id from t1 order by 1";
14447     rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14448     check_execute(stmt, rc);
14449 
14450     rc= mysql_query(mysql, "alter table t1 engine=InnoDB");
14451     myquery(rc);
14452 
14453     bzero(my_bind, sizeof(my_bind));
14454     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14455     my_bind[0].buffer= (void*) id_buf;
14456     my_bind[0].buffer_length= sizeof(id_buf);
14457     my_bind[0].length= &id_len;
14458     check_execute(stmt, rc);
14459     mysql_stmt_bind_result(stmt, my_bind);
14460 
14461     rc= mysql_stmt_execute(stmt);
14462     rc= mysql_stmt_fetch(stmt);
14463     DIE_UNLESS(rc == 0);
14464     if (!opt_silent)
14465       printf("Fetched row %s\n", id_buf);
14466     rc= mysql_rollback(mysql);                  /* should close the cursor */
14467     myquery(rc);
14468 #if 0
14469     rc= mysql_stmt_fetch(stmt);
14470     DIE_UNLESS(rc);
14471     if (!opt_silent)
14472       printf("Got error (as expected): %s\n", mysql_error(mysql));
14473 #endif
14474   }
14475 
14476   mysql_stmt_close(stmt);
14477   rc= mysql_query(mysql, "drop table t1");
14478   myquery(rc);
14479   mysql_autocommit(mysql, TRUE);                /* restore default */
14480 }
14481 
test_bug12001()14482 static void test_bug12001()
14483 {
14484   MYSQL *mysql_local;
14485   MYSQL_RES *result;
14486   const char *query= "DROP TABLE IF EXISTS test_table;"
14487                      "CREATE TABLE test_table(id INT);"
14488                      "INSERT INTO test_table VALUES(10);"
14489                      "UPDATE test_table SET id=20 WHERE id=10;"
14490                      "SELECT * FROM test_table;"
14491                      "INSERT INTO non_existent_table VALUES(11);";
14492   int rc, res;
14493 
14494   myheader("test_bug12001");
14495 
14496   if (!(mysql_local= mysql_client_init(NULL)))
14497   {
14498     fprintf(stdout, "\n mysql_client_init() failed");
14499     exit(1);
14500   }
14501 
14502   /* Create connection that supports multi statements */
14503   if (!mysql_real_connect(mysql_local, opt_host, opt_user,
14504                           opt_password, current_db, opt_port,
14505                           opt_unix_socket, CLIENT_MULTI_STATEMENTS))
14506   {
14507     fprintf(stdout, "\n mysql_real_connect() failed");
14508     exit(1);
14509   }
14510 
14511   rc= mysql_query(mysql_local, query);
14512   myquery(rc);
14513 
14514   do
14515   {
14516     if (mysql_field_count(mysql_local) &&
14517         (result= mysql_use_result(mysql_local)))
14518     {
14519       mysql_free_result(result);
14520     }
14521   }
14522   while (!(res= mysql_next_result(mysql_local)));
14523 
14524   rc= mysql_query(mysql_local, "DROP TABLE IF EXISTS test_table");
14525   myquery(rc);
14526 
14527   mysql_close(mysql_local);
14528   DIE_UNLESS(res==1);
14529 }
14530 
14531 
14532 /* Bug#11909: wrong metadata if fetching from two cursors */
14533 
test_bug11909()14534 static void test_bug11909()
14535 {
14536   MYSQL_STMT *stmt1, *stmt2;
14537   MYSQL_BIND my_bind[7];
14538   int rc;
14539   char firstname[20], midinit[20], lastname[20], workdept[20];
14540   ulong firstname_len, midinit_len, lastname_len, workdept_len;
14541   uint32 empno;
14542   double salary;
14543   float bonus;
14544   const char *stmt_text;
14545 
14546   myheader("test_bug11909");
14547 
14548   stmt_text= "drop table if exists t1";
14549   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14550   myquery(rc);
14551 
14552   stmt_text= "create table t1 ("
14553     "  empno int(11) not null, firstname varchar(20) not null,"
14554     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14555     "  workdept varchar(6) not null, salary double not null,"
14556     "  bonus float not null, primary key (empno)"
14557     ") default charset=latin1 collate=latin1_bin";
14558   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14559   myquery(rc);
14560 
14561   stmt_text= "insert into t1 values "
14562     "(10, 'CHRISTINE', 'I', 'HAAS',     'A00', 52750, 1000), "
14563     "(20, 'MICHAEL',   'L', 'THOMPSON', 'B01', 41250, 800),"
14564     "(30, 'SALLY',     'A', 'KWAN',     'C01', 38250, 800),"
14565     "(50, 'JOHN',      'B', 'GEYER',    'E01', 40175, 800), "
14566     "(60, 'IRVING',    'F', 'STERN',    'D11', 32250, 500)";
14567   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14568   myquery(rc);
14569 
14570   /* ****** Begin of trace ****** */
14571 
14572   stmt1= open_cursor("SELECT empno, firstname, midinit, lastname,"
14573                      "workdept, salary, bonus FROM t1");
14574 
14575   bzero(my_bind, sizeof(my_bind));
14576   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14577   my_bind[0].buffer= (void*) &empno;
14578 
14579   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14580   my_bind[1].buffer= (void*) firstname;
14581   my_bind[1].buffer_length= sizeof(firstname);
14582   my_bind[1].length= &firstname_len;
14583 
14584   my_bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;
14585   my_bind[2].buffer= (void*) midinit;
14586   my_bind[2].buffer_length= sizeof(midinit);
14587   my_bind[2].length= &midinit_len;
14588 
14589   my_bind[3].buffer_type= MYSQL_TYPE_VAR_STRING;
14590   my_bind[3].buffer= (void*) lastname;
14591   my_bind[3].buffer_length= sizeof(lastname);
14592   my_bind[3].length= &lastname_len;
14593 
14594   my_bind[4].buffer_type= MYSQL_TYPE_VAR_STRING;
14595   my_bind[4].buffer= (void*) workdept;
14596   my_bind[4].buffer_length= sizeof(workdept);
14597   my_bind[4].length= &workdept_len;
14598 
14599   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
14600   my_bind[5].buffer= (void*) &salary;
14601 
14602   my_bind[6].buffer_type= MYSQL_TYPE_FLOAT;
14603   my_bind[6].buffer= (void*) &bonus;
14604   rc= mysql_stmt_bind_result(stmt1, my_bind);
14605   check_execute(stmt1, rc);
14606 
14607   rc= mysql_stmt_execute(stmt1);
14608   check_execute(stmt1, rc);
14609 
14610   rc= mysql_stmt_fetch(stmt1);
14611   DIE_UNLESS(rc == 0);
14612   DIE_UNLESS(empno == 10);
14613   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14614   DIE_UNLESS(strcmp(midinit, "I") == 0);
14615   DIE_UNLESS(strcmp(lastname, "HAAS") == 0);
14616   DIE_UNLESS(strcmp(workdept, "A00") == 0);
14617   DIE_UNLESS(salary == (double) 52750.0);
14618   DIE_UNLESS(bonus == (float) 1000.0);
14619 
14620   stmt2= open_cursor("SELECT empno, firstname FROM t1");
14621   rc= mysql_stmt_bind_result(stmt2, my_bind);
14622   check_execute(stmt2, rc);
14623 
14624   rc= mysql_stmt_execute(stmt2);
14625   check_execute(stmt2, rc);
14626 
14627   rc= mysql_stmt_fetch(stmt2);
14628   DIE_UNLESS(rc == 0);
14629 
14630   DIE_UNLESS(empno == 10);
14631   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14632 
14633   rc= mysql_stmt_reset(stmt2);
14634   check_execute(stmt2, rc);
14635 
14636   /* ERROR: next statement should return 0 */
14637 
14638   rc= mysql_stmt_fetch(stmt1);
14639   DIE_UNLESS(rc == 0);
14640 
14641   mysql_stmt_close(stmt1);
14642   mysql_stmt_close(stmt2);
14643   rc= mysql_rollback(mysql);
14644   myquery(rc);
14645 
14646   rc= mysql_query(mysql, "drop table t1");
14647   myquery(rc);
14648 }
14649 
14650 /* Cursors: opening a cursor to a compilicated query with ORDER BY */
14651 
test_bug11901()14652 static void test_bug11901()
14653 {
14654   MYSQL_STMT *stmt;
14655   MYSQL_BIND my_bind[2];
14656   int rc;
14657   char workdept[20];
14658   ulong workdept_len;
14659   uint32 empno;
14660   const char *stmt_text;
14661 
14662   myheader("test_bug11901");
14663 
14664   stmt_text= "drop table if exists t1, t2";
14665   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14666   myquery(rc);
14667 
14668   stmt_text= "create table t1 ("
14669     "  empno int(11) not null, firstname varchar(20) not null,"
14670     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14671     "  workdept varchar(6) not null, salary double not null,"
14672     "  bonus float not null, primary key (empno), "
14673     " unique key (workdept, empno) "
14674     ") default charset=latin1 collate=latin1_bin";
14675   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14676   myquery(rc);
14677 
14678   stmt_text= "insert into t1 values "
14679      "(10,  'CHRISTINE', 'I', 'HAAS',      'A00', 52750, 1000),"
14680      "(20,  'MICHAEL',   'L', 'THOMPSON',  'B01', 41250, 800), "
14681      "(30,  'SALLY',     'A', 'KWAN',      'C01', 38250, 800), "
14682      "(50,  'JOHN',      'B', 'GEYER',     'E01', 40175, 800), "
14683      "(60,  'IRVING',    'F', 'STERN',     'D11', 32250, 500), "
14684      "(70,  'EVA',       'D', 'PULASKI',   'D21', 36170, 700), "
14685      "(90,  'EILEEN',    'W', 'HENDERSON', 'E11', 29750, 600), "
14686      "(100, 'THEODORE',  'Q', 'SPENSER',   'E21', 26150, 500), "
14687      "(110, 'VINCENZO',  'G', 'LUCCHESSI', 'A00', 46500, 900), "
14688      "(120, 'SEAN',      '',  'O\\'CONNELL', 'A00', 29250, 600), "
14689      "(130, 'DOLORES',   'M', 'QUINTANA',  'C01', 23800, 500), "
14690      "(140, 'HEATHER',   'A', 'NICHOLLS',  'C01', 28420, 600), "
14691      "(150, 'BRUCE',     '',  'ADAMSON',   'D11', 25280, 500), "
14692      "(160, 'ELIZABETH', 'R', 'PIANKA',    'D11', 22250, 400), "
14693      "(170, 'MASATOSHI', 'J', 'YOSHIMURA', 'D11', 24680, 500), "
14694      "(180, 'MARILYN',   'S', 'SCOUTTEN',  'D11', 21340, 500), "
14695      "(190, 'JAMES',     'H', 'WALKER',    'D11', 20450, 400), "
14696      "(200, 'DAVID',     '',  'BROWN',     'D11', 27740, 600), "
14697      "(210, 'WILLIAM',   'T', 'JONES',     'D11', 18270, 400), "
14698      "(220, 'JENNIFER',  'K', 'LUTZ',      'D11', 29840, 600), "
14699      "(230, 'JAMES',     'J', 'JEFFERSON', 'D21', 22180, 400), "
14700      "(240, 'SALVATORE', 'M', 'MARINO',    'D21', 28760, 600), "
14701      "(250, 'DANIEL',    'S', 'SMITH',     'D21', 19180, 400), "
14702      "(260, 'SYBIL',     'P', 'JOHNSON',   'D21', 17250, 300), "
14703      "(270, 'MARIA',     'L', 'PEREZ',     'D21', 27380, 500), "
14704      "(280, 'ETHEL',     'R', 'SCHNEIDER', 'E11', 26250, 500), "
14705      "(290, 'JOHN',      'R', 'PARKER',    'E11', 15340, 300), "
14706      "(300, 'PHILIP',    'X', 'SMITH',     'E11', 17750, 400), "
14707      "(310, 'MAUDE',     'F', 'SETRIGHT',  'E11', 15900, 300), "
14708      "(320, 'RAMLAL',    'V', 'MEHTA',     'E21', 19950, 400), "
14709      "(330, 'WING',      '',  'LEE',       'E21', 25370, 500), "
14710      "(340, 'JASON',     'R', 'GOUNOT',    'E21', 23840, 500)";
14711 
14712   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14713   myquery(rc);
14714 
14715   stmt_text= "create table t2 ("
14716     " deptno varchar(6) not null, deptname varchar(20) not null,"
14717     " mgrno int(11) not null, location varchar(20) not null,"
14718     " admrdept varchar(6) not null, refcntd int(11) not null,"
14719     " refcntu int(11) not null, primary key (deptno)"
14720     ") default charset=latin1 collate=latin1_bin";
14721   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14722   myquery(rc);
14723 
14724   stmt_text= "insert into t2 values "
14725     "('A00', 'SPIFFY COMPUTER SERV', 10, '', 'A00', 0, 0), "
14726     "('B01', 'PLANNING',             20, '', 'A00', 0, 0), "
14727     "('C01', 'INFORMATION CENTER',   30, '', 'A00', 0, 0), "
14728     "('D01', 'DEVELOPMENT CENTER',   0,  '', 'A00', 0, 0),"
14729     "('D11', 'MANUFACTURING SYSTEM', 60, '', 'D01', 0, 0), "
14730     "('D21', 'ADMINISTRATION SYSTE', 70, '', 'D01', 0, 0), "
14731     "('E01', 'SUPPORT SERVICES',     50, '', 'A00', 0, 0), "
14732     "('E11', 'OPERATIONS',           90, '', 'E01', 0, 0), "
14733     "('E21', 'SOFTWARE SUPPORT',     100,'', 'E01', 0, 0)";
14734   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14735   myquery(rc);
14736 
14737   /* ****** Begin of trace ****** */
14738 
14739   stmt= open_cursor("select t1.empno, t1.workdept "
14740                     "from (t1 left join t2 on t2.deptno = t1.workdept) "
14741                     "where t2.deptno in "
14742                     "   (select t2.deptno "
14743                     "    from (t1 left join t2 on t2.deptno = t1.workdept) "
14744                     "    where t1.empno = ?) "
14745                     "order by 1");
14746   bzero(my_bind, sizeof(my_bind));
14747 
14748   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14749   my_bind[0].buffer= &empno;
14750   rc= mysql_stmt_bind_param(stmt, my_bind);
14751   check_execute(stmt, rc);
14752 
14753   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14754   my_bind[1].buffer= (void*) workdept;
14755   my_bind[1].buffer_length= sizeof(workdept);
14756   my_bind[1].length= &workdept_len;
14757 
14758   rc= mysql_stmt_bind_result(stmt, my_bind);
14759   check_execute(stmt, rc);
14760 
14761   empno= 10;
14762   /* ERROR: next statement causes a server crash */
14763   rc= mysql_stmt_execute(stmt);
14764   check_execute(stmt, rc);
14765 
14766   mysql_stmt_close(stmt);
14767 
14768   rc= mysql_query(mysql, "drop table t1, t2");
14769   myquery(rc);
14770 }
14771 
14772 /* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */
14773 
test_bug11904()14774 static void test_bug11904()
14775 {
14776   MYSQL_STMT *stmt1;
14777   int rc;
14778   const char *stmt_text;
14779   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
14780   MYSQL_BIND my_bind[2];
14781   int country_id=0;
14782   char row_data[11]= {0};
14783 
14784   myheader("test_bug11904");
14785 
14786   /* create tables */
14787   rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b");
14788   myquery(rc);
14789   rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))");
14790   myquery(rc);
14791 
14792   rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv'),"
14793                           " (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg'),"
14794                           " (3,'berlin'), (3, 'frankfurt')");
14795 
14796   myquery(rc);
14797   mysql_commit(mysql);
14798   /* create statement */
14799   stmt1= mysql_stmt_init(mysql);
14800   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14801 
14802   stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id";
14803 
14804   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14805   check_execute(stmt1, rc);
14806 
14807   memset(my_bind, 0, sizeof(my_bind));
14808   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14809   my_bind[0].buffer=& country_id;
14810   my_bind[0].buffer_length= 0;
14811   my_bind[0].length= 0;
14812 
14813   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14814   my_bind[1].buffer=& row_data;
14815   my_bind[1].buffer_length= sizeof(row_data) - 1;
14816   my_bind[1].length= 0;
14817 
14818   rc= mysql_stmt_bind_result(stmt1, my_bind);
14819   check_execute(stmt1, rc);
14820 
14821   rc= mysql_stmt_execute(stmt1);
14822   check_execute(stmt1, rc);
14823 
14824   rc= mysql_stmt_fetch(stmt1);
14825   check_execute(stmt1, rc);
14826   DIE_UNLESS(country_id == 1);
14827   DIE_UNLESS(memcmp(row_data, "plovdiv", 7) == 0);
14828 
14829   rc= mysql_stmt_fetch(stmt1);
14830   check_execute(stmt1, rc);
14831   DIE_UNLESS(country_id == 2);
14832   DIE_UNLESS(memcmp(row_data, "LA", 2) == 0);
14833 
14834   rc= mysql_stmt_fetch(stmt1);
14835   check_execute(stmt1, rc);
14836   DIE_UNLESS(country_id == 3);
14837   DIE_UNLESS(memcmp(row_data, "berlin", 6) == 0);
14838 
14839   rc= mysql_stmt_close(stmt1);
14840   check_execute(stmt1, rc);
14841 
14842   rc= mysql_query(mysql, "drop table bug11904b");
14843   myquery(rc);
14844 }
14845 
14846 
14847 /* Bug#12243: multiple cursors, crash in a fetch after commit. */
14848 
test_bug12243()14849 static void test_bug12243()
14850 {
14851   MYSQL_STMT *stmt1, *stmt2;
14852   int rc;
14853   const char *stmt_text;
14854   ulong type;
14855 
14856   myheader("test_bug12243");
14857 
14858   if (! have_innodb)
14859   {
14860     if (!opt_silent)
14861       printf("This test requires InnoDB.\n");
14862     return;
14863   }
14864 
14865   /* create tables */
14866   mysql_query(mysql, "drop table if exists t1");
14867   mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
14868   rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
14869   myquery(rc);
14870   mysql_autocommit(mysql, FALSE);
14871   /* create statement */
14872   stmt1= mysql_stmt_init(mysql);
14873   stmt2= mysql_stmt_init(mysql);
14874   type= (ulong) CURSOR_TYPE_READ_ONLY;
14875   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14876   mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14877 
14878   stmt_text= "select a from t1";
14879 
14880   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14881   check_execute(stmt1, rc);
14882   rc= mysql_stmt_execute(stmt1);
14883   check_execute(stmt1, rc);
14884   rc= mysql_stmt_fetch(stmt1);
14885   check_execute(stmt1, rc);
14886 
14887   rc= mysql_stmt_prepare(stmt2, stmt_text, strlen(stmt_text));
14888   check_execute(stmt2, rc);
14889   rc= mysql_stmt_execute(stmt2);
14890   check_execute(stmt2, rc);
14891   rc= mysql_stmt_fetch(stmt2);
14892   check_execute(stmt2, rc);
14893 
14894   rc= mysql_stmt_close(stmt1);
14895   check_execute(stmt1, rc);
14896   rc= mysql_commit(mysql);
14897   myquery(rc);
14898   rc= mysql_stmt_fetch(stmt2);
14899   check_execute(stmt2, rc);
14900 
14901   mysql_stmt_close(stmt2);
14902   rc= mysql_query(mysql, "drop table t1");
14903   myquery(rc);
14904   mysql_autocommit(mysql, TRUE);                /* restore default */
14905 }
14906 
14907 
14908 /*
14909   Bug#11718: query with function, join and order by returns wrong type
14910 */
14911 
test_bug11718()14912 static void test_bug11718()
14913 {
14914   MYSQL_RES	*res;
14915   int rc;
14916   const char *query= "select str_to_date(concat(f3),'%Y%m%d') from t1,t2 "
14917                      "where f1=f2 order by f1";
14918 
14919   myheader("test_bug11718");
14920 
14921   rc= mysql_query(mysql, "drop table if exists t1, t2");
14922   myquery(rc);
14923   rc= mysql_query(mysql, "create table t1 (f1 int)");
14924   myquery(rc);
14925   rc= mysql_query(mysql, "create table t2 (f2 int, f3 numeric(8))");
14926   myquery(rc);
14927   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14928   myquery(rc);
14929   rc= mysql_query(mysql, "insert into t2 values (1,20050101), (2,20050202)");
14930   myquery(rc);
14931   rc= mysql_query(mysql, query);
14932   myquery(rc);
14933   res = mysql_store_result(mysql);
14934 
14935   if (!opt_silent)
14936     printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
14937            "not DATE");
14938   DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
14939   mysql_free_result(res);
14940   rc= mysql_query(mysql, "drop table t1, t2");
14941   myquery(rc);
14942 }
14943 
14944 
14945 /*
14946   Bug #12925: Bad handling of maximum values in getopt
14947 */
test_bug12925()14948 static void test_bug12925()
14949 {
14950   myheader("test_bug12925");
14951   if (opt_getopt_ll_test)
14952     DIE_UNLESS(opt_getopt_ll_test == 25600LL*1024*1024);
14953 }
14954 
14955 
14956 /*
14957   Bug#14210 "Simple query with > operator on large table gives server
14958   crash"
14959 */
14960 
test_bug14210()14961 static void test_bug14210()
14962 {
14963   MYSQL_STMT *stmt;
14964   int rc, i;
14965   const char *stmt_text;
14966   ulong type;
14967 
14968   myheader("test_bug14210");
14969 
14970   mysql_query(mysql, "drop table if exists t1");
14971   /*
14972     To trigger the problem the table must be InnoDB, although the problem
14973     itself is not InnoDB related. In case the table is MyISAM this test
14974     is harmless.
14975   */
14976   mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB");
14977   rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
14978   myquery(rc);
14979   rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
14980   /* Create a big enough table (more than max_heap_table_size) */
14981   for (i= 0; i < 8; i++)
14982   {
14983     rc= mysql_query(mysql, "insert into t1 (a) select a from t1");
14984     myquery(rc);
14985   }
14986   /* create statement */
14987   stmt= mysql_stmt_init(mysql);
14988   type= (ulong) CURSOR_TYPE_READ_ONLY;
14989   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14990 
14991   stmt_text= "select a from t1";
14992 
14993   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14994   check_execute(stmt, rc);
14995   rc= mysql_stmt_execute(stmt);
14996   while ((rc= mysql_stmt_fetch(stmt)) == 0)
14997     ;
14998   DIE_UNLESS(rc == MYSQL_NO_DATA);
14999 
15000   rc= mysql_stmt_close(stmt);
15001 
15002   rc= mysql_query(mysql, "drop table t1");
15003   myquery(rc);
15004   rc= mysql_query(mysql, "set @@session.max_heap_table_size=default");
15005   myquery(rc);
15006 }
15007 
15008 /* Bug#13488: wrong column metadata when fetching from cursor */
15009 
test_bug13488()15010 static void test_bug13488()
15011 {
15012   MYSQL_BIND my_bind[3];
15013   MYSQL_STMT *stmt1;
15014   int rc, f1, f2, f3, i;
15015   const ulong type= CURSOR_TYPE_READ_ONLY;
15016   const char *query= "select * from t1 left join t2 on f1=f2 where f1=1";
15017 
15018   myheader("test_bug13488");
15019 
15020   rc= mysql_query(mysql, "drop table if exists t1, t2");
15021   myquery(rc);
15022   rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)");
15023   myquery(rc);
15024   rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, "
15025                   "f3 int not null)");
15026   myquery(rc);
15027   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
15028   myquery(rc);
15029   rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)");
15030   myquery(rc);
15031 
15032   memset(my_bind, 0, sizeof(my_bind));
15033   for (i= 0; i < 3; i++)
15034   {
15035     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
15036     my_bind[i].buffer_length= 4;
15037     my_bind[i].length= 0;
15038   }
15039   my_bind[0].buffer=&f1;
15040   my_bind[1].buffer=&f2;
15041   my_bind[2].buffer=&f3;
15042 
15043   stmt1= mysql_stmt_init(mysql);
15044   rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type);
15045   check_execute(stmt1, rc);
15046 
15047   rc= mysql_stmt_prepare(stmt1, query, strlen(query));
15048   check_execute(stmt1, rc);
15049 
15050   rc= mysql_stmt_execute(stmt1);
15051   check_execute(stmt1, rc);
15052 
15053   rc= mysql_stmt_bind_result(stmt1, my_bind);
15054   check_execute(stmt1, rc);
15055 
15056   rc= mysql_stmt_fetch(stmt1);
15057   check_execute(stmt1, rc);
15058 
15059   rc= mysql_stmt_free_result(stmt1);
15060   check_execute(stmt1, rc);
15061 
15062   rc= mysql_stmt_reset(stmt1);
15063   check_execute(stmt1, rc);
15064 
15065   rc= mysql_stmt_close(stmt1);
15066   check_execute(stmt1, rc);
15067 
15068   if (!opt_silent)
15069   {
15070     printf("data: f1: %d; f2: %d; f3: %d\n", f1, f2, f3);
15071     printf("data is: %s\n",
15072            (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong");
15073   }
15074   DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
15075   rc= mysql_query(mysql, "drop table t1, t2");
15076   myquery(rc);
15077 }
15078 
15079 /*
15080   Bug#13524: warnings of a previous command are not reset when fetching
15081   from a cursor.
15082 */
15083 
test_bug13524()15084 static void test_bug13524()
15085 {
15086   MYSQL_STMT *stmt;
15087   int rc;
15088   unsigned int warning_count;
15089   const ulong type= CURSOR_TYPE_READ_ONLY;
15090   const char *query= "select * from t1";
15091 
15092   myheader("test_bug13524");
15093 
15094   rc= mysql_query(mysql, "drop table if exists t1, t2");
15095   myquery(rc);
15096   rc= mysql_query(mysql, "create table t1 (a int not null primary key)");
15097   myquery(rc);
15098   rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
15099   myquery(rc);
15100 
15101   stmt= mysql_stmt_init(mysql);
15102   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15103   check_execute(stmt, rc);
15104 
15105   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15106   check_execute(stmt, rc);
15107 
15108   rc= mysql_stmt_execute(stmt);
15109   check_execute(stmt, rc);
15110 
15111   rc= mysql_stmt_fetch(stmt);
15112   check_execute(stmt, rc);
15113 
15114   warning_count= mysql_warning_count(mysql);
15115   DIE_UNLESS(warning_count == 0);
15116 
15117   /* Check that DROP TABLE produced a warning (no such table) */
15118   rc= mysql_query(mysql, "drop table if exists t2");
15119   myquery(rc);
15120   warning_count= mysql_warning_count(mysql);
15121   DIE_UNLESS(warning_count == 1);
15122 
15123   /*
15124     Check that fetch from a cursor cleared the warning from the previous
15125     command.
15126   */
15127   rc= mysql_stmt_fetch(stmt);
15128   check_execute(stmt, rc);
15129   warning_count= mysql_warning_count(mysql);
15130   DIE_UNLESS(warning_count == 0);
15131 
15132   /* Cleanup */
15133   mysql_stmt_close(stmt);
15134   rc= mysql_query(mysql, "drop table t1");
15135   myquery(rc);
15136 }
15137 
15138 /*
15139   Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
15140 */
15141 
test_bug14845()15142 static void test_bug14845()
15143 {
15144   MYSQL_STMT *stmt;
15145   int rc;
15146   const ulong type= CURSOR_TYPE_READ_ONLY;
15147   const char *query= "select count(*) from t1 where 1 = 0";
15148 
15149   myheader("test_bug14845");
15150 
15151   rc= mysql_query(mysql, "drop table if exists t1");
15152   myquery(rc);
15153   rc= mysql_query(mysql, "create table t1 (id int(11) default null, "
15154                          "name varchar(20) default null)"
15155                          "engine=MyISAM DEFAULT CHARSET=utf8");
15156   myquery(rc);
15157   rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')");
15158   myquery(rc);
15159 
15160   stmt= mysql_stmt_init(mysql);
15161   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15162   check_execute(stmt, rc);
15163 
15164   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15165   check_execute(stmt, rc);
15166 
15167   rc= mysql_stmt_execute(stmt);
15168   check_execute(stmt, rc);
15169 
15170   rc= mysql_stmt_fetch(stmt);
15171   DIE_UNLESS(rc == 0);
15172 
15173   rc= mysql_stmt_fetch(stmt);
15174   DIE_UNLESS(rc == MYSQL_NO_DATA);
15175 
15176   /* Cleanup */
15177   mysql_stmt_close(stmt);
15178   rc= mysql_query(mysql, "drop table t1");
15179   myquery(rc);
15180 }
15181 
15182 
15183 /*
15184   Bug #15510: mysql_warning_count returns 0 after mysql_stmt_fetch which
15185   should warn
15186 */
test_bug15510()15187 static void test_bug15510()
15188 {
15189   MYSQL_STMT *stmt;
15190   int rc;
15191   const char *query= "select 1 from dual where 1/0";
15192 
15193   myheader("test_bug15510");
15194 
15195   rc= mysql_query(mysql, "set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'");
15196   myquery(rc);
15197 
15198   stmt= mysql_stmt_init(mysql);
15199 
15200   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15201   check_execute(stmt, rc);
15202 
15203   rc= mysql_stmt_execute(stmt);
15204   check_execute(stmt, rc);
15205 
15206   rc= mysql_stmt_fetch(stmt);
15207   DIE_UNLESS(mysql_warning_count(mysql));
15208 
15209   /* Cleanup */
15210   mysql_stmt_close(stmt);
15211   rc= mysql_query(mysql, "set @@sql_mode=''");
15212   myquery(rc);
15213 }
15214 
15215 
15216 /* Test MYSQL_OPT_RECONNECT, Bug#15719 */
15217 
test_opt_reconnect()15218 static void test_opt_reconnect()
15219 {
15220   MYSQL *lmysql;
15221 
15222 
15223   myheader("test_opt_reconnect");
15224 
15225   if (!(lmysql= mysql_client_init(NULL)))
15226   {
15227     myerror("mysql_client_init() failed");
15228     exit(1);
15229   }
15230 
15231   if (!opt_silent)
15232     fprintf(stdout, "reconnect before mysql_options: %d\n", get_reconnect(lmysql));
15233   DIE_UNLESS(get_reconnect(lmysql) == 0);
15234 
15235   if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
15236   {
15237     myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
15238     DIE_UNLESS(0);
15239   }
15240 
15241   /* reconnect should be 1 */
15242   if (!opt_silent)
15243     fprintf(stdout, "reconnect after mysql_options: %d\n", get_reconnect(lmysql));
15244   DIE_UNLESS(get_reconnect(lmysql) == 1);
15245 
15246   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15247                            opt_password, current_db, opt_port,
15248                            opt_unix_socket, 0)))
15249   {
15250     myerror("connection failed");
15251     DIE_UNLESS(0);
15252   }
15253 
15254   /* reconnect should still be 1 */
15255   if (!opt_silent)
15256     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15257 	    get_reconnect(lmysql));
15258   DIE_UNLESS(get_reconnect(lmysql) == 1);
15259 
15260   mysql_close(lmysql);
15261 
15262   if (!(lmysql= mysql_client_init(NULL)))
15263   {
15264     myerror("mysql_client_init() failed");
15265     DIE_UNLESS(0);
15266   }
15267 
15268   if (!opt_silent)
15269     fprintf(stdout, "reconnect before mysql_real_connect: %d\n", get_reconnect(lmysql));
15270   DIE_UNLESS(get_reconnect(lmysql) == 0);
15271 
15272   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15273                            opt_password, current_db, opt_port,
15274                            opt_unix_socket, 0)))
15275   {
15276     myerror("connection failed");
15277     DIE_UNLESS(0);
15278   }
15279 
15280   /* reconnect should still be 0 */
15281   if (!opt_silent)
15282     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15283 	    get_reconnect(lmysql));
15284   DIE_UNLESS(get_reconnect(lmysql) == 0);
15285 
15286   mysql_close(lmysql);
15287 }
15288 
15289 
15290 #ifndef EMBEDDED_LIBRARY
15291 
test_bug12744()15292 static void test_bug12744()
15293 {
15294   MYSQL_STMT *prep_stmt = NULL;
15295   MYSQL *lmysql;
15296   int rc;
15297   myheader("test_bug12744");
15298 
15299   lmysql= mysql_client_init(NULL);
15300   DIE_UNLESS(lmysql);
15301 
15302   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
15303                           current_db, opt_port, opt_unix_socket, 0))
15304   {
15305     fprintf(stderr, "Failed to connect to the database\n");
15306     DIE_UNLESS(0);
15307   }
15308 
15309   prep_stmt= mysql_stmt_init(lmysql);
15310   rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
15311   DIE_UNLESS(rc == 0);
15312 
15313   mysql_close(lmysql);
15314 
15315   rc= mysql_stmt_execute(prep_stmt);
15316   DIE_UNLESS(rc);
15317   rc= mysql_stmt_reset(prep_stmt);
15318   DIE_UNLESS(rc);
15319   rc= mysql_stmt_close(prep_stmt);
15320   DIE_UNLESS(rc == 0);
15321 }
15322 
15323 #endif /* EMBEDDED_LIBRARY */
15324 
15325 /* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
15326 
test_bug16143()15327 static void test_bug16143()
15328 {
15329   MYSQL_STMT *stmt;
15330   myheader("test_bug16143");
15331 
15332   stmt= mysql_stmt_init(mysql);
15333   /* Check mysql_stmt_sqlstate return "no error" */
15334   DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0);
15335 
15336   mysql_stmt_close(stmt);
15337 }
15338 
15339 
15340 /* Bug #16144: mysql_stmt_attr_get type error */
15341 
test_bug16144()15342 static void test_bug16144()
15343 {
15344   const my_bool flag_orig= (my_bool) 0xde;
15345   my_bool flag= flag_orig;
15346   MYSQL_STMT *stmt;
15347   myheader("test_bug16144");
15348 
15349   /* Check that attr_get returns correct data on little and big endian CPUs */
15350   stmt= mysql_stmt_init(mysql);
15351   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
15352   mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
15353   DIE_UNLESS(flag == flag_orig);
15354 
15355   mysql_stmt_close(stmt);
15356 }
15357 
15358 /*
15359   Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
15360   field length"
15361 */
15362 
test_bug15613()15363 static void test_bug15613()
15364 {
15365   MYSQL_STMT *stmt;
15366   const char *stmt_text;
15367   MYSQL_RES *metadata;
15368   MYSQL_FIELD *field;
15369   int rc;
15370   myheader("test_bug15613");
15371 
15372   /* I. Prepare the table */
15373   rc= mysql_query(mysql, "set names latin1");
15374   myquery(rc);
15375   mysql_query(mysql, "drop table if exists t1");
15376   rc= mysql_query(mysql,
15377                   "create table t1 (t text character set utf8, "
15378                                    "tt tinytext character set utf8, "
15379                                    "mt mediumtext character set utf8, "
15380                                    "lt longtext character set utf8, "
15381                                    "vl varchar(255) character set latin1,"
15382                                    "vb varchar(255) character set binary,"
15383                                    "vu varchar(255) character set utf8)");
15384   myquery(rc);
15385 
15386   stmt= mysql_stmt_init(mysql);
15387 
15388   /* II. Check SELECT metadata */
15389   stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
15390   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15391   metadata= mysql_stmt_result_metadata(stmt);
15392   field= mysql_fetch_fields(metadata);
15393   if (!opt_silent)
15394   {
15395     printf("Field lengths (client character set is latin1):\n"
15396            "text character set utf8:\t\t%lu\n"
15397            "tinytext character set utf8:\t\t%lu\n"
15398            "mediumtext character set utf8:\t\t%lu\n"
15399            "longtext character set utf8:\t\t%lu\n"
15400            "varchar(255) character set latin1:\t%lu\n"
15401            "varchar(255) character set binary:\t%lu\n"
15402            "varchar(255) character set utf8:\t%lu\n",
15403            field[0].length, field[1].length, field[2].length, field[3].length,
15404            field[4].length, field[5].length, field[6].length);
15405   }
15406   DIE_UNLESS(field[0].length == 65535);
15407   DIE_UNLESS(field[1].length == 255);
15408   DIE_UNLESS(field[2].length == 16777215);
15409   DIE_UNLESS(field[3].length == 4294967295UL);
15410   DIE_UNLESS(field[4].length == 255);
15411   DIE_UNLESS(field[5].length == 255);
15412   DIE_UNLESS(field[6].length == 255);
15413   mysql_free_result(metadata);
15414   mysql_stmt_free_result(stmt);
15415 
15416   /* III. Cleanup */
15417   rc= mysql_query(mysql, "drop table t1");
15418   myquery(rc);
15419   rc= mysql_query(mysql, "set names default");
15420   myquery(rc);
15421   mysql_stmt_close(stmt);
15422 }
15423 
15424 /*
15425   Bug#17667: An attacker has the opportunity to bypass query logging.
15426 
15427   Note! Also tests Bug#21813, where prepared statements are used to
15428   run queries
15429 */
test_bug17667()15430 static void test_bug17667()
15431 {
15432   int rc;
15433   MYSQL_STMT *stmt;
15434   enum query_type { QT_NORMAL, QT_PREPARED};
15435   struct buffer_and_length {
15436     enum query_type qt;
15437     const char *buffer;
15438     const uint length;
15439   } statements[]= {
15440     { QT_NORMAL, "drop table if exists bug17667", 29 },
15441     { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
15442     { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
15443     { QT_PREPARED,
15444       "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
15445     { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
15446     { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
15447     { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
15448     { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
15449     { QT_NORMAL, "drop table bug17667", 19 },
15450     { QT_NORMAL, NULL, 0 } };
15451 
15452   struct buffer_and_length *statement_cursor;
15453   FILE *log_file;
15454   char *master_log_filename;
15455 
15456   myheader("test_bug17667");
15457 
15458   master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1);
15459   strxmov(master_log_filename, opt_vardir, "/log/master.log", NullS);
15460   if (!opt_silent)
15461     printf("Opening '%s'\n", master_log_filename);
15462   log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0));
15463   free(master_log_filename);
15464 
15465   if (log_file == NULL)
15466   {
15467     if (!opt_silent)
15468     {
15469       printf("Could not find the log file, VARDIR/log/master.log, so "
15470              "test_bug17667 is not run.\n"
15471              "Run test from the mysql-test/mysql-test-run* program to set up "
15472              "correct environment for this test.\n\n");
15473     }
15474     return;
15475   }
15476 
15477   enable_query_logs(1);
15478 
15479   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15480        statement_cursor++)
15481   {
15482     if (statement_cursor->qt == QT_NORMAL)
15483     {
15484       /* Run statement as normal query */
15485       rc= mysql_real_query(mysql, statement_cursor->buffer,
15486                            statement_cursor->length);
15487       myquery(rc);
15488     }
15489     else if (statement_cursor->qt == QT_PREPARED)
15490     {
15491       /*
15492         Run as prepared statement
15493 
15494         NOTE! All these queries should be in the log twice,
15495         one time for prepare and one time for execute
15496       */
15497       stmt= mysql_stmt_init(mysql);
15498 
15499       rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
15500                              statement_cursor->length);
15501       check_execute(stmt, rc);
15502 
15503       rc= mysql_stmt_execute(stmt);
15504       check_execute(stmt, rc);
15505 
15506       mysql_stmt_close(stmt);
15507     }
15508     else
15509     {
15510       DIE_UNLESS(0==1);
15511     }
15512   }
15513 
15514   /* Make sure the server has written the logs to disk before reading it */
15515   rc= mysql_query(mysql, "flush logs");
15516   myquery(rc);
15517 
15518   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15519        statement_cursor++)
15520   {
15521     int expected_hits= 1, hits= 0;
15522     char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15523     /* more than enough room for the query and some marginalia. */
15524 
15525     /* Prepared statments always occurs twice in log */
15526     if (statement_cursor->qt == QT_PREPARED)
15527       expected_hits++;
15528 
15529     /* Loop until we found expected number of log entries */
15530     do {
15531       /* Loop until statement is found in log */
15532       do {
15533         memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15534 
15535         if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15536         {
15537           /* If fgets returned NULL, it indicates either error or EOF */
15538           if (feof(log_file))
15539             DIE("Found EOF before all statements where found");
15540 
15541           fprintf(stderr, "Got error %d while reading from file\n",
15542                   ferror(log_file));
15543           DIE("Read error");
15544         }
15545 
15546       } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15547                          statement_cursor->buffer,
15548                          statement_cursor->length) == NULL);
15549       hits++;
15550     } while (hits < expected_hits);
15551 
15552     if (!opt_silent)
15553       printf("Found statement starting with \"%s\"\n",
15554              statement_cursor->buffer);
15555   }
15556 
15557   restore_query_logs();
15558 
15559   if (!opt_silent)
15560     printf("success.  All queries found intact in the log.\n");
15561 
15562   my_fclose(log_file, MYF(0));
15563 }
15564 
15565 
15566 /*
15567   Bug#14169: type of group_concat() result changed to blob if tmp_table was
15568   used
15569 */
test_bug14169()15570 static void test_bug14169()
15571 {
15572   MYSQL_STMT *stmt;
15573   const char *stmt_text;
15574   MYSQL_RES *res;
15575   MYSQL_FIELD *field;
15576   int rc;
15577 
15578   myheader("test_bug14169");
15579 
15580   rc= mysql_query(mysql, "drop table if exists t1");
15581   myquery(rc);
15582   rc= mysql_query(mysql, "set session group_concat_max_len=1024");
15583   myquery(rc);
15584   rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))");
15585   myquery(rc);
15586   rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255)),"
15587                          "(2,repeat('b',255))");
15588   myquery(rc);
15589   stmt= mysql_stmt_init(mysql);
15590   stmt_text= "select f2,group_concat(f1) from t1 group by f2";
15591   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15592   myquery(rc);
15593   res= mysql_stmt_result_metadata(stmt);
15594   field= mysql_fetch_fields(res);
15595   if (!opt_silent)
15596     printf("GROUP_CONCAT() result type %i", field[1].type);
15597   DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
15598   mysql_free_result(res);
15599   mysql_stmt_free_result(stmt);
15600   mysql_stmt_close(stmt);
15601 
15602   rc= mysql_query(mysql, "drop table t1");
15603   myquery(rc);
15604 
15605   rc= mysql_query(mysql, "set session group_concat_max_len=@@global.group_concat_max_len");
15606   myquery(rc);
15607 }
15608 
15609 /*
15610    Test that mysql_insert_id() behaves as documented in our manual
15611 */
test_mysql_insert_id()15612 static void test_mysql_insert_id()
15613 {
15614   my_ulonglong res;
15615   int rc;
15616 
15617   myheader("test_mysql_insert_id");
15618 
15619   rc= mysql_query(mysql, "drop table if exists t1,t2");
15620   myquery(rc);
15621   /* table without auto_increment column */
15622   rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
15623   myquery(rc);
15624   rc= mysql_query(mysql, "insert into t1 values (1,'a')");
15625   myquery(rc);
15626   res= mysql_insert_id(mysql);
15627   DIE_UNLESS(res == 0);
15628   rc= mysql_query(mysql, "insert into t1 values (null,'b')");
15629   myquery(rc);
15630   res= mysql_insert_id(mysql);
15631   DIE_UNLESS(res == 0);
15632   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15633   myquery(rc);
15634   res= mysql_insert_id(mysql);
15635   DIE_UNLESS(res == 0);
15636 
15637   /*
15638     Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
15639     sporadically
15640   */
15641   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15642   myquery(rc);
15643   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15644   myquery(rc);
15645   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15646   myquery(rc);
15647   res= mysql_insert_id(mysql);
15648   DIE_UNLESS(res == 0);
15649   rc= mysql_query(mysql, "drop table t2");
15650   myquery(rc);
15651 
15652   rc= mysql_query(mysql, "insert into t1 select null,'d'");
15653   myquery(rc);
15654   res= mysql_insert_id(mysql);
15655   DIE_UNLESS(res == 0);
15656   rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
15657   myquery(rc);
15658   res= mysql_insert_id(mysql);
15659   DIE_UNLESS(res == 300);
15660   rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
15661   myquery(rc);
15662   res= mysql_insert_id(mysql);
15663   /*
15664     Behaviour change: old code used to return 0; but 400 is consistent
15665     with INSERT VALUES, and the manual's section of mysql_insert_id() does not
15666     say INSERT SELECT should be different.
15667   */
15668   DIE_UNLESS(res == 400);
15669 
15670   /* table with auto_increment column */
15671   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15672   myquery(rc);
15673   rc= mysql_query(mysql, "insert into t2 values (1,'a')");
15674   myquery(rc);
15675   res= mysql_insert_id(mysql);
15676   DIE_UNLESS(res == 1);
15677   /* this should not influence next INSERT if it doesn't have auto_inc */
15678   rc= mysql_query(mysql, "insert into t1 values (10,'e')");
15679   myquery(rc);
15680   res= mysql_insert_id(mysql);
15681   DIE_UNLESS(res == 0);
15682 
15683   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15684   myquery(rc);
15685   res= mysql_insert_id(mysql);
15686   DIE_UNLESS(res == 2);
15687   rc= mysql_query(mysql, "insert into t2 select 5,'c'");
15688   myquery(rc);
15689   res= mysql_insert_id(mysql);
15690   /*
15691     Manual says that for multirow insert this should have been 5, but does not
15692     say for INSERT SELECT. This is a behaviour change: old code used to return
15693     0. We try to be consistent with INSERT VALUES.
15694   */
15695   DIE_UNLESS(res == 5);
15696   rc= mysql_query(mysql, "insert into t2 select null,'d'");
15697   myquery(rc);
15698   res= mysql_insert_id(mysql);
15699   DIE_UNLESS(res == 6);
15700   /* with more than one row */
15701   rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
15702   myquery(rc);
15703   res= mysql_insert_id(mysql);
15704   DIE_UNLESS(res == 11);
15705   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15706   myquery(rc);
15707   res= mysql_insert_id(mysql);
15708   /*
15709     Manual says that for multirow insert this should have been 13, but does
15710     not say for INSERT SELECT. This is a behaviour change: old code used to
15711     return 0. We try to be consistent with INSERT VALUES.
15712   */
15713   DIE_UNLESS(res == 13);
15714   rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
15715   myquery(rc);
15716   res= mysql_insert_id(mysql);
15717   DIE_UNLESS(res == 14);
15718   rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
15719   myquery(rc);
15720   res= mysql_insert_id(mysql);
15721   DIE_UNLESS(res == 16);
15722   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15723   myquery_r(rc);
15724   rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
15725   myquery(rc);
15726   res= mysql_insert_id(mysql);
15727   DIE_UNLESS(res == 0);
15728   rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
15729   myquery_r(rc);
15730   res= mysql_insert_id(mysql);
15731   DIE_UNLESS(res == 0);
15732   rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
15733   myquery(rc);
15734   res= mysql_insert_id(mysql);
15735   DIE_UNLESS(res == 0);
15736   /* mixing autogenerated and explicit values */
15737   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
15738   myquery_r(rc);
15739   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
15740   myquery_r(rc);
15741   rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
15742   myquery(rc);
15743   res= mysql_insert_id(mysql);
15744   /*
15745     according to the manual, this might be 20 or 300, but it looks like
15746     auto_increment column takes priority over last_insert_id().
15747   */
15748   DIE_UNLESS(res == 20);
15749   /* If first autogenerated number fails and 2nd works: */
15750   rc= mysql_query(mysql, "drop table t2");
15751   myquery(rc);
15752   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
15753                   "auto_increment, f2 varchar(255), unique (f2))");
15754   myquery(rc);
15755   rc= mysql_query(mysql, "insert into t2 values (null,'e')");
15756   res= mysql_insert_id(mysql);
15757   DIE_UNLESS(res == 1);
15758   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
15759   myquery(rc);
15760   res= mysql_insert_id(mysql);
15761   DIE_UNLESS(res == 2);
15762   /* If autogenerated fails and explicit works: */
15763   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
15764   myquery(rc);
15765   res= mysql_insert_id(mysql);
15766   /*
15767     Behaviour change: old code returned 3 (first autogenerated, even if it
15768     fails); we now return first successful autogenerated.
15769   */
15770   DIE_UNLESS(res == 13);
15771   /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
15772   rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
15773   myquery(rc);
15774   res= mysql_insert_id(mysql);
15775   DIE_UNLESS(res == 0);
15776   rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
15777   myquery(rc);
15778   res= mysql_insert_id(mysql);
15779   DIE_UNLESS(res == 0);
15780   rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
15781   myquery(rc);
15782   res= mysql_insert_id(mysql);
15783   DIE_UNLESS(res == 372);
15784   /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
15785   rc= mysql_query(mysql, "insert into t2 values (null,'g')");
15786   myquery(rc);
15787   res= mysql_insert_id(mysql);
15788   DIE_UNLESS(res == 15);
15789   rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
15790   myquery(rc);
15791   res= mysql_insert_id(mysql);
15792   DIE_UNLESS(res == 0);
15793   /*
15794     Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
15795     mysql_insert_id() returns the id of the row, instead of not being
15796     affected.
15797   */
15798   rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
15799                   "update f2=concat('we updated ',f2)");
15800   myquery(rc);
15801   res= mysql_insert_id(mysql);
15802   DIE_UNLESS(res == 15);
15803 
15804   rc= mysql_query(mysql, "drop table t1,t2");
15805   myquery(rc);
15806 }
15807 
15808 /*
15809   Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
15810 */
15811 
test_bug20152()15812 static void test_bug20152()
15813 {
15814   MYSQL_BIND my_bind[1];
15815   MYSQL_STMT *stmt;
15816   MYSQL_TIME tm;
15817   int rc;
15818   const char *query= "INSERT INTO t1 (f1) VALUES (?)";
15819 
15820   myheader("test_bug20152");
15821 
15822   memset(my_bind, 0, sizeof(my_bind));
15823   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
15824   my_bind[0].buffer= (void*)&tm;
15825 
15826   tm.year = 2006;
15827   tm.month = 6;
15828   tm.day = 18;
15829   tm.hour = 14;
15830   tm.minute = 9;
15831   tm.second = 42;
15832 
15833   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15834   myquery(rc);
15835   rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)");
15836   myquery(rc);
15837 
15838   stmt= mysql_stmt_init(mysql);
15839   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15840   check_execute(stmt, rc);
15841   rc= mysql_stmt_bind_param(stmt, my_bind);
15842   check_execute(stmt, rc);
15843   rc= mysql_stmt_execute(stmt);
15844   check_execute(stmt, rc);
15845   rc= mysql_stmt_close(stmt);
15846   check_execute(stmt, rc);
15847   rc= mysql_query(mysql, "DROP TABLE t1");
15848   myquery(rc);
15849 
15850   if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) {
15851     if (!opt_silent)
15852       printf("OK!");
15853   } else {
15854     printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second);
15855     DIE_UNLESS(0==1);
15856   }
15857 }
15858 
15859 /* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
15860 
test_bug15752()15861 static void test_bug15752()
15862 {
15863   MYSQL mysql_local;
15864   int rc, i;
15865   const int ITERATION_COUNT= 100;
15866   const char *query= "CALL p1()";
15867 
15868   myheader("test_bug15752");
15869 
15870   rc= mysql_query(mysql, "drop procedure if exists p1");
15871   myquery(rc);
15872   rc= mysql_query(mysql, "create procedure p1() select 1");
15873   myquery(rc);
15874 
15875   mysql_client_init(&mysql_local);
15876   if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
15877                            opt_password, current_db, opt_port,
15878                            opt_unix_socket,
15879                            CLIENT_MULTI_STATEMENTS))
15880   {
15881     printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
15882     DIE_UNLESS(0);
15883   }
15884   rc= mysql_real_query(&mysql_local, query, strlen(query));
15885   myquery(rc);
15886   mysql_free_result(mysql_store_result(&mysql_local));
15887 
15888   rc= mysql_real_query(&mysql_local, query, strlen(query));
15889   DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
15890 
15891   if (! opt_silent)
15892     printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
15893 
15894   /* Check some other commands too */
15895 
15896   DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15897   mysql_free_result(mysql_store_result(&mysql_local));
15898   DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15899 
15900   /* The second problem is not reproducible: add the test case */
15901   for (i = 0; i < ITERATION_COUNT; i++)
15902   {
15903     if (mysql_real_query(&mysql_local, query, strlen(query)))
15904     {
15905       printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
15906       break;
15907     }
15908     mysql_free_result(mysql_store_result(&mysql_local));
15909     DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15910     mysql_free_result(mysql_store_result(&mysql_local));
15911     DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15912 
15913   }
15914   mysql_close(&mysql_local);
15915   rc= mysql_query(mysql, "drop procedure p1");
15916   myquery(rc);
15917 }
15918 
15919 /*
15920   Bug#21206: memory corruption when too many cursors are opened at once
15921 
15922   Memory corruption happens when more than 1024 cursors are open
15923   simultaneously.
15924 */
test_bug21206()15925 static void test_bug21206()
15926 {
15927   const size_t cursor_count= 1025;
15928 
15929   const char *create_table[]=
15930   {
15931     "DROP TABLE IF EXISTS t1",
15932     "CREATE TABLE t1 (i INT)",
15933     "INSERT INTO t1 VALUES (1), (2), (3)"
15934   };
15935   const char *query= "SELECT * FROM t1";
15936 
15937   Stmt_fetch *fetch_array=
15938     (Stmt_fetch*) calloc(cursor_count, sizeof(Stmt_fetch));
15939 
15940   Stmt_fetch *fetch;
15941 
15942   DBUG_ENTER("test_bug21206");
15943   myheader("test_bug21206");
15944 
15945   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
15946 
15947   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15948   {
15949     /* Init will exit(1) in case of error */
15950     stmt_fetch_init(fetch, (uint)(fetch - fetch_array), query);
15951   }
15952 
15953   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15954     stmt_fetch_close(fetch);
15955 
15956   free(fetch_array);
15957 
15958   DBUG_VOID_RETURN;
15959 }
15960 
15961 /*
15962   Ensure we execute the status code while testing
15963 */
15964 
test_status()15965 static void test_status()
15966 {
15967   DBUG_ENTER("test_status");
15968   myheader("test_status");
15969 
15970   if (!mysql_stat(mysql))
15971   {
15972     myerror("mysql_stat failed");                 /* purecov: inspected */
15973     die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
15974   }
15975   DBUG_VOID_RETURN;
15976 }
15977 
15978 /*
15979   Bug#21726: Incorrect result with multiple invocations of
15980   LAST_INSERT_ID
15981 
15982   Test that client gets updated value of insert_id on UPDATE that uses
15983   LAST_INSERT_ID(expr).
15984   select_query added to test for bug
15985     #26921 Problem in mysql_insert_id() Embedded C API function
15986 */
test_bug21726()15987 static void test_bug21726()
15988 {
15989   const char *create_table[]=
15990   {
15991     "DROP TABLE IF EXISTS t1",
15992     "CREATE TABLE t1 (i INT)",
15993     "INSERT INTO t1 VALUES (1)",
15994   };
15995   const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
15996   int rc;
15997   my_ulonglong insert_id;
15998   const char *select_query= "SELECT * FROM t1";
15999   MYSQL_RES  *result;
16000 
16001   DBUG_ENTER("test_bug21726");
16002   myheader("test_bug21726");
16003 
16004   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
16005 
16006   rc= mysql_query(mysql, update_query);
16007   myquery(rc);
16008   insert_id= mysql_insert_id(mysql);
16009   DIE_UNLESS(insert_id == 2);
16010 
16011   rc= mysql_query(mysql, update_query);
16012   myquery(rc);
16013   insert_id= mysql_insert_id(mysql);
16014   DIE_UNLESS(insert_id == 3);
16015 
16016   rc= mysql_query(mysql, select_query);
16017   myquery(rc);
16018   insert_id= mysql_insert_id(mysql);
16019   DIE_UNLESS(insert_id == 3);
16020   result= mysql_store_result(mysql);
16021   mysql_free_result(result);
16022 
16023   DBUG_VOID_RETURN;
16024 }
16025 
16026 
16027 /*
16028   BUG#23383: mysql_affected_rows() returns different values than
16029   mysql_stmt_affected_rows()
16030 
16031   Test that both mysql_affected_rows() and mysql_stmt_affected_rows()
16032   return -1 on error, 0 when no rows were affected, and (positive) row
16033   count when some rows were affected.
16034 */
test_bug23383()16035 static void test_bug23383()
16036 {
16037   const char *insert_query= "INSERT INTO t1 VALUES (1), (2)";
16038   const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3";
16039   MYSQL_STMT *stmt;
16040   my_ulonglong row_count;
16041   int rc;
16042 
16043   DBUG_ENTER("test_bug23383");
16044   myheader("test_bug23383");
16045 
16046   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16047   myquery(rc);
16048 
16049   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)");
16050   myquery(rc);
16051 
16052   rc= mysql_query(mysql, insert_query);
16053   myquery(rc);
16054   row_count= mysql_affected_rows(mysql);
16055   DIE_UNLESS(row_count == 2);
16056 
16057   rc= mysql_query(mysql, insert_query);
16058   DIE_UNLESS(rc != 0);
16059   row_count= mysql_affected_rows(mysql);
16060   DIE_UNLESS(row_count == (my_ulonglong)-1);
16061 
16062   rc= mysql_query(mysql, update_query);
16063   myquery(rc);
16064   row_count= mysql_affected_rows(mysql);
16065   DIE_UNLESS(row_count == 0);
16066 
16067   rc= mysql_query(mysql, "DELETE FROM t1");
16068   myquery(rc);
16069 
16070   stmt= mysql_stmt_init(mysql);
16071   DIE_UNLESS(stmt != 0);
16072 
16073   rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query));
16074   check_execute(stmt, rc);
16075 
16076   rc= mysql_stmt_execute(stmt);
16077   check_execute(stmt, rc);
16078   row_count= mysql_stmt_affected_rows(stmt);
16079   DIE_UNLESS(row_count == 2);
16080 
16081   rc= mysql_stmt_execute(stmt);
16082   DIE_UNLESS(rc != 0);
16083   row_count= mysql_stmt_affected_rows(stmt);
16084   DIE_UNLESS(row_count == (my_ulonglong)-1);
16085 
16086   rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query));
16087   check_execute(stmt, rc);
16088 
16089   rc= mysql_stmt_execute(stmt);
16090   check_execute(stmt, rc);
16091   row_count= mysql_stmt_affected_rows(stmt);
16092   DIE_UNLESS(row_count == 0);
16093 
16094   rc= mysql_stmt_close(stmt);
16095   check_execute(stmt, rc);
16096 
16097   rc= mysql_query(mysql, "DROP TABLE t1");
16098   myquery(rc);
16099 
16100   DBUG_VOID_RETURN;
16101 }
16102 
16103 
16104 /*
16105   BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for
16106   expression cols
16107 
16108   Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set
16109   to either expression or its alias, and db, org_table, table,
16110   org_name fields are empty strings.
16111 */
test_bug21635()16112 static void test_bug21635()
16113 {
16114   const char *expr[]=
16115   {
16116     "MIN(i)", "MIN(i)",
16117     "MIN(i) AS A1", "A1",
16118     "MAX(i)", "MAX(i)",
16119     "MAX(i) AS A2", "A2",
16120     "COUNT(i)", "COUNT(i)",
16121     "COUNT(i) AS A3", "A3",
16122   };
16123   char query[MAX_TEST_QUERY_LENGTH];
16124   char *query_end;
16125   MYSQL_RES *result;
16126   MYSQL_FIELD *field;
16127   unsigned int field_count, i, j;
16128   int rc;
16129 
16130   DBUG_ENTER("test_bug21635");
16131   myheader("test_bug21635");
16132 
16133   query_end= strxmov(query, "SELECT ", NullS);
16134   for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i)
16135     query_end= strxmov(query_end, expr[i * 2], ", ", NullS);
16136   query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS);
16137   DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH);
16138 
16139   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16140   myquery(rc);
16141   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)");
16142   myquery(rc);
16143   /*
16144     We need this loop to ensure correct behavior with both constant and
16145     non-constant tables.
16146   */
16147   for (j= 0; j < 2 ; j++)
16148   {
16149     rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16150     myquery(rc);
16151 
16152     rc= mysql_real_query(mysql, query, (ulong)(query_end - query));
16153     myquery(rc);
16154 
16155     result= mysql_use_result(mysql);
16156     DIE_UNLESS(result);
16157 
16158   field_count= mysql_field_count(mysql);
16159   for (i= 0; i < field_count; ++i)
16160   {
16161     field= mysql_fetch_field_direct(result, i);
16162     if (!opt_silent)
16163       if (!opt_silent)
16164         printf("%s -> %s ... ", expr[i * 2], field->name);
16165     fflush(stdout);
16166     DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
16167                field->table[0] == 0 && field->org_name[0] == 0);
16168     DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
16169     if (!opt_silent)
16170       if (!opt_silent)
16171         puts("OK");
16172   }
16173 
16174     mysql_free_result(result);
16175   }
16176   rc= mysql_query(mysql, "DROP TABLE t1");
16177   myquery(rc);
16178 
16179   DBUG_VOID_RETURN;
16180 }
16181 
16182 /*
16183   Bug#24179 "select b into $var" fails with --cursor_protocol"
16184   The failure is correct, check that the returned message is meaningful.
16185 */
16186 
test_bug24179()16187 static void test_bug24179()
16188 {
16189   int rc;
16190   MYSQL_STMT *stmt;
16191 
16192   DBUG_ENTER("test_bug24179");
16193   myheader("test_bug24179");
16194 
16195   stmt= open_cursor("select 1 into @a");
16196   rc= mysql_stmt_execute(stmt);
16197   DIE_UNLESS(rc);
16198   if (!opt_silent)
16199   {
16200     printf("Got error (as expected): %d %s\n",
16201            mysql_stmt_errno(stmt),
16202            mysql_stmt_error(stmt));
16203   }
16204   DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
16205   mysql_stmt_close(stmt);
16206 
16207   DBUG_VOID_RETURN;
16208 }
16209 
16210 
16211 /**
16212   Bug#32265 Server returns different metadata if prepared statement is used
16213 */
16214 
test_bug32265()16215 static void test_bug32265()
16216 {
16217   int rc;
16218   MYSQL_STMT *stmt;
16219   MYSQL_FIELD *field;
16220   MYSQL_RES *metadata;
16221 
16222   DBUG_ENTER("test_bug32265");
16223   myheader("test_bug32265");
16224 
16225   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16226   myquery(rc);
16227   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
16228   myquery(rc);
16229   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16230   myquery(rc);
16231   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
16232   myquery(rc);
16233 
16234   stmt= open_cursor("SELECT * FROM t1");
16235   rc= mysql_stmt_execute(stmt);
16236   check_execute(stmt, rc);
16237 
16238   metadata= mysql_stmt_result_metadata(stmt);
16239   field= mysql_fetch_field(metadata);
16240   DIE_UNLESS(field);
16241   DIE_UNLESS(strcmp(field->table, "t1") == 0);
16242   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16243   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16244   mysql_free_result(metadata);
16245   mysql_stmt_close(stmt);
16246 
16247   stmt= open_cursor("SELECT a '' FROM t1 ``");
16248   rc= mysql_stmt_execute(stmt);
16249   check_execute(stmt, rc);
16250 
16251   metadata= mysql_stmt_result_metadata(stmt);
16252   field= mysql_fetch_field(metadata);
16253   DIE_UNLESS(strcmp(field->table, "") == 0);
16254   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16255   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16256   mysql_free_result(metadata);
16257   mysql_stmt_close(stmt);
16258 
16259   stmt= open_cursor("SELECT a '' FROM t1 ``");
16260   rc= mysql_stmt_execute(stmt);
16261   check_execute(stmt, rc);
16262 
16263   metadata= mysql_stmt_result_metadata(stmt);
16264   field= mysql_fetch_field(metadata);
16265   DIE_UNLESS(strcmp(field->table, "") == 0);
16266   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16267   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16268   mysql_free_result(metadata);
16269   mysql_stmt_close(stmt);
16270 
16271   stmt= open_cursor("SELECT * FROM v1");
16272   rc= mysql_stmt_execute(stmt);
16273   check_execute(stmt, rc);
16274 
16275   metadata= mysql_stmt_result_metadata(stmt);
16276   field= mysql_fetch_field(metadata);
16277   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16278   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16279   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16280   mysql_free_result(metadata);
16281   mysql_stmt_close(stmt);
16282 
16283   stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
16284   rc= mysql_stmt_execute(stmt);
16285   check_execute(stmt, rc);
16286 
16287   metadata= mysql_stmt_result_metadata(stmt);
16288   field= mysql_fetch_field(metadata);
16289   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16290   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16291   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16292   mysql_free_result(metadata);
16293   mysql_stmt_close(stmt);
16294 
16295   rc= mysql_query(mysql, "DROP VIEW v1");
16296   myquery(rc);
16297   rc= mysql_query(mysql, "DROP TABLE t1");
16298   myquery(rc);
16299 
16300   DBUG_VOID_RETURN;
16301 }
16302 
16303 /*
16304   Bug#28075 "COM_DEBUG crashes mysqld"
16305 */
16306 
test_bug28075()16307 static void test_bug28075()
16308 {
16309   int rc;
16310 
16311   DBUG_ENTER("test_bug28075");
16312   myheader("test_bug28075");
16313 
16314   rc= mysql_dump_debug_info(mysql);
16315   DIE_UNLESS(rc == 0);
16316 
16317   rc= mysql_ping(mysql);
16318   DIE_UNLESS(rc == 0);
16319 
16320   DBUG_VOID_RETURN;
16321 }
16322 
16323 
16324 /*
16325   Bug#27876 (SF with cyrillic variable name fails during execution (regression))
16326 */
16327 
test_bug27876()16328 static void test_bug27876()
16329 {
16330   int rc;
16331   MYSQL_RES *result;
16332 
16333   uchar utf8_func[] =
16334   {
16335     0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
16336     0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
16337     0xd0, 0xb0,
16338     0x00
16339   };
16340 
16341   uchar utf8_param[] =
16342   {
16343     0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
16344     0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
16345     0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
16346     0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
16347     0x00
16348   };
16349 
16350   char query[500];
16351 
16352   DBUG_ENTER("test_bug27876");
16353   myheader("test_bug27876");
16354 
16355   rc= mysql_query(mysql, "set names utf8");
16356   myquery(rc);
16357 
16358   rc= mysql_query(mysql, "select version()");
16359   myquery(rc);
16360   result= mysql_store_result(mysql);
16361   mytest(result);
16362   mysql_free_result(result);
16363 
16364   sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
16365   rc= mysql_query(mysql, query);
16366   myquery(rc);
16367 
16368   sprintf(query,
16369           "CREATE FUNCTION %s( %s VARCHAR(25))"
16370           " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
16371           (char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
16372   rc= mysql_query(mysql, query);
16373   myquery(rc);
16374   sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
16375   rc= mysql_query(mysql, query);
16376   myquery(rc);
16377   result= mysql_store_result(mysql);
16378   mytest(result);
16379   mysql_free_result(result);
16380 
16381   sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
16382   rc= mysql_query(mysql, query);
16383   myquery(rc);
16384 
16385   rc= mysql_query(mysql, "set names default");
16386   myquery(rc);
16387 
16388   DBUG_VOID_RETURN;
16389 }
16390 
16391 
16392 /*
16393   Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
16394   flag is set.
16395 */
16396 
test_bug28505()16397 static void test_bug28505()
16398 {
16399   my_ulonglong res;
16400 
16401   myquery(mysql_query(mysql, "drop table if exists t1"));
16402   myquery(mysql_query(mysql, "create table t1(f1 int primary key)"));
16403   myquery(mysql_query(mysql, "insert into t1 values(1)"));
16404   myquery(mysql_query(mysql,
16405                   "insert into t1 values(1) on duplicate key update f1=1"));
16406   res= mysql_affected_rows(mysql);
16407   DIE_UNLESS(!res);
16408   myquery(mysql_query(mysql, "drop table t1"));
16409 }
16410 
16411 
16412 /*
16413   Bug#28934: server crash when receiving malformed com_execute packets
16414 */
16415 
test_bug28934()16416 static void test_bug28934()
16417 {
16418   my_bool error= 0;
16419   MYSQL_BIND bind[5];
16420   MYSQL_STMT *stmt;
16421   int cnt;
16422 
16423   myquery(mysql_query(mysql, "drop table if exists t1"));
16424   myquery(mysql_query(mysql, "create table t1(id int)"));
16425 
16426   myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)"));
16427   stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)");
16428   check_stmt(stmt);
16429 
16430   memset (&bind, 0, sizeof (bind));
16431   for (cnt= 0; cnt < 5; cnt++)
16432   {
16433     bind[cnt].buffer_type= MYSQL_TYPE_LONG;
16434     bind[cnt].buffer= (char*)&cnt;
16435     bind[cnt].buffer_length= 0;
16436   }
16437   myquery(mysql_stmt_bind_param(stmt, bind));
16438 
16439   stmt->param_count=2;
16440   error= mysql_stmt_execute(stmt);
16441   DIE_UNLESS(error != 0);
16442   myerror(NULL);
16443   mysql_stmt_close(stmt);
16444 
16445   myquery(mysql_query(mysql, "drop table t1"));
16446 }
16447 
16448 /*
16449   Test mysql_change_user() C API and COM_CHANGE_USER
16450 */
16451 
test_change_user()16452 static void test_change_user()
16453 {
16454   char buff[256];
16455   const char *user_pw= "mysqltest_pw";
16456   const char *user_no_pw= "mysqltest_no_pw";
16457   const char *pw= "password";
16458   const char *db= "mysqltest_user_test_database";
16459   int rc;
16460   MYSQL*       conn;
16461   MYSQL_RES* res;
16462   DBUG_ENTER("test_change_user");
16463   myheader("test_change_user");
16464 
16465   /* Prepare environment */
16466   sprintf(buff, "drop database if exists %s", db);
16467   rc= mysql_query(mysql, buff);
16468   myquery(rc);
16469 
16470   sprintf(buff, "create database %s", db);
16471   rc= mysql_query(mysql, buff);
16472   myquery(rc);
16473 
16474   rc= mysql_query(mysql, "SET SQL_MODE=''");
16475   myquery(rc);
16476 
16477   sprintf(buff,
16478           "grant select on %s.* to %s@'%%' identified by '%s'",
16479           db,
16480           user_pw,
16481           pw);
16482   rc= mysql_query(mysql, buff);
16483   myquery(rc);
16484 
16485   sprintf(buff,
16486           "grant select on %s.* to %s@'localhost' identified by '%s'",
16487           db,
16488           user_pw,
16489           pw);
16490   rc= mysql_query(mysql, buff);
16491   myquery(rc);
16492 
16493   sprintf(buff,
16494           "grant select on %s.* to %s@'%%'",
16495           db,
16496           user_no_pw);
16497   rc= mysql_query(mysql, buff);
16498   myquery(rc);
16499 
16500   sprintf(buff,
16501           "grant select on %s.* to %s@'localhost'",
16502           db,
16503           user_no_pw);
16504   rc= mysql_query(mysql, buff);
16505   myquery(rc);
16506 
16507   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16508 
16509   /* Try some combinations */
16510   rc= mysql_change_user(conn, NULL, NULL, NULL);
16511   DIE_UNLESS(rc);
16512   if (! opt_silent)
16513     printf("Got error (as expected): %s\n", mysql_error(conn));
16514 
16515 
16516   rc= mysql_change_user(conn, "", NULL, NULL);
16517   DIE_UNLESS(rc);
16518   if (! opt_silent)
16519     printf("Got error (as expected): %s\n", mysql_error(conn));
16520 
16521   rc= mysql_change_user(conn, "", "", NULL);
16522   DIE_UNLESS(rc);
16523   if (! opt_silent)
16524     printf("Got error (as expected): %s\n", mysql_error(conn));
16525 
16526   mysql_close(conn);
16527   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16528 
16529   rc= mysql_change_user(conn, "", "", "");
16530   DIE_UNLESS(rc);
16531   if (! opt_silent)
16532     printf("Got error (as expected): %s\n", mysql_error(conn));
16533 
16534   rc= mysql_change_user(conn, NULL, "", "");
16535   DIE_UNLESS(rc);
16536   if (! opt_silent)
16537     printf("Got error (as expected): %s\n", mysql_error(conn));
16538 
16539 
16540   rc= mysql_change_user(conn, NULL, NULL, "");
16541   DIE_UNLESS(rc);
16542   if (! opt_silent)
16543     printf("Got error (as expected): %s\n", mysql_error(conn));
16544 
16545   mysql_close(conn);
16546   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16547 
16548   rc= mysql_change_user(conn, "", NULL, "");
16549   DIE_UNLESS(rc);
16550   if (! opt_silent)
16551     printf("Got error (as expected): %s\n", mysql_error(conn));
16552 
16553   rc= mysql_change_user(conn, user_pw, NULL, "");
16554   DIE_UNLESS(rc);
16555   if (! opt_silent)
16556     printf("Got error (as expected): %s\n", mysql_error(conn));
16557 
16558   rc= mysql_change_user(conn, user_pw, "", "");
16559   DIE_UNLESS(rc);
16560   if (! opt_silent)
16561     printf("Got error (as expected): %s\n", mysql_error(conn));
16562 
16563   mysql_close(conn);
16564   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16565 
16566   rc= mysql_change_user(conn, user_pw, "", NULL);
16567   DIE_UNLESS(rc);
16568   if (! opt_silent)
16569     printf("Got error (as expected): %s\n", mysql_error(conn));
16570 
16571   rc= mysql_change_user(conn, user_pw, NULL, NULL);
16572   DIE_UNLESS(rc);
16573   if (! opt_silent)
16574     printf("Got error (as expected): %s\n", mysql_error(conn));
16575 
16576   rc= mysql_change_user(conn, user_pw, "", db);
16577   DIE_UNLESS(rc);
16578   if (! opt_silent)
16579     printf("Got error (as expected): %s\n", mysql_error(conn));
16580 
16581   mysql_close(conn);
16582   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16583 
16584   rc= mysql_change_user(conn, user_pw, NULL, db);
16585   DIE_UNLESS(rc);
16586   if (! opt_silent)
16587     printf("Got error (as expected): %s\n", mysql_error(conn));
16588 
16589   rc= mysql_change_user(conn, user_pw, pw, db);
16590   myquery(rc);
16591 
16592   rc= mysql_change_user(conn, user_pw, pw, NULL);
16593   myquery(rc);
16594 
16595   rc= mysql_change_user(conn, user_pw, pw, "");
16596   myquery(rc);
16597 
16598   /* MDEV-14581 : Check that there are no warnings after change user.*/
16599   rc = mysql_query(conn,"SIGNAL SQLSTATE '01000'");
16600   myquery(rc);
16601 
16602   rc = mysql_change_user(conn, user_pw, pw, "");
16603   myquery(rc);
16604 
16605   rc = mysql_query(conn, "SHOW WARNINGS");
16606   myquery(rc);
16607   res = mysql_store_result(conn);
16608   rc = my_process_result_set(res);
16609   DIE_UNLESS(rc == 0);
16610   mysql_free_result(res);
16611 
16612   rc= mysql_change_user(conn, user_no_pw, pw, db);
16613   DIE_UNLESS(rc);
16614   if (! opt_silent)
16615     printf("Got error (as expected): %s\n", mysql_error(conn));
16616 
16617   rc= mysql_change_user(conn, user_no_pw, pw, "");
16618   DIE_UNLESS(rc);
16619   if (! opt_silent)
16620     printf("Got error (as expected): %s\n", mysql_error(conn));
16621 
16622   mysql_close(conn);
16623   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16624 
16625   rc= mysql_change_user(conn, user_no_pw, pw, NULL);
16626   DIE_UNLESS(rc);
16627   if (! opt_silent)
16628     printf("Got error (as expected): %s\n", mysql_error(conn));
16629 
16630   rc= mysql_change_user(conn, user_no_pw, "", NULL);
16631   myquery(rc);
16632 
16633   rc= mysql_change_user(conn, user_no_pw, "", "");
16634   myquery(rc);
16635 
16636   rc= mysql_change_user(conn, user_no_pw, "", db);
16637   myquery(rc);
16638 
16639   rc= mysql_change_user(conn, user_no_pw, NULL, db);
16640   myquery(rc);
16641 
16642   rc= mysql_change_user(conn, "", pw, db);
16643   DIE_UNLESS(rc);
16644   if (! opt_silent)
16645     printf("Got error (as expected): %s\n", mysql_error(conn));
16646 
16647   rc= mysql_change_user(conn, "", pw, "");
16648   DIE_UNLESS(rc);
16649   if (! opt_silent)
16650     printf("Got error (as expected): %s\n", mysql_error(conn));
16651 
16652   mysql_close(conn);
16653   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16654 
16655   rc= mysql_change_user(conn, "", pw, NULL);
16656   DIE_UNLESS(rc);
16657   if (! opt_silent)
16658     printf("Got error (as expected): %s\n", mysql_error(conn));
16659 
16660   rc= mysql_change_user(conn, NULL, pw, NULL);
16661   DIE_UNLESS(rc);
16662   if (! opt_silent)
16663     printf("Got error (as expected): %s\n", mysql_error(conn));
16664 
16665   rc= mysql_change_user(conn, NULL, NULL, db);
16666   DIE_UNLESS(rc);
16667   if (! opt_silent)
16668     printf("Got error (as expected): %s\n", mysql_error(conn));
16669 
16670   mysql_close(conn);
16671   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16672 
16673   rc= mysql_change_user(conn, NULL, "", db);
16674   DIE_UNLESS(rc);
16675   if (! opt_silent)
16676     printf("Got error (as expected): %s\n", mysql_error(conn));
16677 
16678   rc= mysql_change_user(conn, "", "", db);
16679   DIE_UNLESS(rc);
16680   if (! opt_silent)
16681     printf("Got error (as expected): %s\n", mysql_error(conn));
16682 
16683   /* Cleanup the environment */
16684 
16685   mysql_change_user(conn, opt_user, opt_password, current_db);
16686 
16687   mysql_close(conn);
16688 
16689   sprintf(buff, "drop database %s", db);
16690   rc= mysql_query(mysql, buff);
16691   myquery(rc);
16692 
16693   sprintf(buff, "drop user %s@'%%'", user_pw);
16694   rc= mysql_query(mysql, buff);
16695   myquery(rc);
16696 
16697   sprintf(buff, "drop user %s@'%%'", user_no_pw);
16698   rc= mysql_query(mysql, buff);
16699   myquery(rc);
16700 
16701   sprintf(buff, "drop user %s@'localhost'", user_pw);
16702   rc= mysql_query(mysql, buff);
16703   myquery(rc);
16704 
16705   sprintf(buff, "drop user %s@'localhost'", user_no_pw);
16706   rc= mysql_query(mysql, buff);
16707   myquery(rc);
16708 
16709   DBUG_VOID_RETURN;
16710 }
16711 
16712 /*
16713   Bug#27592 (stack overrun when storing datetime value using prepared statements)
16714 */
16715 
test_bug27592()16716 static void test_bug27592()
16717 {
16718   const int NUM_ITERATIONS= 40;
16719   int i;
16720   int rc;
16721   MYSQL_STMT *stmt= NULL;
16722   MYSQL_BIND bind[1];
16723   MYSQL_TIME time_val;
16724 
16725   DBUG_ENTER("test_bug27592");
16726   myheader("test_bug27592");
16727 
16728   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16729   mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
16730 
16731   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
16732   DIE_UNLESS(stmt);
16733 
16734   memset(bind, 0, sizeof(bind));
16735 
16736   bind[0].buffer_type= MYSQL_TYPE_DATETIME;
16737   bind[0].buffer= (char *) &time_val;
16738   bind[0].length= NULL;
16739 
16740   for (i= 0; i < NUM_ITERATIONS; i++)
16741   {
16742     time_val.year= 2007;
16743     time_val.month= 6;
16744     time_val.day= 7;
16745     time_val.hour= 18;
16746     time_val.minute= 41;
16747     time_val.second= 3;
16748 
16749     time_val.second_part=0;
16750     time_val.neg=0;
16751 
16752     rc= mysql_stmt_bind_param(stmt, bind);
16753     check_execute(stmt, rc);
16754 
16755     rc= mysql_stmt_execute(stmt);
16756     check_execute(stmt, rc);
16757   }
16758 
16759   mysql_stmt_close(stmt);
16760 
16761   DBUG_VOID_RETURN;
16762 }
16763 
16764 /*
16765   Bug#29687 mysql_stmt_store_result memory leak in libmysqld
16766 */
16767 
test_bug29687()16768 static void test_bug29687()
16769 {
16770   const int NUM_ITERATIONS= 40;
16771   int i;
16772   int rc;
16773   MYSQL_STMT *stmt= NULL;
16774 
16775   DBUG_ENTER("test_bug29687");
16776   myheader("test_bug29687");
16777 
16778   stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2");
16779   DIE_UNLESS(stmt);
16780 
16781   for (i= 0; i < NUM_ITERATIONS; i++)
16782   {
16783     rc= mysql_stmt_execute(stmt);
16784     check_execute(stmt, rc);
16785     mysql_stmt_store_result(stmt);
16786     while (mysql_stmt_fetch(stmt)==0);
16787     mysql_stmt_free_result(stmt);
16788   }
16789 
16790   mysql_stmt_close(stmt);
16791   DBUG_VOID_RETURN;
16792 }
16793 
16794 
16795 /*
16796   Bug #29692  	Single row inserts can incorrectly report a huge number of
16797   row insertions
16798 */
16799 
test_bug29692()16800 static void test_bug29692()
16801 {
16802   MYSQL* conn;
16803 
16804   if (!(conn= mysql_client_init(NULL)))
16805   {
16806     myerror("test_bug29692 init failed");
16807     exit(1);
16808   }
16809 
16810   if (!(mysql_real_connect(conn, opt_host, opt_user,
16811                            opt_password, opt_db ? opt_db:"test", opt_port,
16812                            opt_unix_socket,  CLIENT_FOUND_ROWS)))
16813   {
16814     myerror("test_bug29692 connection failed");
16815     mysql_close(mysql);
16816     exit(1);
16817   }
16818   myquery(mysql_query(conn, "drop table if exists t1"));
16819   myquery(mysql_query(conn, "create table t1(f1 int)"));
16820   myquery(mysql_query(conn, "insert into t1 values(1)"));
16821   DIE_UNLESS(1 == mysql_affected_rows(conn));
16822   myquery(mysql_query(conn, "drop table t1"));
16823   mysql_close(conn);
16824 }
16825 
16826 /**
16827   Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
16828 */
16829 
test_bug29306()16830 static void test_bug29306()
16831 {
16832   MYSQL_FIELD *field;
16833   int rc;
16834   MYSQL_RES *res;
16835 
16836   DBUG_ENTER("test_bug29306");
16837   myheader("test_bug29306");
16838 
16839   rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
16840   myquery(rc);
16841   rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
16842   myquery(rc);
16843   rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
16844   myquery(rc);
16845   rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
16846   myquery(rc);
16847   rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
16848   myquery(rc);
16849 
16850   /* Checking the view */
16851   res= mysql_list_fields(mysql, "view17557", NULL);
16852   while ((field= mysql_fetch_field(res)))
16853   {
16854     if (! opt_silent)
16855     {
16856       printf("field name %s\n", field->name);
16857       printf("field table %s\n", field->table);
16858       printf("field decimals %d\n", field->decimals);
16859       if (field->decimals < 1)
16860         printf("Error! No decimals! \n");
16861       printf("\n\n");
16862     }
16863     DIE_UNLESS(field->decimals == 1);
16864   }
16865   mysql_free_result(res);
16866 
16867   rc= mysql_query(mysql, "DROP TABLE tab17557");
16868   myquery(rc);
16869   rc= mysql_query(mysql, "DROP VIEW view17557");
16870   myquery(rc);
16871 
16872   DBUG_VOID_RETURN;
16873 }
16874 /*
16875   Bug#30472: libmysql doesn't reset charset, insert_id after succ.
16876   mysql_change_user() call row insertions.
16877 */
16878 
bug30472_retrieve_charset_info(MYSQL * con,char * character_set_name,char * character_set_client,char * character_set_results,char * collation_connection)16879 static void bug30472_retrieve_charset_info(MYSQL *con,
16880                                            char *character_set_name,
16881                                            char *character_set_client,
16882                                            char *character_set_results,
16883                                            char *collation_connection)
16884 {
16885   MYSQL_RES *rs;
16886   MYSQL_ROW row;
16887 
16888   /* Get the cached client character set name. */
16889 
16890   strcpy(character_set_name, mysql_character_set_name(con));
16891 
16892   /* Retrieve server character set information. */
16893 
16894   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
16895   DIE_UNLESS(rs= mysql_store_result(con));
16896   DIE_UNLESS(row= mysql_fetch_row(rs));
16897   strcpy(character_set_client, row[1]);
16898   mysql_free_result(rs);
16899 
16900   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
16901   DIE_UNLESS(rs= mysql_store_result(con));
16902   DIE_UNLESS(row= mysql_fetch_row(rs));
16903   strcpy(character_set_results, row[1]);
16904   mysql_free_result(rs);
16905 
16906   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
16907   DIE_UNLESS(rs= mysql_store_result(con));
16908   DIE_UNLESS(row= mysql_fetch_row(rs));
16909   strcpy(collation_connection, row[1]);
16910   mysql_free_result(rs);
16911 }
16912 
test_bug30472()16913 static void test_bug30472()
16914 {
16915   MYSQL con;
16916 
16917   char character_set_name_1[MY_CS_NAME_SIZE];
16918   char character_set_client_1[MY_CS_NAME_SIZE];
16919   char character_set_results_1[MY_CS_NAME_SIZE];
16920   char collation_connnection_1[MY_CS_NAME_SIZE];
16921 
16922   char character_set_name_2[MY_CS_NAME_SIZE];
16923   char character_set_client_2[MY_CS_NAME_SIZE];
16924   char character_set_results_2[MY_CS_NAME_SIZE];
16925   char collation_connnection_2[MY_CS_NAME_SIZE];
16926 
16927   char character_set_name_3[MY_CS_NAME_SIZE];
16928   char character_set_client_3[MY_CS_NAME_SIZE];
16929   char character_set_results_3[MY_CS_NAME_SIZE];
16930   char collation_connnection_3[MY_CS_NAME_SIZE];
16931 
16932   char character_set_name_4[MY_CS_NAME_SIZE];
16933   char character_set_client_4[MY_CS_NAME_SIZE];
16934   char character_set_results_4[MY_CS_NAME_SIZE];
16935   char collation_connnection_4[MY_CS_NAME_SIZE];
16936 
16937   /* Create a new connection. */
16938 
16939   DIE_UNLESS(mysql_client_init(&con));
16940 
16941   DIE_UNLESS(mysql_real_connect(&con,
16942                                 opt_host,
16943                                 opt_user,
16944                                 opt_password,
16945                                 opt_db ? opt_db : "test",
16946                                 opt_port,
16947                                 opt_unix_socket,
16948                                 CLIENT_FOUND_ROWS));
16949 
16950   /* Retrieve character set information. */
16951 
16952   bug30472_retrieve_charset_info(&con,
16953                                  character_set_name_1,
16954                                  character_set_client_1,
16955                                  character_set_results_1,
16956                                  collation_connnection_1);
16957 
16958   /* Switch client character set. */
16959 
16960   DIE_IF(mysql_set_character_set(&con, "latin2"));
16961 
16962   /* Retrieve character set information. */
16963 
16964   bug30472_retrieve_charset_info(&con,
16965                                  character_set_name_2,
16966                                  character_set_client_2,
16967                                  character_set_results_2,
16968                                  collation_connnection_2);
16969 
16970   /*
16971     Check that
16972       1) character set has been switched and
16973       2) new character set is different from the original one.
16974   */
16975 
16976   DIE_UNLESS(strcmp(character_set_name_2, "latin2") == 0);
16977   DIE_UNLESS(strcmp(character_set_client_2, "latin2") == 0);
16978   DIE_UNLESS(strcmp(character_set_results_2, "latin2") == 0);
16979   DIE_UNLESS(strcmp(collation_connnection_2, "latin2_general_ci") == 0);
16980 
16981   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
16982   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
16983   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
16984   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
16985 
16986   /* Call mysql_change_user() with the same username, password, database. */
16987 
16988   DIE_IF(mysql_change_user(&con,
16989                            opt_user,
16990                            opt_password,
16991                            opt_db ? opt_db : "test"));
16992 
16993   /* Retrieve character set information. */
16994 
16995   bug30472_retrieve_charset_info(&con,
16996                                  character_set_name_3,
16997                                  character_set_client_3,
16998                                  character_set_results_3,
16999                                  collation_connnection_3);
17000 
17001   /* Check that character set information has been reset. */
17002 
17003   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
17004   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
17005   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
17006   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
17007 
17008   /* Change connection-default character set in the client. */
17009 
17010   mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8");
17011 
17012   /*
17013     Call mysql_change_user() in order to check that new connection will
17014     have UTF8 character set on the client and on the server.
17015   */
17016 
17017   DIE_IF(mysql_change_user(&con,
17018                            opt_user,
17019                            opt_password,
17020                            opt_db ? opt_db : "test"));
17021 
17022   /* Retrieve character set information. */
17023 
17024   bug30472_retrieve_charset_info(&con,
17025                                  character_set_name_4,
17026                                  character_set_client_4,
17027                                  character_set_results_4,
17028                                  collation_connnection_4);
17029 
17030   /* Check that we have UTF8 on the server and on the client. */
17031 
17032   DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
17033   DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
17034   DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
17035   DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
17036 
17037   /* That's it. Cleanup. */
17038 
17039   mysql_close(&con);
17040 }
17041 
bug20023_change_user(MYSQL * con)17042 static void bug20023_change_user(MYSQL *con)
17043 {
17044   DIE_IF(mysql_change_user(con,
17045                            opt_user,
17046                            opt_password,
17047                            opt_db ? opt_db : "test"));
17048 }
17049 
query_str_variable(MYSQL * con,const char * var_name,char * str,size_t len)17050 static my_bool query_str_variable(MYSQL *con,
17051                                   const char *var_name,
17052                                   char *str,
17053                                   size_t len)
17054 {
17055   MYSQL_RES *rs;
17056   MYSQL_ROW row;
17057 
17058   char query_buffer[MAX_TEST_QUERY_LENGTH];
17059 
17060   my_bool is_null;
17061 
17062   my_snprintf(query_buffer, sizeof (query_buffer),
17063               "SELECT %s", var_name);
17064 
17065   DIE_IF(mysql_query(con, query_buffer));
17066   DIE_UNLESS(rs= mysql_store_result(con));
17067   DIE_UNLESS(row= mysql_fetch_row(rs));
17068 
17069   is_null= row[0] == NULL;
17070 
17071   if (!is_null)
17072     my_snprintf(str, len, "%s", row[0]);
17073 
17074   mysql_free_result(rs);
17075 
17076   return is_null;
17077 }
17078 
query_int_variable(MYSQL * con,const char * var_name,int * var_value)17079 static my_bool query_int_variable(MYSQL *con,
17080                                   const char *var_name,
17081                                   int *var_value)
17082 {
17083   char str[32];
17084   my_bool is_null= query_str_variable(con, var_name, str, sizeof(str));
17085 
17086   if (!is_null)
17087     *var_value= atoi(str);
17088 
17089   return is_null;
17090 }
17091 
test_bug20023()17092 static void test_bug20023()
17093 {
17094   MYSQL con;
17095 
17096   int sql_big_selects_orig= 0;
17097   /*
17098     Type of max_join_size is ha_rows, which might be ulong or off_t
17099     depending on the platform or configure options. Preserve the string
17100     to avoid type overflow pitfalls.
17101   */
17102   char max_join_size_orig[32];
17103 
17104   int sql_big_selects_2= 0;
17105   int sql_big_selects_3= 0;
17106   int sql_big_selects_4= 0;
17107   int sql_big_selects_5= 0;
17108 
17109   char query_buffer[MAX_TEST_QUERY_LENGTH];
17110 
17111   /* Create a new connection. */
17112 
17113   DIE_UNLESS(mysql_client_init(&con));
17114 
17115   DIE_UNLESS(mysql_real_connect(&con,
17116                                 opt_host,
17117                                 opt_user,
17118                                 opt_password,
17119                                 opt_db ? opt_db : "test",
17120                                 opt_port,
17121                                 opt_unix_socket,
17122                                 CLIENT_FOUND_ROWS));
17123 
17124   /***********************************************************************
17125     Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
17126   ***********************************************************************/
17127 
17128   query_int_variable(&con,
17129                      "@@session.sql_big_selects",
17130                      &sql_big_selects_orig);
17131 
17132   query_str_variable(&con,
17133                      "@@global.max_join_size",
17134                      max_join_size_orig,
17135                      sizeof(max_join_size_orig));
17136 
17137   /***********************************************************************
17138     Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
17139   ***********************************************************************/
17140 
17141   /* Issue COM_CHANGE_USER. */
17142 
17143   bug20023_change_user(&con);
17144 
17145   /* Query SQL_BIG_SELECTS. */
17146 
17147   query_int_variable(&con,
17148                      "@@session.sql_big_selects",
17149                      &sql_big_selects_2);
17150 
17151   /* Check that SQL_BIG_SELECTS is reset properly. */
17152 
17153   DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2);
17154 
17155   /***********************************************************************
17156     Test that if MAX_JOIN_SIZE set to non-default value,
17157     SQL_BIG_SELECTS will be 0.
17158   ***********************************************************************/
17159 
17160   /* Set MAX_JOIN_SIZE to some non-default value. */
17161 
17162   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000"));
17163   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17164 
17165   /* Issue COM_CHANGE_USER. */
17166 
17167   bug20023_change_user(&con);
17168 
17169   /* Query SQL_BIG_SELECTS. */
17170 
17171   query_int_variable(&con,
17172                      "@@session.sql_big_selects",
17173                      &sql_big_selects_3);
17174 
17175   /* Check that SQL_BIG_SELECTS is 0. */
17176 
17177   DIE_UNLESS(sql_big_selects_3 == 0);
17178 
17179   /***********************************************************************
17180     Test that if MAX_JOIN_SIZE set to default value,
17181     SQL_BIG_SELECTS will be 1.
17182   ***********************************************************************/
17183 
17184   /* Set MAX_JOIN_SIZE to the default value (2^64-1). */
17185 
17186   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17187   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17188 
17189   /* Issue COM_CHANGE_USER. */
17190 
17191   bug20023_change_user(&con);
17192 
17193   /* Query SQL_BIG_SELECTS. */
17194 
17195   query_int_variable(&con,
17196                      "@@session.sql_big_selects",
17197                      &sql_big_selects_4);
17198 
17199   /* Check that SQL_BIG_SELECTS is 1. */
17200 
17201   DIE_UNLESS(sql_big_selects_4 == 1);
17202 
17203   /***********************************************************************
17204     Restore MAX_JOIN_SIZE.
17205     Check that SQL_BIG_SELECTS will be the original one.
17206   ***********************************************************************/
17207 
17208   /* Restore MAX_JOIN_SIZE. */
17209 
17210   my_snprintf(query_buffer,
17211            sizeof (query_buffer),
17212            "SET @@global.max_join_size = %s",
17213            max_join_size_orig);
17214 
17215   DIE_IF(mysql_query(&con, query_buffer));
17216 
17217   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17218   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17219 
17220   /* Issue COM_CHANGE_USER. */
17221 
17222   bug20023_change_user(&con);
17223 
17224   /* Query SQL_BIG_SELECTS. */
17225 
17226   query_int_variable(&con,
17227                      "@@session.sql_big_selects",
17228                      &sql_big_selects_5);
17229 
17230   /* Check that SQL_BIG_SELECTS is 1. */
17231 
17232   DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig);
17233 
17234   /***********************************************************************
17235     That's it. Cleanup.
17236   ***********************************************************************/
17237 
17238   mysql_close(&con);
17239 }
17240 
bug31418_impl()17241 static void bug31418_impl()
17242 {
17243   MYSQL con;
17244 
17245   my_bool is_null;
17246   int rc= 0;
17247 
17248   /* Create a new connection. */
17249 
17250   DIE_UNLESS(mysql_client_init(&con));
17251 
17252   DIE_UNLESS(mysql_real_connect(&con,
17253                                 opt_host,
17254                                 opt_user,
17255                                 opt_password,
17256                                 opt_db ? opt_db : "test",
17257                                 opt_port,
17258                                 opt_unix_socket,
17259                                 CLIENT_FOUND_ROWS));
17260 
17261   /***********************************************************************
17262     Check that lock is free:
17263       - IS_FREE_LOCK() should return 1;
17264       - IS_USED_LOCK() should return NULL;
17265   ***********************************************************************/
17266 
17267   is_null= query_int_variable(&con,
17268                               "IS_FREE_LOCK('bug31418')",
17269                               &rc);
17270   DIE_UNLESS(!is_null && rc);
17271 
17272   is_null= query_int_variable(&con,
17273                               "IS_USED_LOCK('bug31418')",
17274                               &rc);
17275   DIE_UNLESS(is_null);
17276 
17277   /***********************************************************************
17278     Acquire lock and check the lock status (the lock must be in use):
17279       - IS_FREE_LOCK() should return 0;
17280       - IS_USED_LOCK() should return non-zero thread id;
17281   ***********************************************************************/
17282 
17283   query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
17284   DIE_UNLESS(rc);
17285 
17286   is_null= query_int_variable(&con,
17287                               "IS_FREE_LOCK('bug31418')",
17288                               &rc);
17289   DIE_UNLESS(!is_null && !rc);
17290 
17291   is_null= query_int_variable(&con,
17292                               "IS_USED_LOCK('bug31418')",
17293                               &rc);
17294   DIE_UNLESS(!is_null && rc);
17295 
17296   /***********************************************************************
17297     Issue COM_CHANGE_USER command and check the lock status
17298     (the lock must be free):
17299       - IS_FREE_LOCK() should return 1;
17300       - IS_USED_LOCK() should return NULL;
17301   **********************************************************************/
17302 
17303   bug20023_change_user(&con);
17304 
17305   is_null= query_int_variable(&con,
17306                               "IS_FREE_LOCK('bug31418')",
17307                               &rc);
17308   DIE_UNLESS(!is_null && rc);
17309 
17310   is_null= query_int_variable(&con,
17311                               "IS_USED_LOCK('bug31418')",
17312                               &rc);
17313   DIE_UNLESS(is_null);
17314 
17315   /***********************************************************************
17316    That's it. Cleanup.
17317   ***********************************************************************/
17318 
17319   mysql_close(&con);
17320 }
17321 
test_bug31418()17322 static void test_bug31418()
17323 {
17324   /* Run test case for BUG#31418 for three different connections. */
17325 
17326   bug31418_impl();
17327 
17328   bug31418_impl();
17329 
17330   bug31418_impl();
17331 }
17332 
17333 
17334 
17335 /**
17336   Bug#31669 Buffer overflow in mysql_change_user()
17337 */
17338 
17339 #define LARGE_BUFFER_SIZE 2048
17340 #define OLD_USERNAME_CHAR_LENGTH 16
17341 
test_bug31669()17342 static void test_bug31669()
17343 {
17344   int rc;
17345   static char buff[LARGE_BUFFER_SIZE+1];
17346 #ifndef EMBEDDED_LIBRARY
17347   static char user[OLD_USERNAME_CHAR_LENGTH+1];
17348   static char db[NAME_CHAR_LEN+1];
17349   static char query[LARGE_BUFFER_SIZE*2];
17350 #endif
17351   MYSQL* conn;
17352 
17353   DBUG_ENTER("test_bug31669");
17354   myheader("test_bug31669");
17355 
17356   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17357 
17358   rc= mysql_change_user(conn, NULL, NULL, NULL);
17359   DIE_UNLESS(rc);
17360 
17361   rc= mysql_change_user(conn, "", "", "");
17362   DIE_UNLESS(rc);
17363 
17364   memset(buff, 'a', sizeof(buff) -  1);
17365   buff[sizeof(buff) -  1]= 0;
17366 
17367   mysql_close(conn);
17368   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17369 
17370   rc= mysql_change_user(conn, buff, buff, buff);
17371   DIE_UNLESS(rc);
17372 
17373   rc = mysql_change_user(conn, opt_user, opt_password, current_db);
17374   DIE_UNLESS(!rc);
17375 
17376 #ifndef EMBEDDED_LIBRARY
17377   memset(db, 'a', sizeof(db));
17378   db[NAME_CHAR_LEN]= 0;
17379   strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
17380   rc= mysql_query(conn, query);
17381   myquery(rc);
17382 
17383   memset(user, 'b', sizeof(user));
17384   user[OLD_USERNAME_CHAR_LENGTH]= 0;
17385   memset(buff, 'c', sizeof(buff));
17386   buff[LARGE_BUFFER_SIZE]= 0;
17387   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
17388                  "'", buff, "' WITH GRANT OPTION", NullS);
17389   rc= mysql_query(conn, query);
17390   myquery(rc);
17391 
17392   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY "
17393                  "'", buff, "' WITH GRANT OPTION", NullS);
17394   rc= mysql_query(conn, query);
17395   myquery(rc);
17396 
17397   rc= mysql_query(conn, "FLUSH PRIVILEGES");
17398   myquery(rc);
17399 
17400   rc= mysql_change_user(conn, user, buff, db);
17401   DIE_UNLESS(!rc);
17402 
17403   user[OLD_USERNAME_CHAR_LENGTH-1]= 'a';
17404   rc= mysql_change_user(conn, user, buff, db);
17405   DIE_UNLESS(rc);
17406 
17407   user[OLD_USERNAME_CHAR_LENGTH-1]= 'b';
17408   buff[LARGE_BUFFER_SIZE-1]= 'd';
17409   rc= mysql_change_user(conn, user, buff, db);
17410   DIE_UNLESS(rc);
17411 
17412   buff[LARGE_BUFFER_SIZE-1]= 'c';
17413   db[NAME_CHAR_LEN-1]= 'e';
17414   rc= mysql_change_user(conn, user, buff, db);
17415   DIE_UNLESS(rc);
17416 
17417   mysql_close(conn);
17418   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17419 
17420   db[NAME_CHAR_LEN-1]= 'a';
17421   rc= mysql_change_user(conn, user, buff, db);
17422   DIE_UNLESS(!rc);
17423 
17424   rc= mysql_change_user(conn, user + 1, buff + 1, db + 1);
17425   DIE_UNLESS(rc);
17426 
17427   rc = mysql_change_user(conn, opt_user, opt_password, current_db);
17428   DIE_UNLESS(!rc);
17429 
17430   strxmov(query, "DROP DATABASE ", db, NullS);
17431   rc= mysql_query(conn, query);
17432   myquery(rc);
17433 
17434   strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
17435   rc= mysql_query(conn, query);
17436   myquery(rc);
17437   DIE_UNLESS(mysql_affected_rows(conn) == 2);
17438 #endif
17439 
17440   mysql_close(conn);
17441 
17442   DBUG_VOID_RETURN;
17443 }
17444 
17445 
17446 /**
17447   Bug#28386 the general log is incomplete
17448 */
17449 
test_bug28386()17450 static void test_bug28386()
17451 {
17452   int rc;
17453   MYSQL_STMT *stmt;
17454   MYSQL_RES *result;
17455   MYSQL_ROW row;
17456   MYSQL_BIND bind;
17457   const char hello[]= "hello world!";
17458 
17459   DBUG_ENTER("test_bug28386");
17460   myheader("test_bug28386");
17461 
17462   rc= mysql_query(mysql, "select @@global.log_output");
17463   myquery(rc);
17464 
17465   result= mysql_store_result(mysql);
17466   DIE_UNLESS(result);
17467 
17468   row= mysql_fetch_row(result);
17469   if (! strstr(row[0], "TABLE"))
17470   {
17471     mysql_free_result(result);
17472     if (! opt_silent)
17473       printf("Skipping the test since logging to tables is not enabled\n");
17474     /* Log output is not to tables */
17475     DBUG_VOID_RETURN;
17476   }
17477   mysql_free_result(result);
17478 
17479   enable_query_logs(1);
17480 
17481   stmt= mysql_simple_prepare(mysql, "SELECT ?");
17482   check_stmt(stmt);
17483 
17484   memset(&bind, 0, sizeof(bind));
17485 
17486   bind.buffer_type= MYSQL_TYPE_STRING;
17487   bind.buffer= (void *) hello;
17488   bind.buffer_length= sizeof(hello);
17489 
17490   mysql_stmt_bind_param(stmt, &bind);
17491   mysql_stmt_send_long_data(stmt, 0, hello, sizeof(hello));
17492 
17493   rc= mysql_stmt_execute(stmt);
17494   check_execute(stmt, rc);
17495 
17496   rc= my_process_stmt_result(stmt);
17497   DIE_UNLESS(rc == 1);
17498 
17499   rc= mysql_stmt_reset(stmt);
17500   check_execute(stmt, rc);
17501 
17502   rc= mysql_stmt_close(stmt);
17503   DIE_UNLESS(!rc);
17504 
17505   rc= mysql_query(mysql, "select * from mysql.general_log where "
17506                          "command_type='Close stmt' or "
17507                          "command_type='Reset stmt' or "
17508                          "command_type='Long Data'");
17509   myquery(rc);
17510 
17511   result= mysql_store_result(mysql);
17512   mytest(result);
17513 
17514   DIE_UNLESS(mysql_num_rows(result) == 3);
17515 
17516   mysql_free_result(result);
17517 
17518   restore_query_logs();
17519 
17520   DBUG_VOID_RETURN;
17521 }
17522 
17523 
test_wl4166_1()17524 static void test_wl4166_1()
17525 {
17526   MYSQL_STMT *stmt;
17527   int        int_data;
17528   char       str_data[50];
17529   char       tiny_data;
17530   short      small_data;
17531   longlong   big_data;
17532   float      real_data;
17533   double     double_data;
17534   ulong      length[7];
17535   my_bool    is_null[7];
17536   MYSQL_BIND my_bind[7];
17537   int rc;
17538   int i;
17539 
17540   myheader("test_wl4166_1");
17541 
17542   rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
17543   myquery(rc);
17544 
17545   rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
17546                          "col2 varchar(15), col3 int, "
17547                          "col4 smallint, col5 bigint, "
17548                          "col6 float, col7 double, "
17549                          "colX varchar(10) default NULL)");
17550   myquery(rc);
17551 
17552   stmt= mysql_simple_prepare(mysql,
17553     "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
17554     "VALUES(?, ?, ?, ?, ?, ?, ?)");
17555   check_stmt(stmt);
17556 
17557   verify_param_count(stmt, 7);
17558 
17559   bzero(my_bind, sizeof(my_bind));
17560   /* tinyint */
17561   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
17562   my_bind[0].buffer= (void *)&tiny_data;
17563   /* string */
17564   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
17565   my_bind[1].buffer= (void *)str_data;
17566   my_bind[1].buffer_length= 1000;                  /* Max string length */
17567   /* integer */
17568   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
17569   my_bind[2].buffer= (void *)&int_data;
17570   /* short */
17571   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
17572   my_bind[3].buffer= (void *)&small_data;
17573   /* bigint */
17574   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
17575   my_bind[4].buffer= (void *)&big_data;
17576   /* float */
17577   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
17578   my_bind[5].buffer= (void *)&real_data;
17579   /* double */
17580   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
17581   my_bind[6].buffer= (void *)&double_data;
17582 
17583   for (i= 0; i < (int) array_elements(my_bind); i++)
17584   {
17585     my_bind[i].length= &length[i];
17586     my_bind[i].is_null= &is_null[i];
17587     is_null[i]= 0;
17588   }
17589 
17590   rc= mysql_stmt_bind_param(stmt, my_bind);
17591   check_execute(stmt, rc);
17592 
17593   int_data= 320;
17594   small_data= 1867;
17595   big_data= 1000;
17596   real_data= 2;
17597   double_data= 6578.001;
17598 
17599   /* now, execute the prepared statement to insert 10 records.. */
17600   for (tiny_data= 0; tiny_data < 10; tiny_data++)
17601   {
17602     length[1]= sprintf(str_data, "MySQL%d", int_data);
17603     rc= mysql_stmt_execute(stmt);
17604     check_execute(stmt, rc);
17605     int_data += 25;
17606     small_data += 10;
17607     big_data += 100;
17608     real_data += 1;
17609     double_data += 10.09;
17610   }
17611 
17612   /* force a re-prepare with some DDL */
17613 
17614   rc= mysql_query(mysql,
17615     "ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
17616   myquery(rc);
17617 
17618   /*
17619     execute the prepared statement again,
17620     without changing the types of parameters already bound.
17621   */
17622 
17623   for (tiny_data= 50; tiny_data < 60; tiny_data++)
17624   {
17625     length[1]= sprintf(str_data, "MySQL%d", int_data);
17626     rc= mysql_stmt_execute(stmt);
17627     check_execute(stmt, rc);
17628     int_data += 25;
17629     small_data += 10;
17630     big_data += 100;
17631     real_data += 1;
17632     double_data += 10.09;
17633   }
17634 
17635   mysql_stmt_close(stmt);
17636 
17637   rc= mysql_query(mysql, "DROP TABLE table_4166");
17638   myquery(rc);
17639 }
17640 
17641 
test_wl4166_2()17642 static void test_wl4166_2()
17643 {
17644   MYSQL_STMT *stmt;
17645   int        c_int;
17646   MYSQL_TIME d_date;
17647   MYSQL_BIND bind_out[2];
17648   int rc;
17649 
17650   myheader("test_wl4166_2");
17651 
17652   rc= mysql_query(mysql, "SET SQL_MODE=''");
17653   myquery(rc);
17654 
17655   rc= mysql_query(mysql, "drop table if exists t1");
17656   myquery(rc);
17657   rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
17658   myquery(rc);
17659   rc= mysql_query(mysql,
17660                   "insert into t1 (c_int, d_date) values (42, '1948-05-15')");
17661   myquery(rc);
17662 
17663   stmt= mysql_simple_prepare(mysql, "select * from t1");
17664   check_stmt(stmt);
17665 
17666   bzero(bind_out, sizeof(bind_out));
17667   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
17668   bind_out[0].buffer= (void*) &c_int;
17669 
17670   bind_out[1].buffer_type= MYSQL_TYPE_DATE;
17671   bind_out[1].buffer= (void*) &d_date;
17672 
17673   rc= mysql_stmt_bind_result(stmt, bind_out);
17674   check_execute(stmt, rc);
17675 
17676   /* int -> varchar transition */
17677 
17678   rc= mysql_query(mysql,
17679                   "alter table t1 change column c_int c_int varchar(11)");
17680   myquery(rc);
17681 
17682   rc= mysql_stmt_execute(stmt);
17683   check_execute(stmt, rc);
17684 
17685   rc= mysql_stmt_fetch(stmt);
17686   check_execute(stmt, rc);
17687 
17688   DIE_UNLESS(c_int == 42);
17689   DIE_UNLESS(d_date.year == 1948);
17690   DIE_UNLESS(d_date.month == 5);
17691   DIE_UNLESS(d_date.day == 15);
17692 
17693   rc= mysql_stmt_fetch(stmt);
17694   DIE_UNLESS(rc == MYSQL_NO_DATA);
17695 
17696   /* varchar to int retrieval with truncation */
17697 
17698   rc= mysql_query(mysql, "update t1 set c_int='abcde'");
17699   myquery(rc);
17700 
17701   rc= mysql_stmt_execute(stmt);
17702   check_execute(stmt, rc);
17703 
17704   rc= mysql_stmt_fetch(stmt);
17705   check_execute_r(stmt, rc);
17706 
17707   DIE_UNLESS(c_int == 0);
17708 
17709   rc= mysql_stmt_fetch(stmt);
17710   DIE_UNLESS(rc == MYSQL_NO_DATA);
17711 
17712   /* alter table and increase the number of columns */
17713   rc= mysql_query(mysql, "alter table t1 add column d_int int");
17714   myquery(rc);
17715 
17716   rc= mysql_stmt_execute(stmt);
17717   check_execute_r(stmt, rc);
17718 
17719   rc= mysql_stmt_reset(stmt);
17720   check_execute(stmt, rc);
17721 
17722   /* decrease the number of columns */
17723   rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
17724   myquery(rc);
17725 
17726   rc= mysql_stmt_execute(stmt);
17727   check_execute_r(stmt, rc);
17728 
17729   mysql_stmt_close(stmt);
17730   rc= mysql_query(mysql, "drop table t1");
17731   myquery(rc);
17732 }
17733 
17734 
17735 /**
17736   Test how warnings generated during assignment of parameters
17737   are (currently not) preserve in case of reprepare.
17738 */
17739 
test_wl4166_3()17740 static void test_wl4166_3()
17741 {
17742   int rc;
17743   MYSQL_STMT *stmt;
17744   MYSQL_BIND my_bind[1];
17745   MYSQL_TIME tm[1];
17746 
17747   myheader("test_wl4166_3");
17748 
17749   rc= mysql_query(mysql, "drop table if exists t1");
17750   myquery(rc);
17751 
17752   rc= mysql_query(mysql, "create table t1 (year datetime)");
17753   myquery(rc);
17754 
17755   stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)");
17756   check_stmt(stmt);
17757   verify_param_count(stmt, 1);
17758 
17759   bzero((char*) my_bind, sizeof(my_bind));
17760   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17761   my_bind[0].buffer= &tm[0];
17762 
17763   rc= mysql_stmt_bind_param(stmt, my_bind);
17764   check_execute(stmt, rc);
17765 
17766   tm[0].year= 10000;
17767   tm[0].month= 1; tm[0].day= 1;
17768   tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
17769   tm[0].second_part= 0; tm[0].neg= 0;
17770 
17771   /* Cause a statement reprepare */
17772   rc= mysql_query(mysql, "alter table t1 add column c int");
17773   myquery(rc);
17774 
17775   rc= mysql_stmt_execute(stmt);
17776   check_execute(stmt, rc);
17777   /*
17778     The warning about data truncation when assigning a parameter is lost.
17779     This is a bug.
17780   */
17781   my_process_warnings(mysql, 0);
17782 
17783   verify_col_data("t1", "year", "0000-00-00 00:00:00");
17784 
17785   mysql_stmt_close(stmt);
17786 
17787   rc= mysql_query(mysql, "drop table t1");
17788   myquery(rc);
17789 }
17790 
17791 
17792 /**
17793   Test that long data parameters, as well as parameters
17794   that were originally in a different character set, are
17795   preserved in case of reprepare.
17796 */
17797 
test_wl4166_4()17798 static void test_wl4166_4()
17799 {
17800   MYSQL_STMT *stmt;
17801   int rc;
17802   const char *stmt_text;
17803   MYSQL_BIND bind_array[2];
17804 
17805   /* Represented as numbers to keep UTF8 tools from clobbering them. */
17806   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
17807   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
17808   char buf1[16], buf2[16];
17809   ulong buf1_len, buf2_len;
17810 
17811   myheader("test_wl4166_4");
17812 
17813   rc= mysql_query(mysql, "drop table if exists t1");
17814   myquery(rc);
17815 
17816   /*
17817     Create table with binary columns, set session character set to cp1251,
17818     client character set to koi8, and make sure that there is conversion
17819     on insert and no conversion on select
17820   */
17821   rc= mysql_query(mysql,
17822                   "create table t1 (c1 varbinary(255), c2 varbinary(255))");
17823   myquery(rc);
17824   rc= mysql_query(mysql, "set character_set_client=koi8r, "
17825                          "character_set_connection=cp1251, "
17826                          "character_set_results=koi8r");
17827   myquery(rc);
17828 
17829   bzero((char*) bind_array, sizeof(bind_array));
17830 
17831   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
17832 
17833   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
17834   bind_array[1].buffer= (void *) koi8;
17835   bind_array[1].buffer_length= strlen(koi8);
17836 
17837   stmt= mysql_stmt_init(mysql);
17838   check_stmt(stmt);
17839 
17840   stmt_text= "insert into t1 (c1, c2) values (?, ?)";
17841 
17842   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17843   check_execute(stmt, rc);
17844 
17845   mysql_stmt_bind_param(stmt, bind_array);
17846 
17847   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
17848 
17849   /* Cause a reprepare at statement execute */
17850   rc= mysql_query(mysql, "alter table t1 add column d int");
17851   myquery(rc);
17852 
17853   rc= mysql_stmt_execute(stmt);
17854   check_execute(stmt, rc);
17855 
17856   stmt_text= "select c1, c2 from t1";
17857 
17858   /* c1 and c2 are binary so no conversion will be done on select */
17859   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17860   check_execute(stmt, rc);
17861 
17862   rc= mysql_stmt_execute(stmt);
17863   check_execute(stmt, rc);
17864 
17865   bind_array[0].buffer= buf1;
17866   bind_array[0].buffer_length= sizeof(buf1);
17867   bind_array[0].length= &buf1_len;
17868 
17869   bind_array[1].buffer= buf2;
17870   bind_array[1].buffer_length= sizeof(buf2);
17871   bind_array[1].length= &buf2_len;
17872 
17873   mysql_stmt_bind_result(stmt, bind_array);
17874 
17875   rc= mysql_stmt_fetch(stmt);
17876   check_execute(stmt, rc);
17877 
17878   DIE_UNLESS(buf1_len == strlen(cp1251));
17879   DIE_UNLESS(buf2_len == strlen(cp1251));
17880   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
17881   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
17882 
17883   rc= mysql_stmt_fetch(stmt);
17884   DIE_UNLESS(rc == MYSQL_NO_DATA);
17885 
17886   mysql_stmt_close(stmt);
17887 
17888   rc= mysql_query(mysql, "drop table t1");
17889   myquery(rc);
17890   rc= mysql_query(mysql, "set names default");
17891   myquery(rc);
17892 }
17893 
17894 /**
17895   Bug#36004 mysql_stmt_prepare resets the list of warnings
17896 */
17897 
test_bug36004()17898 static void test_bug36004()
17899 {
17900   int rc, warning_count= 0;
17901   MYSQL_STMT *stmt;
17902 
17903   DBUG_ENTER("test_bug36004");
17904   myheader("test_bug36004");
17905 
17906   rc= mysql_query(mysql, "drop table if exists inexistant");
17907   myquery(rc);
17908 
17909   DIE_UNLESS(mysql_warning_count(mysql) == 1);
17910   query_int_variable(mysql, "@@warning_count", &warning_count);
17911   DIE_UNLESS(warning_count);
17912 
17913   stmt= mysql_simple_prepare(mysql, "select 1");
17914   check_stmt(stmt);
17915 
17916   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17917   query_int_variable(mysql, "@@warning_count", &warning_count);
17918   DIE_UNLESS(warning_count);
17919 
17920   rc= mysql_stmt_execute(stmt);
17921   check_execute(stmt, rc);
17922 
17923   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17924   mysql_stmt_close(stmt);
17925 
17926   query_int_variable(mysql, "@@warning_count", &warning_count);
17927   DIE_UNLESS(warning_count);
17928 
17929   stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
17930   check_stmt(stmt);
17931 
17932   query_int_variable(mysql, "@@warning_count", &warning_count);
17933   DIE_UNLESS(warning_count == 0);
17934   mysql_stmt_close(stmt);
17935 
17936   DBUG_VOID_RETURN;
17937 }
17938 
17939 /**
17940   Test that COM_REFRESH issues a implicit commit.
17941 */
17942 
test_wl4284_1()17943 static void test_wl4284_1()
17944 {
17945   int rc;
17946   MYSQL_ROW row;
17947   MYSQL_RES *result;
17948 
17949   DBUG_ENTER("test_wl4284_1");
17950   myheader("test_wl4284_1");
17951 
17952   /* set AUTOCOMMIT to OFF */
17953   rc= mysql_autocommit(mysql, FALSE);
17954   myquery(rc);
17955 
17956   rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
17957   myquery(rc);
17958 
17959   rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
17960   myquery(rc);
17961 
17962   rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
17963   myquery(rc);
17964 
17965   rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
17966   myquery(rc);
17967 
17968   rc= mysql_rollback(mysql);
17969   myquery(rc);
17970 
17971   rc= mysql_query(mysql, "SELECT * FROM trans");
17972   myquery(rc);
17973 
17974   result= mysql_use_result(mysql);
17975   mytest(result);
17976 
17977   row= mysql_fetch_row(result);
17978   mytest(row);
17979 
17980   mysql_free_result(result);
17981 
17982   /* set AUTOCOMMIT to ON */
17983   rc= mysql_autocommit(mysql, TRUE);
17984   myquery(rc);
17985 
17986   rc= mysql_query(mysql, "DROP TABLE trans");
17987   myquery(rc);
17988 
17989   DBUG_VOID_RETURN;
17990 }
17991 
17992 
test_bug38486(void)17993 static void test_bug38486(void)
17994 {
17995   MYSQL_STMT *stmt;
17996   const char *stmt_text;
17997   unsigned long type= CURSOR_TYPE_READ_ONLY;
17998 
17999   DBUG_ENTER("test_bug38486");
18000   myheader("test_bug38486");
18001 
18002   stmt= mysql_stmt_init(mysql);
18003   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18004   stmt_text= "CREATE TABLE t1 (a INT)";
18005   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
18006   mysql_stmt_execute(stmt);
18007   mysql_stmt_close(stmt);
18008 
18009   stmt= mysql_stmt_init(mysql);
18010   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18011   stmt_text= "INSERT INTO t1 VALUES (1)";
18012   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
18013   mysql_stmt_execute(stmt);
18014   mysql_stmt_close(stmt);
18015 
18016   DBUG_VOID_RETURN;
18017 }
18018 
18019 
18020 /**
18021      Bug# 33831 mysql_real_connect() should fail if
18022      given an already connected MYSQL handle.
18023 */
18024 
test_bug33831(void)18025 static void test_bug33831(void)
18026 {
18027   MYSQL *l_mysql;
18028 
18029   DBUG_ENTER("test_bug33831");
18030 
18031   if (!(l_mysql= mysql_client_init(NULL)))
18032   {
18033     myerror("mysql_client_init() failed");
18034     DIE_UNLESS(0);
18035   }
18036   if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
18037                            opt_password, current_db, opt_port,
18038                            opt_unix_socket, 0)))
18039   {
18040     myerror("connection failed");
18041     DIE_UNLESS(0);
18042   }
18043 
18044   if (mysql_real_connect(l_mysql, opt_host, opt_user,
18045                          opt_password, current_db, opt_port,
18046                          opt_unix_socket, 0))
18047   {
18048     myerror("connection should have failed");
18049     DIE_UNLESS(0);
18050   }
18051 
18052   mysql_close(l_mysql);
18053 
18054   DBUG_VOID_RETURN;
18055 }
18056 
18057 
test_bug40365(void)18058 static void test_bug40365(void)
18059 {
18060   uint         rc, i;
18061   MYSQL_STMT   *stmt= 0;
18062   MYSQL_BIND   my_bind[2];
18063   my_bool      is_null[2]= {0};
18064   MYSQL_TIME   tm[2];
18065 
18066   DBUG_ENTER("test_bug40365");
18067 
18068   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18069   myquery(rc);
18070   rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \
18071                                           c2 DATE)");
18072   myquery(rc);
18073 
18074   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)");
18075   check_stmt(stmt);
18076   verify_param_count(stmt, 2);
18077 
18078   bzero((char*) my_bind, sizeof(my_bind));
18079   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
18080   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
18081   for (i= 0; i < (int) array_elements(my_bind); i++)
18082   {
18083     my_bind[i].buffer= (void *) &tm[i];
18084     my_bind[i].is_null= &is_null[i];
18085   }
18086 
18087   rc= mysql_stmt_bind_param(stmt, my_bind);
18088   check_execute(stmt, rc);
18089 
18090   for (i= 0; i < (int) array_elements(my_bind); i++)
18091   {
18092     tm[i].neg= 0;
18093     tm[i].second_part= 0;
18094     tm[i].year= 2009;
18095     tm[i].month= 2;
18096     tm[i].day= 29;
18097     tm[i].hour= 0;
18098     tm[i].minute= 0;
18099     tm[i].second= 0;
18100   }
18101   rc= mysql_stmt_execute(stmt);
18102   check_execute(stmt, rc);
18103 
18104   rc= mysql_commit(mysql);
18105   myquery(rc);
18106   mysql_stmt_close(stmt);
18107 
18108   stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1");
18109   check_stmt(stmt);
18110 
18111   rc= mysql_stmt_bind_result(stmt, my_bind);
18112   check_execute(stmt, rc);
18113 
18114   rc= mysql_stmt_execute(stmt);
18115   check_execute(stmt, rc);
18116 
18117   rc= mysql_stmt_store_result(stmt);
18118   check_execute(stmt, rc);
18119 
18120   rc= mysql_stmt_fetch(stmt);
18121   check_execute(stmt, rc);
18122 
18123   if (!opt_silent)
18124     fprintf(stdout, "\n");
18125 
18126   for (i= 0; i < array_elements(my_bind); i++)
18127   {
18128     if (!opt_silent)
18129       fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d ",
18130               i, tm[i].year, tm[i].month, tm[i].day);
18131     DIE_UNLESS(tm[i].year == 0);
18132     DIE_UNLESS(tm[i].month == 0);
18133     DIE_UNLESS(tm[i].day == 0);
18134   }
18135   mysql_stmt_close(stmt);
18136   rc= mysql_commit(mysql);
18137   myquery(rc);
18138 
18139   DBUG_VOID_RETURN;
18140 }
18141 
18142 
18143 /**
18144   Subtest for Bug#43560. Verifies that a loss of connection on the server side
18145   is handled well by the mysql_stmt_execute() call, i.e., no SIGSEGV due to
18146   a vio socket that is cleared upon closed connection.
18147 
18148   Assumes the presence of the close_conn_after_stmt_execute debug feature in
18149   the server. Verifies that it is connected to a debug server before proceeding
18150   with the test.
18151  */
test_bug43560(void)18152 static void test_bug43560(void)
18153 {
18154   MYSQL*       conn;
18155   uint         rc;
18156   MYSQL_STMT   *stmt= 0;
18157   MYSQL_BIND   bind;
18158   my_bool      is_null= 0;
18159   char         buffer[256];
18160   const uint   BUFSIZE= sizeof(buffer);
18161   const char*  values[] = {"eins", "zwei", "drei", "viele", NULL};
18162   const char   insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
18163   unsigned long length;
18164   const unsigned int drop_db= opt_drop_db;
18165 
18166   DBUG_ENTER("test_bug43560");
18167   myheader("test_bug43560");
18168 
18169   /* Make sure we only run against a debug server. */
18170   if (!strstr(mysql->server_version, "debug"))
18171   {
18172     fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
18173     DBUG_VOID_RETURN;
18174   }
18175   if (opt_unix_socket)
18176   {
18177     fprintf(stdout, "Skipping test_bug43560: connected via UNIX socket\n");
18178     DBUG_VOID_RETURN;
18179   }
18180   /*
18181     Set up a separate connection for this test to avoid messing up the
18182     general MYSQL object used in other subtests. Use TCP protocol to avoid
18183     problems with the buffer semantics of AF_UNIX, and turn off auto reconnect.
18184   */
18185   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
18186 
18187   rc= mysql_query(conn, "DROP TABLE IF EXISTS t1");
18188   myquery(rc);
18189   rc= mysql_query(conn,
18190     "CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))");
18191   myquery(rc);
18192 
18193   stmt= mysql_stmt_init(conn);
18194   check_stmt(stmt);
18195   rc= mysql_stmt_prepare(stmt, insert_str, strlen(insert_str));
18196   check_execute(stmt, rc);
18197 
18198   bind.buffer_type= MYSQL_TYPE_STRING;
18199   bind.buffer_length= BUFSIZE;
18200   bind.buffer= buffer;
18201   bind.is_null= &is_null;
18202   bind.length= &length;
18203   rc= mysql_stmt_bind_param(stmt, &bind);
18204   check_execute(stmt, rc);
18205 
18206   /* First execute; should succeed. */
18207   strncpy(buffer, values[0], BUFSIZE);
18208   length= strlen(buffer);
18209   rc= mysql_stmt_execute(stmt);
18210   check_execute(stmt, rc);
18211 
18212   /*
18213     Set up the server to close this session's server-side socket after
18214     next execution of prep statement.
18215   */
18216   rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'");
18217   myquery(rc);
18218 
18219   /* Second execute; should fail due to socket closed during execution. */
18220   strncpy(buffer, values[1], BUFSIZE);
18221   length= strlen(buffer);
18222   rc= mysql_stmt_execute(stmt);
18223   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18224 
18225   /*
18226     Third execute; should fail (connection already closed), or SIGSEGV in
18227     case of a Bug#43560 type regression in which case the whole test fails.
18228   */
18229   strncpy(buffer, values[2], BUFSIZE);
18230   length= strlen(buffer);
18231   rc= mysql_stmt_execute(stmt);
18232   DIE_UNLESS(rc && (mysql_stmt_errno(stmt) == CR_SERVER_LOST ||
18233                     mysql_stmt_errno(stmt) == CR_SERVER_GONE_ERROR));
18234 
18235   opt_drop_db= 0;
18236   client_disconnect(conn);
18237   rc= mysql_query(mysql, "DROP TABLE t1");
18238   myquery(rc);
18239   opt_drop_db= drop_db;
18240 
18241   DBUG_VOID_RETURN;
18242 }
18243 
18244 
18245 /**
18246   Bug#36326: nested transaction and select
18247 */
18248 
test_bug36326()18249 static void test_bug36326()
18250 {
18251   int rc;
18252 
18253   DBUG_ENTER("test_bug36326");
18254   myheader("test_bug36326");
18255 
18256   if (! is_query_cache_available())
18257   {
18258     fprintf(stdout, "Skipping test_bug36326: Query cache not available.\n");
18259     DBUG_VOID_RETURN;
18260   }
18261 
18262   rc= mysql_autocommit(mysql, TRUE);
18263   myquery(rc);
18264   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18265   myquery(rc);
18266   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
18267   myquery(rc);
18268   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
18269   myquery(rc);
18270   rc= mysql_query(mysql,
18271                   "set @save_query_cache_type="
18272                   "@@global.query_cache_type,"
18273                   "@save_query_cache_size="
18274                   "@@global.query_cache_size");
18275   myquery(rc);
18276   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
18277   myquery(rc);
18278   rc= mysql_query(mysql, "SET LOCAL query_cache_type = 1");
18279   myquery(rc);
18280   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576");
18281   myquery(rc);
18282   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18283   DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
18284   rc= mysql_query(mysql, "BEGIN");
18285   myquery(rc);
18286   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
18287   rc= mysql_query(mysql, "SELECT * FROM t1");
18288   myquery(rc);
18289   rc= my_process_result(mysql);
18290   DIE_UNLESS(rc == 1);
18291   rc= mysql_rollback(mysql);
18292   myquery(rc);
18293   rc= mysql_query(mysql, "ROLLBACK");
18294   myquery(rc);
18295   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18296   rc= mysql_query(mysql, "SELECT * FROM t1");
18297   myquery(rc);
18298   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18299   rc= my_process_result(mysql);
18300   DIE_UNLESS(rc == 1);
18301   rc= mysql_query(mysql, "DROP TABLE t1");
18302   myquery(rc);
18303   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = @save_query_cache_size");
18304   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = @save_query_cache_type");
18305   myquery(rc);
18306 
18307   DBUG_VOID_RETURN;
18308 }
18309 
18310 /**
18311   Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
18312              string value.
18313 */
18314 
test_bug41078(void)18315 static void test_bug41078(void)
18316 {
18317   uint         rc;
18318   MYSQL_STMT   *stmt= 0;
18319   MYSQL_BIND   param, result;
18320   ulong        cursor_type= CURSOR_TYPE_READ_ONLY;
18321   ulong        len;
18322   char         str[64];
18323   const char   param_str[]= "abcdefghijklmn";
18324   my_bool      is_null, error;
18325 
18326   DBUG_ENTER("test_bug41078");
18327 
18328   rc= mysql_query(mysql, "SET NAMES UTF8");
18329   myquery(rc);
18330 
18331   stmt= mysql_simple_prepare(mysql, "SELECT ?");
18332   check_stmt(stmt);
18333   verify_param_count(stmt, 1);
18334 
18335   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type);
18336   check_execute(stmt, rc);
18337 
18338   bzero(&param, sizeof(param));
18339   param.buffer_type= MYSQL_TYPE_STRING;
18340   param.buffer= (void *) param_str;
18341   len= sizeof(param_str) - 1;
18342   param.length= &len;
18343 
18344   rc= mysql_stmt_bind_param(stmt, &param);
18345   check_execute(stmt, rc);
18346 
18347   rc= mysql_stmt_execute(stmt);
18348   check_execute(stmt, rc);
18349 
18350   bzero(&result, sizeof(result));
18351   result.buffer_type= MYSQL_TYPE_STRING;
18352   result.buffer= str;
18353   result.buffer_length= sizeof(str);
18354   result.is_null= &is_null;
18355   result.length= &len;
18356   result.error=  &error;
18357 
18358   rc= mysql_stmt_bind_result(stmt, &result);
18359   check_execute(stmt, rc);
18360 
18361   rc= mysql_stmt_store_result(stmt);
18362   check_execute(stmt, rc);
18363 
18364   rc= mysql_stmt_fetch(stmt);
18365   check_execute(stmt, rc);
18366 
18367   DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str));
18368 
18369   mysql_stmt_close(stmt);
18370 
18371   DBUG_VOID_RETURN;
18372 }
18373 
18374 /**
18375   Bug#45010: invalid memory reads during parsing some strange statements
18376 */
test_bug45010()18377 static void test_bug45010()
18378 {
18379   int rc;
18380   const char query1[]= "select a.\x80",
18381              query2[]= "describe `table\xef";
18382 
18383   DBUG_ENTER("test_bug45010");
18384   myheader("test_bug45010");
18385 
18386   rc= mysql_query(mysql, "set names utf8");
18387   myquery(rc);
18388 
18389   /* \x80 (-128) could be used as a index of ident_map. */
18390   rc= mysql_real_query(mysql, query1, sizeof(query1) - 1);
18391   DIE_UNLESS(rc);
18392 
18393   /* \xef (-17) could be used to skip 3 bytes past the buffer end. */
18394   rc= mysql_real_query(mysql, query2, sizeof(query2) - 1);
18395   DIE_UNLESS(rc);
18396 
18397   rc= mysql_query(mysql, "set names default");
18398   myquery(rc);
18399 
18400   DBUG_VOID_RETURN;
18401 }
18402 
18403 /**
18404   Bug#44495: Prepared Statement:
18405              CALL p(<x>) - `thd->protocol == &thd->protocol_text' failed
18406 */
18407 
test_bug44495()18408 static void test_bug44495()
18409 {
18410   int rc;
18411   MYSQL con;
18412   MYSQL_STMT *stmt;
18413 
18414   DBUG_ENTER("test_bug44495");
18415   myheader("test_44495");
18416 
18417   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18418   myquery(rc);
18419 
18420   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN arg VARCHAR(25))"
18421                          "  BEGIN SET @stmt = CONCAT('SELECT \"', arg, '\"');"
18422                          "  PREPARE ps1 FROM @stmt;"
18423                          "  EXECUTE ps1;"
18424                          "  DROP PREPARE ps1;"
18425                          "END;");
18426   myquery(rc);
18427 
18428   DIE_UNLESS(mysql_client_init(&con));
18429 
18430   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18431                                 current_db, opt_port, opt_unix_socket,
18432                                 CLIENT_MULTI_RESULTS));
18433 
18434   stmt= mysql_simple_prepare(&con, "CALL p1('abc')");
18435   check_stmt(stmt);
18436 
18437   rc= mysql_stmt_execute(stmt);
18438   check_execute(stmt, rc);
18439 
18440   rc= my_process_stmt_result(stmt);
18441   DIE_UNLESS(rc == 1);
18442 
18443   mysql_stmt_close(stmt);
18444 
18445   mysql_close(&con);
18446 
18447   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18448   myquery(rc);
18449 
18450   DBUG_VOID_RETURN;
18451 }
18452 
test_bug53371()18453 static void test_bug53371()
18454 {
18455   int rc;
18456   MYSQL_RES *result;
18457 
18458   myheader("test_bug53371");
18459 
18460   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18461   myquery(rc);
18462   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
18463   myquery(rc);
18464   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18465 
18466   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18467   myquery(rc);
18468   rc= mysql_query(mysql, "CREATE DATABASE bug53371");
18469   myquery(rc);
18470   rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
18471   myquery(rc);
18472 
18473   rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
18474   myquery(rc);
18475 
18476   rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
18477   DIE_UNLESS(rc);
18478   DIE_UNLESS(mysql_errno(mysql) == 1142);
18479 
18480   result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
18481   DIE_IF(result);
18482 
18483   result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
18484   DIE_IF(result);
18485 
18486   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
18487   myquery(rc);
18488   rc= mysql_query(mysql, "DROP TABLE t1");
18489   myquery(rc);
18490   rc= mysql_query(mysql, "DROP DATABASE bug53371");
18491   myquery(rc);
18492   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18493   myquery(rc);
18494 }
18495 
18496 
18497 
18498 /**
18499   Bug#42373: libmysql can mess a connection at connect
18500 */
test_bug42373()18501 static void test_bug42373()
18502 {
18503   int rc;
18504   MYSQL con;
18505   MYSQL_STMT *stmt;
18506 
18507   DBUG_ENTER("test_bug42373");
18508   myheader("test_42373");
18509 
18510   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18511   myquery(rc);
18512 
18513   rc= mysql_query(mysql, "CREATE PROCEDURE p1()"
18514                          "  BEGIN"
18515                          "  SELECT 1;"
18516                          "  INSERT INTO t1 VALUES (2);"
18517                          "END;");
18518   myquery(rc);
18519 
18520   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18521   myquery(rc);
18522 
18523   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18524   myquery(rc);
18525 
18526   /* Try with a stored procedure. */
18527   DIE_UNLESS(mysql_client_init(&con));
18528 
18529   mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()");
18530 
18531   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18532                                 current_db, opt_port, opt_unix_socket,
18533                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18534 
18535   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18536   check_stmt(stmt);
18537 
18538   rc= mysql_stmt_execute(stmt);
18539   check_execute(stmt, rc);
18540 
18541   rc= my_process_stmt_result(stmt);
18542   DIE_UNLESS(rc == 1);
18543 
18544   mysql_stmt_close(stmt);
18545   mysql_close(&con);
18546 
18547   /* Now try with a multi-statement. */
18548   DIE_UNLESS(mysql_client_init(&con));
18549 
18550   mysql_options(&con, MYSQL_INIT_COMMAND,
18551                 "SELECT 3; INSERT INTO t1 VALUES (4)");
18552 
18553   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18554                                 current_db, opt_port, opt_unix_socket,
18555                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18556 
18557   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18558   check_stmt(stmt);
18559 
18560   rc= mysql_stmt_execute(stmt);
18561   check_execute(stmt, rc);
18562 
18563   rc= my_process_stmt_result(stmt);
18564   DIE_UNLESS(rc == 2);
18565 
18566   mysql_stmt_close(stmt);
18567   mysql_close(&con);
18568 
18569   rc= mysql_query(mysql, "DROP TABLE t1");
18570   myquery(rc);
18571 
18572   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18573   myquery(rc);
18574 
18575   DBUG_VOID_RETURN;
18576 }
18577 
18578 
18579 /**
18580   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18581 */
18582 
test_bug54041_impl()18583 static void test_bug54041_impl()
18584 {
18585   int rc;
18586   MYSQL_STMT *stmt;
18587   MYSQL_BIND bind;
18588 
18589   DBUG_ENTER("test_bug54041");
18590   myheader("test_bug54041");
18591 
18592   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18593   myquery(rc);
18594 
18595   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18596   myquery(rc);
18597 
18598   stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?");
18599   check_stmt(stmt);
18600   verify_param_count(stmt, 1);
18601 
18602   memset(&bind, 0, sizeof(bind));
18603 
18604   /* Any type that does not support long data handling. */
18605   bind.buffer_type= MYSQL_TYPE_LONG;
18606 
18607   rc= mysql_stmt_bind_param(stmt, &bind);
18608   check_execute(stmt, rc);
18609 
18610   /*
18611     Trick the client API into sending a long data packet for
18612     the parameter. Long data is only supported for string and
18613     binary types.
18614   */
18615   stmt->params[0].buffer_type= MYSQL_TYPE_STRING;
18616 
18617   rc= mysql_stmt_send_long_data(stmt, 0, "data", 5);
18618   check_execute(stmt, rc);
18619 
18620   /* Undo API violation. */
18621   stmt->params[0].buffer_type= MYSQL_TYPE_LONG;
18622 
18623   rc= mysql_stmt_execute(stmt);
18624   /* Incorrect arguments. */
18625   check_execute_r(stmt, rc);
18626 
18627   mysql_stmt_close(stmt);
18628 
18629   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18630   myquery(rc);
18631 
18632   DBUG_VOID_RETURN;
18633 }
18634 
18635 
18636 /**
18637   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18638 */
18639 
test_bug54041()18640 static void test_bug54041()
18641 {
18642   enable_query_logs(0);
18643   test_bug54041_impl();
18644   disable_query_logs();
18645   test_bug54041_impl();
18646   restore_query_logs();
18647 }
18648 
18649 
18650 /**
18651   Bug#47485: mysql_store_result returns a result set for a prepared statement
18652 */
test_bug47485()18653 static void test_bug47485()
18654 {
18655   MYSQL_STMT   *stmt;
18656   MYSQL_RES    *res;
18657   MYSQL_BIND    bind[2];
18658   int           rc;
18659   const char*   sql_select = "SELECT 1, 'a'";
18660   int           int_data;
18661   char          str_data[16];
18662   my_bool       is_null[2];
18663   my_bool       error[2];
18664   unsigned long length[2];
18665 
18666   DBUG_ENTER("test_bug47485");
18667   myheader("test_bug47485");
18668 
18669   stmt= mysql_stmt_init(mysql);
18670   check_stmt(stmt);
18671   rc= mysql_stmt_prepare(stmt, sql_select, strlen(sql_select));
18672   check_execute(stmt, rc);
18673 
18674   rc= mysql_stmt_execute(stmt);
18675   check_execute(stmt, rc);
18676 
18677   res = mysql_store_result(mysql);
18678   DIE_UNLESS(res == NULL);
18679 
18680   mysql_stmt_reset(stmt);
18681 
18682   rc= mysql_stmt_execute(stmt);
18683   check_execute(stmt, rc);
18684 
18685   res = mysql_use_result(mysql);
18686   DIE_UNLESS(res == NULL);
18687 
18688   mysql_stmt_reset(stmt);
18689 
18690   memset(bind, 0, sizeof(bind));
18691   bind[0].buffer_type= MYSQL_TYPE_LONG;
18692   bind[0].buffer= (char *)&int_data;
18693   bind[0].is_null= &is_null[0];
18694   bind[0].length= &length[0];
18695   bind[0].error= &error[0];
18696 
18697   bind[1].buffer_type= MYSQL_TYPE_STRING;
18698   bind[1].buffer= (char *)str_data;
18699   bind[1].buffer_length= sizeof(str_data);
18700   bind[1].is_null= &is_null[1];
18701   bind[1].length= &length[1];
18702   bind[1].error= &error[1];
18703 
18704   rc= mysql_stmt_bind_result(stmt, bind);
18705   check_execute(stmt, rc);
18706 
18707   rc= mysql_stmt_execute(stmt);
18708   check_execute(stmt, rc);
18709 
18710   rc= mysql_stmt_store_result(stmt);
18711   check_execute(stmt, rc);
18712 
18713   while (!(rc= mysql_stmt_fetch(stmt)))
18714     ;
18715 
18716   DIE_UNLESS(rc == MYSQL_NO_DATA);
18717 
18718   mysql_stmt_reset(stmt);
18719 
18720   memset(bind, 0, sizeof(bind));
18721   bind[0].buffer_type= MYSQL_TYPE_LONG;
18722   bind[0].buffer= (char *)&int_data;
18723   bind[0].is_null= &is_null[0];
18724   bind[0].length= &length[0];
18725   bind[0].error= &error[0];
18726 
18727   bind[1].buffer_type= MYSQL_TYPE_STRING;
18728   bind[1].buffer= (char *)str_data;
18729   bind[1].buffer_length= sizeof(str_data);
18730   bind[1].is_null= &is_null[1];
18731   bind[1].length= &length[1];
18732   bind[1].error= &error[1];
18733 
18734   rc= mysql_stmt_bind_result(stmt, bind);
18735   check_execute(stmt, rc);
18736 
18737   rc= mysql_stmt_execute(stmt);
18738   check_execute(stmt, rc);
18739 
18740   while (!(rc= mysql_stmt_fetch(stmt)))
18741     ;
18742 
18743   DIE_UNLESS(rc == MYSQL_NO_DATA);
18744 
18745   mysql_stmt_close(stmt);
18746 
18747   DBUG_VOID_RETURN;
18748 }
18749 
18750 
18751 /*
18752   Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server
18753 */
test_bug58036()18754 static void test_bug58036()
18755 {
18756   MYSQL *conn;
18757   DBUG_ENTER("test_bug58036");
18758   myheader("test_bug58036");
18759 
18760   /* Part1: try to connect with ucs2 client character set */
18761   conn= mysql_client_init(NULL);
18762   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18763 
18764   if (mysql_real_connect(conn, opt_host, opt_user,
18765                          opt_password,  opt_db ? opt_db : "test",
18766                          opt_port, opt_unix_socket, 0))
18767   {
18768     if (!opt_silent)
18769       printf("mysql_real_connect() succeeded (failure expected)\n");
18770     mysql_close(conn);
18771     DIE("");
18772   }
18773 
18774   if (!opt_silent)
18775     printf("Got mysql_real_connect() error (expected): %s (%d)\n",
18776            mysql_error(conn), mysql_errno(conn));
18777   DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR ||
18778              mysql_errno(conn)== CR_CANT_READ_CHARSET);
18779   mysql_close(conn);
18780 
18781 
18782   /*
18783     Part2:
18784     - connect with latin1
18785     - then change client character set to ucs2
18786     - then try mysql_change_user()
18787   */
18788   conn= mysql_client_init(NULL);
18789   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1");
18790   if (!mysql_real_connect(conn, opt_host, opt_user,
18791                          opt_password, opt_db ? opt_db : "test",
18792                          opt_port, opt_unix_socket, 0))
18793   {
18794     if (!opt_silent)
18795       printf("mysql_real_connect() failed: %s (%d)\n",
18796              mysql_error(conn), mysql_errno(conn));
18797     mysql_close(conn);
18798     DIE("");
18799   }
18800 
18801   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18802   if (!mysql_change_user(conn, opt_user, opt_password, NULL))
18803   {
18804     if (!opt_silent)
18805       printf("mysql_change_user() succedded, error expected!");
18806     mysql_close(conn);
18807     DIE("");
18808   }
18809 
18810   if (!opt_silent)
18811     printf("Got mysql_change_user() error (expected): %s (%d)\n",
18812            mysql_error(conn), mysql_errno(conn));
18813   mysql_close(conn);
18814   DBUG_VOID_RETURN;
18815 }
18816 
18817 
18818 /*
18819   Bug#49972: Crash in prepared statements.
18820 
18821   The following case lead to a server crash:
18822     - Use binary protocol;
18823     - Prepare a statement with OUT-parameter;
18824     - Execute the statement;
18825     - Cause re-prepare of the statement (change dependencies);
18826     - Execute the statement again -- crash here.
18827 */
18828 
test_bug49972()18829 static void test_bug49972()
18830 {
18831   int rc;
18832   MYSQL_STMT *stmt;
18833 
18834   MYSQL_BIND in_param_bind;
18835   MYSQL_BIND out_param_bind;
18836   int int_data;
18837   my_bool is_null;
18838 
18839   DBUG_ENTER("test_bug49972");
18840   myheader("test_bug49972");
18841 
18842   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
18843   myquery(rc);
18844 
18845   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18846   myquery(rc);
18847 
18848   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18849   myquery(rc);
18850 
18851   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a");
18852   myquery(rc);
18853 
18854   stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)");
18855   check_stmt(stmt);
18856 
18857   bzero((char *) &in_param_bind, sizeof (in_param_bind));
18858 
18859   in_param_bind.buffer_type= MYSQL_TYPE_LONG;
18860   in_param_bind.buffer= (char *) &int_data;
18861   in_param_bind.length= 0;
18862   in_param_bind.is_null= 0;
18863 
18864   rc= mysql_stmt_bind_param(stmt, &in_param_bind);
18865 
18866   rc= mysql_stmt_execute(stmt);
18867   check_execute(stmt, rc);
18868 
18869   {
18870     bzero(&out_param_bind, sizeof (out_param_bind));
18871 
18872     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18873     out_param_bind.is_null= &is_null;
18874     out_param_bind.buffer= &int_data;
18875     out_param_bind.buffer_length= sizeof (int_data);
18876 
18877     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18878     check_execute(stmt, rc);
18879 
18880     rc= mysql_stmt_fetch(stmt);
18881     rc= mysql_stmt_fetch(stmt);
18882     DBUG_ASSERT(rc == MYSQL_NO_DATA);
18883 
18884     mysql_stmt_next_result(stmt);
18885     mysql_stmt_fetch(stmt);
18886   }
18887 
18888   rc= mysql_query(mysql, "DROP FUNCTION f1");
18889   myquery(rc);
18890 
18891   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18892   myquery(rc);
18893 
18894   rc= mysql_stmt_execute(stmt);
18895   check_execute(stmt, rc);
18896 
18897   {
18898     bzero(&out_param_bind, sizeof (out_param_bind));
18899 
18900     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18901     out_param_bind.is_null= &is_null;
18902     out_param_bind.buffer= &int_data;
18903     out_param_bind.buffer_length= sizeof (int_data);
18904 
18905     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18906     check_execute(stmt, rc);
18907 
18908     rc= mysql_stmt_fetch(stmt);
18909     rc= mysql_stmt_fetch(stmt);
18910     DBUG_ASSERT(rc == MYSQL_NO_DATA);
18911 
18912     mysql_stmt_next_result(stmt);
18913     mysql_stmt_fetch(stmt);
18914   }
18915 
18916   mysql_stmt_close(stmt);
18917 
18918   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18919   myquery(rc);
18920 
18921   rc= mysql_query(mysql, "DROP FUNCTION f1");
18922   myquery(rc);
18923 
18924   DBUG_VOID_RETURN;
18925 }
18926 
18927 
18928 /*
18929   Bug #56976:   Severe Denial Of Service in prepared statements
18930 */
test_bug56976()18931 static void test_bug56976()
18932 {
18933   MYSQL_STMT   *stmt;
18934   MYSQL_BIND    bind[1];
18935   int           rc;
18936   const char*   query = "SELECT LENGTH(?)";
18937   char *long_buffer;
18938   unsigned long i, packet_len = 256 * 1024L;
18939   unsigned long dos_len    = 35000000;
18940 
18941   DBUG_ENTER("test_bug56976");
18942   myheader("test_bug56976");
18943 
18944   stmt= mysql_stmt_init(mysql);
18945   check_stmt(stmt);
18946 
18947   rc= mysql_stmt_prepare(stmt, query, strlen(query));
18948   check_execute(stmt, rc);
18949 
18950   memset(bind, 0, sizeof(bind));
18951   bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;
18952 
18953   rc= mysql_stmt_bind_param(stmt, bind);
18954   check_execute(stmt, rc);
18955 
18956   long_buffer= (char*) my_malloc(packet_len, MYF(0));
18957   DIE_UNLESS(long_buffer);
18958 
18959   memset(long_buffer, 'a', packet_len);
18960 
18961   for (i= 0; i < dos_len / packet_len; i++)
18962   {
18963     rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len);
18964     check_execute(stmt, rc);
18965   }
18966 
18967   my_free(long_buffer);
18968   rc= mysql_stmt_execute(stmt);
18969 
18970   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);
18971 
18972   mysql_stmt_close(stmt);
18973 
18974   DBUG_VOID_RETURN;
18975 }
18976 
18977 /*
18978   Test that CLIENT_PROGRESS works.
18979 */
18980 
18981 uint progress_stage, progress_max_stage, progress_count;
18982 
report_progress(const MYSQL * mysql,uint stage,uint max_stage,double progress,const char * proc_info,uint proc_info_length)18983 static void report_progress(const MYSQL *mysql __attribute__((unused)),
18984                             uint stage, uint max_stage,
18985                             double progress __attribute__((unused)),
18986                             const char *proc_info __attribute__((unused)),
18987                             uint proc_info_length __attribute__((unused)))
18988 {
18989   progress_stage= stage;
18990   progress_max_stage= max_stage;
18991   progress_count++;
18992 }
18993 
18994 
test_progress_reporting()18995 static void test_progress_reporting()
18996 {
18997   int rc, i;
18998   MYSQL*       conn;
18999 
19000   /* Progress reporting doesn't work yet with embedded server */
19001   if (embedded_server_arg_count)
19002     return;
19003 
19004   myheader("test_progress_reporting");
19005 
19006 
19007   conn= client_connect(CLIENT_PROGRESS_OBSOLETE, MYSQL_PROTOCOL_TCP, 0);
19008   DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS_OBSOLETE);
19009 
19010   mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);
19011   rc= mysql_query(conn, "set @save=@@global.progress_report_time");
19012   myquery(rc);
19013   rc= mysql_query(conn, "set @@global.progress_report_time=1");
19014   myquery(rc);
19015 
19016   rc= mysql_query(conn, "drop table if exists t1,t2");
19017   myquery(rc);
19018   rc= mysql_query(conn, "create table t1 (f2 varchar(255)) engine=aria");
19019   myquery(rc);
19020   rc= mysql_query(conn, "create table t2 like t1");
19021   myquery(rc);
19022   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))");
19023   myquery(rc);
19024   for (i= 0 ; i < 5 ; i++)
19025   {
19026     rc= mysql_query(conn, "insert into t2 (f2) select f2 from t1");
19027     myquery(rc);
19028     rc= mysql_query(conn, "insert into t1 (f2) select f2 from t2");
19029     myquery(rc);
19030   }
19031 
19032   progress_stage= progress_max_stage= progress_count= 0;
19033   rc= mysql_query(conn, "alter table t1 add f1 int primary key auto_increment, order by f2");
19034   myquery(rc);
19035   if (!opt_silent)
19036     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19037            progress_count, progress_stage, progress_max_stage);
19038   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 3);
19039 
19040   progress_stage= progress_max_stage= progress_count= 0;
19041   rc= mysql_query(conn, "create index f2 on t1 (f2)");
19042   myquery(rc);
19043   if (!opt_silent)
19044     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19045            progress_count, progress_stage, progress_max_stage);
19046   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 2);
19047 
19048   progress_stage= progress_max_stage= progress_count= 0;
19049   rc= mysql_query(conn, "drop index f2 on t1");
19050   myquery(rc);
19051   if (!opt_silent)
19052     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19053            progress_count, progress_stage, progress_max_stage);
19054   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 2);
19055 
19056   rc= mysql_query(conn, "set @@global.progress_report_time=@save");
19057   myquery(rc);
19058   mysql_close(conn);
19059 }
19060 
19061 /**
19062   MDEV-3885 - connection suicide via mysql_kill() causes assertion in server
19063 */
19064 
test_mdev3885()19065 static void test_mdev3885()
19066 {
19067   int rc;
19068   MYSQL *conn;
19069 
19070   myheader("test_mdev3885");
19071   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
19072   rc= mysql_kill(conn, mysql_thread_id(conn));
19073   DIE_UNLESS(rc);
19074   mysql_close(conn);
19075 }
19076 
19077 
19078 /**
19079   Bug#57058 SERVER_QUERY_WAS_SLOW not wired up.
19080 */
19081 
test_bug57058()19082 static void test_bug57058()
19083 {
19084   MYSQL_RES *res;
19085   int rc;
19086 
19087   DBUG_ENTER("test_bug57058");
19088   myheader("test_bug57058");
19089 
19090   rc= mysql_query(mysql, "set @@session.long_query_time=0.1");
19091   myquery(rc);
19092 
19093   DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW));
19094 
19095   rc= mysql_query(mysql, "select sleep(1)");
19096   myquery(rc);
19097 
19098   /*
19099     Important: the flag is sent in the last EOF packet of
19100     the query, the one which ends the result. Read the
19101     result to see the "slow" status.
19102   */
19103   res= mysql_store_result(mysql);
19104 
19105   DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW);
19106 
19107   mysql_free_result(res);
19108 
19109   rc= mysql_query(mysql, "set @@session.long_query_time=default");
19110   myquery(rc);
19111 
19112   DBUG_VOID_RETURN;
19113 }
19114 
19115 
19116 /**
19117   Bug#11766854: 60075: MYSQL_LOAD_CLIENT_PLUGIN DOESN'T CLEAR ERROR
19118 */
19119 
test_bug11766854()19120 static void test_bug11766854()
19121 {
19122   struct st_mysql_client_plugin *plugin;
19123 
19124   DBUG_ENTER("test_bug11766854");
19125   myheader("test_bug11766854");
19126 
19127   plugin= mysql_load_plugin(mysql, "foo", -1, 0);
19128   DIE_UNLESS(plugin == 0);
19129 
19130   plugin= mysql_load_plugin(mysql, "qa_auth_client", -1, 0);
19131   DIE_UNLESS(plugin != 0);
19132   DIE_IF(mysql_errno(mysql));
19133 
19134   DBUG_VOID_RETURN;
19135 }
19136 
19137 /**
19138   Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR
19139                        CHAR/VARCHAR/TEXT COLUMNS IN VIEWS
19140 */
test_bug12337762()19141 static void test_bug12337762()
19142 {
19143   int rc,i=0;
19144   MYSQL_RES *result;
19145   MYSQL_FIELD *field;
19146   unsigned int tab_charsetnr[3]= {0};
19147 
19148   DBUG_ENTER("test_bug12337762");
19149   myheader("test_bug12337762");
19150 
19151   /*
19152     Creating table with specific charset.
19153   */
19154   rc= mysql_query(mysql, "drop table if exists charset_tab");
19155   rc= mysql_query(mysql, "create table charset_tab("\
19156                          "txt1 varchar(32) character set Latin1,"\
19157                          "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
19158                          "txt3 varchar(32) character set utf8 collate utf8_bin"\
19159 						 ")");
19160 
19161   DIE_UNLESS(rc == 0);
19162   DIE_IF(mysql_errno(mysql));
19163 
19164   /*
19165     Creating view from table created earlier.
19166   */
19167   rc= mysql_query(mysql, "drop view if exists charset_view");
19168   rc= mysql_query(mysql, "create view charset_view as "\
19169                          "select * from charset_tab;");
19170   DIE_UNLESS(rc == 0);
19171   DIE_IF(mysql_errno(mysql));
19172 
19173   /*
19174     Checking field information for table.
19175   */
19176   result= mysql_list_fields(mysql, "charset_tab", NULL);
19177   DIE_IF(mysql_errno(mysql));
19178   i=0;
19179   while((field= mysql_fetch_field(result)))
19180   {
19181     printf("field name %s\n", field->name);
19182     printf("field table %s\n", field->table);
19183     printf("field type %d\n", field->type);
19184     printf("field charset %d\n", field->charsetnr);
19185     tab_charsetnr[i++]= field->charsetnr;
19186     printf("\n");
19187   }
19188   mysql_free_result(result);
19189 
19190   /*
19191     Checking field information for view.
19192   */
19193   result= mysql_list_fields(mysql, "charset_view", NULL);
19194   DIE_IF(mysql_errno(mysql));
19195   i=0;
19196   while((field= mysql_fetch_field(result)))
19197   {
19198     printf("field name %s\n", field->name);
19199     printf("field table %s\n", field->table);
19200     printf("field type %d\n", field->type);
19201     printf("field charset %d\n", field->charsetnr);
19202     printf("\n");
19203     /*
19204       charset value for field must be same for both, view and table.
19205     */
19206     DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
19207   }
19208   mysql_free_result(result);
19209 
19210   DBUG_VOID_RETURN;
19211 }
19212 
19213 /*
19214    MDEV-4603: mysql_stmt_reset doesn't clear
19215               all result sets (from stored procedures).
19216    This test requires also fix for MDEV-4604
19217 */
test_mdev4603()19218 static void test_mdev4603()
19219 {
19220   MYSQL *my;
19221   MYSQL_STMT *stmt;
19222   int i, rc;
19223   int a[] = {10,20,30};
19224   MYSQL_BIND bind[3];
19225 
19226   myheader("test_mdev4603");
19227   my= mysql_client_init(NULL);
19228 
19229   if (!mysql_real_connect(my, opt_host, opt_user,
19230                                opt_password, current_db, opt_port,
19231                                opt_unix_socket, CLIENT_MULTI_RESULTS))
19232     DIE("mysql_real_connect failed");
19233 
19234   /* 1st test:
19235      use a procedure with out param
19236   */
19237   rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1");
19238   myquery(rc);
19239 
19240   rc= mysql_query(mysql, "CREATE PROCEDURE p1(OUT p_out VARCHAR(19), IN p_in INT, INOUT p_inout INT)"
19241                          "BEGIN "
19242                           "  SET p_in = 300, p_out := 'This is OUT param', p_inout = 200; "
19243                           "  SELECT p_inout, p_in, substring(p_out, 9);"
19244                          "END");
19245   myquery(rc);
19246 
19247   stmt= mysql_stmt_init(mysql);
19248   DIE_UNLESS(stmt != NULL);
19249 
19250   rc= mysql_stmt_prepare(stmt, "CALL P1(?,?,?)", 14);
19251   DIE_UNLESS(rc == 0);
19252 
19253   DIE_UNLESS(mysql_stmt_param_count(stmt) == 3);
19254 
19255   memset(bind, 0, sizeof(MYSQL_BIND) * 3);
19256   for (i=0; i < 3; i++)
19257   {
19258     bind[i].buffer= &a[i];
19259     bind[i].buffer_type= MYSQL_TYPE_LONG;
19260   }
19261   bind[0].buffer_type= MYSQL_TYPE_NULL;
19262   rc= mysql_stmt_bind_param(stmt, bind);
19263   DIE_UNLESS(rc == 0);
19264 
19265   rc= mysql_stmt_execute(stmt);
19266   DIE_UNLESS(rc == 0);
19267 
19268   rc= mysql_stmt_fetch(stmt);
19269   DIE_UNLESS(rc == 0);
19270 
19271   rc= mysql_stmt_reset(stmt);
19272   DIE_UNLESS(rc == 0);
19273 
19274   /*connection shouldn't be blocked now */
19275 
19276   rc= mysql_query(mysql, "DROP PROCEDURE p1");
19277   myquery(rc);
19278 
19279   /* 2nd test:
19280      reset all result sets */
19281   rc= mysql_query(my, "CREATE PROCEDURE p1() "
19282                       "BEGIN"
19283                       "  SELECT 1,2,3 FROM DUAL;"
19284                       "  SELECT 'foo' FROM DUAL;"
19285                       "END");
19286   myquery(rc);
19287 
19288   rc= mysql_stmt_prepare(stmt, "CALL P1()", 9);
19289   DIE_UNLESS(rc == 0);
19290 
19291   rc= mysql_stmt_execute(stmt);
19292   DIE_UNLESS(rc == 0);
19293 
19294   rc= mysql_stmt_reset(stmt);
19295   DIE_UNLESS(rc == 0);
19296 
19297   /* 3rd test:
19298      mysql_stmt_close should also flush all pending
19299      result sets
19300   */
19301 
19302   rc= mysql_stmt_prepare(stmt, "CALL P1()", 9);
19303   DIE_UNLESS(rc == 0);
19304 
19305   rc= mysql_stmt_execute(stmt);
19306   DIE_UNLESS(rc == 0);
19307 
19308   rc= mysql_stmt_close(stmt);
19309   DIE_UNLESS(rc == 0);
19310 
19311   rc= mysql_query(my, "DROP PROCEDURE p1");
19312   myquery(rc);
19313 
19314   mysql_close(my);
19315 }
19316 
19317 /*
19318   BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
19319 */
19320 
test_bug11754979()19321 static void test_bug11754979()
19322 {
19323   MYSQL* conn;
19324   DBUG_ENTER("test_bug11754979");
19325 
19326   myheader("test_bug11754979");
19327   DIE_UNLESS((conn= mysql_client_init(NULL)));
19328   DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
19329              opt_password, opt_db ? opt_db:"test", opt_port,
19330              opt_unix_socket,  CLIENT_FOUND_ROWS));
19331   myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
19332   myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
19333   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
19334   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
19335                             "ON DUPLICATE KEY UPDATE id = 4"));
19336   DIE_UNLESS(mysql_affected_rows(conn) == 2);
19337   myquery(mysql_query(conn, "DROP TABLE t1"));
19338   mysql_close(conn);
19339 
19340   DBUG_VOID_RETURN;
19341 }
19342 
test_ps_sp_out_params()19343 static void test_ps_sp_out_params()
19344 {
19345   MYSQL *my;
19346   MYSQL_STMT *stmt;
19347   MYSQL_BIND bind[1];
19348   char buffer[20];
19349   int status, rc;
19350 
19351   myheader("test_ps_sp_out_params");
19352   my= mysql_client_init(NULL);
19353 
19354   if (!mysql_real_connect(my, opt_host, opt_user,
19355                                opt_password, current_db, opt_port,
19356                                opt_unix_socket, CLIENT_MULTI_RESULTS))
19357     DIE("mysql_real_connect failed");
19358 
19359   rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1");
19360   myquery(rc);
19361 
19362   rc= mysql_query(my,
19363     "CREATE PROCEDURE p1(OUT out_param VARCHAR(19)) "
19364     "BEGIN"
19365     " SELECT 'foo' FROM DUAL;"
19366     " SET out_param='foo';"
19367     " SELECT 'foo' FROM DUAL;"
19368     "END");
19369   myquery(rc);
19370 
19371   stmt= mysql_stmt_init(my);
19372 
19373   rc= mysql_stmt_prepare(stmt, "CALL P1(?)", 10);
19374   DIE_UNLESS(rc==0);
19375 
19376   DIE_UNLESS(mysql_stmt_param_count(stmt) == 1);
19377 
19378   memset(bind, 0, sizeof(MYSQL_BIND));
19379   bind[0].buffer= buffer;
19380   bind[0].buffer_length= sizeof(buffer);
19381   bind[0].buffer_type= MYSQL_TYPE_STRING;
19382 
19383   mysql_stmt_bind_param(stmt, bind);
19384 
19385   rc= mysql_stmt_execute(stmt);
19386   check_execute(stmt, rc);
19387 
19388   do {
19389     if (mysql_stmt_field_count(stmt))
19390     {
19391       /* since server sends a status packet at the end,
19392          there must follow at least one additional packet */
19393       DIE_UNLESS(mysql_more_results(stmt->mysql));
19394 
19395       mysql_stmt_bind_result(stmt, bind);
19396 
19397       rc= mysql_stmt_fetch(stmt);
19398       DIE_UNLESS(rc== 0);
19399 
19400       DIE_UNLESS(strcmp(buffer, "foo") == 0);
19401     }
19402     status= mysql_stmt_next_result(stmt);
19403   } while (status == 0);
19404 
19405   rc= mysql_stmt_reset(stmt);
19406   DIE_UNLESS(rc== 0);
19407 
19408   mysql_stmt_close(stmt);
19409   mysql_close(my);
19410 
19411   printf("end\n");
19412 }
19413 
19414 /*
19415   Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
19416 */
test_bug13001491()19417 static void test_bug13001491()
19418 {
19419   int rc;
19420   char query[MAX_TEST_QUERY_LENGTH];
19421   MYSQL *c;
19422 
19423   myheader("test_bug13001491");
19424 
19425   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19426            "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
19427            opt_host ? opt_host : "'localhost'");
19428 
19429   rc= mysql_query(mysql, query);
19430   myquery(rc);
19431 
19432   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19433            "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
19434            opt_host ? opt_host : "'localhost'");
19435 
19436   rc= mysql_query(mysql, query);
19437   myquery(rc);
19438 
19439   c= mysql_client_init(NULL);
19440 
19441   DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
19442                                 current_db, opt_port, opt_unix_socket,
19443                                 CLIENT_MULTI_STATEMENTS |
19444                                 CLIENT_MULTI_RESULTS));
19445 
19446   rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
19447   myquery(rc);
19448 
19449   rc= mysql_query(c,
19450     "CREATE PROCEDURE p1() "
19451     "BEGIN "
19452     " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
19453     " SELECT COUNT(*) "
19454     " FROM INFORMATION_SCHEMA.PROCESSLIST "
19455     " GROUP BY user "
19456     " ORDER BY NULL "
19457     " INTO @a; "
19458     "END");
19459   myquery(rc);
19460 
19461   rc= mysql_query(c, "CALL p1()");
19462   myquery(rc);
19463 
19464   mysql_free_result(mysql_store_result(c));
19465 
19466   /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
19467   rc= mysql_refresh(c, REFRESH_GRANT |
19468                        REFRESH_TABLES | REFRESH_HOSTS |
19469                        REFRESH_STATUS | REFRESH_THREADS);
19470   myquery(rc);
19471 
19472   /*
19473     Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
19474     fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
19475     location.
19476   */
19477   mysql_refresh(c, REFRESH_LOG);
19478 
19479   rc= mysql_query(c, "DROP PROCEDURE p1");
19480   myquery(rc);
19481 
19482   mysql_close(c);
19483   c= NULL;
19484 
19485   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19486            "DROP USER mysqltest_u1@%s",
19487            opt_host ? opt_host : "'localhost'");
19488 
19489   rc= mysql_query(mysql, query);
19490   myquery(rc);
19491 }
19492 
test_mdev4326()19493 static void test_mdev4326()
19494 {
19495   MYSQL_STMT   *stmt;
19496   MYSQL_BIND    bind;
19497   char query[]= "SELECT * FROM mysql.user LIMIT ?";
19498   char str_data[]= "1";
19499   unsigned long length= 0;
19500   int int_data= 1;
19501   int rc, count;
19502   my_bool is_null= 0;
19503   my_bool error= 0;
19504   myheader("test_mdev4326");
19505 
19506   rc= mysql_change_user(mysql, opt_user, opt_password, "mysql");
19507   myquery(rc);
19508 
19509   rc= mysql_query(mysql, "SET GLOBAL general_log = 1");
19510   myquery(rc);
19511 
19512   stmt= mysql_stmt_init(mysql);
19513   check_stmt(stmt);
19514 
19515   /* Numeric parameter test */
19516 
19517   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19518   check_execute(stmt, rc);
19519   check_stmt(stmt);
19520   verify_param_count(stmt, 1);
19521 
19522   memset((char *)&bind, 0, sizeof(bind));
19523   bind.buffer_type= MYSQL_TYPE_LONG;
19524   bind.buffer= (char *)&int_data;
19525   bind.is_null= &is_null;
19526   bind.length= &length;
19527   bind.error= &error;
19528 
19529   rc= mysql_stmt_bind_param(stmt, &bind);
19530   check_execute(stmt, rc);
19531   rc= mysql_stmt_execute(stmt);
19532   check_execute(stmt, rc);
19533   count= 0;
19534   while (!(rc= mysql_stmt_fetch(stmt)))
19535     count++;
19536   DIE_UNLESS(count == 1);
19537   rc= mysql_stmt_execute(stmt);
19538   check_execute(stmt, rc);
19539   count= 0;
19540   while (!(rc= mysql_stmt_fetch(stmt)))
19541     count++;
19542   DIE_UNLESS(count == 1);
19543   int_data= 0;
19544   rc= mysql_stmt_execute(stmt);
19545   check_execute(stmt, rc);
19546   count= 0;
19547   while (!(rc= mysql_stmt_fetch(stmt)))
19548     count++;
19549   DIE_UNLESS(count == 0);
19550   rc= mysql_stmt_close(stmt);
19551   check_execute(stmt, rc);
19552 
19553   /* String parameter test */
19554 
19555   stmt= mysql_stmt_init(mysql);
19556   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19557   check_execute(stmt, rc);
19558   check_stmt(stmt);
19559   verify_param_count(stmt, 1);
19560 
19561   memset((char *)&bind, 0, sizeof(bind));
19562   bind.buffer_type= MYSQL_TYPE_STRING;
19563   bind.buffer= (char *)str_data;
19564   length= bind.buffer_length= sizeof(str_data);
19565   bind.is_null= &is_null;
19566   bind.length= &length;
19567   bind.error= &error;
19568 
19569   rc= mysql_stmt_bind_param(stmt, &bind);
19570   check_execute(stmt, rc);
19571   rc= mysql_stmt_execute(stmt);
19572   check_execute(stmt, rc);
19573   count= 0;
19574   while (!(rc= mysql_stmt_fetch(stmt)))
19575     count++;
19576   DIE_UNLESS(count == 1);
19577   rc= mysql_stmt_execute(stmt);
19578   check_execute(stmt, rc);
19579   count= 0;
19580   while (!(rc= mysql_stmt_fetch(stmt)))
19581     count++;
19582   DIE_UNLESS(count == 1);
19583   str_data[0]= '0';
19584   rc= mysql_stmt_execute(stmt);
19585   check_execute(stmt, rc);
19586   count= 0;
19587   while (!(rc= mysql_stmt_fetch(stmt)))
19588     count++;
19589   DIE_UNLESS(count == 0);
19590   rc= mysql_stmt_close(stmt);
19591   check_execute(stmt, rc);
19592 
19593   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
19594   myquery(rc);
19595 }
19596 
19597 /* Test uses MYSQL_PROTOCOL_SOCKET, not on Windows */
19598 
19599 #ifndef _WIN32
19600 /**
19601    BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST()
19602 */
test_bug17512527()19603 static void test_bug17512527()
19604 {
19605   MYSQL *conn;
19606   MYSQL_STMT *stmt1, *stmt2;
19607   unsigned long thread_id;
19608   char query[MAX_TEST_QUERY_LENGTH];
19609   int rc;
19610 
19611   conn= client_connect(0, MYSQL_PROTOCOL_SOCKET, 1);
19612 
19613   stmt1 = mysql_stmt_init(conn);
19614   check_stmt(stmt1);
19615   rc= mysql_stmt_prepare(stmt1, STRING_WITH_LEN("SELECT 1"));
19616   check_execute(stmt1, rc);
19617 
19618   stmt2 = mysql_stmt_init(conn);
19619   check_stmt(stmt2);
19620 
19621   thread_id= mysql_thread_id(conn);
19622   sprintf(query, "KILL %lu", thread_id);
19623   if (thread_query(query))
19624     exit(1);
19625 
19626   rc= mysql_stmt_prepare(stmt2, STRING_WITH_LEN("SELECT 2"));
19627   check_execute(stmt2, rc);
19628 
19629   rc= mysql_stmt_execute(stmt1);
19630   check_execute_r(stmt1, rc);
19631 
19632   rc= mysql_stmt_execute(stmt2);
19633   check_execute(stmt2, rc);
19634 
19635   mysql_close(conn);
19636 
19637   mysql_stmt_close(stmt2);
19638   mysql_stmt_close(stmt1);
19639 }
19640 #endif
19641 
19642 
19643 /*
19644   Check compressed protocol
19645 */
19646 
test_compressed_protocol()19647 static void test_compressed_protocol()
19648 {
19649   MYSQL *mysql_local;
19650   char query[4096], *end;
19651   int i;
19652   myheader("test_compressed_protocol");
19653 
19654   if (!(mysql_local= mysql_client_init(NULL)))
19655   {
19656     fprintf(stderr, "\n mysql_client_init() failed");
19657     exit(1);
19658   }
19659 
19660   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
19661                            opt_password, current_db, opt_port,
19662                            opt_unix_socket, CLIENT_COMPRESS)))
19663   {
19664     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
19665     exit(1);
19666   }
19667   mysql_options(mysql_local,MYSQL_OPT_COMPRESS,NullS);
19668 
19669   end= strmov(strfill(strmov(query, "select length(\""),1000,'a'),"\")");
19670 
19671   for (i=0 ; i < 2 ; i++)
19672   {
19673     MYSQL_RES *res;
19674 
19675     int rc= mysql_real_query(mysql, query, (int) (end-query));
19676     myquery(rc);
19677     res= mysql_store_result(mysql);
19678     DBUG_ASSERT(res != 0);
19679     mysql_free_result(res);
19680   }
19681 
19682   mysql_close(mysql_local);
19683 }
19684 
19685 /*
19686   Check big packets
19687 */
19688 
test_big_packet()19689 static void test_big_packet()
19690 {
19691   MYSQL *mysql_local;
19692   char *query, *end;
19693   /* We run the tests with a server with max packet size of 3200000 */
19694   size_t big_packet= 31000000L;
19695   int i;
19696   MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
19697   long org_max_allowed_packet= *mysql_params->p_max_allowed_packet;
19698   long opt_net_buffer_length= *mysql_params->p_net_buffer_length;
19699 
19700   myheader("test_big_packet");
19701 
19702   query= (char*) my_malloc(big_packet+1024, MYF(MY_WME));
19703   DIE_UNLESS(query);
19704 
19705   if (!(mysql_local= mysql_client_init(NULL)))
19706   {
19707     fprintf(stderr, "\n mysql_client_init() failed");
19708     exit(1);
19709   }
19710 
19711   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
19712                            opt_password, current_db, opt_port,
19713                            opt_unix_socket, 0)))
19714   {
19715     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
19716     mysql_close(mysql_local);
19717     exit(1);
19718   }
19719 
19720   *mysql_params->p_max_allowed_packet= big_packet+1000;
19721   *mysql_params->p_net_buffer_length=  8L*256L*256L;
19722 
19723   end= strmov(strfill(strmov(query, "select length(\""), big_packet,'a'),"\")");
19724 
19725   for (i=0 ; i < 2 ; i++)
19726   {
19727     MYSQL_RES *res;
19728     int rc= mysql_real_query(mysql, query, (int) (end-query));
19729     myquery(rc);
19730     res= mysql_store_result(mysql);
19731     DBUG_ASSERT(res != 0);
19732     mysql_free_result(res);
19733   }
19734 
19735   mysql_close(mysql_local);
19736   my_free(query);
19737 
19738   *mysql_params->p_max_allowed_packet= org_max_allowed_packet;
19739   *mysql_params->p_net_buffer_length = opt_net_buffer_length;
19740 }
19741 
19742 
test_prepare_analyze()19743 static void test_prepare_analyze()
19744 {
19745   MYSQL_STMT *stmt;
19746   const char *query= "ANALYZE SELECT 1";
19747   int rc;
19748   myheader("test_prepare_analyze");
19749 
19750   stmt= mysql_stmt_init(mysql);
19751   check_stmt(stmt);
19752   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19753   check_execute(stmt, rc);
19754 
19755   rc= mysql_stmt_execute(stmt);
19756   check_execute(stmt, rc);
19757 
19758   rc= mysql_stmt_store_result(stmt);
19759   check_execute(stmt, rc);
19760 
19761   while (!(rc= mysql_stmt_fetch(stmt)))
19762     ;
19763 
19764   DIE_UNLESS(rc == MYSQL_NO_DATA);
19765 
19766   rc= mysql_stmt_close(stmt);
19767   check_execute(stmt, rc);
19768 }
19769 
test_mdev12579()19770 static void test_mdev12579()
19771 {
19772   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
19773   MYSQL_BIND bind[2];
19774   int rc;
19775   long l=3;
19776   const char *data = "123456";
19777 
19778   rc= mysql_query(mysql, "CREATE TABLE mdev12579 (k integer,t LONGTEXT,b LONGBLOB,x integer)");
19779   myquery(rc);
19780 
19781   rc= mysql_stmt_prepare(stmt, "INSERT INTO mdev12579 VALUES (1,?,NULL,?)", -1);
19782   myquery(rc);
19783 
19784   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19785   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19786   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19787 
19788   memset(bind, 0, sizeof(MYSQL_BIND) * 2);
19789   bind[0].buffer_type= MYSQL_TYPE_VAR_STRING;
19790   bind[1].buffer_type= MYSQL_TYPE_LONG;
19791   bind[1].buffer= &l;
19792   mysql_stmt_bind_param(stmt, bind);
19793 
19794   rc= mysql_stmt_execute(stmt);
19795   check_execute(stmt, rc);
19796 
19797   mysql_stmt_close(stmt);
19798 
19799   rc= mysql_query(mysql, "DROP TABLE mdev12579");
19800   myquery(rc);
19801 }
19802 
19803 /* Test test_mdev14013 sql_mode=EMPTY_STRING_IS_NULL */
19804 
test_mdev14013()19805 static void test_mdev14013()
19806 {
19807   MYSQL *lmysql;
19808   MYSQL_STMT *stmt1;
19809   MYSQL_BIND  my_bind[2];
19810   MYSQL_RES   *result;
19811   char       str_data[20];
19812   unsigned int  count;
19813   int   rc;
19814   char query[MAX_TEST_QUERY_LENGTH];
19815 
19816   myheader("test_mdev14013");
19817 
19818   if (!opt_silent)
19819     fprintf(stdout, "\n Establishing a test connection ...");
19820   if (!(lmysql= mysql_client_init(NULL)))
19821   {
19822     myerror("mysql_client_init() failed");
19823     exit(1);
19824   }
19825   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
19826                            opt_password, current_db, opt_port,
19827                            opt_unix_socket, 0)))
19828   {
19829     myerror("connection failed");
19830     exit(1);
19831   }
19832   mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
19833   if (!opt_silent)
19834     fprintf(stdout, "OK");
19835 
19836   /* set AUTOCOMMIT to ON*/
19837   mysql_autocommit(lmysql, TRUE);
19838 
19839   strmov(query, "SET SQL_MODE= \"EMPTY_STRING_IS_NULL\"");
19840   if (!opt_silent)
19841     fprintf(stdout, "\n With %s", query);
19842   rc= mysql_query(mysql, query);
19843   myquery(rc);
19844 
19845   rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_mdev14013");
19846   myquery(rc);
19847 
19848   rc= mysql_query(lmysql, "CREATE TABLE test_mdev14013(id int, val varchar(10))");
19849   myquery(rc);
19850 
19851   strmov(query, "INSERT INTO test_mdev14013(id,val) VALUES(?,?)");
19852   stmt1= mysql_simple_prepare(mysql, query);
19853   check_stmt(stmt1);
19854 
19855   verify_param_count(stmt1, 2);
19856 
19857   /*
19858     We need to bzero bind structure because mysql_stmt_bind_param checks all
19859     its members.
19860   */
19861   bzero((char*) my_bind, sizeof(my_bind));
19862 
19863   my_bind[0].buffer= (void *)&count;
19864   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
19865   count= 100;
19866 
19867   strcpy(str_data,"");
19868   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
19869   my_bind[1].buffer= (char *) str_data;
19870   my_bind[1].buffer_length= strlen(str_data);
19871 
19872   rc= mysql_stmt_bind_param(stmt1, my_bind);
19873 
19874   rc= mysql_stmt_execute(stmt1);
19875   check_execute(stmt1, rc);
19876 
19877   verify_st_affected_rows(stmt1, 1);
19878 
19879   rc= mysql_stmt_close(stmt1);
19880 
19881   strmov(query, "SET SQL_MODE= default");
19882   if (!opt_silent)
19883     fprintf(stdout, "\n With %s\n", query);
19884   rc= mysql_query(mysql, query);
19885   myquery(rc);
19886 
19887   strmov(query, "INSERT INTO test_mdev14013(id,val) VALUES(?,?)");
19888   stmt1= mysql_simple_prepare(mysql, query);
19889   check_stmt(stmt1);
19890 
19891   count= 200;
19892   rc= mysql_stmt_bind_param(stmt1, my_bind);
19893 
19894   rc= mysql_stmt_execute(stmt1);
19895   check_execute(stmt1, rc);
19896 
19897   verify_st_affected_rows(stmt1, 1);
19898 
19899   rc= mysql_stmt_close(stmt1);
19900   if (!opt_silent)
19901     fprintf(stdout, "\n test_mdev14013(x) returned: %d", rc);
19902   DIE_UNLESS( rc == 0);
19903 
19904   rc= mysql_query(mysql, "SELECT id, val FROM test_mdev14013 order by id");
19905   myquery(rc);
19906 
19907   result= mysql_store_result(mysql);
19908   mytest(result);
19909 
19910   rc= my_process_result_set(result);
19911   DIE_UNLESS(rc == 2);
19912   mysql_free_result(result);
19913 
19914   rc= mysql_query(mysql, "SELECT id, val FROM test_mdev14013 where val is null");
19915   myquery(rc);
19916 
19917   result= mysql_store_result(mysql);
19918   mytest(result);
19919 
19920   rc= my_process_result_set(result);
19921   DIE_UNLESS(rc == 1);
19922   mysql_free_result(result);
19923 
19924   myquery(mysql_query(mysql, "drop table test_mdev14013"));
19925   mysql_close(lmysql);
19926 }
19927 
test_mdev14013_1()19928 static void test_mdev14013_1()
19929 {
19930   MYSQL *lmysql;
19931   MYSQL_STMT *stmt1;
19932   MYSQL_BIND  my_bind[3];
19933   char       str_data[3][255];
19934   int  rc;
19935   char query[MAX_TEST_QUERY_LENGTH];
19936 
19937   myheader("test_mdev14013_1");
19938 
19939   if (!opt_silent)
19940     fprintf(stdout, "\n Establishing a test connection ...");
19941   if (!(lmysql= mysql_client_init(NULL)))
19942   {
19943     myerror("mysql_client_init() failed");
19944     exit(1);
19945   }
19946   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
19947                            opt_password, current_db, opt_port,
19948                            opt_unix_socket, 0)))
19949   {
19950     myerror("connection failed");
19951     exit(1);
19952   }
19953   mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
19954   if (!opt_silent)
19955     fprintf(stdout, "OK");
19956 
19957   /* set AUTOCOMMIT to ON*/
19958   mysql_autocommit(lmysql, TRUE);
19959 
19960   strmov(query, "SET SQL_MODE= \"EMPTY_STRING_IS_NULL\"");
19961   if (!opt_silent)
19962     fprintf(stdout, "\n With %s", query);
19963   rc= mysql_query(mysql, query);
19964   myquery(rc);
19965 
19966   rc= mysql_query(mysql,
19967     "CREATE OR REPLACE PROCEDURE test_mdev14013_p1("
19968     "   IN i1 VARCHAR(255) , "
19969     "   INOUT io1 VARCHAR(255), "
19970     "   OUT o2 VARBINARY(255)) "
19971     "BEGIN "
19972     "   SET o2 = concat(concat(coalesce(i1,'i1 is null'),' - '),coalesce(i1,'io1 is null')); "
19973     "END");
19974   myquery(rc);
19975 
19976   strmov(query, "CALL test_mdev14013_p1(?, ?, ?)");
19977   stmt1= mysql_simple_prepare(mysql, query);
19978   check_stmt(stmt1);
19979 
19980   /* Init PS-parameters. */
19981 
19982   bzero((char *) my_bind, sizeof (my_bind));
19983 
19984   strcpy(str_data[0],"");
19985   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
19986   my_bind[0].buffer= (char *) str_data[0];
19987   my_bind[0].buffer_length= strlen(str_data[0]);
19988 
19989   strcpy(str_data[1],"");
19990   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
19991   my_bind[1].buffer= (char *) str_data[1];
19992   my_bind[1].buffer_length= strlen(str_data[1]);
19993 
19994   strcpy(str_data[2],"");
19995   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
19996   my_bind[2].buffer= (char *) str_data[2];
19997   my_bind[2].buffer_length= strlen(str_data[2]);
19998 
19999   /* Bind parameters. */
20000 
20001   rc= mysql_stmt_bind_param(stmt1, my_bind);
20002   check_execute(stmt1, rc);
20003   /* Execute */
20004 
20005   rc= mysql_stmt_execute(stmt1);
20006   check_execute(stmt1, rc);
20007 
20008   my_bind[0].buffer_length= sizeof(str_data[0]);
20009   my_bind[1].buffer_length= sizeof(str_data[1]);
20010 
20011   mysql_stmt_bind_result(stmt1, my_bind);
20012   rc= mysql_stmt_fetch(stmt1);
20013 
20014   if (!opt_silent)
20015     fprintf(stdout,"\nstr_data[1]=%s\n",str_data[1]);
20016 
20017   DIE_UNLESS(strcmp(str_data[1], "i1 is null - io1 is null") == 0);
20018 
20019   rc= mysql_stmt_close(stmt1);
20020   DIE_UNLESS( rc == 0);
20021 
20022   myquery(mysql_query(mysql, "drop procedure test_mdev14013_p1"));
20023   mysql_close(lmysql);
20024 }
20025 
20026 
test_mdev14454_internal(const char * init,unsigned int csid,const char * value)20027 static void test_mdev14454_internal(const char *init,
20028                                     unsigned int csid,
20029                                     const char *value)
20030 {
20031   MYSQL_STMT *stmt;
20032   MYSQL_BIND bind;
20033   const char *stmtstr= "CALL P1(?)";
20034   char res[20];
20035   int rc;
20036 
20037   if ((rc= mysql_query_or_error(mysql, init)) ||
20038       (rc= mysql_query_or_error(mysql, "DROP PROCEDURE IF EXISTS p1")) ||
20039       (rc= mysql_query_or_error(mysql,
20040                                "CREATE PROCEDURE p1"
20041                                "("
20042                                "  OUT param1 TEXT CHARACTER SET utf8"
20043                                ")"
20044                                "BEGIN "
20045                                "  SET param1 = _latin1'test\xFF'; "
20046                                "END")))
20047     DIE("Initiation failed");
20048 
20049   stmt= mysql_stmt_init(mysql);
20050   rc= mysql_stmt_prepare(stmt, stmtstr, strlen(stmtstr));
20051   DIE_UNLESS(rc == 0);
20052   DIE_UNLESS(mysql_stmt_param_count(stmt) == 1);
20053 
20054   bind.buffer_type= MYSQL_TYPE_NULL;
20055   rc= mysql_stmt_bind_param(stmt, &bind);
20056   DIE_UNLESS(rc == 0);
20057 
20058   rc= mysql_stmt_execute(stmt);
20059   DIE_UNLESS(rc == 0);
20060 
20061   memset(res, 0, sizeof(res));
20062   memset(&bind, 0, sizeof(bind));
20063   bind.buffer_type= MYSQL_TYPE_STRING;
20064   bind.buffer_length= sizeof(res);
20065   bind.buffer= res;
20066 
20067   do {
20068     if (mysql->server_status & SERVER_PS_OUT_PARAMS)
20069     {
20070       MYSQL_FIELD *field;
20071       printf("\nOUT param result set:\n");
20072       DIE_UNLESS(mysql_stmt_field_count(stmt) == 1);
20073       field= &stmt->fields[0];
20074       printf("Field: %s\n", field->name);
20075       printf("Type: %d\n", field->type);
20076       printf("Collation: %d\n", field->charsetnr);
20077       printf("Length: %lu\n", field->length);
20078       DIE_UNLESS(stmt->fields[0].charsetnr == csid);
20079 
20080       rc= mysql_stmt_bind_result(stmt, &bind);
20081       DIE_UNLESS(rc == 0);
20082       rc= mysql_stmt_fetch(stmt);
20083       DIE_UNLESS(rc == 0);
20084       printf("Value: %s\n", res);
20085       DIE_UNLESS(strcmp(res, value) == 0);
20086     }
20087     else if (mysql_stmt_field_count(stmt))
20088     {
20089       printf("sp result set\n");
20090     }
20091   } while (mysql_stmt_next_result(stmt) == 0);
20092 
20093   mysql_stmt_close(stmt);
20094   DIE_UNLESS(mysql_query_or_error(mysql, "DROP PROCEDURE p1") == 0);
20095 }
20096 
20097 
test_mdev14454()20098 static void test_mdev14454()
20099 {
20100   myheader("test_mdev14454");
20101   test_mdev14454_internal("SET NAMES latin1", 8, "test\xFF");
20102   test_mdev14454_internal("SET NAMES utf8", 33, "test\xC3\xBF");
20103 }
20104 
20105 
20106 typedef struct {
20107   char sig[12];
20108   char ver_cmd;
20109   char fam;
20110   short len;
20111   union {
20112     struct {  /* for TCP/UDP over IPv4, len = 12 */
20113       int src_addr;
20114       int dst_addr;
20115       short src_port;
20116       short dst_port;
20117     } ip4;
20118     struct {  /* for TCP/UDP over IPv6, len = 36 */
20119       char  src_addr[16];
20120       char  dst_addr[16];
20121       short src_port;
20122       short dst_port;
20123     } ip6;
20124     struct {  /* for AF_UNIX sockets, len = 216 */
20125       char src_addr[108];
20126       char dst_addr[108];
20127     } unx;
20128   } addr;
20129 } v2_proxy_header;
20130 
20131 #ifndef EMBEDDED_LIBRARY
test_proxy_header_tcp(const char * ipaddr,int port)20132 static void test_proxy_header_tcp(const char *ipaddr, int port)
20133 {
20134 
20135   int rc;
20136   MYSQL_RES *result;
20137   int family = (strchr(ipaddr,':') == NULL)?AF_INET:AF_INET6;
20138   char query[256];
20139   char text_header[256];
20140   char addr_bin[16];
20141   v2_proxy_header v2_header;
20142   void *header_data[2];
20143   size_t header_lengths[2];
20144   int i;
20145 
20146   // normalize IPv4-mapped IPv6 addresses, e.g ::ffff:127.0.0.2 to 127.0.0.2
20147   const char *normalized_addr= strncmp(ipaddr, "::ffff:", 7)?ipaddr : ipaddr + 7;
20148 
20149   memset(&v2_header, 0, sizeof(v2_header));
20150   sprintf(text_header,"PROXY %s %s %s %d 3306\r\n",family == AF_INET?"TCP4":"TCP6", ipaddr, ipaddr, port);
20151 
20152   inet_pton(family,ipaddr,addr_bin);
20153 
20154   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20155   v2_header.ver_cmd = (0x2 << 4) | 0x1; /* Version (0x2) , Command = PROXY (0x1) */
20156   if(family == AF_INET)
20157   {
20158     v2_header.fam= 0x11;
20159     v2_header.len= htons(12);
20160     v2_header.addr.ip4.src_port= htons(port);
20161     v2_header.addr.ip4.dst_port= htons(3306);
20162     memcpy(&v2_header.addr.ip4.src_addr,addr_bin, sizeof (v2_header.addr.ip4.src_addr));
20163     memcpy(&v2_header.addr.ip4.dst_addr,addr_bin, sizeof (v2_header.addr.ip4.dst_addr));
20164   }
20165   else
20166   {
20167     v2_header.fam= 0x21;
20168     v2_header.len= htons(36);
20169     v2_header.addr.ip6.src_port= htons(port);
20170     v2_header.addr.ip6.dst_port= htons(3306);
20171     memcpy(v2_header.addr.ip6.src_addr,addr_bin, sizeof (v2_header.addr.ip6.src_addr));
20172     memcpy(v2_header.addr.ip6.dst_addr,addr_bin, sizeof (v2_header.addr.ip6.dst_addr));
20173   }
20174 
20175   sprintf(query,"CREATE USER 'u'@'%s' IDENTIFIED BY 'password'",normalized_addr);
20176   rc= mysql_query(mysql, query);
20177   myquery(rc);
20178 
20179   header_data[0]= text_header;
20180   header_data[1]= &v2_header;
20181 
20182   header_lengths[0]= strlen(text_header);
20183   header_lengths[1]= family == AF_INET ? 28 : 52;
20184 
20185   for (i = 0; i < 2; i++)
20186   {
20187     MYSQL *m;
20188     size_t addrlen;
20189     MYSQL_ROW row;
20190     m = mysql_client_init(NULL);
20191     DIE_UNLESS(m);
20192     mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header_data[i], header_lengths[i]);
20193     if (!mysql_real_connect(m, opt_host, "u", "password", NULL, opt_port, opt_unix_socket, 0))
20194     {
20195        DIE_UNLESS(0);
20196     }
20197     rc= mysql_query(m, "select host from information_schema.processlist WHERE ID = connection_id()");
20198     myquery(rc);
20199     /* get the result */
20200     result= mysql_store_result(m);
20201     mytest(result);
20202     row = mysql_fetch_row(result);
20203     addrlen = strlen(normalized_addr);
20204     printf("%.*s %.*s\n", (int)addrlen, row[0], (int)addrlen, normalized_addr);
20205     DIE_UNLESS(strncmp(row[0], normalized_addr, addrlen) == 0);
20206     DIE_UNLESS(atoi(row[0] + addrlen+1) == port);
20207     mysql_free_result(result);
20208     mysql_close(m);
20209   }
20210   sprintf(query,"DROP USER 'u'@'%s'",normalized_addr);
20211   rc = mysql_query(mysql, query);
20212   myquery(rc);
20213 }
20214 
20215 
20216 /* Test proxy protocol with AF_UNIX (localhost) */
test_proxy_header_localhost()20217 static void test_proxy_header_localhost()
20218 {
20219   v2_proxy_header v2_header;
20220   void *header_data = &v2_header;
20221   size_t header_length= 216 + 16;
20222   MYSQL *m;
20223   MYSQL_RES *result;
20224   MYSQL_ROW row;
20225   int rc;
20226 
20227   memset(&v2_header, 0, sizeof(v2_header));
20228   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20229   v2_header.ver_cmd = (0x2 << 4) | 0x1; /* Version (0x2) , Command = PROXY (0x1) */
20230   v2_header.fam= 0x31;
20231   v2_header.len= htons(216);
20232   strcpy(v2_header.addr.unx.src_addr,"/tmp/mysql.sock");
20233   strcpy(v2_header.addr.unx.dst_addr,"/tmp/mysql.sock");
20234   rc = mysql_query(mysql, "CREATE USER 'u'@'localhost' IDENTIFIED BY 'password'");
20235   myquery(rc);
20236   m = mysql_client_init(NULL);
20237   DIE_UNLESS(m != NULL);
20238   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header_data, header_length);
20239   DIE_UNLESS(mysql_real_connect(m, opt_host, "u", "password", NULL, opt_port, opt_unix_socket, 0) == m);
20240   DIE_UNLESS(mysql_query(m, "select host from information_schema.processlist WHERE ID = connection_id()") == 0);
20241   /* get the result */
20242   result= mysql_store_result(m);
20243   mytest(result);
20244   row = mysql_fetch_row(result);
20245   DIE_UNLESS(strcmp(row[0], "localhost") == 0);
20246   mysql_free_result(result);
20247   mysql_close(m);
20248   rc = mysql_query(mysql,  "DROP USER 'u'@'localhost'");
20249   myquery(rc);
20250 }
20251 
20252 /* Proxy header ignoring */
test_proxy_header_ignore()20253 static void test_proxy_header_ignore()
20254 {
20255   int rc;
20256   MYSQL *m = mysql_client_init(NULL);
20257   v2_proxy_header v2_header;
20258   DIE_UNLESS(m != NULL);
20259   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, "PROXY UNKNOWN\r\n",15);
20260   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == m);
20261   mysql_close(m);
20262 
20263   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20264   v2_header.ver_cmd = (0x2 << 4) | 0x0; /* Version (0x2) , Command = LOCAL (0x0) */
20265   v2_header.fam= 0x0; /* AF_UNSPEC*/
20266   v2_header.len= htons(0);
20267   m = mysql_client_init(NULL);
20268   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header,16);
20269   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == m);
20270   mysql_close(m);
20271 
20272   /* test for connection denied with empty proxy_protocol_networks */
20273   rc = mysql_query(mysql, "select @@proxy_protocol_networks into @sv_proxy_protocol_networks");
20274   myquery(rc);
20275   mysql_query(mysql, "set global proxy_protocol_networks=default");
20276   myquery(rc);
20277   m = mysql_client_init(NULL);
20278   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header,16);
20279   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == 0);
20280   mysql_close(m);
20281   mysql_query(mysql, "set global proxy_protocol_networks= @sv_proxy_protocol_networks");
20282   myquery(rc);
20283 }
20284 
20285 
test_proxy_header()20286 static void test_proxy_header()
20287 {
20288   test_proxy_header_tcp("192.0.2.1",3333);
20289   test_proxy_header_tcp("2001:db8:85a3::8a2e:370:7334",2222);
20290   test_proxy_header_tcp("::ffff:192.0.2.1",2222);
20291   test_proxy_header_localhost();
20292   test_proxy_header_ignore();
20293 }
20294 
20295 
test_bulk_autoinc()20296 static void test_bulk_autoinc()
20297 {
20298   int rc;
20299   MYSQL_STMT *stmt;
20300   MYSQL_BIND bind[1];
20301   MYSQL_ROW  row;
20302   char       indicator[]= {0, STMT_INDICATOR_NULL, 0/*STMT_INDICATOR_IGNORE*/};
20303   my_bool   error[1];
20304   int        i, id[]= {2, 3, 777}, count= sizeof(id)/sizeof(id[0]);
20305   MYSQL_RES *result;
20306 
20307   rc= mysql_query(mysql, "DROP TABLE IF EXISTS ai_field_value");
20308   myquery(rc);
20309   rc= mysql_query(mysql, "CREATE TABLE ai_field_value (id int not null primary key auto_increment)");
20310   myquery(rc);
20311   stmt= mysql_stmt_init(mysql);
20312   rc= mysql_stmt_prepare(stmt, "INSERT INTO ai_field_value(id) values(?)", -1);
20313   check_execute(stmt, rc);
20314 
20315   memset(bind, 0, sizeof(bind));
20316   bind[0].buffer_type = MYSQL_TYPE_LONG;
20317   bind[0].buffer = (void *)id;
20318   bind[0].buffer_length = 0;
20319   bind[0].is_null = NULL;
20320   bind[0].length = NULL;
20321   bind[0].error = error;
20322   bind[0].u.indicator= indicator;
20323 
20324   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20325   rc= mysql_stmt_bind_param(stmt, bind);
20326   check_execute(stmt, rc);
20327 
20328   rc= mysql_stmt_execute(stmt);
20329   check_execute(stmt, rc);
20330 
20331   mysql_stmt_close(stmt);
20332 
20333   rc= mysql_query(mysql, "SELECT id FROM ai_field_value");
20334   myquery(rc);
20335 
20336   result= mysql_store_result(mysql);
20337   mytest(result);
20338 
20339   i= 0;
20340   while ((row= mysql_fetch_row(result)))
20341   {
20342     DIE_IF(atoi(row[0]) != id[i++]);
20343   }
20344   mysql_free_result(result);
20345   rc= mysql_query(mysql, "DROP TABLE ai_field_value");
20346   myquery(rc);
20347 }
20348 
test_bulk_delete()20349 static void test_bulk_delete()
20350 {
20351   int rc;
20352   MYSQL_STMT *stmt;
20353   MYSQL_BIND bind[1];
20354   MYSQL_ROW  row;
20355   char       indicator[]= {0, 0, 0};
20356   my_bool   error[1];
20357   int        i, id[]= {1, 2, 4}, count= sizeof(id)/sizeof(id[0]);
20358   MYSQL_RES *result;
20359 
20360   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20361   myquery(rc);
20362   rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key)");
20363   myquery(rc);
20364   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1),(2),(3),(4)");
20365   myquery(rc);
20366   verify_affected_rows(4);
20367 
20368   stmt= mysql_stmt_init(mysql);
20369   rc= mysql_stmt_prepare(stmt, "DELETE FROM t1 where id=?", -1);
20370   check_execute(stmt, rc);
20371 
20372   memset(bind, 0, sizeof(bind));
20373   bind[0].buffer_type = MYSQL_TYPE_LONG;
20374   bind[0].buffer = (void *)id;
20375   bind[0].buffer_length = 0;
20376   bind[0].is_null = NULL;
20377   bind[0].length = NULL;
20378   bind[0].error = error;
20379   bind[0].u.indicator= indicator;
20380 
20381   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20382   rc= mysql_stmt_bind_param(stmt, bind);
20383   check_execute(stmt, rc);
20384 
20385   rc= mysql_stmt_execute(stmt);
20386   check_execute(stmt, rc);
20387   verify_affected_rows(3);
20388 
20389   mysql_stmt_close(stmt);
20390 
20391   rc= mysql_query(mysql, "SELECT id FROM t1");
20392   myquery(rc);
20393 
20394   result= mysql_store_result(mysql);
20395   mytest(result);
20396 
20397   i= 0;
20398   while ((row= mysql_fetch_row(result)))
20399   {
20400     i++;
20401     DIE_IF(atoi(row[0]) != 3);
20402   }
20403   DIE_IF(i != 1);
20404   mysql_free_result(result);
20405 
20406   rc= mysql_query(mysql, "DROP TABLE t1");
20407   myquery(rc);
20408 }
20409 
test_bulk_replace()20410 static void test_bulk_replace()
20411 {
20412   int rc;
20413   MYSQL_STMT *stmt;
20414   MYSQL_BIND bind[2];
20415   MYSQL_ROW  row;
20416   int        i,
20417              id[]= {1, 2, 3, 4},
20418              val[]= {1, 1, 1, 1},
20419              count= sizeof(id)/sizeof(id[0]);
20420   MYSQL_RES *result;
20421 
20422   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20423   myquery(rc);
20424   rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key, active int)");
20425   myquery(rc);
20426   rc= mysql_query(mysql, "insert into t1 values (1, 0), (2, 0), (3, 0)");
20427   myquery(rc);
20428   verify_affected_rows(3);
20429 
20430   stmt= mysql_stmt_init(mysql);
20431   rc= mysql_stmt_prepare(stmt, "replace into t1 (id, active) values (?, ?)", -1);
20432   check_execute(stmt, rc);
20433 
20434   memset(bind, 0, sizeof(bind));
20435   bind[0].buffer_type = MYSQL_TYPE_LONG;
20436   bind[0].buffer = (void *)id;
20437   bind[0].buffer_length = 0;
20438   bind[1].buffer_type = MYSQL_TYPE_LONG;
20439   bind[1].buffer = (void *)val;
20440   bind[1].buffer_length = 0;
20441 
20442   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20443   rc= mysql_stmt_bind_param(stmt, bind);
20444   check_execute(stmt, rc);
20445 
20446   rc= mysql_stmt_execute(stmt);
20447   check_execute(stmt, rc);
20448 
20449   mysql_stmt_close(stmt);
20450 
20451   rc= mysql_query(mysql, "SELECT active FROM t1");
20452   myquery(rc);
20453 
20454   result= mysql_store_result(mysql);
20455   mytest(result);
20456 
20457   i= 0;
20458   while ((row= mysql_fetch_row(result)))
20459   {
20460     i++;
20461     DIE_IF(atoi(row[0]) != 1);
20462   }
20463   DIE_IF(i != 4);
20464   mysql_free_result(result);
20465 
20466   rc= mysql_query(mysql, "DROP TABLE t1");
20467   myquery(rc);
20468 }
20469 #endif
20470 
20471 
test_ps_params_in_ctes()20472 static void test_ps_params_in_ctes()
20473 {
20474   int rc;
20475   const char *query;
20476   MYSQL_BIND ps_params[1];
20477   int int_data[1];
20478   MYSQL_STMT *stmt;
20479 
20480   rc= mysql_query(mysql, "create table t1(a int, b int, key(a))");
20481   myquery(rc);
20482 
20483   rc= mysql_query(mysql, "insert into t1 (a) values "
20484                          "(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)");
20485   myquery(rc);
20486 
20487   query=
20488     "explain "
20489     "with T as "
20490     "( "
20491     "  select * from t1 where t1.a=? limit 2 "
20492     ") "
20493     "select * from T as TA, T as TB;";
20494 
20495   stmt= mysql_stmt_init(mysql);
20496   check_stmt(stmt);
20497 
20498   rc= mysql_stmt_prepare(stmt, query, (uint) strlen(query));
20499   check_execute(stmt, rc);
20500 
20501   int_data[0]=2;
20502 
20503   ps_params[0].buffer_type= MYSQL_TYPE_LONG;
20504   ps_params[0].buffer= (char *) &int_data[0];
20505   ps_params[0].length= 0;
20506   ps_params[0].is_null= 0;
20507 
20508   rc= mysql_stmt_bind_param(stmt, ps_params);
20509   check_execute(stmt, rc);
20510 
20511   rc= mysql_stmt_execute(stmt);
20512   check_execute(stmt, rc);
20513 
20514   rc= mysql_stmt_store_result(stmt);
20515   check_execute(stmt, rc);
20516 
20517   mysql_stmt_close(stmt);
20518 
20519   rc= mysql_query(mysql, "drop table t1");
20520   myquery(rc);
20521 }
20522 
display_result_metadata(MYSQL_FIELD * field,uint num_fields)20523 void display_result_metadata(MYSQL_FIELD *field,
20524                              uint num_fields)
20525 {
20526   MYSQL_FIELD* field_end;
20527 
20528   mct_log("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
20529           "Column_alias\tType\tLength\tMax length\tIs_null\t"
20530           "Flags\tDecimals\tCharsetnr\n");
20531   for (field_end= field+num_fields; field < field_end; field++)
20532   {
20533     mct_log("%s\t", field->catalog);
20534     mct_log("%s\t", field->db);
20535     mct_log("%s\t", field->org_table);
20536     mct_log("%s\t", field->table);
20537     mct_log("%s\t", field->org_name);
20538     mct_log("%s\t", field->name);
20539     mct_log("%u\t", field->type);
20540     mct_log("%lu\t", field->length);
20541     mct_log("%lu\t", field->max_length);
20542     mct_log("%s\t", (IS_NOT_NULL(field->flags) ?  "N" : "Y"));
20543     mct_log("%u\t", field->flags);
20544     mct_log("%u\t", field->decimals);
20545     mct_log("%u\n", field->charsetnr);
20546   }
20547 }
20548 
test_mdev_26145()20549 static void test_mdev_26145()
20550 {
20551   MYSQL_STMT *stmt;
20552   MYSQL_RES *result;
20553   MYSQL_FIELD *fields;
20554   int        rc, num_fields;
20555 
20556   myheader("test_mdev_26145");
20557 
20558   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20559   myquery(rc);
20560 
20561   rc= mysql_query(mysql, "CREATE TABLE t1(a INT)");
20562   myquery(rc);
20563 
20564   stmt= mysql_simple_prepare(
20565     mysql, "(SELECT MAX(a) FROM t1) UNION (SELECT MAX(a) FROM t1)");
20566   check_stmt(stmt);
20567 
20568   rc= mysql_stmt_execute(stmt);
20569   check_execute(stmt, rc);
20570 
20571   result= mysql_stmt_result_metadata(stmt);
20572   DIE_UNLESS(result);
20573 
20574   num_fields= mysql_stmt_field_count(stmt);
20575   fields= mysql_fetch_fields(result);
20576 
20577   mct_start_logging("test_mdev26145");
20578   display_result_metadata(fields, num_fields);
20579   mct_close_log();
20580 
20581   mysql_free_result(result);
20582   mysql_stmt_close(stmt);
20583 
20584   rc= mysql_query(mysql, "DROP TABLE t1");
20585 
20586   myquery(rc);
20587 }
20588 
test_mdev24827()20589 static void test_mdev24827()
20590 {
20591   int rc;
20592   MYSQL_STMT *stmt;
20593   unsigned long cursor = CURSOR_TYPE_READ_ONLY;
20594   const char* query=
20595     "SELECT t2.c1 AS c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 "
20596     "WHERE EXISTS (SELECT 1 FROM t1 WHERE c2 = -1) ORDER BY c1";
20597 
20598   myheader("test_mdev24827");
20599 
20600   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20601   myquery(rc);
20602 
20603   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
20604   myquery(rc);
20605 
20606   rc= mysql_query(mysql, "CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT)");
20607   myquery(rc);
20608 
20609   rc= mysql_query(mysql, "CREATE TABLE t2 (c1 INT PRIMARY KEY, c2 INT, "
20610                   "KEY idx_c2(c2))");
20611   myquery(rc);
20612 
20613   rc= mysql_query(mysql, "INSERT INTO t1 (c1, c2) "
20614                   "SELECT seq, seq FROM seq_1_to_10000");
20615   myquery(rc);
20616 
20617   rc= mysql_query(mysql, "INSERT INTO t2 (c1, c2) "
20618                   "SELECT seq, seq FROM seq_1_to_20000");
20619   myquery(rc);
20620 
20621   stmt= mysql_stmt_init(mysql);
20622   check_stmt(stmt);
20623 
20624   rc= mysql_stmt_prepare(stmt, query, strlen(query));
20625   check_execute(stmt, rc);
20626 
20627   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor);
20628   check_execute(stmt, rc);
20629 
20630   rc= mysql_stmt_execute(stmt);
20631   check_execute(stmt, rc);
20632   mysql_stmt_close(stmt);
20633 
20634   rc= mysql_query(mysql, "DROP TABLE t1");
20635   myquery(rc);
20636 
20637   rc= mysql_query(mysql, "DROP TABLE t2");
20638   myquery(rc);
20639 }
20640 
test_mdev_20516()20641 static void test_mdev_20516()
20642 {
20643   MYSQL_STMT *stmt;
20644   int        rc;
20645   unsigned long cursor= CURSOR_TYPE_READ_ONLY;
20646   const char* query=
20647     "CREATE VIEW v1 AS SELECT * FROM t1";
20648 
20649   myheader("test_mdev_20516");
20650 
20651   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20652   myquery(rc);
20653 
20654   rc= mysql_query(mysql, "CREATE TABLE t1(a INT)");
20655   myquery(rc);
20656 
20657   stmt= mysql_stmt_init(mysql);
20658   check_stmt(stmt);
20659 
20660   rc= mysql_stmt_prepare(stmt, query, strlen(query));
20661   check_execute(stmt, rc);
20662 
20663   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor);
20664   check_execute(stmt, rc);
20665 
20666   rc= mysql_stmt_execute(stmt);
20667   check_execute(stmt, rc);
20668   mysql_stmt_close(stmt);
20669 
20670   rc= mysql_query(mysql, "DROP TABLE t1");
20671   myquery(rc);
20672 }
20673 
print_metadata(MYSQL_RES * rs_metadata,int num_fields)20674 static void print_metadata(MYSQL_RES *rs_metadata, int num_fields)
20675 {
20676   int i;
20677   MYSQL_FIELD *fields= mysql_fetch_fields(rs_metadata);
20678 
20679   for (i = 0; i < num_fields; ++i)
20680   {
20681     mct_log("  - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
20682         "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
20683         "type: %d; decimals: %d\n",
20684         (int) i,
20685         (const char *) fields[i].name,
20686         (const char *) fields[i].org_name,
20687         (const char *) fields[i].table,
20688         (const char *) fields[i].org_table,
20689         (const char *) fields[i].db,
20690         (const char *) fields[i].catalog,
20691         (int) fields[i].length,
20692         (int) fields[i].max_length,
20693         (int) fields[i].type,
20694         (int) fields[i].decimals);
20695 
20696   }
20697 }
20698 
test_explain_meta()20699 static void test_explain_meta()
20700 {
20701   MYSQL_STMT *stmt;
20702   int num_fields;
20703   char query[MAX_TEST_QUERY_LENGTH];
20704   MYSQL_RES *rs_metadata;
20705   int rc;
20706 
20707   myheader("test_explain_meta");
20708   mct_start_logging("test_explain_meta");
20709 
20710   strmov(query, "SELECT 1");
20711   stmt= mysql_simple_prepare(mysql, query);
20712   check_stmt(stmt);
20713 
20714   rs_metadata= mysql_stmt_result_metadata(stmt);
20715 
20716   num_fields= mysql_stmt_field_count(stmt);
20717   mct_log("SELECT number of fields: %d\n", (int) num_fields);
20718   if (num_fields != 1)
20719   {
20720     mct_close_log();
20721     DIE("num_fields != 1");
20722   }
20723   mysql_free_result(rs_metadata);
20724   mysql_stmt_close(stmt);
20725 
20726   strmov(query, "EXPLAIN SELECT 1");
20727   stmt= mysql_simple_prepare(mysql, query);
20728   check_stmt(stmt);
20729 
20730   rs_metadata= mysql_stmt_result_metadata(stmt);
20731 
20732   num_fields= mysql_stmt_field_count(stmt);
20733   mct_log("EXPALIN number of fields: %d\n", (int) num_fields);
20734   if (num_fields != 10)
20735   {
20736     mct_close_log();
20737     DIE("num_fields != 10");
20738   }
20739   print_metadata(rs_metadata, num_fields);
20740   mysql_free_result(rs_metadata);
20741   mysql_stmt_close(stmt);
20742 
20743   strmov(query, "EXPLAIN format=json SELECT 1");
20744   stmt= mysql_simple_prepare(mysql, query);
20745   check_stmt(stmt);
20746 
20747   rs_metadata= mysql_stmt_result_metadata(stmt);
20748 
20749   num_fields= mysql_stmt_field_count(stmt);
20750   mct_log("EXPALIN JSON number of fields: %d\n", (int) num_fields);
20751   if (num_fields != 1)
20752   {
20753     mct_close_log();
20754     DIE("num_fields != 1");
20755   }
20756   print_metadata(rs_metadata, num_fields);
20757   mysql_free_result(rs_metadata);
20758   mysql_stmt_close(stmt);
20759 
20760 
20761   strmov(query, "ANALYZE SELECT 1");
20762   stmt= mysql_simple_prepare(mysql, query);
20763   check_stmt(stmt);
20764 
20765   rs_metadata= mysql_stmt_result_metadata(stmt);
20766 
20767   num_fields= mysql_stmt_field_count(stmt);
20768   mct_log("ANALYZE number of fields: %d\n", (int) num_fields);
20769   if (num_fields != 13)
20770   {
20771     mct_close_log();
20772     DIE("num_fields != 13");
20773   }
20774   print_metadata(rs_metadata, num_fields);
20775   mysql_free_result(rs_metadata);
20776   mysql_stmt_close(stmt);
20777 
20778   strmov(query, "ANALYZE format=json SELECT 1");
20779   stmt= mysql_simple_prepare(mysql, query);
20780   check_stmt(stmt);
20781 
20782   rs_metadata= mysql_stmt_result_metadata(stmt);
20783 
20784   num_fields= mysql_stmt_field_count(stmt);
20785   mct_log("ANALYZE JSON number of fields: %d\n", (int) num_fields);
20786   if (num_fields != 1)
20787   {
20788     mct_close_log();
20789     DIE("num_fields != 1");
20790   }
20791   print_metadata(rs_metadata, num_fields);
20792   mysql_free_result(rs_metadata);
20793   mysql_stmt_close(stmt);
20794 
20795   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
20796   myquery(rc);
20797 
20798   strmov(query, "EXPLAIN INSERT INTO t1 values (1)");
20799   stmt= mysql_simple_prepare(mysql, query);
20800   check_stmt(stmt);
20801 
20802   rs_metadata= mysql_stmt_result_metadata(stmt);
20803 
20804   num_fields= mysql_stmt_field_count(stmt);
20805   mct_log("EXPALIN INSERT number of fields: %d\n", (int) num_fields);
20806   if (num_fields != 10)
20807   {
20808     mct_close_log();
20809     DIE("num_fields != 10");
20810   }
20811   print_metadata(rs_metadata, num_fields);
20812   mysql_free_result(rs_metadata);
20813   mysql_stmt_close(stmt);
20814 
20815   strmov(query, "EXPLAIN format=json INSERT INTO t1 values(1)");
20816   stmt= mysql_simple_prepare(mysql, query);
20817   check_stmt(stmt);
20818 
20819   rs_metadata= mysql_stmt_result_metadata(stmt);
20820 
20821   num_fields= mysql_stmt_field_count(stmt);
20822   mct_log("EXPALIN JSON INSERT number of fields: %d\n", (int) num_fields);
20823   if (num_fields != 1)
20824   {
20825     mct_close_log();
20826     DIE("num_fields != 1");
20827   }
20828   print_metadata(rs_metadata, num_fields);
20829   mysql_free_result(rs_metadata);
20830   mysql_stmt_close(stmt);
20831 
20832 
20833   strmov(query, "ANALYZE INSERT INTO t1 values(1)");
20834   stmt= mysql_simple_prepare(mysql, query);
20835   check_stmt(stmt);
20836 
20837   rs_metadata= mysql_stmt_result_metadata(stmt);
20838 
20839   num_fields= mysql_stmt_field_count(stmt);
20840   mct_log("ANALYZE INSERT number of fields: %d\n", (int) num_fields);
20841   if (num_fields != 13)
20842   {
20843     mct_close_log();
20844     DIE("num_fields != 13");
20845   }
20846   print_metadata(rs_metadata, num_fields);
20847   mysql_free_result(rs_metadata);
20848   mysql_stmt_close(stmt);
20849 
20850   strmov(query, "ANALYZE format=json INSERT INTO t1 values(1)");
20851   stmt= mysql_simple_prepare(mysql, query);
20852   check_stmt(stmt);
20853 
20854   rs_metadata= mysql_stmt_result_metadata(stmt);
20855 
20856   num_fields= mysql_stmt_field_count(stmt);
20857   mct_log("ANALYZE JSON INSERT number of fields: %d\n", (int) num_fields);
20858   if (num_fields != 1)
20859   {
20860     mct_close_log();
20861     DIE("num_fields != 1");
20862   }
20863   print_metadata(rs_metadata, num_fields);
20864   mysql_free_result(rs_metadata);
20865   mysql_stmt_close(stmt);
20866 
20867 
20868   strmov(query, "EXPLAIN UPDATE t1 set a=2");
20869   stmt= mysql_simple_prepare(mysql, query);
20870   check_stmt(stmt);
20871 
20872   rs_metadata= mysql_stmt_result_metadata(stmt);
20873 
20874   num_fields= mysql_stmt_field_count(stmt);
20875   mct_log("EXPALIN UPDATE number of fields: %d\n", (int) num_fields);
20876   if (num_fields != 10)
20877   {
20878     mct_close_log();
20879     DIE("num_fields != 10");
20880   }
20881   print_metadata(rs_metadata, num_fields);
20882   mysql_free_result(rs_metadata);
20883   mysql_stmt_close(stmt);
20884 
20885   strmov(query, "EXPLAIN format=json  UPDATE t1 set a=2");
20886   stmt= mysql_simple_prepare(mysql, query);
20887   check_stmt(stmt);
20888 
20889   rs_metadata= mysql_stmt_result_metadata(stmt);
20890 
20891   num_fields= mysql_stmt_field_count(stmt);
20892   mct_log("EXPALIN JSON UPDATE number of fields: %d\n", (int) num_fields);
20893   if (num_fields != 1)
20894   {
20895     mct_close_log();
20896     DIE("num_fields != 1");
20897   }
20898   print_metadata(rs_metadata, num_fields);
20899   mysql_free_result(rs_metadata);
20900   mysql_stmt_close(stmt);
20901 
20902 
20903   strmov(query, "ANALYZE UPDATE t1 set a=2");
20904   stmt= mysql_simple_prepare(mysql, query);
20905   check_stmt(stmt);
20906 
20907   rs_metadata= mysql_stmt_result_metadata(stmt);
20908 
20909   num_fields= mysql_stmt_field_count(stmt);
20910   mct_log("ANALYZE UPDATE number of fields: %d\n", (int) num_fields);
20911   if (num_fields != 13)
20912   {
20913     mct_close_log();
20914     DIE("num_fields != 13");
20915   }
20916   print_metadata(rs_metadata, num_fields);
20917   mysql_free_result(rs_metadata);
20918   mysql_stmt_close(stmt);
20919 
20920   strmov(query, "ANALYZE format=json UPDATE t1 set a=2");
20921   stmt= mysql_simple_prepare(mysql, query);
20922   check_stmt(stmt);
20923 
20924   rs_metadata= mysql_stmt_result_metadata(stmt);
20925 
20926   num_fields= mysql_stmt_field_count(stmt);
20927   mct_log("ANALYZE JSON UPDATE number of fields: %d\n", (int) num_fields);
20928   if (num_fields != 1)
20929   {
20930     mct_close_log();
20931     DIE("num_fields != 1");
20932   }
20933   print_metadata(rs_metadata, num_fields);
20934   mysql_free_result(rs_metadata);
20935   mysql_stmt_close(stmt);
20936 
20937 
20938   strmov(query, "EXPLAIN DELETE FROM t1");
20939   stmt= mysql_simple_prepare(mysql, query);
20940   check_stmt(stmt);
20941 
20942   rs_metadata= mysql_stmt_result_metadata(stmt);
20943 
20944   num_fields= mysql_stmt_field_count(stmt);
20945   mct_log("EXPALIN DELETE number of fields: %d\n", (int) num_fields);
20946   if (num_fields != 10)
20947   {
20948     mct_close_log();
20949     DIE("num_fields != 10");
20950   }
20951   print_metadata(rs_metadata, num_fields);
20952   mysql_free_result(rs_metadata);
20953   mysql_stmt_close(stmt);
20954 
20955   strmov(query, "EXPLAIN format=json DELETE FROM t1");
20956   stmt= mysql_simple_prepare(mysql, query);
20957   check_stmt(stmt);
20958 
20959   rs_metadata= mysql_stmt_result_metadata(stmt);
20960 
20961   num_fields= mysql_stmt_field_count(stmt);
20962   mct_log("EXPALIN JSON DELETE number of fields: %d\n", (int) num_fields);
20963   if (num_fields != 1)
20964   {
20965     mct_close_log();
20966     DIE("num_fields != 1");
20967   }
20968   print_metadata(rs_metadata, num_fields);
20969   mysql_free_result(rs_metadata);
20970   mysql_stmt_close(stmt);
20971 
20972 
20973   strmov(query, "ANALYZE DELETE FROM t1");
20974   stmt= mysql_simple_prepare(mysql, query);
20975   check_stmt(stmt);
20976 
20977   rs_metadata= mysql_stmt_result_metadata(stmt);
20978 
20979   num_fields= mysql_stmt_field_count(stmt);
20980   mct_log("ANALYZE DELETE number of fields: %d\n", (int) num_fields);
20981   if (num_fields != 13)
20982   {
20983     mct_close_log();
20984     DIE("num_fields != 13");
20985   }
20986   print_metadata(rs_metadata, num_fields);
20987   mysql_free_result(rs_metadata);
20988   mysql_stmt_close(stmt);
20989 
20990   strmov(query, "ANALYZE format=json DELETE FROM t1");
20991   stmt= mysql_simple_prepare(mysql, query);
20992   check_stmt(stmt);
20993 
20994   rs_metadata= mysql_stmt_result_metadata(stmt);
20995 
20996   num_fields= mysql_stmt_field_count(stmt);
20997   mct_log("ANALYZE JSON DELETE number of fields: %d\n", (int) num_fields);
20998   if (num_fields != 1)
20999   {
21000     mct_close_log();
21001     DIE("num_fields != 1");
21002   }
21003   print_metadata(rs_metadata, num_fields);
21004   mysql_free_result(rs_metadata);
21005   mysql_stmt_close(stmt);
21006 
21007   rc= mysql_query(mysql, "DROP TABLE t1");
21008   myquery(rc);
21009   mct_close_log();
21010 }
21011 
21012 
21013 #ifndef EMBEDDED_LIBRARY
21014 #define MDEV19838_MAX_PARAM_COUNT 32
21015 #define MDEV19838_FIELDS_COUNT 17
test_mdev19838()21016 static void test_mdev19838()
21017 {
21018   int rc;
21019   MYSQL_BIND bind[MDEV19838_MAX_PARAM_COUNT];
21020   unsigned int i, paramCount = 1;
21021   char charvalue[] = "012345678901234567890123456789012345";
21022   MYSQL_STMT *stmt;
21023 
21024   myheader("test_mdev19838");
21025 
21026   rc = mysql_query(mysql, "CREATE TABLE mdev19838("
21027           "f1  char(36),"
21028           "f2  char(36),"
21029           "f3  char(36),"
21030           "f4  char(36),"
21031           "f5  char(36),"
21032           "f6  char(36),"
21033           "f7  char(36),"
21034           "f8  char(36),"
21035           "f9  char(36),"
21036           "f10 char(36),"
21037           "f11 char(36),"
21038           "f12 char(36),"
21039           "f13 char(36),"
21040           "f14 char(36),"
21041           "f15 char(36),"
21042           "f16 char(36),"
21043           "f17 char(36)"
21044     ")");
21045   myquery(rc);
21046 
21047   stmt = mysql_stmt_init(mysql);
21048   check_stmt(stmt);
21049 
21050   memset(bind, 0, sizeof(bind));
21051 
21052   for (i = 0; i < MDEV19838_MAX_PARAM_COUNT; ++i)
21053   {
21054     bind[i].buffer = charvalue;
21055     bind[i].buffer_type = MYSQL_TYPE_STRING;
21056     bind[i].buffer_length = strlen(charvalue) + 1;
21057     bind[i].length = &bind[i].length_value;
21058     bind[i].length_value = bind[i].buffer_length - 1;
21059   }
21060 
21061   for (paramCount = 1; paramCount < MDEV19838_FIELDS_COUNT; ++paramCount)
21062   {
21063     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21064 
21065     rc = mysql_stmt_bind_param(stmt, bind);
21066     check_execute(stmt, rc);
21067 
21068     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21069       "(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
21070       " VALUES "
21071       "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21072 
21073     /* Expecting an error */
21074     DIE_UNLESS(rc != 0);
21075 
21076     mysql_stmt_close(stmt);
21077     stmt = mysql_stmt_init(mysql);
21078     check_stmt(stmt);
21079   }
21080 
21081   paramCount = 0;
21082   mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21083   rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838(f1)"
21084     " VALUES (?)", -1);
21085   /* Expecting an error */
21086   DIE_UNLESS(rc != 0);
21087   mysql_stmt_close(stmt);
21088 
21089   stmt = mysql_stmt_init(mysql);
21090   check_stmt(stmt);
21091   /* Correct number of parameters */
21092   paramCount = MDEV19838_FIELDS_COUNT;
21093   mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21094   mysql_stmt_bind_param(stmt, bind);
21095 
21096   rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21097     "(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
21098     " VALUES "
21099     "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21100   check_execute(stmt, rc);
21101 
21102   /* MYSQL_TYPE_TINY = 1. This parameter byte can be read as "parameters send" flag byte.
21103      Checking that wrong packet is still detected */
21104   bind[0].buffer_type = MYSQL_TYPE_TINY;
21105   bind[0].length_value = 1;
21106   bind[0].buffer_length = 1;
21107 
21108   for (paramCount = 8; paramCount > 0; --paramCount)
21109   {
21110     mysql_stmt_close(stmt);
21111     stmt = mysql_stmt_init(mysql);
21112     check_stmt(stmt);
21113 
21114     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21115 
21116     rc = mysql_stmt_bind_param(stmt, bind);
21117     check_execute(stmt, rc);
21118 
21119     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21120       "(f1, f2, f3, f4, f5, f6, f7, f8, f9)"
21121       " VALUES "
21122       "(?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21123 
21124     /* Expecting an error */
21125     DIE_UNLESS(rc != 0);
21126   }
21127 
21128   /* Test of query w/out parameters, with parameter sent and not sent */
21129   for (paramCount = MDEV19838_MAX_PARAM_COUNT; paramCount != (unsigned int)-1; --paramCount)
21130   {
21131     mysql_stmt_close(stmt);
21132     stmt = mysql_stmt_init(mysql);
21133     check_stmt(stmt);
21134 
21135     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21136 
21137     if (paramCount > 0)
21138     {
21139       rc = mysql_stmt_bind_param(stmt, bind);
21140       check_execute(stmt, rc);
21141     }
21142 
21143     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21144       "(f1)"
21145       " VALUES "
21146       "(0x1111111111111111)", -1);
21147 
21148     /*
21149       We allow junk at the end of the packet in case of
21150       no parameters. So it will succeed.
21151     */
21152     DIE_UNLESS(rc == 0);
21153   }
21154 
21155   mysql_stmt_close(stmt);
21156 
21157   rc = mysql_query(mysql, "drop table mdev19838");
21158   myquery(rc);
21159 }
21160 #endif // EMBEDDED_LIBRARY
21161 
21162 
21163 static struct my_tests_st my_tests[]= {
21164   { "test_mdev_20516", test_mdev_20516 },
21165   { "test_mdev24827", test_mdev24827 },
21166   { "test_mdev_26145", test_mdev_26145 },
21167   { "disable_query_logs", disable_query_logs },
21168   { "test_view_sp_list_fields", test_view_sp_list_fields },
21169   { "client_query", client_query },
21170   { "test_prepare_insert_update", test_prepare_insert_update},
21171 #ifdef EMBEDDED_LIBRARY
21172   { "test_embedded_start_stop", test_embedded_start_stop },
21173 #endif
21174 #ifdef NOT_YET_WORKING
21175   { "test_drop_temp", test_drop_temp },
21176 #endif
21177   { "test_fetch_seek", test_fetch_seek },
21178   { "test_fetch_nobuffs", test_fetch_nobuffs },
21179   { "test_open_direct", test_open_direct },
21180   { "test_fetch_null", test_fetch_null },
21181   { "test_ps_null_param", test_ps_null_param },
21182   { "test_fetch_date", test_fetch_date },
21183   { "test_fetch_str", test_fetch_str },
21184   { "test_fetch_long", test_fetch_long },
21185   { "test_fetch_short", test_fetch_short },
21186   { "test_fetch_tiny", test_fetch_tiny },
21187   { "test_fetch_bigint", test_fetch_bigint },
21188   { "test_fetch_float", test_fetch_float },
21189   { "test_fetch_double", test_fetch_double },
21190   { "test_bind_result_ext", test_bind_result_ext },
21191   { "test_bind_result_ext1", test_bind_result_ext1 },
21192   { "test_select_direct", test_select_direct },
21193   { "test_select_prepare", test_select_prepare },
21194   { "test_select", test_select },
21195   { "test_select_version", test_select_version },
21196   { "test_ps_conj_select", test_ps_conj_select },
21197   { "test_select_show_table", test_select_show_table },
21198   { "test_func_fields", test_func_fields },
21199   { "test_long_data", test_long_data },
21200   { "test_insert", test_insert },
21201   { "test_set_variable", test_set_variable },
21202   { "test_select_show", test_select_show },
21203   { "test_prepare_noparam", test_prepare_noparam },
21204   { "test_bind_result", test_bind_result },
21205   { "test_prepare_simple", test_prepare_simple },
21206   { "test_prepare", test_prepare },
21207   { "test_null", test_null },
21208   { "test_debug_example", test_debug_example },
21209   { "test_update", test_update },
21210   { "test_simple_update", test_simple_update },
21211   { "test_simple_delete", test_simple_delete },
21212   { "test_double_compare", test_double_compare },
21213   { "client_store_result", client_store_result },
21214   { "client_use_result", client_use_result },
21215   { "test_tran_bdb", test_tran_bdb },
21216   { "test_tran_innodb", test_tran_innodb },
21217   { "test_prepare_ext", test_prepare_ext },
21218   { "test_prepare_syntax", test_prepare_syntax },
21219   { "test_field_names", test_field_names },
21220   { "test_field_flags", test_field_flags },
21221   { "test_long_data_str", test_long_data_str },
21222   { "test_long_data_str1", test_long_data_str1 },
21223   { "test_long_data_bin", test_long_data_bin },
21224   { "test_warnings", test_warnings },
21225   { "test_errors", test_errors },
21226   { "test_prepare_resultset", test_prepare_resultset },
21227   { "test_stmt_close", test_stmt_close },
21228   { "test_prepare_field_result", test_prepare_field_result },
21229   { "test_multi_stmt", test_multi_stmt },
21230   { "test_multi_statements", test_multi_statements },
21231   { "test_prepare_multi_statements", test_prepare_multi_statements },
21232   { "test_store_result", test_store_result },
21233   { "test_store_result1", test_store_result1 },
21234   { "test_store_result2", test_store_result2 },
21235   { "test_subselect", test_subselect },
21236   { "test_date", test_date },
21237   { "test_date_date", test_date_date },
21238   { "test_date_time", test_date_time },
21239   { "test_date_ts", test_date_ts },
21240   { "test_date_dt", test_date_dt },
21241   { "test_prepare_alter", test_prepare_alter },
21242   { "test_manual_sample", test_manual_sample },
21243   { "test_pure_coverage", test_pure_coverage },
21244   { "test_buffers", test_buffers },
21245   { "test_ushort_bug", test_ushort_bug },
21246   { "test_sshort_bug", test_sshort_bug },
21247   { "test_stiny_bug", test_stiny_bug },
21248   { "test_field_misc", test_field_misc },
21249   { "test_set_option", test_set_option },
21250 #ifndef EMBEDDED_LIBRARY
21251   { "test_prepare_grant", test_prepare_grant },
21252 
21253 #endif
21254   { "test_frm_bug", test_frm_bug },
21255   { "test_explain_bug", test_explain_bug },
21256   { "test_decimal_bug", test_decimal_bug },
21257   { "test_nstmts", test_nstmts },
21258   { "test_logs;", test_logs },
21259   { "test_cuted_rows", test_cuted_rows },
21260   { "test_fetch_offset", test_fetch_offset },
21261   { "test_fetch_column", test_fetch_column },
21262   { "test_mem_overun", test_mem_overun },
21263   { "test_list_fields", test_list_fields },
21264   { "test_list_information_schema_fields", test_list_information_schema_fields },
21265   { "test_list_fields_default", test_list_fields_default },
21266   { "test_free_result", test_free_result },
21267   { "test_free_store_result", test_free_store_result },
21268   { "test_sqlmode", test_sqlmode },
21269   { "test_ts", test_ts },
21270   { "test_bug1115", test_bug1115 },
21271   { "test_bug1180", test_bug1180 },
21272   { "test_bug1500", test_bug1500 },
21273   { "test_bug1644", test_bug1644 },
21274   { "test_bug1946", test_bug1946 },
21275   { "test_bug2248", test_bug2248 },
21276   { "test_parse_error_and_bad_length", test_parse_error_and_bad_length },
21277   { "test_bug2247", test_bug2247 },
21278   { "test_subqueries", test_subqueries },
21279   { "test_bad_union", test_bad_union },
21280   { "test_distinct", test_distinct },
21281   { "test_subqueries_ref", test_subqueries_ref },
21282   { "test_union", test_union },
21283   { "test_bug3117", test_bug3117 },
21284   { "test_join", test_join },
21285   { "test_selecttmp", test_selecttmp },
21286   { "test_create_drop", test_create_drop },
21287   { "test_rename", test_rename },
21288   { "test_do_set", test_do_set },
21289   { "test_multi", test_multi },
21290   { "test_insert_select", test_insert_select },
21291   { "test_bind_nagative", test_bind_nagative },
21292   { "test_derived", test_derived },
21293   { "test_xjoin", test_xjoin },
21294   { "test_bug3035", test_bug3035 },
21295   { "test_union2", test_union2 },
21296   { "test_bug1664", test_bug1664 },
21297   { "test_union_param", test_union_param },
21298   { "test_order_param", test_order_param },
21299   { "test_ps_i18n", test_ps_i18n },
21300   { "test_bug3796", test_bug3796 },
21301   { "test_bug4026", test_bug4026 },
21302   { "test_bug4079", test_bug4079 },
21303   { "test_bug4236", test_bug4236 },
21304   { "test_bug4030", test_bug4030 },
21305   { "test_bug5126", test_bug5126 },
21306   { "test_bug4231", test_bug4231 },
21307   { "test_bug5399", test_bug5399 },
21308   { "test_bug5194", test_bug5194 },
21309   { "test_bug5315", test_bug5315 },
21310   { "test_bug6049", test_bug6049 },
21311   { "test_bug6058", test_bug6058 },
21312   { "test_bug6059", test_bug6059 },
21313   { "test_bug6046", test_bug6046 },
21314   { "test_bug6081", test_bug6081 },
21315   { "test_bug6096", test_bug6096 },
21316   { "test_datetime_ranges", test_datetime_ranges },
21317   { "test_datetime_ranges_mdev15289", test_datetime_ranges_mdev15289 },
21318   { "test_bug4172", test_bug4172 },
21319   { "test_conversion", test_conversion },
21320   { "test_rewind", test_rewind },
21321   { "test_bug6761", test_bug6761 },
21322   { "test_view", test_view },
21323   { "test_view_where", test_view_where },
21324   { "test_view_2where", test_view_2where },
21325   { "test_view_star", test_view_star },
21326   { "test_view_insert", test_view_insert },
21327   { "test_left_join_view", test_left_join_view },
21328   { "test_view_insert_fields", test_view_insert_fields },
21329   { "test_basic_cursors", test_basic_cursors },
21330   { "test_cursors_with_union", test_cursors_with_union },
21331   { "test_cursors_with_procedure", test_cursors_with_procedure },
21332   { "test_truncation", test_truncation },
21333   { "test_truncation_option", test_truncation_option },
21334   { "test_client_character_set", test_client_character_set },
21335   { "test_bug8330", test_bug8330 },
21336   { "test_bug7990", test_bug7990 },
21337   { "test_bug8378", test_bug8378 },
21338   { "test_bug8722", test_bug8722 },
21339   { "test_bug8880", test_bug8880 },
21340   { "test_open_cursor_prepared_statement_query_cache",
21341     test_open_cursor_prepared_statement_query_cache },
21342   { "test_bug9159", test_bug9159 },
21343   { "test_bug9520", test_bug9520 },
21344   { "test_bug9478", test_bug9478 },
21345   { "test_bug9643", test_bug9643 },
21346   { "test_bug10729", test_bug10729 },
21347   { "test_bug11111", test_bug11111 },
21348   { "test_bug9992", test_bug9992 },
21349   { "test_bug10736", test_bug10736 },
21350   { "test_bug10794", test_bug10794 },
21351   { "test_bug11172", test_bug11172 },
21352   { "test_bug11656", test_bug11656 },
21353   { "test_bug10214", test_bug10214 },
21354   { "test_bug9735", test_bug9735 },
21355   { "test_bug11183", test_bug11183 },
21356   { "test_bug11037", test_bug11037 },
21357   { "test_bug10760", test_bug10760 },
21358   { "test_bug12001", test_bug12001 },
21359   { "test_bug11718", test_bug11718 },
21360   { "test_bug12925", test_bug12925 },
21361   { "test_bug11909", test_bug11909 },
21362   { "test_bug11901", test_bug11901 },
21363   { "test_bug11904", test_bug11904 },
21364   { "test_bug12243", test_bug12243 },
21365   { "test_bug14210", test_bug14210 },
21366   { "test_bug13488", test_bug13488 },
21367   { "test_bug13524", test_bug13524 },
21368   { "test_bug14845", test_bug14845 },
21369   { "test_opt_reconnect", test_opt_reconnect },
21370   { "test_bug15510", test_bug15510},
21371 #ifndef EMBEDDED_LIBRARY
21372   { "test_bug12744", test_bug12744 },
21373 #endif
21374   { "test_bug16143", test_bug16143 },
21375   { "test_bug16144", test_bug16144 },
21376   { "test_bug15613", test_bug15613 },
21377   { "test_bug20152", test_bug20152 },
21378   { "test_bug14169", test_bug14169 },
21379   { "test_bug17667", test_bug17667 },
21380   { "test_bug15752", test_bug15752 },
21381   { "test_mysql_insert_id", test_mysql_insert_id },
21382   { "test_bug19671", test_bug19671 },
21383   { "test_bug21206", test_bug21206 },
21384   { "test_bug21726", test_bug21726 },
21385   { "test_bug15518", test_bug15518 },
21386   { "test_bug23383", test_bug23383 },
21387   { "test_bug32265", test_bug32265 },
21388   { "test_bug21635", test_bug21635 },
21389   { "test_status",   test_status   },
21390   { "test_bug24179", test_bug24179 },
21391   { "test_ps_query_cache", test_ps_query_cache },
21392   { "test_bug28075", test_bug28075 },
21393   { "test_bug27876", test_bug27876 },
21394   { "test_bug28505", test_bug28505 },
21395   { "test_bug28934", test_bug28934 },
21396   { "test_bug27592", test_bug27592 },
21397   { "test_bug29687", test_bug29687 },
21398   { "test_bug29692", test_bug29692 },
21399   { "test_bug29306", test_bug29306 },
21400   { "test_change_user", test_change_user },
21401   { "test_bug30472", test_bug30472 },
21402   { "test_bug20023", test_bug20023 },
21403   { "test_bug45010", test_bug45010 },
21404   { "test_bug53371", test_bug53371 },
21405   { "test_bug31418", test_bug31418 },
21406   { "test_bug31669", test_bug31669 },
21407   { "test_bug28386", test_bug28386 },
21408   { "test_wl4166_1", test_wl4166_1 },
21409   { "test_wl4166_2", test_wl4166_2 },
21410   { "test_wl4166_3", test_wl4166_3 },
21411   { "test_wl4166_4", test_wl4166_4 },
21412   { "test_bug36004", test_bug36004 },
21413   { "test_wl4284_1", test_wl4284_1 },
21414   { "test_wl4435",   test_wl4435 },
21415   { "test_wl4435_2", test_wl4435_2 },
21416   { "test_wl4435_3", test_wl4435_3 },
21417   { "test_bug38486", test_bug38486 },
21418   { "test_bug33831", test_bug33831 },
21419   { "test_bug40365", test_bug40365 },
21420   { "test_bug43560", test_bug43560 },
21421   { "test_bug36326", test_bug36326 },
21422   { "test_bug41078", test_bug41078 },
21423   { "test_bug44495", test_bug44495 },
21424   { "test_bug49972", test_bug49972 },
21425   { "test_bug42373", test_bug42373 },
21426   { "test_bug54041", test_bug54041 },
21427   { "test_bug47485", test_bug47485 },
21428   { "test_bug58036", test_bug58036 },
21429   { "test_bug57058", test_bug57058 },
21430   { "test_bug56976", test_bug56976 },
21431   { "test_mdev3885", test_mdev3885 },
21432   { "test_mdev4603", test_mdev4603 },
21433   { "test_bug11766854", test_bug11766854 },
21434   { "test_bug12337762", test_bug12337762 },
21435   { "test_progress_reporting", test_progress_reporting },
21436   { "test_bug11754979", test_bug11754979 },
21437   { "test_bug13001491", test_bug13001491 },
21438   { "test_mdev4326", test_mdev4326 },
21439   { "test_ps_sp_out_params", test_ps_sp_out_params },
21440 #ifndef _WIN32
21441   { "test_bug17512527", test_bug17512527},
21442 #endif
21443   { "test_compressed_protocol", test_compressed_protocol },
21444   { "test_big_packet", test_big_packet },
21445   { "test_prepare_analyze", test_prepare_analyze },
21446   { "test_mdev12579", test_mdev12579 },
21447   { "test_mdev14013", test_mdev14013 },
21448   { "test_mdev14013_1", test_mdev14013_1 },
21449   { "test_mdev14454", test_mdev14454 },
21450 #ifndef EMBEDDED_LIBRARY
21451   { "test_proxy_header", test_proxy_header},
21452   { "test_bulk_autoinc", test_bulk_autoinc},
21453   { "test_bulk_delete", test_bulk_delete },
21454   { "test_bulk_replace", test_bulk_replace },
21455 #endif
21456   { "test_ps_params_in_ctes", test_ps_params_in_ctes },
21457   { "test_explain_meta", test_explain_meta },
21458 #ifndef EMBEDDED_LIBRARY
21459   { "test_mdev19838", test_mdev19838 },
21460 #endif
21461   { 0, 0 }
21462 };
21463 
21464 
get_my_tests()21465 static struct my_tests_st *get_my_tests() { return my_tests; }
21466