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 #include "my_valgrind.h"
44 
45 static const my_bool my_true= 1;
46 
47 
48 /* Query processing */
49 
get_reconnect(MYSQL * mysql)50 static my_bool get_reconnect(MYSQL *mysql)
51 {
52 #ifdef EMBEDDED_LIBRARY
53   return mysql->reconnect;
54 #else
55   my_bool reconnect;
56   mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect);
57   return reconnect;
58 #endif
59 }
60 
client_query()61 static void client_query()
62 {
63   int rc;
64 
65   myheader("client_query");
66 
67   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
68   myquery(rc);
69 
70   rc= mysql_query(mysql, "CREATE TABLE t1("
71                          "id int primary key auto_increment, "
72                          "name varchar(20))");
73   myquery(rc);
74 
75   rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))");
76   myquery_r(rc);
77 
78   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')");
79   myquery(rc);
80 
81   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')");
82   myquery(rc);
83 
84   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')");
85   myquery(rc);
86 
87   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
88   myquery(rc);
89 
90   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
91   myquery(rc);
92 
93   rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' "
94                           "WHERE name= 'deleted'");
95   myquery(rc);
96 
97   rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'");
98   myquery_r(rc);
99 
100   myquery(mysql_query(mysql, "drop table t1"));
101 }
102 
103 
104 /* Store result processing */
105 
client_store_result()106 static void client_store_result()
107 {
108   MYSQL_RES *result;
109   int       rc;
110 
111   myheader("client_store_result");
112 
113   rc= mysql_query(mysql, "SELECT * FROM t1");
114   myquery(rc);
115 
116   /* get the result */
117   result= mysql_store_result(mysql);
118   mytest(result);
119 
120   (void) my_process_result_set(result);
121   mysql_free_result(result);
122 }
123 
124 
125 /* Fetch the results */
126 
client_use_result()127 static void client_use_result()
128 {
129   MYSQL_RES *result;
130   int       rc;
131   myheader("client_use_result");
132 
133   rc= mysql_query(mysql, "SELECT * FROM t1");
134   myquery(rc);
135 
136   /* get the result */
137   result= mysql_use_result(mysql);
138   mytest(result);
139 
140   (void) my_process_result_set(result);
141   mysql_free_result(result);
142 }
143 
144 
145 /* Query processing */
146 
test_debug_example()147 static void test_debug_example()
148 {
149   int rc;
150   MYSQL_RES *result;
151 
152   myheader("test_debug_example");
153 
154   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_debug_example");
155   myquery(rc);
156 
157   rc= mysql_query(mysql, "CREATE TABLE test_debug_example("
158                          "id INT PRIMARY KEY AUTO_INCREMENT, "
159                          "name VARCHAR(20), xxx INT)");
160   myquery(rc);
161 
162   rc= mysql_query(mysql, "INSERT INTO test_debug_example (name) "
163                          "VALUES ('mysql')");
164   myquery(rc);
165 
166   rc= mysql_query(mysql, "UPDATE test_debug_example SET name='updated' "
167                          "WHERE name='deleted'");
168   myquery(rc);
169 
170   rc= mysql_query(mysql, "SELECT * FROM test_debug_example where name='mysql'");
171   myquery(rc);
172 
173   result= mysql_use_result(mysql);
174   mytest(result);
175 
176   (void) my_process_result_set(result);
177   mysql_free_result(result);
178 
179   rc= mysql_query(mysql, "DROP TABLE test_debug_example");
180   myquery(rc);
181 }
182 
183 
184 /* Test autocommit feature for BDB tables */
185 
test_tran_bdb()186 static void test_tran_bdb()
187 {
188   MYSQL_RES *result;
189   MYSQL_ROW row;
190   int       rc;
191 
192   myheader("test_tran_bdb");
193 
194   /* set AUTOCOMMIT to OFF */
195   rc= mysql_autocommit(mysql, FALSE);
196   myquery(rc);
197 
198   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction");
199   myquery(rc);
200 
201 
202   /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
203   rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction( "
204                          "col1 int , col2 varchar(30)) ENGINE= BDB");
205   myquery(rc);
206 
207   /* insert a row and commit the transaction */
208   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')");
209   myquery(rc);
210 
211   rc= mysql_commit(mysql);
212   myquery(rc);
213 
214   /* now insert the second row, and roll back the transaction */
215   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
216   myquery(rc);
217 
218   rc= mysql_rollback(mysql);
219   myquery(rc);
220 
221   /* delete first row, and roll it back */
222   rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
223   myquery(rc);
224 
225   rc= mysql_rollback(mysql);
226   myquery(rc);
227 
228   /* test the results now, only one row should exist */
229   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
230   myquery(rc);
231 
232   /* get the result */
233   result= mysql_store_result(mysql);
234   mytest(result);
235 
236   (void) my_process_result_set(result);
237   mysql_free_result(result);
238 
239   /* test the results now, only one row should exist */
240   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
241   myquery(rc);
242 
243   /* get the result */
244   result= mysql_use_result(mysql);
245   mytest(result);
246 
247   row= mysql_fetch_row(result);
248   mytest(row);
249 
250   row= mysql_fetch_row(result);
251   mytest_r(row);
252 
253   mysql_free_result(result);
254   mysql_autocommit(mysql, TRUE);
255 }
256 
257 
258 /* Test autocommit feature for InnoDB tables */
259 
test_tran_innodb()260 static void test_tran_innodb()
261 {
262   MYSQL_RES *result;
263   MYSQL_ROW row;
264   int       rc;
265 
266   myheader("test_tran_innodb");
267 
268   /* set AUTOCOMMIT to OFF */
269   rc= mysql_autocommit(mysql, FALSE);
270   myquery(rc);
271 
272   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction");
273   myquery(rc);
274 
275   /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
276   rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction(col1 int, "
277                          "col2 varchar(30)) ENGINE= InnoDB");
278   myquery(rc);
279 
280   /* insert a row and commit the transaction */
281   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')");
282   myquery(rc);
283 
284   rc= mysql_commit(mysql);
285   myquery(rc);
286 
287   /* now insert the second row, and roll back the transaction */
288   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
289   myquery(rc);
290 
291   rc= mysql_rollback(mysql);
292   myquery(rc);
293 
294   /* delete first row, and roll it back */
295   rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
296   myquery(rc);
297 
298   rc= mysql_rollback(mysql);
299   myquery(rc);
300 
301   /* test the results now, only one row should exist */
302   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
303   myquery(rc);
304 
305   /* get the result */
306   result= mysql_store_result(mysql);
307   mytest(result);
308 
309   (void) my_process_result_set(result);
310   mysql_free_result(result);
311 
312   /* test the results now, only one row should exist */
313   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
314   myquery(rc);
315 
316   /* get the result */
317   result= mysql_use_result(mysql);
318   mytest(result);
319 
320   row= mysql_fetch_row(result);
321   mytest(row);
322 
323   row= mysql_fetch_row(result);
324   mytest_r(row);
325 
326   mysql_free_result(result);
327   mysql_autocommit(mysql, TRUE);
328 }
329 
330 
331 /* Test for BUG#7242 */
332 
test_prepare_insert_update()333 static void test_prepare_insert_update()
334 {
335   MYSQL_STMT *stmt;
336   int        rc;
337   int        i;
338   const char *testcase[]= {
339     "CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B))",
340     "INSERT t1 VALUES (1,2,10), (3,4,20)",
341     "INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100",
342     "SELECT * FROM t1",
343     "INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0",
344     "SELECT * FROM t1",
345     "INSERT t1 VALUES (2,1,11), (7,4,40) ON DUPLICATE KEY UPDATE c=c+VALUES(a)",
346     NULL};
347   const char **cur_query;
348 
349   myheader("test_prepare_insert_update");
350 
351   for (cur_query= testcase; *cur_query; cur_query++)
352   {
353     char query[MAX_TEST_QUERY_LENGTH];
354     printf("\nRunning query: %s", *cur_query);
355     strmov(query, *cur_query);
356     stmt= mysql_simple_prepare(mysql, query);
357     check_stmt(stmt);
358 
359     verify_param_count(stmt, 0);
360     rc= mysql_stmt_execute(stmt);
361 
362     check_execute(stmt, rc);
363     /* try the last query several times */
364     if (!cur_query[1])
365     {
366       for (i=0; i < 3;i++)
367       {
368         printf("\nExecuting last statement again");
369         rc= mysql_stmt_execute(stmt);
370         check_execute(stmt, rc);
371         rc= mysql_stmt_execute(stmt);
372         check_execute(stmt, rc);
373       }
374     }
375     mysql_stmt_close(stmt);
376   }
377 
378   rc= mysql_commit(mysql);
379   myquery(rc);
380 }
381 
382 
383 /* Test simple prepares of all DML statements */
384 
test_prepare_simple()385 static void test_prepare_simple()
386 {
387   MYSQL_STMT *stmt;
388   int        rc;
389   char query[MAX_TEST_QUERY_LENGTH];
390 
391   myheader("test_prepare_simple");
392 
393   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_simple");
394   myquery(rc);
395 
396   rc= mysql_query(mysql, "CREATE TABLE test_prepare_simple("
397                          "id int, name varchar(50))");
398   myquery(rc);
399 
400   /* insert */
401   strmov(query, "INSERT INTO test_prepare_simple VALUES(?, ?)");
402   stmt= mysql_simple_prepare(mysql, query);
403   check_stmt(stmt);
404 
405   verify_param_count(stmt, 2);
406   mysql_stmt_close(stmt);
407 
408   /* update */
409   strmov(query, "UPDATE test_prepare_simple SET id=? "
410                 "WHERE id=? AND CONVERT(name USING utf8)= ?");
411   stmt= mysql_simple_prepare(mysql, query);
412   check_stmt(stmt);
413 
414   verify_param_count(stmt, 3);
415   mysql_stmt_close(stmt);
416 
417   /* delete */
418   strmov(query, "DELETE FROM test_prepare_simple WHERE id=10");
419   stmt= mysql_simple_prepare(mysql, query);
420   check_stmt(stmt);
421 
422   verify_param_count(stmt, 0);
423 
424   rc= mysql_stmt_execute(stmt);
425   check_execute(stmt, rc);
426   mysql_stmt_close(stmt);
427 
428   /* delete */
429   strmov(query, "DELETE FROM test_prepare_simple WHERE id=?");
430   stmt= mysql_simple_prepare(mysql, query);
431   check_stmt(stmt);
432 
433   verify_param_count(stmt, 1);
434 
435   mysql_stmt_close(stmt);
436 
437   /* select */
438   strmov(query, "SELECT * FROM test_prepare_simple WHERE id=? "
439                 "AND CONVERT(name USING utf8)= ?");
440   stmt= mysql_simple_prepare(mysql, query);
441   check_stmt(stmt);
442 
443   verify_param_count(stmt, 2);
444 
445   mysql_stmt_close(stmt);
446 
447   /* show create */
448   strmov(query, "SHOW CREATE TABLE test_prepare_simple");
449   stmt= mysql_simple_prepare(mysql, query);
450   check_stmt(stmt);
451   DIE_UNLESS(mysql_stmt_field_count(stmt) == 2);
452   mysql_stmt_close(stmt);
453 
454   /* show create database */
455   strmov(query, "SHOW CREATE DATABASE test");
456   stmt= mysql_simple_prepare(mysql, query);
457   check_stmt(stmt);
458   DIE_UNLESS(mysql_stmt_field_count(stmt) == 2);
459   mysql_stmt_close(stmt);
460 
461   /* show grants */
462   strmov(query, "SHOW GRANTS");
463   stmt= mysql_simple_prepare(mysql, query);
464   check_stmt(stmt);
465   DIE_UNLESS(mysql_stmt_field_count(stmt) == 1);
466   mysql_stmt_close(stmt);
467 
468   /* show slave status */
469   strmov(query, "SHOW SLAVE STATUS");
470   stmt= mysql_simple_prepare(mysql, query);
471   check_stmt(stmt);
472   DIE_UNLESS(mysql_stmt_field_count(stmt) == 53);
473   mysql_stmt_close(stmt);
474 
475   /* show master status */
476   strmov(query, "SHOW MASTER STATUS");
477   stmt= mysql_simple_prepare(mysql, query);
478   check_stmt(stmt);
479   DIE_UNLESS(mysql_stmt_field_count(stmt) == 4);
480   mysql_stmt_close(stmt);
481 
482   /* show create procedure */
483   strmov(query, "SHOW CREATE PROCEDURE e1;");
484   stmt= mysql_simple_prepare(mysql, query);
485   check_stmt(stmt);
486   DIE_UNLESS(mysql_stmt_field_count(stmt) == 6);
487   mysql_stmt_close(stmt);
488 
489   /* show create function */
490   strmov(query, "SHOW CREATE FUNCTION e1;");
491   stmt= mysql_simple_prepare(mysql, query);
492   check_stmt(stmt);
493   DIE_UNLESS(mysql_stmt_field_count(stmt) == 6);
494   mysql_stmt_close(stmt);
495 
496   /* now fetch the results ..*/
497   rc= mysql_commit(mysql);
498   myquery(rc);
499 }
500 
501 /************************************************************************/
502 
503 #define FILE_PATH_SIZE 4096
504 
505 char mct_log_file_path[FILE_PATH_SIZE];
506 FILE *mct_log_file= NULL;
507 
mct_start_logging(const char * test_case_name)508 void mct_start_logging(const char *test_case_name)
509 {
510   const char *tmp_dir= getenv("MYSQL_TMP_DIR");
511 
512   if (!tmp_dir)
513   {
514     printf("Warning: MYSQL_TMP_DIR is not set. Logging is disabled.\n");
515     return;
516   }
517 
518   if (mct_log_file)
519   {
520     printf("Warning: can not start logging for test case '%s' "
521            "because log is already open\n",
522            (const char *) test_case_name);
523     return;
524   }
525 
526   /*
527     Path is: <tmp_dir>/<test_case_name>.out.log
528     10 is length of '/' + '.out.log' + \0
529   */
530 
531   if (strlen(tmp_dir) + strlen(test_case_name) + 10 > FILE_PATH_SIZE)
532   {
533     printf("Warning: MYSQL_TMP_DIR is too long. Logging is disabled.\n");
534     return;
535   }
536 
537   my_snprintf(mct_log_file_path, FILE_PATH_SIZE,
538               "%s/%s.out.log",
539               (const char *) tmp_dir,
540               (const char *) test_case_name);
541 
542   mct_log_file= my_fopen(mct_log_file_path, O_WRONLY | O_BINARY, MYF(MY_WME));
543 
544   if (!mct_log_file)
545   {
546     printf("Warning: can not open log file (%s): %s. Logging is disabled.\n",
547         (const char *) mct_log_file_path,
548         (const char *) strerror(errno));
549     return;
550   }
551 }
552 
mct_log(const char * format,...)553 void mct_log(const char *format, ...)
554 {
555   va_list args;
556   va_start(args, format);
557   vprintf(format, args);
558   va_end(args);
559 
560   if (mct_log_file)
561   {
562     va_list args;
563     va_start(args, format);
564     vfprintf(mct_log_file, format, args);
565     va_end(args);
566   }
567 }
568 
mct_close_log()569 void mct_close_log()
570 {
571   if (!mct_log_file)
572     return;
573 
574   my_fclose(mct_log_file, MYF(0));
575   mct_log_file= NULL;
576 }
577 
578 #define WL4435_NUM_PARAMS 10
579 #define WL4435_STRING_SIZE 30
580 
test_wl4435()581 static void test_wl4435()
582 {
583   MYSQL_STMT *stmt;
584   int        rc;
585   char query[MAX_TEST_QUERY_LENGTH];
586 
587   char       str_data[20][WL4435_STRING_SIZE];
588   double     dbl_data[20];
589   char       dec_data[20][WL4435_STRING_SIZE];
590   int        int_data[20];
591   ulong      str_length= WL4435_STRING_SIZE;
592   my_bool    is_null;
593   MYSQL_BIND ps_params[WL4435_NUM_PARAMS];
594 
595   int exec_counter;
596 
597   myheader("test_wl4435");
598   mct_start_logging("test_wl4435");
599 
600   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
601   myquery(rc);
602 
603   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p2");
604   myquery(rc);
605 
606   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
607   myquery(rc);
608 
609   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
610   myquery(rc);
611 
612   rc= mysql_query(mysql, "CREATE TABLE t1(a1 INT, a2 CHAR(32), "
613                        "  a3 DOUBLE(4, 2), a4 DECIMAL(3, 1))");
614   myquery(rc);
615 
616   rc= mysql_query(mysql, "CREATE TABLE t2(b0 INT, b1 INT, b2 CHAR(32), "
617                        "  b3 DOUBLE(4, 2), b4 DECIMAL(3, 1))");
618   myquery(rc);
619 
620   rc= mysql_query(mysql, "INSERT INTO t1 VALUES"
621     "(1, '11', 12.34, 56.7), "
622     "(2, '12', 56.78, 90.1), "
623     "(3, '13', 23.45, 67.8)");
624   myquery(rc);
625 
626   rc= mysql_query(mysql, "INSERT INTO t2 VALUES"
627     "(100, 10, '110', 70.70, 10.1), "
628     "(200, 20, '120', 80.80, 20.2), "
629     "(300, 30, '130', 90.90, 30.3)");
630   myquery(rc);
631 
632   rc= mysql_query(mysql,
633     "CREATE PROCEDURE p1("
634     "   IN v0 INT, "
635     "   OUT v_str_1 CHAR(32), "
636     "   OUT v_dbl_1 DOUBLE(4, 2), "
637     "   OUT v_dec_1 DECIMAL(6, 3), "
638     "   OUT v_int_1 INT, "
639     "   IN v1 INT, "
640     "   INOUT v_str_2 CHAR(64), "
641     "   INOUT v_dbl_2 DOUBLE(5, 3), "
642     "   INOUT v_dec_2 DECIMAL(7, 4), "
643     "   INOUT v_int_2 INT)"
644     "BEGIN "
645     "   SET v0 = -1; "
646     "   SET v1 = -1; "
647     "   SET v_str_1 = 'test_1'; "
648     "   SET v_dbl_1 = 12.34; "
649     "   SET v_dec_1 = 567.891; "
650     "   SET v_int_1 = 2345; "
651     "   SET v_str_2 = 'test_2'; "
652     "   SET v_dbl_2 = 67.891; "
653     "   SET v_dec_2 = 234.6789; "
654     "   SET v_int_2 = 6789; "
655     "   SELECT * FROM t1; "
656     "   SELECT * FROM t2; "
657     "END");
658   myquery(rc);
659 
660   rc= mysql_query(mysql,
661     "CREATE PROCEDURE p2("
662     "   IN i1 VARCHAR(255) CHARACTER SET koi8r, "
663     "   OUT o1 VARCHAR(255) CHARACTER SET cp1251, "
664     "   OUT o2 VARBINARY(255)) "
665     "BEGIN "
666     "   SET o1 = i1; "
667     "   SET o2 = i1; "
668     "END");
669   myquery(rc);
670 
671   strmov(query, "CALL p1(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
672   stmt= mysql_simple_prepare(mysql, query);
673   check_stmt(stmt);
674 
675   /* Init PS-parameters. */
676 
677   memset(str_data, 0, sizeof str_data);
678   memset(dbl_data, 0, sizeof dbl_data);
679   memset(dec_data, 0, sizeof dec_data);
680   memset(int_data, 0, sizeof int_data);
681 
682   bzero((char *) ps_params, sizeof (ps_params));
683 
684   /* - v0 -- INT */
685 
686   ps_params[0].buffer_type= MYSQL_TYPE_LONG;
687   ps_params[0].buffer= (char *) &int_data[0];
688   ps_params[0].length= 0;
689   ps_params[0].is_null= 0;
690 
691   /* - v_str_1 -- CHAR(32) */
692 
693   ps_params[1].buffer_type= MYSQL_TYPE_STRING;
694   ps_params[1].buffer= (char *) str_data[0];
695   ps_params[1].buffer_length= WL4435_STRING_SIZE;
696   ps_params[1].length= &str_length;
697   ps_params[1].is_null= 0;
698 
699   /* - v_dbl_1 -- DOUBLE */
700 
701   ps_params[2].buffer_type= MYSQL_TYPE_DOUBLE;
702   ps_params[2].buffer= (char *) &dbl_data[0];
703   ps_params[2].length= 0;
704   ps_params[2].is_null= 0;
705 
706   /* - v_dec_1 -- DECIMAL */
707 
708   ps_params[3].buffer_type= MYSQL_TYPE_NEWDECIMAL;
709   ps_params[3].buffer= (char *) dec_data[0];
710   ps_params[3].buffer_length= WL4435_STRING_SIZE;
711   ps_params[3].length= 0;
712   ps_params[3].is_null= 0;
713 
714   /* - v_int_1 -- INT */
715 
716   ps_params[4].buffer_type= MYSQL_TYPE_LONG;
717   ps_params[4].buffer= (char *) &int_data[0];
718   ps_params[4].length= 0;
719   ps_params[4].is_null= 0;
720 
721   /* - v1 -- INT */
722 
723   ps_params[5].buffer_type= MYSQL_TYPE_LONG;
724   ps_params[5].buffer= (char *) &int_data[0];
725   ps_params[5].length= 0;
726   ps_params[5].is_null= 0;
727 
728   /* - v_str_2 -- CHAR(32) */
729 
730   ps_params[6].buffer_type= MYSQL_TYPE_STRING;
731   ps_params[6].buffer= (char *) str_data[0];
732   ps_params[6].buffer_length= WL4435_STRING_SIZE;
733   ps_params[6].length= &str_length;
734   ps_params[6].is_null= 0;
735 
736   /* - v_dbl_2 -- DOUBLE */
737 
738   ps_params[7].buffer_type= MYSQL_TYPE_DOUBLE;
739   ps_params[7].buffer= (char *) &dbl_data[0];
740   ps_params[7].length= 0;
741   ps_params[7].is_null= 0;
742 
743   /* - v_dec_2 -- DECIMAL */
744 
745   ps_params[8].buffer_type= MYSQL_TYPE_DECIMAL;
746   ps_params[8].buffer= (char *) dec_data[0];
747   ps_params[8].buffer_length= WL4435_STRING_SIZE;
748   ps_params[8].length= 0;
749   ps_params[8].is_null= 0;
750 
751   /* - v_int_2 -- INT */
752 
753   ps_params[9].buffer_type= MYSQL_TYPE_LONG;
754   ps_params[9].buffer= (char *) &int_data[0];
755   ps_params[9].length= 0;
756   ps_params[9].is_null= 0;
757 
758   /* Bind parameters. */
759 
760   rc= mysql_stmt_bind_param(stmt, ps_params);
761 
762   /* Execute! */
763 
764   for (exec_counter= 0; exec_counter < 3; ++exec_counter)
765   {
766     int i;
767     int num_fields;
768     MYSQL_BIND *rs_bind;
769 
770     mct_log("\nexec_counter: %d\n", (int) exec_counter);
771 
772     rc= mysql_stmt_execute(stmt);
773     check_execute(stmt, rc);
774 
775     while (1)
776     {
777       MYSQL_FIELD *fields;
778 
779       MYSQL_RES *rs_metadata= mysql_stmt_result_metadata(stmt);
780 
781       num_fields= mysql_stmt_field_count(stmt);
782       fields= mysql_fetch_fields(rs_metadata);
783 
784       rs_bind= (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
785       bzero(rs_bind, sizeof (MYSQL_BIND) * num_fields);
786 
787       mct_log("num_fields: %d\n", (int) num_fields);
788 
789       for (i = 0; i < num_fields; ++i)
790       {
791         mct_log("  - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
792                 "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
793                 "type: %d; decimals: %d\n",
794                 (int) i,
795                 (const char *) fields[i].name,
796                 (const char *) fields[i].org_name,
797                 (const char *) fields[i].table,
798                 (const char *) fields[i].org_table,
799                 (const char *) fields[i].db,
800                 (const char *) fields[i].catalog,
801                 (int) fields[i].length,
802                 (int) fields[i].max_length,
803                 (int) fields[i].type,
804                 (int) fields[i].decimals);
805 
806         rs_bind[i].buffer_type= fields[i].type;
807         rs_bind[i].is_null= &is_null;
808 
809         switch (fields[i].type)
810         {
811           case MYSQL_TYPE_LONG:
812             rs_bind[i].buffer= (char *) &(int_data[i]);
813             rs_bind[i].buffer_length= sizeof (int_data);
814             break;
815 
816           case MYSQL_TYPE_STRING:
817             rs_bind[i].buffer= (char *) str_data[i];
818             rs_bind[i].buffer_length= WL4435_STRING_SIZE;
819             rs_bind[i].length= &str_length;
820             break;
821 
822           case MYSQL_TYPE_DOUBLE:
823             rs_bind[i].buffer= (char *) &dbl_data[i];
824             rs_bind[i].buffer_length= sizeof (dbl_data);
825             break;
826 
827           case MYSQL_TYPE_NEWDECIMAL:
828             rs_bind[i].buffer= (char *) dec_data[i];
829             rs_bind[i].buffer_length= WL4435_STRING_SIZE;
830             rs_bind[i].length= &str_length;
831             break;
832 
833           default:
834             fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
835             exit(1);
836         }
837       }
838 
839       rc= mysql_stmt_bind_result(stmt, rs_bind);
840       check_execute(stmt, rc);
841 
842       mct_log("Data:\n");
843 
844       while (1)
845       {
846         int rc= mysql_stmt_fetch(stmt);
847 
848         if (rc == 1 || rc == MYSQL_NO_DATA)
849           break;
850 
851         mct_log(" ");
852 
853         for (i = 0; i < num_fields; ++i)
854         {
855           switch (rs_bind[i].buffer_type)
856           {
857             case MYSQL_TYPE_LONG:
858               mct_log(" int: %ld;",
859                       (long) *((int *) rs_bind[i].buffer));
860               break;
861 
862             case MYSQL_TYPE_STRING:
863               mct_log(" str: '%s';",
864                       (char *) rs_bind[i].buffer);
865               break;
866 
867             case MYSQL_TYPE_DOUBLE:
868               mct_log(" dbl: %lf;",
869                       (double) *((double *) rs_bind[i].buffer));
870               break;
871 
872             case MYSQL_TYPE_NEWDECIMAL:
873               mct_log(" dec: '%s';",
874                       (char *) rs_bind[i].buffer);
875               break;
876 
877             default:
878               printf("  unexpected type (%d)\n",
879                 rs_bind[i].buffer_type);
880           }
881         }
882         mct_log("\n");
883       }
884 
885       mct_log("EOF\n");
886 
887       rc= mysql_stmt_next_result(stmt);
888       mct_log("mysql_stmt_next_result(): %d; field_count: %d\n",
889               (int) rc, (int) mysql->field_count);
890 
891       free(rs_bind);
892       mysql_free_result(rs_metadata);
893 
894       if (rc > 0)
895       {
896         printf("Error: %s (errno: %d)\n",
897                mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
898         DIE(rc > 0);
899       }
900 
901       if (rc)
902         break;
903 
904       if (!mysql->field_count)
905       {
906         /* This is the last OK-packet. No more resultsets. */
907         break;
908       }
909     }
910 
911   }
912 
913   mysql_stmt_close(stmt);
914 
915   mct_close_log();
916 
917   rc= mysql_commit(mysql);
918   myquery(rc);
919 
920   /* i18n part of test case. */
921 
922   {
923     const char *str_koi8r= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
924     const char *str_cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
925     char o1_buffer[255];
926     ulong o1_length;
927     char o2_buffer[255];
928     ulong o2_length;
929 
930     MYSQL_BIND rs_bind[2];
931 
932     strmov(query, "CALL p2(?, ?, ?)");
933     stmt= mysql_simple_prepare(mysql, query);
934     check_stmt(stmt);
935 
936     /* Init PS-parameters. */
937 
938     bzero((char *) ps_params, sizeof (ps_params));
939 
940     ps_params[0].buffer_type= MYSQL_TYPE_STRING;
941     ps_params[0].buffer= (char *) str_koi8r;
942     ps_params[0].buffer_length= strlen(str_koi8r);
943 
944     ps_params[1].buffer_type= MYSQL_TYPE_STRING;
945     ps_params[1].buffer= o1_buffer;
946     ps_params[1].buffer_length= 0;
947 
948     ps_params[2].buffer_type= MYSQL_TYPE_STRING;
949     ps_params[2].buffer= o2_buffer;
950     ps_params[2].buffer_length= 0;
951 
952     /* Bind parameters. */
953 
954     rc= mysql_stmt_bind_param(stmt, ps_params);
955     check_execute(stmt, rc);
956 
957     /* Prevent converting to character_set_results. */
958 
959     rc= mysql_query(mysql, "SET NAMES binary");
960     myquery(rc);
961 
962     /* Execute statement. */
963 
964     rc= mysql_stmt_execute(stmt);
965     check_execute(stmt, rc);
966 
967     /* Bind result. */
968 
969     bzero(rs_bind, sizeof (rs_bind));
970 
971     rs_bind[0].buffer_type= MYSQL_TYPE_STRING;
972     rs_bind[0].buffer= o1_buffer;
973     rs_bind[0].buffer_length= sizeof (o1_buffer);
974     rs_bind[0].length= &o1_length;
975 
976     rs_bind[1].buffer_type= MYSQL_TYPE_BLOB;
977     rs_bind[1].buffer= o2_buffer;
978     rs_bind[1].buffer_length= sizeof (o2_buffer);
979     rs_bind[1].length= &o2_length;
980 
981     rc= mysql_stmt_bind_result(stmt, rs_bind);
982     check_execute(stmt, rc);
983 
984     /* Fetch result. */
985 
986     rc= mysql_stmt_fetch(stmt);
987     check_execute(stmt, rc);
988 
989     /* Check result. */
990 
991     DIE_UNLESS(o1_length == strlen(str_cp1251));
992     DIE_UNLESS(o2_length == strlen(str_koi8r));
993     DIE_UNLESS(!memcmp(o1_buffer, str_cp1251, o1_length));
994     DIE_UNLESS(!memcmp(o2_buffer, str_koi8r, o2_length));
995 
996     rc= mysql_stmt_fetch(stmt);
997     DIE_UNLESS(rc == MYSQL_NO_DATA);
998 
999     rc= mysql_stmt_next_result(stmt);
1000     DIE_UNLESS(rc == 0 && mysql->field_count == 0);
1001 
1002     mysql_stmt_close(stmt);
1003 
1004     rc= mysql_commit(mysql);
1005     myquery(rc);
1006   }
1007 }
1008 
test_wl4435_2()1009 static void test_wl4435_2()
1010 {
1011   MYSQL_STMT *stmt;
1012   int  i;
1013   int  rc;
1014   char query[MAX_TEST_QUERY_LENGTH];
1015 
1016   myheader("test_wl4435_2");
1017   mct_start_logging("test_wl4435_2");
1018 
1019   /*
1020     Do a few iterations so that we catch any problem with incorrect
1021     handling/flushing prepared statement results.
1022   */
1023 
1024   for (i= 0; i < 10; ++i)
1025   {
1026     /*
1027       Prepare a procedure. That can be moved out of the loop, but it was
1028       left in the loop for the sake of having as many statements as
1029       possible.
1030     */
1031 
1032     rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
1033     myquery(rc);
1034 
1035     rc= mysql_query(mysql,
1036       "CREATE PROCEDURE p1()"
1037       "BEGIN "
1038       "  SELECT 1; "
1039       "  SELECT 2, 3 UNION SELECT 4, 5; "
1040       "  SELECT 6, 7, 8; "
1041       "END");
1042     myquery(rc);
1043 
1044     /* Invoke a procedure, that returns several result sets. */
1045 
1046     strmov(query, "CALL p1()");
1047     stmt= mysql_simple_prepare(mysql, query);
1048     check_stmt(stmt);
1049 
1050     /* Execute! */
1051 
1052     rc= mysql_stmt_execute(stmt);
1053     check_execute(stmt, rc);
1054 
1055     /* Flush all the results. */
1056 
1057     mysql_stmt_close(stmt);
1058 
1059     /* Clean up. */
1060     rc= mysql_commit(mysql);
1061     myquery(rc);
1062 
1063     rc= mysql_query(mysql, "DROP PROCEDURE p1");
1064     myquery(rc);
1065   }
1066   mct_close_log();
1067 }
1068 
1069 
1070 #define WL4435_TEST(sql_type, sql_value, \
1071                     c_api_in_type, c_api_out_type, \
1072                     c_type, c_type_ext, \
1073                     printf_args, assert_condition) \
1074 \
1075   do { \
1076   int rc; \
1077   MYSQL_STMT *ps; \
1078   MYSQL_BIND psp; \
1079   MYSQL_RES *rs_metadata; \
1080   MYSQL_FIELD *fields; \
1081   c_type pspv c_type_ext; \
1082   my_bool psp_null= FALSE; \
1083   \
1084   bzero(&pspv, sizeof (pspv)); \
1085   \
1086   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); \
1087   myquery(rc); \
1088   \
1089   rc= mysql_query(mysql, \
1090     "CREATE PROCEDURE p1(OUT v " sql_type ") SET v = " sql_value ";"); \
1091   myquery(rc); \
1092   \
1093   ps = mysql_simple_prepare(mysql, "CALL p1(?)"); \
1094   check_stmt(ps); \
1095   \
1096   bzero(&psp, sizeof (psp)); \
1097   psp.buffer_type= c_api_in_type; \
1098   psp.is_null= &psp_null; \
1099   psp.buffer= (char *) &pspv; \
1100   psp.buffer_length= sizeof (psp); \
1101   \
1102   rc= mysql_stmt_bind_param(ps, &psp); \
1103   check_execute(ps, rc); \
1104   \
1105   rc= mysql_stmt_execute(ps); \
1106   check_execute(ps, rc); \
1107   \
1108   DIE_UNLESS(mysql->server_status & SERVER_PS_OUT_PARAMS); \
1109   DIE_UNLESS(mysql_stmt_field_count(ps) == 1); \
1110   \
1111   rs_metadata= mysql_stmt_result_metadata(ps); \
1112   fields= mysql_fetch_fields(rs_metadata); \
1113   mysql_free_result(rs_metadata);               \
1114   \
1115   rc= mysql_stmt_bind_result(ps, &psp); \
1116   check_execute(ps, rc); \
1117   \
1118   rc= mysql_stmt_fetch(ps); \
1119   DIE_UNLESS(rc == 0); \
1120   \
1121   DIE_UNLESS(fields[0].type == c_api_out_type); \
1122   printf printf_args; \
1123   printf("; in type: %d; out type: %d\n", \
1124          (int) c_api_in_type, (int) c_api_out_type); \
1125   \
1126   rc= mysql_stmt_fetch(ps); \
1127   DIE_UNLESS(rc == MYSQL_NO_DATA); \
1128   \
1129   rc= mysql_stmt_next_result(ps); \
1130   DIE_UNLESS(rc == 0); \
1131   \
1132   mysql_stmt_free_result(ps); \
1133   mysql_stmt_close(ps); \
1134   \
1135   DIE_UNLESS(assert_condition); \
1136   \
1137   } while (0)
1138 
test_wl4435_3()1139 static void test_wl4435_3()
1140 {
1141   char tmp[255];
1142 
1143   memset(tmp, 0, sizeof tmp);
1144   puts("");
1145 
1146   /*
1147   // The following types are not supported:
1148   //   - ENUM
1149   //   - SET
1150   //
1151   // The following types are supported but can not be used for
1152   // OUT-parameters:
1153   //   - MEDIUMINT;
1154   //   - BIT(..);
1155   //
1156   // The problem is that those types are not supported for IN-parameters,
1157   // and OUT-parameters should be bound as IN-parameters before execution.
1158   //
1159   // The following types should not be used:
1160   //   - MYSQL_TYPE_YEAR (use MYSQL_TYPE_SHORT instead);
1161   //   - MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB
1162   //     (use MYSQL_TYPE_BLOB instead);
1163   */
1164 
1165   WL4435_TEST("TINYINT", "127",
1166               MYSQL_TYPE_TINY, MYSQL_TYPE_TINY,
1167               char, ,
1168               ("  - TINYINT / char / MYSQL_TYPE_TINY:\t\t\t %d", (int) pspv),
1169               pspv == 127);
1170 
1171   WL4435_TEST("SMALLINT", "32767",
1172               MYSQL_TYPE_SHORT, MYSQL_TYPE_SHORT,
1173               short, ,
1174               ("  - SMALLINT / short / MYSQL_TYPE_SHORT:\t\t %d", (int) pspv),
1175               pspv == 32767);
1176 
1177   WL4435_TEST("INT", "2147483647",
1178               MYSQL_TYPE_LONG, MYSQL_TYPE_LONG,
1179               int, ,
1180               ("  - INT / int / MYSQL_TYPE_LONG:\t\t\t %d", pspv),
1181               pspv == 2147483647l);
1182 
1183   WL4435_TEST("BIGINT", "9223372036854775807",
1184               MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG,
1185               long long, ,
1186               ("  - BIGINT / long long / MYSQL_TYPE_LONGLONG:\t\t %lld", pspv),
1187               pspv == 9223372036854775807ll);
1188 
1189   WL4435_TEST("TIMESTAMP", "'2007-11-18 15:01:02'",
1190               MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP,
1191               MYSQL_TIME, ,
1192               ("  - TIMESTAMP / MYSQL_TIME / MYSQL_TYPE_TIMESTAMP:\t "
1193                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1194                (int) pspv.year, (int) pspv.month, (int) pspv.day,
1195                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1196               pspv.year == 2007 && pspv.month == 11 && pspv.day == 18 &&
1197               pspv.hour == 15 && pspv.minute == 1 && pspv.second == 2);
1198 
1199   WL4435_TEST("DATETIME", "'1234-11-12 12:34:59'",
1200               MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME,
1201               MYSQL_TIME, ,
1202               ("  - DATETIME / MYSQL_TIME / MYSQL_TYPE_DATETIME:\t "
1203                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1204                (int) pspv.year, (int) pspv.month, (int) pspv.day,
1205                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1206               pspv.year == 1234 && pspv.month == 11 && pspv.day == 12 &&
1207               pspv.hour == 12 && pspv.minute == 34 && pspv.second == 59);
1208 
1209   WL4435_TEST("TIME", "'123:45:01'",
1210               MYSQL_TYPE_TIME, MYSQL_TYPE_TIME,
1211               MYSQL_TIME, ,
1212               ("  - TIME / MYSQL_TIME / MYSQL_TYPE_TIME:\t\t "
1213                "%.3d:%.2d:%.2d",
1214                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1215               pspv.hour == 123 && pspv.minute == 45 && pspv.second == 1);
1216 
1217   WL4435_TEST("DATE", "'1234-11-12'",
1218               MYSQL_TYPE_DATE, MYSQL_TYPE_DATE,
1219               MYSQL_TIME, ,
1220               ("  - DATE / MYSQL_TIME / MYSQL_TYPE_DATE:\t\t "
1221                "%.4d-%.2d-%.2d",
1222                (int) pspv.year, (int) pspv.month, (int) pspv.day),
1223               pspv.year == 1234 && pspv.month == 11 && pspv.day == 12);
1224 
1225   WL4435_TEST("YEAR", "'2010'",
1226               MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR,
1227               short, ,
1228               ("  - YEAR / short / MYSQL_TYPE_SHORT:\t\t\t %.4d", (int) pspv),
1229               pspv == 2010);
1230 
1231   WL4435_TEST("FLOAT(7, 4)", "123.4567",
1232               MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT,
1233               float, ,
1234               ("  - FLOAT / float / MYSQL_TYPE_FLOAT:\t\t\t %g", (double) pspv),
1235               pspv - 123.4567 < 0.0001);
1236 
1237   WL4435_TEST("DOUBLE(8, 5)", "123.45678",
1238               MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE,
1239               double, ,
1240               ("  - DOUBLE / double / MYSQL_TYPE_DOUBLE:\t\t %g", (double) pspv),
1241               pspv - 123.45678 < 0.00001);
1242 
1243   WL4435_TEST("DECIMAL(9, 6)", "123.456789",
1244               MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL,
1245               char, [255],
1246               ("  - DECIMAL / char[] / MYSQL_TYPE_NEWDECIMAL:\t\t '%s'", (char *) pspv),
1247               !strcmp(pspv, "123.456789"));
1248 
1249   WL4435_TEST("CHAR(32)", "REPEAT('C', 16)",
1250               MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1251               char, [255],
1252               ("  - CHAR(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1253               !strcmp(pspv, "CCCCCCCCCCCCCCCC"));
1254 
1255   WL4435_TEST("VARCHAR(32)", "REPEAT('V', 16)",
1256               MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1257               char, [255],
1258               ("  - VARCHAR(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1259               !strcmp(pspv, "VVVVVVVVVVVVVVVV"));
1260 
1261   WL4435_TEST("TINYTEXT", "REPEAT('t', 16)",
1262               MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1263               char, [255],
1264               ("  - TINYTEXT / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1265               !strcmp(pspv, "tttttttttttttttt"));
1266 
1267   WL4435_TEST("TEXT", "REPEAT('t', 16)",
1268               MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1269               char, [255],
1270               ("  - TEXT / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1271               !strcmp(pspv, "tttttttttttttttt"));
1272 
1273   WL4435_TEST("MEDIUMTEXT", "REPEAT('t', 16)",
1274               MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1275               char, [255],
1276               ("  - MEDIUMTEXT / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1277               !strcmp(pspv, "tttttttttttttttt"));
1278 
1279   WL4435_TEST("LONGTEXT", "REPEAT('t', 16)",
1280               MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1281               char, [255],
1282               ("  - LONGTEXT / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1283               !strcmp(pspv, "tttttttttttttttt"));
1284 
1285   WL4435_TEST("BINARY(32)", "REPEAT('\1', 16)",
1286               MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1287               char, [255],
1288               ("  - BINARY(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1289               memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1290 
1291   WL4435_TEST("VARBINARY(32)", "REPEAT('\1', 16)",
1292               MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1293               char, [255],
1294               ("  - VARBINARY(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1295               memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1296 
1297   WL4435_TEST("TINYBLOB", "REPEAT('\2', 16)",
1298               MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1299               char, [255],
1300               ("  - TINYBLOB / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1301               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1302 
1303   WL4435_TEST("BLOB", "REPEAT('\2', 16)",
1304               MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1305               char, [255],
1306               ("  - BLOB / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1307               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1308 
1309   WL4435_TEST("MEDIUMBLOB", "REPEAT('\2', 16)",
1310               MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1311               char, [255],
1312               ("  - MEDIUMBLOB / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1313               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1314 
1315   WL4435_TEST("LONGBLOB", "REPEAT('\2', 16)",
1316               MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1317               char, [255],
1318               ("  - LONGBLOB / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1319               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1320 }
1321 
1322 
1323 /* Test simple prepare field results */
1324 
test_prepare_field_result()1325 static void test_prepare_field_result()
1326 {
1327   MYSQL_STMT *stmt;
1328   MYSQL_RES  *result;
1329   int        rc;
1330   char query[MAX_TEST_QUERY_LENGTH];
1331 
1332   myheader("test_prepare_field_result");
1333 
1334   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_field_result");
1335   myquery(rc);
1336 
1337   rc= mysql_query(mysql, "CREATE TABLE test_prepare_field_result(int_c int, "
1338                          "var_c varchar(50), ts_c timestamp, "
1339                          "char_c char(4), date_c date, extra tinyint)");
1340   myquery(rc);
1341 
1342   /* insert */
1343   strmov(query, "SELECT int_c, var_c, date_c as date, ts_c, char_c FROM "
1344                 " test_prepare_field_result as t1 WHERE int_c=?");
1345   stmt= mysql_simple_prepare(mysql, query);
1346   check_stmt(stmt);
1347 
1348   verify_param_count(stmt, 1);
1349 
1350   result= mysql_stmt_result_metadata(stmt);
1351   mytest(result);
1352 
1353   my_print_result_metadata(result);
1354 
1355   if (!opt_silent)
1356     fprintf(stdout, "\n\n field attributes:\n");
1357   verify_prepare_field(result, 0, "int_c", "int_c", MYSQL_TYPE_LONG,
1358                        "t1", "test_prepare_field_result", current_db, 11, 0);
1359   verify_prepare_field(result, 1, "var_c", "var_c", MYSQL_TYPE_VAR_STRING,
1360                        "t1", "test_prepare_field_result", current_db, 50, 0);
1361   verify_prepare_field(result, 2, "date", "date_c", MYSQL_TYPE_DATE,
1362                        "t1", "test_prepare_field_result", current_db, 10, 0);
1363   verify_prepare_field(result, 3, "ts_c", "ts_c", MYSQL_TYPE_TIMESTAMP,
1364                        "t1", "test_prepare_field_result", current_db, 19, 0);
1365   verify_prepare_field(result, 4, "char_c", "char_c",
1366                        (mysql_get_server_version(mysql) <= 50000 ?
1367                         MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING),
1368                        "t1", "test_prepare_field_result", current_db, 4, 0);
1369 
1370   verify_field_count(result, 5);
1371   mysql_free_result(result);
1372   mysql_stmt_close(stmt);
1373 }
1374 
1375 
1376 /* Test simple prepare field results */
1377 
test_prepare_syntax()1378 static void test_prepare_syntax()
1379 {
1380   MYSQL_STMT *stmt;
1381   int        rc;
1382   char query[MAX_TEST_QUERY_LENGTH];
1383 
1384   myheader("test_prepare_syntax");
1385 
1386   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_syntax");
1387   myquery(rc);
1388 
1389   rc= mysql_query(mysql, "CREATE TABLE test_prepare_syntax("
1390                          "id int, name varchar(50), extra int)");
1391   myquery(rc);
1392 
1393   strmov(query, "INSERT INTO test_prepare_syntax VALUES(?");
1394   stmt= mysql_simple_prepare(mysql, query);
1395   check_stmt_r(stmt);
1396 
1397   strmov(query, "SELECT id, name FROM test_prepare_syntax WHERE id=? AND WHERE");
1398   stmt= mysql_simple_prepare(mysql, query);
1399   check_stmt_r(stmt);
1400 
1401   /* now fetch the results ..*/
1402   rc= mysql_commit(mysql);
1403   myquery(rc);
1404 }
1405 
1406 
1407 /* Test a simple prepare */
1408 
test_prepare()1409 static void test_prepare()
1410 {
1411   MYSQL_STMT *stmt;
1412   int        rc, i;
1413   int        int_data, o_int_data;
1414   char       str_data[50], data[50];
1415   char       tiny_data, o_tiny_data;
1416   short      small_data, o_small_data;
1417   longlong   big_data, o_big_data;
1418   float      real_data, o_real_data;
1419   double     double_data, o_double_data;
1420   ulong      length[7], len;
1421   my_bool    is_null[7];
1422   char	     llbuf[22];
1423   MYSQL_BIND my_bind[7];
1424   char query[MAX_TEST_QUERY_LENGTH];
1425 
1426   myheader("test_prepare");
1427 
1428   rc= mysql_autocommit(mysql, TRUE);
1429   myquery(rc);
1430 
1431   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
1432   myquery(rc);
1433 
1434   rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 tinyint, "
1435                          "col2 varchar(15), col3 int, "
1436                          "col4 smallint, col5 bigint, "
1437                          "col6 float, col7 double )");
1438   myquery(rc);
1439 
1440   /* insert by prepare */
1441   strxmov(query, "INSERT INTO my_prepare VALUES(?, ?, ?, ?, ?, ?, ?)", NullS);
1442   stmt= mysql_simple_prepare(mysql, query);
1443   check_stmt(stmt);
1444 
1445   verify_param_count(stmt, 7);
1446 
1447   bzero((char*) my_bind, sizeof(my_bind));
1448 
1449   /* tinyint */
1450   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1451   my_bind[0].buffer= (void *)&tiny_data;
1452   /* string */
1453   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1454   my_bind[1].buffer= (void *)str_data;
1455   my_bind[1].buffer_length= 1000;                  /* Max string length */
1456   /* integer */
1457   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
1458   my_bind[2].buffer= (void *)&int_data;
1459   /* short */
1460   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
1461   my_bind[3].buffer= (void *)&small_data;
1462   /* bigint */
1463   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
1464   my_bind[4].buffer= (void *)&big_data;
1465   /* float */
1466   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
1467   my_bind[5].buffer= (void *)&real_data;
1468   /* double */
1469   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
1470   my_bind[6].buffer= (void *)&double_data;
1471 
1472   for (i= 0; i < (int) array_elements(my_bind); i++)
1473   {
1474     my_bind[i].length= &length[i];
1475     my_bind[i].is_null= &is_null[i];
1476     is_null[i]= 0;
1477   }
1478 
1479   rc= mysql_stmt_bind_param(stmt, my_bind);
1480   check_execute(stmt, rc);
1481 
1482   int_data= 320;
1483   small_data= 1867;
1484   big_data= 1000;
1485   real_data= 2;
1486   double_data= 6578.001;
1487 
1488   /* now, execute the prepared statement to insert 10 records.. */
1489   for (tiny_data= 0; tiny_data < 100; tiny_data++)
1490   {
1491     length[1]= sprintf(str_data, "MySQL%d", int_data);
1492     rc= mysql_stmt_execute(stmt);
1493     check_execute(stmt, rc);
1494     int_data += 25;
1495     small_data += 10;
1496     big_data += 100;
1497     real_data += 1;
1498     double_data += 10.09;
1499   }
1500 
1501   mysql_stmt_close(stmt);
1502 
1503   /* now fetch the results ..*/
1504   rc= mysql_commit(mysql);
1505   myquery(rc);
1506 
1507   /* test the results now, only one row should exist */
1508   rc= my_stmt_result("SELECT * FROM my_prepare");
1509   DIE_UNLESS(tiny_data == (char) rc);
1510 
1511   stmt= mysql_simple_prepare(mysql, "SELECT * FROM my_prepare");
1512   check_stmt(stmt);
1513 
1514   rc= mysql_stmt_bind_result(stmt, my_bind);
1515   check_execute(stmt, rc);
1516 
1517   /* get the result */
1518   rc= mysql_stmt_execute(stmt);
1519   check_execute(stmt, rc);
1520 
1521   o_int_data= 320;
1522   o_small_data= 1867;
1523   o_big_data= 1000;
1524   o_real_data= 2;
1525   o_double_data= 6578.001;
1526 
1527   /* now, execute the prepared statement to insert 10 records.. */
1528   for (o_tiny_data= 0; o_tiny_data < 100; o_tiny_data++)
1529   {
1530     len= sprintf(data, "MySQL%d", o_int_data);
1531 
1532     rc= mysql_stmt_fetch(stmt);
1533     check_execute(stmt, rc);
1534 
1535     if (!opt_silent)
1536     {
1537       fprintf(stdout, "\n");
1538       fprintf(stdout, "\n\t tiny   : %d (%lu)", tiny_data, length[0]);
1539       fprintf(stdout, "\n\t short  : %d (%lu)", small_data, length[3]);
1540       fprintf(stdout, "\n\t int    : %d (%lu)", int_data, length[2]);
1541       fprintf(stdout, "\n\t big    : %s (%lu)", llstr(big_data, llbuf),
1542               length[4]);
1543 
1544       fprintf(stdout, "\n\t float  : %f (%lu)", real_data, length[5]);
1545       fprintf(stdout, "\n\t double : %f (%lu)", double_data, length[6]);
1546 
1547       fprintf(stdout, "\n\t str    : %s (%lu)", str_data, length[1]);
1548     }
1549 
1550     DIE_UNLESS(tiny_data == o_tiny_data);
1551     DIE_UNLESS(is_null[0] == 0);
1552     DIE_UNLESS(length[0] == 1);
1553 
1554     DIE_UNLESS(int_data == o_int_data);
1555     DIE_UNLESS(length[2] == 4);
1556 
1557     DIE_UNLESS(small_data == o_small_data);
1558     DIE_UNLESS(length[3] == 2);
1559 
1560     DIE_UNLESS(big_data == o_big_data);
1561     DIE_UNLESS(length[4] == 8);
1562 
1563     DIE_UNLESS(real_data == o_real_data);
1564     DIE_UNLESS(length[5] == 4);
1565 
1566     DIE_UNLESS(cmp_double(&double_data, &o_double_data));
1567     DIE_UNLESS(length[6] == 8);
1568 
1569     DIE_UNLESS(strcmp(data, str_data) == 0);
1570     DIE_UNLESS(length[1] == len);
1571 
1572     o_int_data += 25;
1573     o_small_data += 10;
1574     o_big_data += 100;
1575     o_real_data += 1;
1576     o_double_data += 10.09;
1577   }
1578 
1579   rc= mysql_stmt_fetch(stmt);
1580   DIE_UNLESS(rc == MYSQL_NO_DATA);
1581 
1582   mysql_stmt_close(stmt);
1583 
1584 }
1585 
1586 
1587 /* Test double comparision */
1588 
test_double_compare()1589 static void test_double_compare()
1590 {
1591   MYSQL_STMT *stmt;
1592   int        rc;
1593   char       real_data[10], tiny_data;
1594   double     double_data;
1595   MYSQL_RES  *result;
1596   MYSQL_BIND my_bind[3];
1597   ulong      length[3];
1598   char query[MAX_TEST_QUERY_LENGTH];
1599 
1600   myheader("test_double_compare");
1601 
1602   rc= mysql_autocommit(mysql, TRUE);
1603   myquery(rc);
1604 
1605   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_double_compare");
1606   myquery(rc);
1607 
1608   rc= mysql_query(mysql, "CREATE TABLE test_double_compare(col1 tinyint, "
1609                          " col2 float, col3 double )");
1610   myquery(rc);
1611 
1612   rc= mysql_query(mysql, "INSERT INTO test_double_compare "
1613                          "VALUES (1, 10.2, 34.5)");
1614   myquery(rc);
1615 
1616   strmov(query, "UPDATE test_double_compare SET col1=100 "
1617                 "WHERE col1 = ? AND col2 = ? AND COL3 = ?");
1618   stmt= mysql_simple_prepare(mysql, query);
1619   check_stmt(stmt);
1620 
1621   verify_param_count(stmt, 3);
1622 
1623   /* Always bzero bind array because there can be internal members */
1624   bzero((char*) my_bind, sizeof(my_bind));
1625 
1626   /* tinyint */
1627   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1628   my_bind[0].buffer= (void *)&tiny_data;
1629 
1630   /* string->float */
1631   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1632   my_bind[1].buffer= (void *)&real_data;
1633   my_bind[1].buffer_length= sizeof(real_data);
1634   my_bind[1].length= &length[1];
1635   length[1]= 10;
1636 
1637   /* double */
1638   my_bind[2].buffer_type= MYSQL_TYPE_DOUBLE;
1639   my_bind[2].buffer= (void *)&double_data;
1640 
1641   tiny_data= 1;
1642   memset(real_data, 0, sizeof real_data);
1643   strmov(real_data, "10.2");
1644   double_data= 34.5;
1645   rc= mysql_stmt_bind_param(stmt, my_bind);
1646   check_execute(stmt, rc);
1647 
1648   rc= mysql_stmt_execute(stmt);
1649   check_execute(stmt, rc);
1650 
1651   verify_affected_rows(0);
1652 
1653   mysql_stmt_close(stmt);
1654 
1655   /* now fetch the results ..*/
1656   rc= mysql_commit(mysql);
1657   myquery(rc);
1658 
1659   /* test the results now, only one row should exist */
1660   rc= mysql_query(mysql, "SELECT * FROM test_double_compare");
1661   myquery(rc);
1662 
1663   /* get the result */
1664   result= mysql_store_result(mysql);
1665   mytest(result);
1666 
1667   rc= my_process_result_set(result);
1668   DIE_UNLESS((int)tiny_data == rc);
1669   mysql_free_result(result);
1670 }
1671 
1672 
1673 /* Test simple null */
1674 
test_null()1675 static void test_null()
1676 {
1677   MYSQL_STMT *stmt;
1678   int        rc;
1679   uint       nData;
1680   MYSQL_BIND my_bind[2];
1681   my_bool    is_null[2];
1682   char query[MAX_TEST_QUERY_LENGTH];
1683 
1684   myheader("test_null");
1685 
1686   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_null");
1687   myquery(rc);
1688 
1689   rc= mysql_query(mysql, "CREATE TABLE test_null(col1 int, col2 varchar(50))");
1690   myquery(rc);
1691 
1692   /* insert by prepare, wrong column name */
1693   strmov(query, "INSERT INTO test_null(col3, col2) VALUES(?, ?)");
1694   stmt= mysql_simple_prepare(mysql, query);
1695   check_stmt_r(stmt);
1696 
1697   strmov(query, "INSERT INTO test_null(col1, col2) VALUES(?, ?)");
1698   stmt= mysql_simple_prepare(mysql, query);
1699   check_stmt(stmt);
1700 
1701   verify_param_count(stmt, 2);
1702 
1703   /* Always bzero all members of bind parameter */
1704   bzero((char*) my_bind, sizeof(my_bind));
1705 
1706   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1707   my_bind[0].is_null= &is_null[0];
1708   is_null[0]= 1;
1709   my_bind[1]= my_bind[0];
1710 
1711   rc= mysql_stmt_bind_param(stmt, my_bind);
1712   check_execute(stmt, rc);
1713 
1714   /* now, execute the prepared statement to insert 10 records.. */
1715   for (nData= 0; nData<10; nData++)
1716   {
1717     rc= mysql_stmt_execute(stmt);
1718     check_execute(stmt, rc);
1719   }
1720 
1721   /* Re-bind with MYSQL_TYPE_NULL */
1722   my_bind[0].buffer_type= MYSQL_TYPE_NULL;
1723   is_null[0]= 0; /* reset */
1724   my_bind[1]= my_bind[0];
1725 
1726   rc= mysql_stmt_bind_param(stmt, my_bind);
1727   check_execute(stmt, rc);
1728 
1729   for (nData= 0; nData<10; nData++)
1730   {
1731     rc= mysql_stmt_execute(stmt);
1732     check_execute(stmt, rc);
1733   }
1734 
1735   mysql_stmt_close(stmt);
1736 
1737   /* now fetch the results ..*/
1738   rc= mysql_commit(mysql);
1739   myquery(rc);
1740 
1741   nData*= 2;
1742   rc= my_stmt_result("SELECT * FROM test_null");;
1743   DIE_UNLESS((int) nData == rc);
1744 
1745   /* Fetch results */
1746   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1747   my_bind[0].buffer= (void *)&nData; /* this buffer won't be altered */
1748   my_bind[0].length= 0;
1749   my_bind[1]= my_bind[0];
1750   my_bind[0].is_null= &is_null[0];
1751   my_bind[1].is_null= &is_null[1];
1752 
1753   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_null");
1754   check_stmt(stmt);
1755 
1756   rc= mysql_stmt_execute(stmt);
1757   check_execute(stmt, rc);
1758 
1759   rc= mysql_stmt_bind_result(stmt, my_bind);
1760   check_execute(stmt, rc);
1761 
1762   rc= 0;
1763   is_null[0]= is_null[1]= 0;
1764   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1765   {
1766     DIE_UNLESS(is_null[0]);
1767     DIE_UNLESS(is_null[1]);
1768     rc++;
1769     is_null[0]= is_null[1]= 0;
1770   }
1771   DIE_UNLESS(rc == (int) nData);
1772   mysql_stmt_close(stmt);
1773 }
1774 
1775 
1776 /* Test for NULL as PS parameter (BUG#3367, BUG#3371) */
1777 
test_ps_null_param()1778 static void test_ps_null_param()
1779 {
1780   MYSQL_STMT *stmt;
1781   int        rc;
1782 
1783   MYSQL_BIND in_bind;
1784   my_bool    in_is_null;
1785   long int   in_long;
1786 
1787   MYSQL_BIND out_bind;
1788   ulong      out_length;
1789   my_bool    out_is_null;
1790   char       out_str_data[20];
1791 
1792   const char *queries[]= {"select ?", "select ?+1",
1793                     "select col1 from test_ps_nulls where col1 <=> ?",
1794                     NULL
1795                     };
1796   const char **cur_query= queries;
1797 
1798   myheader("test_null_ps_param_in_result");
1799 
1800   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ps_nulls");
1801   myquery(rc);
1802 
1803   rc= mysql_query(mysql, "CREATE TABLE test_ps_nulls(col1 int)");
1804   myquery(rc);
1805 
1806   rc= mysql_query(mysql, "INSERT INTO test_ps_nulls values (1), (null)");
1807   myquery(rc);
1808 
1809   /* Always bzero all members of bind parameter */
1810   bzero((char*) &in_bind, sizeof(in_bind));
1811   bzero((char*) &out_bind, sizeof(out_bind));
1812 
1813   in_bind.buffer_type= MYSQL_TYPE_LONG;
1814   in_bind.is_null= &in_is_null;
1815   in_bind.length= 0;
1816   in_bind.buffer= (void *)&in_long;
1817   in_is_null= 1;
1818   in_long= 1;
1819 
1820   out_bind.buffer_type= MYSQL_TYPE_STRING;
1821   out_bind.is_null= &out_is_null;
1822   out_bind.length= &out_length;
1823   out_bind.buffer= out_str_data;
1824   out_bind.buffer_length= array_elements(out_str_data);
1825 
1826   /* Execute several queries, all returning NULL in result. */
1827   for(cur_query= queries; *cur_query; cur_query++)
1828   {
1829     char query[MAX_TEST_QUERY_LENGTH];
1830     strmov(query, *cur_query);
1831     stmt= mysql_simple_prepare(mysql, query);
1832     check_stmt(stmt);
1833     verify_param_count(stmt, 1);
1834 
1835     rc= mysql_stmt_bind_param(stmt, &in_bind);
1836     check_execute(stmt, rc);
1837     rc= mysql_stmt_bind_result(stmt, &out_bind);
1838     check_execute(stmt, rc);
1839     rc= mysql_stmt_execute(stmt);
1840     check_execute(stmt, rc);
1841     rc= mysql_stmt_fetch(stmt);
1842     DIE_UNLESS(rc != MYSQL_NO_DATA);
1843     DIE_UNLESS(out_is_null);
1844     rc= mysql_stmt_fetch(stmt);
1845     DIE_UNLESS(rc == MYSQL_NO_DATA);
1846     mysql_stmt_close(stmt);
1847   }
1848 }
1849 
1850 
1851 /* Test fetch null */
1852 
test_fetch_null()1853 static void test_fetch_null()
1854 {
1855   MYSQL_STMT *stmt;
1856   int        rc;
1857   int        i, nData;
1858   MYSQL_BIND my_bind[11];
1859   ulong      length[11];
1860   my_bool    is_null[11];
1861   char query[MAX_TEST_QUERY_LENGTH];
1862 
1863   myheader("test_fetch_null");
1864 
1865   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null");
1866   myquery(rc);
1867 
1868   rc= mysql_query(mysql, "CREATE TABLE test_fetch_null("
1869                          " col1 tinyint, col2 smallint, "
1870                          " col3 int, col4 bigint, "
1871                          " col5 float, col6 double, "
1872                          " col7 date, col8 time, "
1873                          " col9 varbinary(10), "
1874                          " col10 varchar(50), "
1875                          " col11 char(20))");
1876   myquery(rc);
1877 
1878   rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) "
1879                          "VALUES (1000), (88), (389789)");
1880   myquery(rc);
1881 
1882   rc= mysql_commit(mysql);
1883   myquery(rc);
1884 
1885   /* fetch */
1886   bzero((char*) my_bind, sizeof(my_bind));
1887   for (i= 0; i < (int) array_elements(my_bind); i++)
1888   {
1889     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
1890     my_bind[i].is_null= &is_null[i];
1891     my_bind[i].length= &length[i];
1892   }
1893   my_bind[i-1].buffer= (void *)&nData;              /* Last column is not null */
1894 
1895   strmov((char *)query , "SELECT * FROM test_fetch_null");
1896 
1897   rc= my_stmt_result(query);
1898   DIE_UNLESS(rc == 3);
1899 
1900   stmt= mysql_simple_prepare(mysql, query);
1901   check_stmt(stmt);
1902 
1903   rc= mysql_stmt_bind_result(stmt, my_bind);
1904   check_execute(stmt, rc);
1905 
1906   rc= mysql_stmt_execute(stmt);
1907   check_execute(stmt, rc);
1908 
1909   rc= 0;
1910   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1911   {
1912     rc++;
1913     for (i= 0; i < 10; i++)
1914     {
1915       if (!opt_silent)
1916         fprintf(stdout, "\n data[%d] : %s", i,
1917                 is_null[i] ? "NULL" : "NOT NULL");
1918       DIE_UNLESS(is_null[i]);
1919     }
1920     if (!opt_silent)
1921       fprintf(stdout, "\n data[%d]: %d", i, nData);
1922     DIE_UNLESS(nData == 1000 || nData == 88 || nData == 389789);
1923     DIE_UNLESS(is_null[i] == 0);
1924     DIE_UNLESS(length[i] == 4);
1925   }
1926   DIE_UNLESS(rc == 3);
1927   mysql_stmt_close(stmt);
1928 }
1929 
1930 
1931 /* Test simple select */
1932 
test_select_version()1933 static void test_select_version()
1934 {
1935   MYSQL_STMT *stmt;
1936   int        rc;
1937 
1938   myheader("test_select_version");
1939 
1940   stmt= mysql_simple_prepare(mysql, "SELECT @@version");
1941   check_stmt(stmt);
1942 
1943   verify_param_count(stmt, 0);
1944 
1945   rc= mysql_stmt_execute(stmt);
1946   check_execute(stmt, rc);
1947 
1948   my_process_stmt_result(stmt);
1949   mysql_stmt_close(stmt);
1950 }
1951 
1952 
1953 /* Test simple show */
1954 
test_select_show_table()1955 static void test_select_show_table()
1956 {
1957   MYSQL_STMT *stmt;
1958   int        rc, i;
1959 
1960   myheader("test_select_show_table");
1961 
1962   stmt= mysql_simple_prepare(mysql, "SHOW TABLES FROM mysql");
1963   check_stmt(stmt);
1964 
1965   verify_param_count(stmt, 0);
1966 
1967   for (i= 1; i < 3; i++)
1968   {
1969     rc= mysql_stmt_execute(stmt);
1970     check_execute(stmt, rc);
1971   }
1972 
1973   my_process_stmt_result(stmt);
1974   mysql_stmt_close(stmt);
1975 }
1976 
1977 
1978 /* Test simple select to debug */
1979 
test_select_direct()1980 static void test_select_direct()
1981 {
1982   int        rc;
1983   MYSQL_RES  *result;
1984 
1985   myheader("test_select_direct");
1986 
1987   rc= mysql_autocommit(mysql, TRUE);
1988   myquery(rc);
1989 
1990   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
1991   myquery(rc);
1992 
1993   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
1994                                                  " id2 float, "
1995                                                  " id3 double, "
1996                                                  " name varchar(50))");
1997   myquery(rc);
1998 
1999   /* insert a row and commit the transaction */
2000   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')");
2001   myquery(rc);
2002 
2003   rc= mysql_commit(mysql);
2004   myquery(rc);
2005 
2006   rc= mysql_query(mysql, "SELECT * FROM test_select");
2007   myquery(rc);
2008 
2009   /* get the result */
2010   result= mysql_store_result(mysql);
2011   mytest(result);
2012 
2013   (void) my_process_result_set(result);
2014   mysql_free_result(result);
2015 }
2016 
2017 
2018 /* Test simple select with prepare */
2019 
test_select_prepare()2020 static void test_select_prepare()
2021 {
2022   int        rc;
2023   MYSQL_STMT *stmt;
2024 
2025   myheader("test_select_prepare");
2026 
2027   rc= mysql_autocommit(mysql, TRUE);
2028   myquery(rc);
2029 
2030   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2031   myquery(rc);
2032 
2033   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
2034   myquery(rc);
2035 
2036   /* insert a row and commit the transaction */
2037   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
2038   myquery(rc);
2039 
2040   rc= mysql_commit(mysql);
2041   myquery(rc);
2042 
2043   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
2044   check_stmt(stmt);
2045 
2046   rc= mysql_stmt_execute(stmt);
2047   check_execute(stmt, rc);
2048 
2049   rc= my_process_stmt_result(stmt);
2050   DIE_UNLESS(rc == 1);
2051   mysql_stmt_close(stmt);
2052 
2053   rc= mysql_query(mysql, "DROP TABLE test_select");
2054   myquery(rc);
2055 
2056   rc= mysql_query(mysql, "CREATE TABLE test_select(id tinyint, id1 int, "
2057                                                 "  id2 float, id3 float, "
2058                                                 "  name varchar(50))");
2059   myquery(rc);
2060 
2061   /* insert a row and commit the transaction */
2062   rc= mysql_query(mysql, "INSERT INTO test_select(id, id1, id2, name) VALUES(10, 5, 2.3, 'venu')");
2063   myquery(rc);
2064 
2065   rc= mysql_commit(mysql);
2066   myquery(rc);
2067 
2068   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
2069   check_stmt(stmt);
2070 
2071   rc= mysql_stmt_execute(stmt);
2072   check_execute(stmt, rc);
2073 
2074   rc= my_process_stmt_result(stmt);
2075   DIE_UNLESS(rc == 1);
2076   mysql_stmt_close(stmt);
2077 }
2078 
2079 
2080 /* Test simple select */
2081 
test_select()2082 static void test_select()
2083 {
2084   MYSQL_STMT *stmt;
2085   int        rc;
2086   char       szData[25];
2087   int        nData= 1;
2088   MYSQL_BIND my_bind[2];
2089   ulong length[2];
2090   char query[MAX_TEST_QUERY_LENGTH];
2091 
2092   myheader("test_select");
2093 
2094   rc= mysql_autocommit(mysql, TRUE);
2095   myquery(rc);
2096 
2097   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2098   myquery(rc);
2099 
2100   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
2101   myquery(rc);
2102 
2103   /* insert a row and commit the transaction */
2104   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
2105   myquery(rc);
2106 
2107   /* now insert the second row, and roll back the transaction */
2108   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(20, 'mysql')");
2109   myquery(rc);
2110 
2111   rc= mysql_commit(mysql);
2112   myquery(rc);
2113 
2114   strmov(query, "SELECT * FROM test_select WHERE id= ? "
2115                 "AND CONVERT(name USING utf8) =?");
2116   stmt= mysql_simple_prepare(mysql, query);
2117   check_stmt(stmt);
2118 
2119   verify_param_count(stmt, 2);
2120 
2121   /* Always bzero all members of bind parameter */
2122   bzero((char*) my_bind, sizeof(my_bind));
2123 
2124   /* string data */
2125   nData= 10;
2126   strmov(szData, (char *)"venu");
2127   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2128   my_bind[1].buffer= (void *)szData;
2129   my_bind[1].buffer_length= 4;
2130   my_bind[1].length= &length[1];
2131   length[1]= 4;
2132 
2133   my_bind[0].buffer= (void *)&nData;
2134   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2135 
2136   rc= mysql_stmt_bind_param(stmt, my_bind);
2137   check_execute(stmt, rc);
2138 
2139   rc= mysql_stmt_execute(stmt);
2140   check_execute(stmt, rc);
2141 
2142   rc= my_process_stmt_result(stmt);
2143   DIE_UNLESS(rc == 1);
2144 
2145   mysql_stmt_close(stmt);
2146 }
2147 
2148 
2149 /*
2150   Test for BUG#3420 ("select id1, value1 from t where id= ? or value= ?"
2151   returns all rows in the table)
2152 */
2153 
test_ps_conj_select()2154 static void test_ps_conj_select()
2155 {
2156   MYSQL_STMT *stmt;
2157   int        rc;
2158   MYSQL_BIND my_bind[2];
2159   int32      int_data;
2160   char       str_data[32];
2161   unsigned long str_length;
2162   char query[MAX_TEST_QUERY_LENGTH];
2163   myheader("test_ps_conj_select");
2164 
2165   rc= mysql_query(mysql, "drop table if exists t1");
2166   myquery(rc);
2167 
2168   rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2169                          "value2 varchar(100), value1 varchar(100))");
2170   myquery(rc);
2171 
2172   rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2173                           "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2174   myquery(rc);
2175 
2176   strmov(query, "SELECT id1, value1 from t1 where id1= ? or "
2177                 "CONVERT(value1 USING utf8)= ?");
2178   stmt= mysql_simple_prepare(mysql, query);
2179   check_stmt(stmt);
2180 
2181   verify_param_count(stmt, 2);
2182 
2183   /* Always bzero all members of bind parameter */
2184   bzero((char*) my_bind, sizeof(my_bind));
2185 
2186   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2187   my_bind[0].buffer= (void *)&int_data;
2188 
2189   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2190   my_bind[1].buffer= (void *)str_data;
2191   my_bind[1].buffer_length= array_elements(str_data);
2192   my_bind[1].length= &str_length;
2193 
2194   rc= mysql_stmt_bind_param(stmt, my_bind);
2195   check_execute(stmt, rc);
2196 
2197   int_data= 1;
2198   strmov(str_data, "hh");
2199   str_length= strlen(str_data);
2200 
2201   rc= mysql_stmt_execute(stmt);
2202   check_execute(stmt, rc);
2203 
2204   rc= my_process_stmt_result(stmt);
2205   DIE_UNLESS(rc == 3);
2206 
2207   mysql_stmt_close(stmt);
2208 }
2209 
2210 
2211 /* reads Qcache_hits from server and returns its value */
query_cache_hits(MYSQL * conn)2212 static uint query_cache_hits(MYSQL *conn)
2213 {
2214   MYSQL_RES *res;
2215   MYSQL_ROW row;
2216   int rc;
2217   uint result;
2218 
2219   rc= mysql_query(conn, "show status like 'qcache_hits'");
2220   myquery(rc);
2221   res= mysql_use_result(conn);
2222   DIE_UNLESS(res);
2223 
2224   row= mysql_fetch_row(res);
2225   DIE_UNLESS(row);
2226 
2227   result= atoi(row[1]);
2228   mysql_free_result(res);
2229   return result;
2230 }
2231 
2232 
2233 /*
2234   utility for the next test; expects 3 rows in the result from a SELECT,
2235   compares each row/field with an expected value.
2236  */
2237 #define test_ps_query_cache_result(i1,s1,l1,i2,s2,l2,i3,s3,l3)    \
2238   r_metadata= mysql_stmt_result_metadata(stmt);                   \
2239   DIE_UNLESS(r_metadata != NULL);                                 \
2240   rc= mysql_stmt_fetch(stmt);                                     \
2241   check_execute(stmt, rc);                                        \
2242   if (!opt_silent)                                                \
2243     fprintf(stdout, "\n row 1: %d, %s(%lu)", r_int_data,          \
2244             r_str_data, r_str_length);                            \
2245   DIE_UNLESS((r_int_data == i1) && (r_str_length == l1) &&        \
2246              (strcmp(r_str_data, s1) == 0));                      \
2247   rc= mysql_stmt_fetch(stmt);                                     \
2248   check_execute(stmt, rc);                                        \
2249   if (!opt_silent)                                                \
2250     fprintf(stdout, "\n row 2: %d, %s(%lu)", r_int_data,          \
2251             r_str_data, r_str_length);                            \
2252   DIE_UNLESS((r_int_data == i2) && (r_str_length == l2) &&        \
2253              (strcmp(r_str_data, s2) == 0));                      \
2254   rc= mysql_stmt_fetch(stmt);                                     \
2255   check_execute(stmt, rc);                                        \
2256   if (!opt_silent)                                                \
2257     fprintf(stdout, "\n row 3: %d, %s(%lu)", r_int_data,          \
2258             r_str_data, r_str_length);                            \
2259   DIE_UNLESS((r_int_data == i3) && (r_str_length == l3) &&        \
2260              (strcmp(r_str_data, s3) == 0));                      \
2261   rc= mysql_stmt_fetch(stmt);                                     \
2262   DIE_UNLESS(rc == MYSQL_NO_DATA);                                \
2263   mysql_free_result(r_metadata);
2264 
2265 
2266 /*
2267   Check that query cache is available in server.
2268 */
is_query_cache_available()2269 static my_bool is_query_cache_available()
2270 {
2271   int rc;
2272   MYSQL_RES *result;
2273   MYSQL_ROW row;
2274   int res= -1;
2275 
2276   rc= mysql_query(mysql, "SHOW VARIABLES LIKE 'have_query_cache'");
2277   myquery(rc);
2278 
2279   result= mysql_store_result(mysql);
2280   DIE_UNLESS(result);
2281 
2282   row= mysql_fetch_row(result);
2283   DIE_UNLESS(row != NULL);
2284   if (strcmp(row[1], "YES") == 0)
2285     res= 1;
2286   else if (strcmp(row[1], "NO") == 0)
2287     res= 0;
2288   mysql_free_result(result);
2289 
2290   DIE_UNLESS(res == 0 || res == 1);
2291   return res;
2292 }
2293 
2294 /*
2295   Test that prepared statements make use of the query cache just as normal
2296   statements (BUG#735).
2297 */
test_ps_query_cache()2298 static void test_ps_query_cache()
2299 {
2300   MYSQL      *lmysql= mysql;
2301   MYSQL_STMT *stmt;
2302   int        rc;
2303   MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */
2304   int32      p_int_data, r_int_data;
2305   char       p_str_data[32], r_str_data[32];
2306   unsigned long p_str_length, r_str_length;
2307   MYSQL_RES  *r_metadata;
2308   char       query[MAX_TEST_QUERY_LENGTH];
2309   uint       hits1, hits2;
2310   enum enum_test_ps_query_cache
2311   {
2312     /*
2313       We iterate the same prepare/executes block, but have iterations where
2314       we vary the query cache conditions.
2315     */
2316     /* the query cache is enabled for the duration of prep&execs: */
2317     TEST_QCACHE_ON= 0,
2318     /*
2319       same but using a new connection (to see if qcache serves results from
2320       the previous connection as it should):
2321     */
2322     TEST_QCACHE_ON_WITH_OTHER_CONN,
2323     /*
2324       First border case: disables the query cache before prepare and
2325       re-enables it before execution (to test if we have no bug then):
2326     */
2327     TEST_QCACHE_OFF_ON,
2328     /*
2329       Second border case: enables the query cache before prepare and
2330       disables it before execution:
2331     */
2332     TEST_QCACHE_ON_OFF
2333   };
2334   enum enum_test_ps_query_cache iteration;
2335 
2336   myheader("test_ps_query_cache");
2337 
2338   if (! is_query_cache_available())
2339   {
2340     fprintf(stdout, "Skipping test_ps_query_cache: Query cache not available.\n");
2341     return;
2342   }
2343 
2344   rc= mysql_set_character_set(mysql, "utf8");
2345   myquery(rc);
2346 
2347   /* prepare the table */
2348 
2349   rc= mysql_query(mysql, "drop table if exists t1");
2350   myquery(rc);
2351 
2352   rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2353                          "value2 varchar(100), value1 varchar(100))");
2354   myquery(rc);
2355 
2356   rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2357                           "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2358   myquery(rc);
2359 
2360   rc= mysql_query(mysql,
2361                   "set @save_query_cache_type="
2362                   "@@global.query_cache_type,"
2363                   "@save_query_cache_size="
2364                   "@@global.query_cache_size");
2365   myquery(rc);
2366   rc= mysql_query(lmysql, "set global query_cache_type=ON");
2367   myquery(rc);
2368   rc= mysql_query(lmysql, "set local query_cache_type=ON");
2369   myquery(rc);
2370 
2371   for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++)
2372   {
2373 
2374     switch (iteration) {
2375     case TEST_QCACHE_ON:
2376     case TEST_QCACHE_ON_OFF:
2377       rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2378       myquery(rc);
2379       break;
2380     case TEST_QCACHE_OFF_ON:
2381       rc= mysql_query(lmysql, "set global query_cache_size=0");
2382       myquery(rc);
2383       break;
2384     case TEST_QCACHE_ON_WITH_OTHER_CONN:
2385       if (!opt_silent)
2386         fprintf(stdout, "\n Establishing a test connection ...");
2387       if (!(lmysql= mysql_client_init(NULL)))
2388       {
2389         printf("mysql_client_init() failed");
2390         DIE_UNLESS(0);
2391       }
2392       if (!(mysql_real_connect(lmysql, opt_host, opt_user,
2393                                opt_password, current_db, opt_port,
2394                                opt_unix_socket, 0)))
2395       {
2396         printf("connection failed");
2397         mysql_close(lmysql);
2398         DIE_UNLESS(0);
2399       }
2400       rc= mysql_query(lmysql, "SET SQL_MODE=''");
2401       myquery(rc);
2402       rc= mysql_set_character_set(lmysql, "utf8");
2403       myquery(rc);
2404 
2405       if (!opt_silent)
2406         fprintf(stdout, "OK");
2407       break;
2408     }
2409 
2410     strmov(query, "select id1, value1 from t1 where id1= ? or "
2411            "CONVERT(value1 USING utf8)= ?");
2412     stmt= mysql_simple_prepare(lmysql, query);
2413     check_stmt(stmt);
2414 
2415     verify_param_count(stmt, 2);
2416 
2417     switch (iteration) {
2418     case TEST_QCACHE_OFF_ON:
2419       rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2420       myquery(rc);
2421       break;
2422     case TEST_QCACHE_ON_OFF:
2423       rc= mysql_query(lmysql, "set global query_cache_size=0");
2424       myquery(rc);
2425     default:
2426       break;
2427     }
2428 
2429     bzero((char*) p_bind, sizeof(p_bind));
2430     p_bind[0].buffer_type= MYSQL_TYPE_LONG;
2431     p_bind[0].buffer= (void *)&p_int_data;
2432     p_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2433     p_bind[1].buffer= (void *)p_str_data;
2434     p_bind[1].buffer_length= array_elements(p_str_data);
2435     p_bind[1].length= &p_str_length;
2436 
2437     rc= mysql_stmt_bind_param(stmt, p_bind);
2438     check_execute(stmt, rc);
2439 
2440     p_int_data= 1;
2441     strmov(p_str_data, "hh");
2442     p_str_length= strlen(p_str_data);
2443 
2444     bzero((char*) r_bind, sizeof(r_bind));
2445     r_bind[0].buffer_type= MYSQL_TYPE_LONG;
2446     r_bind[0].buffer= (void *)&r_int_data;
2447     r_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2448     r_bind[1].buffer= (void *)r_str_data;
2449     r_bind[1].buffer_length= array_elements(r_str_data);
2450     r_bind[1].length= &r_str_length;
2451 
2452     rc= mysql_stmt_bind_result(stmt, r_bind);
2453     check_execute(stmt, rc);
2454 
2455     rc= mysql_stmt_execute(stmt);
2456     check_execute(stmt, rc);
2457 
2458     test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2459 
2460     /* now retry with the same parameter values and see qcache hits */
2461     hits1= query_cache_hits(lmysql);
2462     rc= mysql_stmt_execute(stmt);
2463     check_execute(stmt, rc);
2464     test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2465     hits2= query_cache_hits(lmysql);
2466     switch(iteration) {
2467     case TEST_QCACHE_ON_WITH_OTHER_CONN:
2468     case TEST_QCACHE_ON:                 /* should have hit */
2469       DIE_UNLESS(hits2-hits1 == 1);
2470       break;
2471     case TEST_QCACHE_OFF_ON:
2472     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2473       DIE_UNLESS(hits2-hits1 == 0);
2474       break;
2475     }
2476 
2477     /* now modify parameter values and see qcache hits */
2478     strmov(p_str_data, "ii");
2479     p_str_length= strlen(p_str_data);
2480     rc= mysql_stmt_execute(stmt);
2481     check_execute(stmt, rc);
2482     test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2483     hits1= query_cache_hits(lmysql);
2484 
2485     switch(iteration) {
2486     case TEST_QCACHE_ON:
2487     case TEST_QCACHE_OFF_ON:
2488     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2489       DIE_UNLESS(hits2-hits1 == 0);
2490       break;
2491     case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2492       DIE_UNLESS(hits1-hits2 == 1);
2493       break;
2494     }
2495 
2496     rc= mysql_stmt_execute(stmt);
2497     check_execute(stmt, rc);
2498 
2499     test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2500     hits2= query_cache_hits(lmysql);
2501 
2502     mysql_stmt_close(stmt);
2503 
2504     switch(iteration) {
2505     case TEST_QCACHE_ON:                 /* should have hit */
2506       DIE_UNLESS(hits2-hits1 == 1);
2507       break;
2508     case TEST_QCACHE_OFF_ON:
2509     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2510       DIE_UNLESS(hits2-hits1 == 0);
2511       break;
2512     case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2513       DIE_UNLESS(hits2-hits1 == 1);
2514       break;
2515     }
2516 
2517   } /* for(iteration=...) */
2518 
2519   if (lmysql != mysql)
2520     mysql_close(lmysql);
2521 
2522   rc= mysql_query(mysql, "set global query_cache_size=@save_query_cache_size");
2523   myquery(rc);
2524   rc= mysql_query(mysql, "set global query_cache_type=@save_query_cache_type");
2525   myquery(rc);
2526 }
2527 
2528 
2529 /* Test BUG#1115 (incorrect string parameter value allocation) */
2530 
test_bug1115()2531 static void test_bug1115()
2532 {
2533   MYSQL_STMT *stmt;
2534   int rc;
2535   MYSQL_BIND my_bind[1];
2536   ulong length[1];
2537   char szData[11];
2538   char query[MAX_TEST_QUERY_LENGTH];
2539 
2540   myheader("test_bug1115");
2541 
2542   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2543   myquery(rc);
2544 
2545   rc= mysql_query(mysql, "CREATE TABLE test_select(\
2546 session_id  char(9) NOT NULL, \
2547     a       int(8) unsigned NOT NULL, \
2548     b        int(5) NOT NULL, \
2549     c      int(5) NOT NULL, \
2550     d  datetime NOT NULL)");
2551   myquery(rc);
2552   rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2553                          "(\"abc\", 1, 2, 3, 2003-08-30), "
2554                          "(\"abd\", 1, 2, 3, 2003-08-30), "
2555                          "(\"abf\", 1, 2, 3, 2003-08-30), "
2556                          "(\"abg\", 1, 2, 3, 2003-08-30), "
2557                          "(\"abh\", 1, 2, 3, 2003-08-30), "
2558                          "(\"abj\", 1, 2, 3, 2003-08-30), "
2559                          "(\"abk\", 1, 2, 3, 2003-08-30), "
2560                          "(\"abl\", 1, 2, 3, 2003-08-30), "
2561                          "(\"abq\", 1, 2, 3, 2003-08-30) ");
2562   myquery(rc);
2563   rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2564                          "(\"abw\", 1, 2, 3, 2003-08-30), "
2565                          "(\"abe\", 1, 2, 3, 2003-08-30), "
2566                          "(\"abr\", 1, 2, 3, 2003-08-30), "
2567                          "(\"abt\", 1, 2, 3, 2003-08-30), "
2568                          "(\"aby\", 1, 2, 3, 2003-08-30), "
2569                          "(\"abu\", 1, 2, 3, 2003-08-30), "
2570                          "(\"abi\", 1, 2, 3, 2003-08-30), "
2571                          "(\"abo\", 1, 2, 3, 2003-08-30), "
2572                          "(\"abp\", 1, 2, 3, 2003-08-30), "
2573                          "(\"abz\", 1, 2, 3, 2003-08-30), "
2574                          "(\"abx\", 1, 2, 3, 2003-08-30)");
2575   myquery(rc);
2576 
2577   strmov(query, "SELECT * FROM test_select WHERE "
2578                 "CONVERT(session_id USING utf8)= ?");
2579   stmt= mysql_simple_prepare(mysql, query);
2580   check_stmt(stmt);
2581 
2582   verify_param_count(stmt, 1);
2583 
2584   /* Always bzero all members of bind parameter */
2585   bzero((char*) my_bind, sizeof(my_bind));
2586 
2587   strmov(szData, (char *)"abc");
2588   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2589   my_bind[0].buffer= (void *)szData;
2590   my_bind[0].buffer_length= 10;
2591   my_bind[0].length= &length[0];
2592   length[0]= 3;
2593 
2594   rc= mysql_stmt_bind_param(stmt, my_bind);
2595   check_execute(stmt, rc);
2596 
2597   rc= mysql_stmt_execute(stmt);
2598   check_execute(stmt, rc);
2599 
2600   rc= my_process_stmt_result(stmt);
2601   DIE_UNLESS(rc == 1);
2602 
2603   strmov(szData, (char *)"venu");
2604   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2605   my_bind[0].buffer= (void *)szData;
2606   my_bind[0].buffer_length= 10;
2607   my_bind[0].length= &length[0];
2608   length[0]= 4;
2609   my_bind[0].is_null= 0;
2610 
2611   rc= mysql_stmt_bind_param(stmt, my_bind);
2612   check_execute(stmt, rc);
2613 
2614   rc= mysql_stmt_execute(stmt);
2615   check_execute(stmt, rc);
2616 
2617   rc= my_process_stmt_result(stmt);
2618   DIE_UNLESS(rc == 0);
2619 
2620   strmov(szData, (char *)"abc");
2621   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2622   my_bind[0].buffer= (void *)szData;
2623   my_bind[0].buffer_length= 10;
2624   my_bind[0].length= &length[0];
2625   length[0]= 3;
2626   my_bind[0].is_null= 0;
2627 
2628   rc= mysql_stmt_bind_param(stmt, my_bind);
2629   check_execute(stmt, rc);
2630 
2631   rc= mysql_stmt_execute(stmt);
2632   check_execute(stmt, rc);
2633 
2634   rc= my_process_stmt_result(stmt);
2635   DIE_UNLESS(rc == 1);
2636 
2637   mysql_stmt_close(stmt);
2638 }
2639 
2640 
2641 /* Test BUG#1180 (optimized away part of WHERE clause) */
2642 
test_bug1180()2643 static void test_bug1180()
2644 {
2645   MYSQL_STMT *stmt;
2646   int rc;
2647   MYSQL_BIND my_bind[1];
2648   ulong length[1];
2649   char szData[11];
2650   char query[MAX_TEST_QUERY_LENGTH];
2651 
2652   myheader("test_select_bug");
2653 
2654   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2655   myquery(rc);
2656 
2657   rc= mysql_query(mysql, "CREATE TABLE test_select(session_id  char(9) NOT NULL)");
2658   myquery(rc);
2659   rc= mysql_query(mysql, "INSERT INTO test_select VALUES (\"abc\")");
2660   myquery(rc);
2661 
2662   strmov(query, "SELECT * FROM test_select WHERE ?= \"1111\" and "
2663                 "session_id= \"abc\"");
2664   stmt= mysql_simple_prepare(mysql, query);
2665   check_stmt(stmt);
2666 
2667   verify_param_count(stmt, 1);
2668 
2669   /* Always bzero all members of bind parameter */
2670   bzero((char*) my_bind, sizeof(my_bind));
2671 
2672   strmov(szData, (char *)"abc");
2673   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2674   my_bind[0].buffer= (void *)szData;
2675   my_bind[0].buffer_length= 10;
2676   my_bind[0].length= &length[0];
2677   length[0]= 3;
2678   my_bind[0].is_null= 0;
2679 
2680   rc= mysql_stmt_bind_param(stmt, my_bind);
2681   check_execute(stmt, rc);
2682 
2683   rc= mysql_stmt_execute(stmt);
2684   check_execute(stmt, rc);
2685 
2686   rc= my_process_stmt_result(stmt);
2687   DIE_UNLESS(rc == 0);
2688 
2689   strmov(szData, (char *)"1111");
2690   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2691   my_bind[0].buffer= (void *)szData;
2692   my_bind[0].buffer_length= 10;
2693   my_bind[0].length= &length[0];
2694   length[0]= 4;
2695   my_bind[0].is_null= 0;
2696 
2697   rc= mysql_stmt_bind_param(stmt, my_bind);
2698   check_execute(stmt, rc);
2699 
2700   rc= mysql_stmt_execute(stmt);
2701   check_execute(stmt, rc);
2702 
2703   rc= my_process_stmt_result(stmt);
2704   DIE_UNLESS(rc == 1);
2705 
2706   strmov(szData, (char *)"abc");
2707   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2708   my_bind[0].buffer= (void *)szData;
2709   my_bind[0].buffer_length= 10;
2710   my_bind[0].length= &length[0];
2711   length[0]= 3;
2712   my_bind[0].is_null= 0;
2713 
2714   rc= mysql_stmt_bind_param(stmt, my_bind);
2715   check_execute(stmt, rc);
2716 
2717   rc= mysql_stmt_execute(stmt);
2718   check_execute(stmt, rc);
2719 
2720   rc= my_process_stmt_result(stmt);
2721   DIE_UNLESS(rc == 0);
2722 
2723   mysql_stmt_close(stmt);
2724 }
2725 
2726 
2727 /*
2728   Test BUG#1644 (Insertion of more than 3 NULL columns with parameter
2729   binding fails)
2730 */
2731 
test_bug1644()2732 static void test_bug1644()
2733 {
2734   MYSQL_STMT *stmt;
2735   MYSQL_RES *result;
2736   MYSQL_ROW row;
2737   MYSQL_BIND my_bind[4];
2738   int num;
2739   my_bool isnull;
2740   int rc, i;
2741   char query[MAX_TEST_QUERY_LENGTH];
2742 
2743   myheader("test_bug1644");
2744 
2745   rc= mysql_query(mysql, "DROP TABLE IF EXISTS foo_dfr");
2746   myquery(rc);
2747 
2748   rc= mysql_query(mysql,
2749            "CREATE TABLE foo_dfr(col1 int, col2 int, col3 int, col4 int);");
2750   myquery(rc);
2751 
2752   strmov(query, "INSERT INTO foo_dfr VALUES (?, ?, ?, ? )");
2753   stmt= mysql_simple_prepare(mysql, query);
2754   check_stmt(stmt);
2755 
2756   verify_param_count(stmt, 4);
2757 
2758   /* Always bzero all members of bind parameter */
2759   bzero((char*) my_bind, sizeof(my_bind));
2760 
2761   num= 22;
2762   isnull= 0;
2763   for (i= 0 ; i < 4 ; i++)
2764   {
2765     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
2766     my_bind[i].buffer= (void *)&num;
2767     my_bind[i].is_null= &isnull;
2768   }
2769 
2770   rc= mysql_stmt_bind_param(stmt, my_bind);
2771   check_execute(stmt, rc);
2772 
2773   rc= mysql_stmt_execute(stmt);
2774   check_execute(stmt, rc);
2775 
2776   isnull= 1;
2777   for (i= 0 ; i < 4 ; i++)
2778     my_bind[i].is_null= &isnull;
2779 
2780   rc= mysql_stmt_bind_param(stmt, my_bind);
2781   check_execute(stmt, rc);
2782 
2783   rc= mysql_stmt_execute(stmt);
2784   check_execute(stmt, rc);
2785 
2786   isnull= 0;
2787   num= 88;
2788   for (i= 0 ; i < 4 ; i++)
2789     my_bind[i].is_null= &isnull;
2790 
2791   rc= mysql_stmt_bind_param(stmt, my_bind);
2792   check_execute(stmt, rc);
2793 
2794   rc= mysql_stmt_execute(stmt);
2795   check_execute(stmt, rc);
2796 
2797   mysql_stmt_close(stmt);
2798 
2799   rc= mysql_query(mysql, "SELECT * FROM foo_dfr");
2800   myquery(rc);
2801 
2802   result= mysql_store_result(mysql);
2803   mytest(result);
2804 
2805   rc= my_process_result_set(result);
2806   DIE_UNLESS(rc == 3);
2807 
2808   mysql_data_seek(result, 0);
2809 
2810   row= mysql_fetch_row(result);
2811   mytest(row);
2812   for (i= 0 ; i < 4 ; i++)
2813   {
2814     DIE_UNLESS(strcmp(row[i], "22") == 0);
2815   }
2816   row= mysql_fetch_row(result);
2817   mytest(row);
2818   for (i= 0 ; i < 4 ; i++)
2819   {
2820     DIE_UNLESS(row[i] == 0);
2821   }
2822   row= mysql_fetch_row(result);
2823   mytest(row);
2824   for (i= 0 ; i < 4 ; i++)
2825   {
2826     DIE_UNLESS(strcmp(row[i], "88") == 0);
2827   }
2828   row= mysql_fetch_row(result);
2829   mytest_r(row);
2830 
2831   mysql_free_result(result);
2832 }
2833 
2834 
2835 /* Test simple select show */
2836 
test_select_show()2837 static void test_select_show()
2838 {
2839   MYSQL_STMT *stmt;
2840   int        rc;
2841   char query[MAX_TEST_QUERY_LENGTH];
2842 
2843   myheader("test_select_show");
2844 
2845   mysql_autocommit(mysql, TRUE);
2846 
2847   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_show");
2848   myquery(rc);
2849 
2850   rc= mysql_query(mysql, "CREATE TABLE test_show(id int(4) NOT NULL primary "
2851                          " key, name char(2))");
2852   myquery(rc);
2853 
2854   stmt= mysql_simple_prepare(mysql, "show columns from test_show");
2855   check_stmt(stmt);
2856 
2857   verify_param_count(stmt, 0);
2858 
2859   rc= mysql_stmt_execute(stmt);
2860   check_execute(stmt, rc);
2861 
2862   my_process_stmt_result(stmt);
2863   mysql_stmt_close(stmt);
2864 
2865   stmt= mysql_simple_prepare(mysql, "show tables from mysql like ?");
2866   check_stmt_r(stmt);
2867 
2868   strxmov(query, "show tables from ", current_db, " like \'test_show\'", NullS);
2869   stmt= mysql_simple_prepare(mysql, query);
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, "describe test_show");
2879   check_stmt(stmt);
2880 
2881   rc= mysql_stmt_execute(stmt);
2882   check_execute(stmt, rc);
2883 
2884   my_process_stmt_result(stmt);
2885   mysql_stmt_close(stmt);
2886 
2887   stmt= mysql_simple_prepare(mysql, "show keys from test_show");
2888   check_stmt(stmt);
2889 
2890   rc= mysql_stmt_execute(stmt);
2891   check_execute(stmt, rc);
2892 
2893   rc= my_process_stmt_result(stmt);
2894   DIE_UNLESS(rc == 1);
2895   mysql_stmt_close(stmt);
2896 }
2897 
2898 
2899 /* Test simple update */
2900 
test_simple_update()2901 static void test_simple_update()
2902 {
2903   MYSQL_STMT *stmt;
2904   int        rc;
2905   char       szData[25];
2906   int        nData= 1;
2907   MYSQL_RES  *result;
2908   MYSQL_BIND my_bind[2];
2909   ulong      length[2];
2910   char query[MAX_TEST_QUERY_LENGTH];
2911 
2912   myheader("test_simple_update");
2913 
2914   rc= mysql_autocommit(mysql, TRUE);
2915   myquery(rc);
2916 
2917   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
2918   myquery(rc);
2919 
2920   rc= mysql_query(mysql, "CREATE TABLE test_update(col1 int, "
2921                          " col2 varchar(50), col3 int )");
2922   myquery(rc);
2923 
2924   rc= mysql_query(mysql, "INSERT INTO test_update VALUES(1, 'MySQL', 100)");
2925   myquery(rc);
2926 
2927   verify_affected_rows(1);
2928 
2929   rc= mysql_commit(mysql);
2930   myquery(rc);
2931 
2932   /* insert by prepare */
2933   strmov(query, "UPDATE test_update SET col2= ? WHERE col1= ?");
2934   stmt= mysql_simple_prepare(mysql, query);
2935   check_stmt(stmt);
2936 
2937   verify_param_count(stmt, 2);
2938 
2939   /* Always bzero all members of bind parameter */
2940   bzero((char*) my_bind, sizeof(my_bind));
2941 
2942   nData= 1;
2943   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2944   my_bind[0].buffer= szData;                /* string data */
2945   my_bind[0].buffer_length= sizeof(szData);
2946   my_bind[0].length= &length[0];
2947   length[0]= sprintf(szData, "updated-data");
2948 
2949   my_bind[1].buffer= (void *) &nData;
2950   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
2951 
2952   rc= mysql_stmt_bind_param(stmt, my_bind);
2953   check_execute(stmt, rc);
2954 
2955   rc= mysql_stmt_execute(stmt);
2956   check_execute(stmt, rc);
2957   verify_affected_rows(1);
2958 
2959   mysql_stmt_close(stmt);
2960 
2961   /* now fetch the results ..*/
2962   rc= mysql_commit(mysql);
2963   myquery(rc);
2964 
2965   /* test the results now, only one row should exist */
2966   rc= mysql_query(mysql, "SELECT * FROM test_update");
2967   myquery(rc);
2968 
2969   /* get the result */
2970   result= mysql_store_result(mysql);
2971   mytest(result);
2972 
2973   rc= my_process_result_set(result);
2974   DIE_UNLESS(rc == 1);
2975   mysql_free_result(result);
2976 }
2977 
2978 
2979 /* Test simple long data handling */
2980 
test_long_data()2981 static void test_long_data()
2982 {
2983   MYSQL_STMT *stmt;
2984   int        rc, int_data;
2985   char       *data= NullS;
2986   MYSQL_RES  *result;
2987   MYSQL_BIND my_bind[3];
2988   char query[MAX_TEST_QUERY_LENGTH];
2989 
2990   myheader("test_long_data");
2991 
2992   rc= mysql_autocommit(mysql, TRUE);
2993   myquery(rc);
2994 
2995   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
2996   myquery(rc);
2997 
2998   rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, "
2999                          "      col2 long varchar, col3 long varbinary)");
3000   myquery(rc);
3001 
3002   strmov(query, "INSERT INTO test_long_data(col1, col2) VALUES(?)");
3003   stmt= mysql_simple_prepare(mysql, query);
3004   check_stmt_r(stmt);
3005 
3006   strmov(query, "INSERT INTO test_long_data(col1, col2, col3) VALUES(?, ?, ?)");
3007   stmt= mysql_simple_prepare(mysql, query);
3008   check_stmt(stmt);
3009 
3010   verify_param_count(stmt, 3);
3011 
3012   /* Always bzero all members of bind parameter */
3013   bzero((char*) my_bind, sizeof(my_bind));
3014 
3015   my_bind[0].buffer= (void *)&int_data;
3016   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3017 
3018   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3019 
3020   my_bind[2]= my_bind[1];
3021   rc= mysql_stmt_bind_param(stmt, my_bind);
3022   check_execute(stmt, rc);
3023 
3024   int_data= 999;
3025   data= (char *)"Michael";
3026 
3027   /* supply data in pieces */
3028   rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
3029   data= (char *)" 'Monty' Widenius";
3030   rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
3031   check_execute(stmt, rc);
3032   rc= mysql_stmt_send_long_data(stmt, 2, "Venu (venu@mysql.com)", 4);
3033   check_execute(stmt, rc);
3034 
3035   /* execute */
3036   rc= mysql_stmt_execute(stmt);
3037   if (!opt_silent)
3038     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3039   check_execute(stmt, rc);
3040 
3041   rc= mysql_commit(mysql);
3042   myquery(rc);
3043 
3044   /* now fetch the results ..*/
3045   rc= mysql_query(mysql, "SELECT * FROM test_long_data");
3046   myquery(rc);
3047 
3048   /* get the result */
3049   result= mysql_store_result(mysql);
3050   mytest(result);
3051 
3052   rc= my_process_result_set(result);
3053   DIE_UNLESS(rc == 1);
3054   mysql_free_result(result);
3055 
3056   verify_col_data("test_long_data", "col1", "999");
3057   verify_col_data("test_long_data", "col2", "Michael 'Monty' Widenius");
3058   verify_col_data("test_long_data", "col3", "Venu");
3059   mysql_stmt_close(stmt);
3060 }
3061 
3062 
3063 /* Test long data (string) handling */
3064 
test_long_data_str()3065 static void test_long_data_str()
3066 {
3067   MYSQL_STMT *stmt;
3068   int        rc, i;
3069   char       data[255];
3070   long       length;
3071   ulong      length1;
3072   MYSQL_RES  *result;
3073   MYSQL_BIND my_bind[2];
3074   my_bool    is_null[2];
3075   char query[MAX_TEST_QUERY_LENGTH];
3076 
3077   myheader("test_long_data_str");
3078 
3079   rc= mysql_autocommit(mysql, TRUE);
3080   myquery(rc);
3081 
3082   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
3083   myquery(rc);
3084 
3085   rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(id int, longstr long varchar)");
3086   myquery(rc);
3087 
3088   strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
3089   stmt= mysql_simple_prepare(mysql, query);
3090   check_stmt(stmt);
3091 
3092   verify_param_count(stmt, 2);
3093 
3094   /* Always bzero all members of bind parameter */
3095   bzero((char*) my_bind, sizeof(my_bind));
3096 
3097   my_bind[0].buffer= (void *)&length;
3098   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3099   my_bind[0].is_null= &is_null[0];
3100   is_null[0]= 0;
3101   length= 0;
3102 
3103   my_bind[1].buffer= data;                          /* string data */
3104   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3105   my_bind[1].length= &length1;
3106   my_bind[1].is_null= &is_null[1];
3107   is_null[1]= 0;
3108   rc= mysql_stmt_bind_param(stmt, my_bind);
3109   check_execute(stmt, rc);
3110 
3111   length= 40;
3112   strmov(data, "MySQL AB");
3113 
3114   /* supply data in pieces */
3115   for(i= 0; i < 4; i++)
3116   {
3117     rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 5);
3118     check_execute(stmt, rc);
3119   }
3120   /* execute */
3121   rc= mysql_stmt_execute(stmt);
3122   if (!opt_silent)
3123     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3124   check_execute(stmt, rc);
3125 
3126   mysql_stmt_close(stmt);
3127 
3128   rc= mysql_commit(mysql);
3129   myquery(rc);
3130 
3131   /* now fetch the results ..*/
3132   rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr FROM test_long_data_str");
3133   myquery(rc);
3134 
3135   /* get the result */
3136   result= mysql_store_result(mysql);
3137   mytest(result);
3138 
3139   rc= my_process_result_set(result);
3140   DIE_UNLESS(rc == 1);
3141   mysql_free_result(result);
3142 
3143   sprintf(data, "%d", i*5);
3144   verify_col_data("test_long_data_str", "LENGTH(longstr)", data);
3145   data[0]= '\0';
3146   while (i--)
3147    strxmov(data, data, "MySQL", NullS);
3148   verify_col_data("test_long_data_str", "longstr", data);
3149 
3150   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3151   myquery(rc);
3152 }
3153 
3154 
3155 /* Test long data (string) handling */
3156 
test_long_data_str1()3157 static void test_long_data_str1()
3158 {
3159   MYSQL_STMT *stmt;
3160   int        rc, i;
3161   char       data[255];
3162   long       length;
3163   ulong      max_blob_length, blob_length= 0, length1;
3164   my_bool    true_value;
3165   MYSQL_RES  *result;
3166   MYSQL_BIND my_bind[2];
3167   MYSQL_FIELD *field;
3168   char query[MAX_TEST_QUERY_LENGTH];
3169 
3170   myheader("test_long_data_str1");
3171 
3172   rc= mysql_autocommit(mysql, TRUE);
3173   myquery(rc);
3174 
3175   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
3176   myquery(rc);
3177 
3178   rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(longstr long varchar, blb long varbinary)");
3179   myquery(rc);
3180 
3181   strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
3182   stmt= mysql_simple_prepare(mysql, query);
3183   check_stmt(stmt);
3184 
3185   verify_param_count(stmt, 2);
3186 
3187   /* Always bzero all members of bind parameter */
3188   bzero((char*) my_bind, sizeof(my_bind));
3189 
3190   my_bind[0].buffer= data;            /* string data */
3191   my_bind[0].buffer_length= sizeof(data);
3192   my_bind[0].length= &length1;
3193   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3194   length1= 0;
3195 
3196   my_bind[1]= my_bind[0];
3197   my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3198 
3199   rc= mysql_stmt_bind_param(stmt, my_bind);
3200   check_execute(stmt, rc);
3201   length= sprintf(data, "MySQL AB");
3202 
3203   /* supply data in pieces */
3204   for (i= 0; i < 3; i++)
3205   {
3206     rc= mysql_stmt_send_long_data(stmt, 0, data, length);
3207     check_execute(stmt, rc);
3208 
3209     rc= mysql_stmt_send_long_data(stmt, 1, data, 2);
3210     check_execute(stmt, rc);
3211   }
3212 
3213   /* execute */
3214   rc= mysql_stmt_execute(stmt);
3215   if (!opt_silent)
3216     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3217   check_execute(stmt, rc);
3218 
3219   mysql_stmt_close(stmt);
3220 
3221   rc= mysql_commit(mysql);
3222   myquery(rc);
3223 
3224   /* now fetch the results ..*/
3225   rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr, LENGTH(blb), blb FROM test_long_data_str");
3226   myquery(rc);
3227 
3228   /* get the result */
3229   result= mysql_store_result(mysql);
3230 
3231   mysql_field_seek(result, 1);
3232   field= mysql_fetch_field(result);
3233   max_blob_length= field->max_length;
3234 
3235   mytest(result);
3236 
3237   rc= my_process_result_set(result);
3238   DIE_UNLESS(rc == 1);
3239   mysql_free_result(result);
3240 
3241   sprintf(data, "%ld", (long)i*length);
3242   verify_col_data("test_long_data_str", "length(longstr)", data);
3243 
3244   sprintf(data, "%d", i*2);
3245   verify_col_data("test_long_data_str", "length(blb)", data);
3246 
3247   /* Test length of field->max_length */
3248   stmt= mysql_simple_prepare(mysql, "SELECT * from test_long_data_str");
3249   check_stmt(stmt);
3250   verify_param_count(stmt, 0);
3251 
3252   rc= mysql_stmt_execute(stmt);
3253   check_execute(stmt, rc);
3254 
3255   rc= mysql_stmt_store_result(stmt);
3256   check_execute(stmt, rc);
3257 
3258   result= mysql_stmt_result_metadata(stmt);
3259   field= mysql_fetch_fields(result);
3260 
3261   /* First test what happens if STMT_ATTR_UPDATE_MAX_LENGTH is not used */
3262   DIE_UNLESS(field->max_length == 0);
3263   mysql_free_result(result);
3264 
3265   /* Enable updating of field->max_length */
3266   true_value= 1;
3267   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &true_value);
3268   rc= mysql_stmt_execute(stmt);
3269   check_execute(stmt, rc);
3270 
3271   rc= mysql_stmt_store_result(stmt);
3272   check_execute(stmt, rc);
3273 
3274   result= mysql_stmt_result_metadata(stmt);
3275   field= mysql_fetch_fields(result);
3276 
3277   DIE_UNLESS(field->max_length == max_blob_length);
3278 
3279   /* Fetch results into a data buffer that is smaller than data */
3280   bzero((char*) my_bind, sizeof(*my_bind));
3281   my_bind[0].buffer_type= MYSQL_TYPE_BLOB;
3282   my_bind[0].buffer= (void *) &data; /* this buffer won't be altered */
3283   my_bind[0].buffer_length= 16;
3284   my_bind[0].length= &blob_length;
3285   my_bind[0].error= &my_bind[0].error_value;
3286   rc= mysql_stmt_bind_result(stmt, my_bind);
3287   data[16]= 0;
3288 
3289   rc= mysql_stmt_fetch(stmt);
3290   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
3291   DIE_UNLESS(my_bind[0].error_value);
3292   DIE_UNLESS(strlen(data) == 16);
3293   DIE_UNLESS(blob_length == max_blob_length);
3294 
3295   /* Fetch all data */
3296   bzero((char*) (my_bind+1), sizeof(*my_bind));
3297   my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3298   my_bind[1].buffer= (void *) &data; /* this buffer won't be altered */
3299   my_bind[1].buffer_length= sizeof(data);
3300   my_bind[1].length= &blob_length;
3301   bzero(data, sizeof(data));
3302   mysql_stmt_fetch_column(stmt, my_bind+1, 0, 0);
3303   DIE_UNLESS(strlen(data) == max_blob_length);
3304 
3305   mysql_free_result(result);
3306   mysql_stmt_close(stmt);
3307 
3308   /* Drop created table */
3309   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3310   myquery(rc);
3311 }
3312 
3313 
3314 /* Test long data (binary) handling */
3315 
test_long_data_bin()3316 static void test_long_data_bin()
3317 {
3318   MYSQL_STMT *stmt;
3319   int        rc;
3320   char       data[255];
3321   long       length;
3322   MYSQL_RES  *result;
3323   MYSQL_BIND my_bind[2];
3324   char query[MAX_TEST_QUERY_LENGTH];
3325 
3326 
3327   myheader("test_long_data_bin");
3328 
3329   rc= mysql_autocommit(mysql, TRUE);
3330   myquery(rc);
3331 
3332   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_bin");
3333   myquery(rc);
3334 
3335   rc= mysql_query(mysql, "CREATE TABLE test_long_data_bin(id int, longbin long varbinary)");
3336   myquery(rc);
3337 
3338   strmov(query, "INSERT INTO test_long_data_bin VALUES(?, ?)");
3339   stmt= mysql_simple_prepare(mysql, query);
3340   check_stmt(stmt);
3341 
3342   verify_param_count(stmt, 2);
3343 
3344   /* Always bzero all members of bind parameter */
3345   bzero((char*) my_bind, sizeof(my_bind));
3346 
3347   my_bind[0].buffer= (void *)&length;
3348   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3349   length= 0;
3350 
3351   my_bind[1].buffer= data;           /* string data */
3352   my_bind[1].buffer_type= MYSQL_TYPE_LONG_BLOB;
3353   rc= mysql_stmt_bind_param(stmt, my_bind);
3354   check_execute(stmt, rc);
3355 
3356   length= 10;
3357   strmov(data, "MySQL AB");
3358 
3359   /* supply data in pieces */
3360   {
3361     int i;
3362     for (i= 0; i < 100; i++)
3363     {
3364       rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 4);
3365       check_execute(stmt, rc);
3366     }
3367   }
3368   /* execute */
3369   rc= mysql_stmt_execute(stmt);
3370   if (!opt_silent)
3371     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3372   check_execute(stmt, rc);
3373 
3374   mysql_stmt_close(stmt);
3375 
3376   rc= mysql_commit(mysql);
3377   myquery(rc);
3378 
3379   /* now fetch the results ..*/
3380   rc= mysql_query(mysql, "SELECT LENGTH(longbin), longbin FROM test_long_data_bin");
3381   myquery(rc);
3382 
3383   /* get the result */
3384   result= mysql_store_result(mysql);
3385   mytest(result);
3386 
3387   rc= my_process_result_set(result);
3388   DIE_UNLESS(rc == 1);
3389   mysql_free_result(result);
3390 }
3391 
3392 
3393 /* Test simple delete */
3394 
test_simple_delete()3395 static void test_simple_delete()
3396 {
3397   MYSQL_STMT *stmt;
3398   int        rc;
3399   char       szData[30]= {0};
3400   int        nData= 1;
3401   MYSQL_RES  *result;
3402   MYSQL_BIND my_bind[2];
3403   ulong length[2];
3404   char query[MAX_TEST_QUERY_LENGTH];
3405 
3406   myheader("test_simple_delete");
3407 
3408   rc= mysql_autocommit(mysql, TRUE);
3409   myquery(rc);
3410 
3411   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_simple_delete");
3412   myquery(rc);
3413 
3414   rc= mysql_query(mysql, "CREATE TABLE test_simple_delete(col1 int, \
3415                                 col2 varchar(50), col3 int )");
3416   myquery(rc);
3417 
3418   rc= mysql_query(mysql, "INSERT INTO test_simple_delete VALUES(1, 'MySQL', 100)");
3419   myquery(rc);
3420 
3421   verify_affected_rows(1);
3422 
3423   rc= mysql_commit(mysql);
3424   myquery(rc);
3425 
3426   /* insert by prepare */
3427   strmov(query, "DELETE FROM test_simple_delete WHERE col1= ? AND "
3428                 "CONVERT(col2 USING utf8)= ? AND col3= 100");
3429   stmt= mysql_simple_prepare(mysql, query);
3430   check_stmt(stmt);
3431 
3432   verify_param_count(stmt, 2);
3433 
3434   /* Always bzero all members of bind parameter */
3435   bzero((char*) my_bind, sizeof(my_bind));
3436 
3437   nData= 1;
3438   strmov(szData, "MySQL");
3439   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3440   my_bind[1].buffer= szData;               /* string data */
3441   my_bind[1].buffer_length= sizeof(szData);
3442   my_bind[1].length= &length[1];
3443   length[1]= 5;
3444 
3445   my_bind[0].buffer= (void *)&nData;
3446   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3447 
3448   rc= mysql_stmt_bind_param(stmt, my_bind);
3449   check_execute(stmt, rc);
3450 
3451   rc= mysql_stmt_execute(stmt);
3452   check_execute(stmt, rc);
3453 
3454   verify_affected_rows(1);
3455 
3456   mysql_stmt_close(stmt);
3457 
3458   /* now fetch the results ..*/
3459   rc= mysql_commit(mysql);
3460   myquery(rc);
3461 
3462   /* test the results now, only one row should exist */
3463   rc= mysql_query(mysql, "SELECT * FROM test_simple_delete");
3464   myquery(rc);
3465 
3466   /* get the result */
3467   result= mysql_store_result(mysql);
3468   mytest(result);
3469 
3470   rc= my_process_result_set(result);
3471   DIE_UNLESS(rc == 0);
3472   mysql_free_result(result);
3473 }
3474 
3475 
3476 /* Test simple update */
3477 
test_update()3478 static void test_update()
3479 {
3480   MYSQL_STMT *stmt;
3481   int        rc;
3482   char       szData[25];
3483   int        nData= 1;
3484   MYSQL_RES  *result;
3485   MYSQL_BIND my_bind[2];
3486   ulong length[2];
3487   char query[MAX_TEST_QUERY_LENGTH];
3488 
3489   myheader("test_update");
3490 
3491   rc= mysql_autocommit(mysql, TRUE);
3492   myquery(rc);
3493 
3494   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
3495   myquery(rc);
3496 
3497   rc= mysql_query(mysql, "CREATE TABLE test_update("
3498                                "col1 int primary key auto_increment, "
3499                                "col2 varchar(50), col3 int )");
3500   myquery(rc);
3501 
3502   strmov(query, "INSERT INTO test_update(col2, col3) VALUES(?, ?)");
3503   stmt= mysql_simple_prepare(mysql, query);
3504   check_stmt(stmt);
3505 
3506   verify_param_count(stmt, 2);
3507 
3508   /* Always bzero all members of bind parameter */
3509   bzero((char*) my_bind, sizeof(my_bind));
3510 
3511   /* string data */
3512   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3513   my_bind[0].buffer= szData;
3514   my_bind[0].buffer_length= sizeof(szData);
3515   my_bind[0].length= &length[0];
3516   length[0]= sprintf(szData, "inserted-data");
3517 
3518   my_bind[1].buffer= (void *)&nData;
3519   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3520 
3521   rc= mysql_stmt_bind_param(stmt, my_bind);
3522   check_execute(stmt, rc);
3523 
3524   nData= 100;
3525   rc= mysql_stmt_execute(stmt);
3526   check_execute(stmt, rc);
3527 
3528   verify_affected_rows(1);
3529   mysql_stmt_close(stmt);
3530 
3531   strmov(query, "UPDATE test_update SET col2= ? WHERE col3= ?");
3532   stmt= mysql_simple_prepare(mysql, query);
3533   check_stmt(stmt);
3534 
3535   verify_param_count(stmt, 2);
3536   nData= 100;
3537 
3538   /* Always bzero all members of bind parameter */
3539   bzero((char*) my_bind, sizeof(my_bind));
3540 
3541   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3542   my_bind[0].buffer= szData;
3543   my_bind[0].buffer_length= sizeof(szData);
3544   my_bind[0].length= &length[0];
3545   length[0]= sprintf(szData, "updated-data");
3546 
3547   my_bind[1].buffer= (void *)&nData;
3548   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3549 
3550   rc= mysql_stmt_bind_param(stmt, my_bind);
3551   check_execute(stmt, rc);
3552 
3553   rc= mysql_stmt_execute(stmt);
3554   check_execute(stmt, rc);
3555   verify_affected_rows(1);
3556 
3557   mysql_stmt_close(stmt);
3558 
3559   /* now fetch the results ..*/
3560   rc= mysql_commit(mysql);
3561   myquery(rc);
3562 
3563   /* test the results now, only one row should exist */
3564   rc= mysql_query(mysql, "SELECT * FROM test_update");
3565   myquery(rc);
3566 
3567   /* get the result */
3568   result= mysql_store_result(mysql);
3569   mytest(result);
3570 
3571   rc= my_process_result_set(result);
3572   DIE_UNLESS(rc == 1);
3573   mysql_free_result(result);
3574 }
3575 
3576 
3577 /* Test prepare without parameters */
3578 
test_prepare_noparam()3579 static void test_prepare_noparam()
3580 {
3581   MYSQL_STMT *stmt;
3582   int        rc;
3583   MYSQL_RES  *result;
3584   char query[MAX_TEST_QUERY_LENGTH];
3585 
3586   myheader("test_prepare_noparam");
3587 
3588   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
3589   myquery(rc);
3590 
3591 
3592   rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 int, col2 varchar(50))");
3593   myquery(rc);
3594 
3595   /* insert by prepare */
3596   strmov(query, "INSERT INTO my_prepare VALUES(10, 'venu')");
3597   stmt= mysql_simple_prepare(mysql, query);
3598   check_stmt(stmt);
3599 
3600   verify_param_count(stmt, 0);
3601 
3602   rc= mysql_stmt_execute(stmt);
3603   check_execute(stmt, rc);
3604 
3605   mysql_stmt_close(stmt);
3606 
3607   /* now fetch the results ..*/
3608   rc= mysql_commit(mysql);
3609   myquery(rc);
3610 
3611   /* test the results now, only one row should exist */
3612   rc= mysql_query(mysql, "SELECT * FROM my_prepare");
3613   myquery(rc);
3614 
3615   /* get the result */
3616   result= mysql_store_result(mysql);
3617   mytest(result);
3618 
3619   rc= my_process_result_set(result);
3620   DIE_UNLESS(rc == 1);
3621   mysql_free_result(result);
3622 }
3623 
3624 
3625 /* Test simple bind result */
3626 
test_bind_result()3627 static void test_bind_result()
3628 {
3629   MYSQL_STMT *stmt;
3630   int        rc;
3631   int        nData;
3632   ulong      length1;
3633   char       szData[100];
3634   MYSQL_BIND my_bind[2];
3635   my_bool    is_null[2];
3636 
3637   myheader("test_bind_result");
3638 
3639   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3640   myquery(rc);
3641 
3642   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(col1 int , col2 varchar(50))");
3643   myquery(rc);
3644 
3645   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(10, 'venu')");
3646   myquery(rc);
3647 
3648   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(20, 'MySQL')");
3649   myquery(rc);
3650 
3651   rc= mysql_query(mysql, "INSERT INTO test_bind_result(col2) VALUES('monty')");
3652   myquery(rc);
3653 
3654   rc= mysql_commit(mysql);
3655   myquery(rc);
3656 
3657   /* fetch */
3658 
3659   bzero((char*) my_bind, sizeof(my_bind));
3660   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3661   my_bind[0].buffer= (void *) &nData;      /* integer data */
3662   my_bind[0].is_null= &is_null[0];
3663 
3664   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3665   my_bind[1].buffer= szData;                /* string data */
3666   my_bind[1].buffer_length= sizeof(szData);
3667   my_bind[1].length= &length1;
3668   my_bind[1].is_null= &is_null[1];
3669 
3670   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
3671   check_stmt(stmt);
3672 
3673   rc= mysql_stmt_bind_result(stmt, my_bind);
3674   check_execute(stmt, rc);
3675 
3676   rc= mysql_stmt_execute(stmt);
3677   check_execute(stmt, rc);
3678 
3679   rc= mysql_stmt_fetch(stmt);
3680   check_execute(stmt, rc);
3681 
3682   if (!opt_silent)
3683     fprintf(stdout, "\n row 1: %d, %s(%lu)", nData, szData, length1);
3684   DIE_UNLESS(nData == 10);
3685   DIE_UNLESS(strcmp(szData, "venu") == 0);
3686   DIE_UNLESS(length1 == 4);
3687 
3688   rc= mysql_stmt_fetch(stmt);
3689   check_execute(stmt, rc);
3690 
3691   if (!opt_silent)
3692     fprintf(stdout, "\n row 2: %d, %s(%lu)", nData, szData, length1);
3693   DIE_UNLESS(nData == 20);
3694   DIE_UNLESS(strcmp(szData, "MySQL") == 0);
3695   DIE_UNLESS(length1 == 5);
3696 
3697   rc= mysql_stmt_fetch(stmt);
3698   check_execute(stmt, rc);
3699 
3700   if (!opt_silent && is_null[0])
3701     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
3702   DIE_UNLESS(is_null[0]);
3703   DIE_UNLESS(strcmp(szData, "monty") == 0);
3704   DIE_UNLESS(length1 == 5);
3705 
3706   rc= mysql_stmt_fetch(stmt);
3707   DIE_UNLESS(rc == MYSQL_NO_DATA);
3708 
3709   mysql_stmt_close(stmt);
3710 }
3711 
3712 
3713 /* Test ext bind result */
3714 
test_bind_result_ext()3715 static void test_bind_result_ext()
3716 {
3717   MYSQL_STMT *stmt;
3718   int        rc, i;
3719   uchar      t_data;
3720   short      s_data;
3721   int        i_data;
3722   longlong   b_data;
3723   float      f_data;
3724   double     d_data;
3725   char       szData[20], bData[20];
3726   ulong       szLength, bLength;
3727   MYSQL_BIND my_bind[8];
3728   ulong      length[8];
3729   my_bool    is_null[8];
3730   char	     llbuf[22];
3731   myheader("test_bind_result_ext");
3732 
3733   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3734   myquery(rc);
3735 
3736   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, "
3737                                                       " c2 smallint, "
3738                                                       " c3 int, c4 bigint, "
3739                                                       " c5 float, c6 double, "
3740                                                       " c7 varbinary(10), "
3741                                                       " c8 varchar(50))");
3742   myquery(rc);
3743 
3744   rc= mysql_query(mysql, "INSERT INTO test_bind_result "
3745                          "VALUES (19, 2999, 3999, 4999999, "
3746                          " 2345.6, 5678.89563, 'venu', 'mysql')");
3747   myquery(rc);
3748 
3749   rc= mysql_commit(mysql);
3750   myquery(rc);
3751 
3752   bzero((char*) my_bind, sizeof(my_bind));
3753   for (i= 0; i < (int) array_elements(my_bind); i++)
3754   {
3755     my_bind[i].length=  &length[i];
3756     my_bind[i].is_null= &is_null[i];
3757   }
3758 
3759   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
3760   my_bind[0].buffer= (void *)&t_data;
3761 
3762   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
3763   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
3764 
3765   my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
3766   my_bind[1].buffer= (void *)&s_data;
3767 
3768   my_bind[2].buffer= (void *)&i_data;
3769   my_bind[3].buffer= (void *)&b_data;
3770 
3771   my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
3772   my_bind[4].buffer= (void *)&f_data;
3773 
3774   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
3775   my_bind[5].buffer= (void *)&d_data;
3776 
3777   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
3778   my_bind[6].buffer= (void *)szData;
3779   my_bind[6].buffer_length= sizeof(szData);
3780   my_bind[6].length= &szLength;
3781 
3782   my_bind[7].buffer_type= MYSQL_TYPE_TINY_BLOB;
3783   my_bind[7].buffer= (void *)&bData;
3784   my_bind[7].length= &bLength;
3785   my_bind[7].buffer_length= sizeof(bData);
3786 
3787   stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3788   check_stmt(stmt);
3789 
3790   rc= mysql_stmt_bind_result(stmt, my_bind);
3791   check_execute(stmt, rc);
3792 
3793   rc= mysql_stmt_execute(stmt);
3794   check_execute(stmt, rc);
3795 
3796   rc= mysql_stmt_fetch(stmt);
3797   check_execute(stmt, rc);
3798 
3799   if (!opt_silent)
3800   {
3801     fprintf(stdout, "\n data (tiny)   : %d", t_data);
3802     fprintf(stdout, "\n data (short)  : %d", s_data);
3803     fprintf(stdout, "\n data (int)    : %d", i_data);
3804     fprintf(stdout, "\n data (big)    : %s", llstr(b_data, llbuf));
3805 
3806     fprintf(stdout, "\n data (float)  : %f", f_data);
3807     fprintf(stdout, "\n data (double) : %f", d_data);
3808 
3809     fprintf(stdout, "\n data (str)    : %s(%lu)", szData, szLength);
3810 
3811     bData[bLength]= '\0';                         /* bData is binary */
3812     fprintf(stdout, "\n data (bin)    : %s(%lu)", bData, bLength);
3813   }
3814 
3815   DIE_UNLESS(t_data == 19);
3816   DIE_UNLESS(s_data == 2999);
3817   DIE_UNLESS(i_data == 3999);
3818   DIE_UNLESS(b_data == 4999999);
3819   /*DIE_UNLESS(f_data == 2345.60);*/
3820   /*DIE_UNLESS(d_data == 5678.89563);*/
3821   DIE_UNLESS(strcmp(szData, "venu") == 0);
3822   DIE_UNLESS(strncmp(bData, "mysql", 5) == 0);
3823   DIE_UNLESS(szLength == 4);
3824   DIE_UNLESS(bLength == 5);
3825 
3826   rc= mysql_stmt_fetch(stmt);
3827   DIE_UNLESS(rc == MYSQL_NO_DATA);
3828 
3829   mysql_stmt_close(stmt);
3830 }
3831 
3832 
3833 /* Test ext bind result */
3834 
test_bind_result_ext1()3835 static void test_bind_result_ext1()
3836 {
3837   MYSQL_STMT *stmt;
3838   uint       i;
3839   int        rc;
3840   char       t_data[20];
3841   float      s_data;
3842   short      i_data;
3843   uchar      b_data;
3844   int        f_data;
3845   long       bData;
3846   char       d_data[20];
3847   double     szData;
3848   MYSQL_BIND my_bind[8];
3849   ulong      length[8];
3850   my_bool    is_null[8];
3851   myheader("test_bind_result_ext1");
3852 
3853   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3854   myquery(rc);
3855 
3856   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, \
3857                                                         c3 int, c4 bigint, \
3858                                                         c5 float, c6 double, \
3859                                                         c7 varbinary(10), \
3860                                                         c8 varchar(10))");
3861   myquery(rc);
3862 
3863   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(120, 2999, 3999, 54, \
3864                                                               2.6, 58.89, \
3865                                                               '206', '6.7')");
3866   myquery(rc);
3867 
3868   rc= mysql_commit(mysql);
3869   myquery(rc);
3870 
3871   bzero((char*) my_bind, sizeof(my_bind));
3872   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3873   my_bind[0].buffer= (void *) t_data;
3874   my_bind[0].buffer_length= sizeof(t_data);
3875   my_bind[0].error= &my_bind[0].error_value;
3876 
3877   my_bind[1].buffer_type= MYSQL_TYPE_FLOAT;
3878   my_bind[1].buffer= (void *)&s_data;
3879   my_bind[1].buffer_length= 0;
3880   my_bind[1].error= &my_bind[1].error_value;
3881 
3882   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
3883   my_bind[2].buffer= (void *)&i_data;
3884   my_bind[2].buffer_length= 0;
3885   my_bind[2].error= &my_bind[2].error_value;
3886 
3887   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
3888   my_bind[3].buffer= (void *)&b_data;
3889   my_bind[3].buffer_length= 0;
3890   my_bind[3].error= &my_bind[3].error_value;
3891 
3892   my_bind[4].buffer_type= MYSQL_TYPE_LONG;
3893   my_bind[4].buffer= (void *)&f_data;
3894   my_bind[4].buffer_length= 0;
3895   my_bind[4].error= &my_bind[4].error_value;
3896 
3897   my_bind[5].buffer_type= MYSQL_TYPE_STRING;
3898   my_bind[5].buffer= (void *)d_data;
3899   my_bind[5].buffer_length= sizeof(d_data);
3900   my_bind[5].error= &my_bind[5].error_value;
3901 
3902   my_bind[6].buffer_type= MYSQL_TYPE_LONG;
3903   my_bind[6].buffer= (void *)&bData;
3904   my_bind[6].buffer_length= 0;
3905   my_bind[6].error= &my_bind[6].error_value;
3906 
3907   my_bind[7].buffer_type= MYSQL_TYPE_DOUBLE;
3908   my_bind[7].buffer= (void *)&szData;
3909   my_bind[7].buffer_length= 0;
3910   my_bind[7].error= &my_bind[7].error_value;
3911 
3912   for (i= 0; i < array_elements(my_bind); i++)
3913   {
3914     my_bind[i].is_null= &is_null[i];
3915     my_bind[i].length= &length[i];
3916   }
3917 
3918   stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3919   check_stmt(stmt);
3920 
3921   rc= mysql_stmt_bind_result(stmt, my_bind);
3922   check_execute(stmt, rc);
3923 
3924   rc= mysql_stmt_execute(stmt);
3925   check_execute(stmt, rc);
3926 
3927   rc= mysql_stmt_fetch(stmt);
3928   printf("rc=%d\n", rc);
3929   DIE_UNLESS(rc == 0);
3930 
3931   if (!opt_silent)
3932   {
3933     fprintf(stdout, "\n data (tiny)   : %s(%lu)", t_data, length[0]);
3934     fprintf(stdout, "\n data (short)  : %f(%lu)", s_data, length[1]);
3935     fprintf(stdout, "\n data (int)    : %d(%lu)", i_data, length[2]);
3936     fprintf(stdout, "\n data (big)    : %d(%lu)", b_data, length[3]);
3937 
3938     fprintf(stdout, "\n data (float)  : %d(%lu)", f_data, length[4]);
3939     fprintf(stdout, "\n data (double) : %s(%lu)", d_data, length[5]);
3940 
3941     fprintf(stdout, "\n data (bin)    : %ld(%lu)", bData, length[6]);
3942     fprintf(stdout, "\n data (str)    : %g(%lu)", szData, length[7]);
3943   }
3944 
3945   DIE_UNLESS(strcmp(t_data, "120") == 0);
3946   DIE_UNLESS(i_data == 3999);
3947   DIE_UNLESS(f_data == 2);
3948   DIE_UNLESS(strcmp(d_data, "58.89") == 0);
3949   DIE_UNLESS(b_data == 54);
3950 
3951   DIE_UNLESS(length[0] == 3);
3952   DIE_UNLESS(length[1] == 4);
3953   DIE_UNLESS(length[2] == 2);
3954   DIE_UNLESS(length[3] == 1);
3955   DIE_UNLESS(length[4] == 4);
3956   DIE_UNLESS(length[5] == 5);
3957   DIE_UNLESS(length[6] == 4);
3958   DIE_UNLESS(length[7] == 8);
3959 
3960   rc= mysql_stmt_fetch(stmt);
3961   DIE_UNLESS(rc == MYSQL_NO_DATA);
3962 
3963   mysql_stmt_close(stmt);
3964 }
3965 
3966 
3967 /* Generalized fetch conversion routine for all basic types */
3968 
bind_fetch(int row_count)3969 static void bind_fetch(int row_count)
3970 {
3971   MYSQL_STMT   *stmt;
3972   int          rc, i, count= row_count;
3973   int32        data[10];
3974   int8         i8_data;
3975   int16        i16_data;
3976   int32        i32_data;
3977   longlong     i64_data;
3978   float        f_data;
3979   double       d_data;
3980   char         s_data[10];
3981   ulong        length[10];
3982   MYSQL_BIND   my_bind[7];
3983   my_bool      is_null[7];
3984 
3985   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_bind_fetch VALUES "
3986                                     "(?, ?, ?, ?, ?, ?, ?)");
3987   check_stmt(stmt);
3988 
3989   verify_param_count(stmt, 7);
3990 
3991   /* Always bzero all members of bind parameter */
3992   bzero((char*) my_bind, sizeof(my_bind));
3993 
3994   for (i= 0; i < (int) array_elements(my_bind); i++)
3995   {
3996     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
3997     my_bind[i].buffer= (void *) &data[i];
3998   }
3999   rc= mysql_stmt_bind_param(stmt, my_bind);
4000   check_execute(stmt, rc);
4001 
4002   while (count--)
4003   {
4004     rc= 10+count;
4005     for (i= 0; i < (int) array_elements(my_bind); i++)
4006     {
4007       data[i]= rc+i;
4008       rc+= 12;
4009     }
4010     rc= mysql_stmt_execute(stmt);
4011     check_execute(stmt, rc);
4012   }
4013 
4014   rc= mysql_commit(mysql);
4015   myquery(rc);
4016 
4017   mysql_stmt_close(stmt);
4018 
4019   rc= my_stmt_result("SELECT * FROM test_bind_fetch");
4020   DIE_UNLESS(row_count == rc);
4021 
4022   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_fetch");
4023   check_stmt(stmt);
4024 
4025   for (i= 0; i < (int) array_elements(my_bind); i++)
4026   {
4027     my_bind[i].buffer= (void *) &data[i];
4028     my_bind[i].length= &length[i];
4029     my_bind[i].is_null= &is_null[i];
4030   }
4031 
4032   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4033   my_bind[0].buffer= (void *)&i8_data;
4034 
4035   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
4036   my_bind[1].buffer= (void *)&i16_data;
4037 
4038   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
4039   my_bind[2].buffer= (void *)&i32_data;
4040 
4041   my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
4042   my_bind[3].buffer= (void *)&i64_data;
4043 
4044   my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
4045   my_bind[4].buffer= (void *)&f_data;
4046 
4047   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
4048   my_bind[5].buffer= (void *)&d_data;
4049 
4050   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
4051   my_bind[6].buffer= (void *)&s_data;
4052   my_bind[6].buffer_length= sizeof(s_data);
4053 
4054   rc= mysql_stmt_bind_result(stmt, my_bind);
4055   check_execute(stmt, rc);
4056 
4057   rc= mysql_stmt_execute(stmt);
4058   check_execute(stmt, rc);
4059 
4060   rc= mysql_stmt_store_result(stmt);
4061   check_execute(stmt, rc);
4062 
4063   while (row_count--)
4064   {
4065     rc= mysql_stmt_fetch(stmt);
4066     check_execute(stmt, rc);
4067 
4068     if (!opt_silent)
4069     {
4070       fprintf(stdout, "\n");
4071       fprintf(stdout, "\n tiny     : %ld(%lu)", (ulong) i8_data, length[0]);
4072       fprintf(stdout, "\n short    : %ld(%lu)", (ulong) i16_data, length[1]);
4073       fprintf(stdout, "\n int      : %ld(%lu)", (ulong) i32_data, length[2]);
4074       fprintf(stdout, "\n longlong : %ld(%lu)", (ulong) i64_data, length[3]);
4075       fprintf(stdout, "\n float    : %f(%lu)",  f_data,  length[4]);
4076       fprintf(stdout, "\n double   : %g(%lu)",  d_data,  length[5]);
4077       fprintf(stdout, "\n char     : %s(%lu)",  s_data,  length[6]);
4078     }
4079     rc= 10+row_count;
4080 
4081     /* TINY */
4082     DIE_UNLESS((int) i8_data == rc);
4083     DIE_UNLESS(length[0] == 1);
4084     rc+= 13;
4085 
4086     /* SHORT */
4087     DIE_UNLESS((int) i16_data == rc);
4088     DIE_UNLESS(length[1] == 2);
4089     rc+= 13;
4090 
4091     /* LONG */
4092     DIE_UNLESS((int) i32_data == rc);
4093     DIE_UNLESS(length[2] == 4);
4094     rc+= 13;
4095 
4096     /* LONGLONG */
4097     DIE_UNLESS((int) i64_data == rc);
4098     DIE_UNLESS(length[3] == 8);
4099     rc+= 13;
4100 
4101     /* FLOAT */
4102     DIE_UNLESS((int)f_data == rc);
4103     DIE_UNLESS(length[4] == 4);
4104     rc+= 13;
4105 
4106     /* DOUBLE */
4107     DIE_UNLESS((int)d_data == rc);
4108     DIE_UNLESS(length[5] == 8);
4109     rc+= 13;
4110 
4111     /* CHAR */
4112     {
4113       char buff[20];
4114       long len= sprintf(buff, "%d", rc);
4115       DIE_UNLESS(strcmp(s_data, buff) == 0);
4116       DIE_UNLESS(length[6] == (ulong) len);
4117     }
4118   }
4119   rc= mysql_stmt_fetch(stmt);
4120   DIE_UNLESS(rc == MYSQL_NO_DATA);
4121 
4122   mysql_stmt_close(stmt);
4123 }
4124 
4125 
4126 /* Test fetching of date, time and ts */
4127 
test_fetch_date()4128 static void test_fetch_date()
4129 {
4130   MYSQL_STMT *stmt;
4131   uint       i;
4132   int        rc, year;
4133   char       date[25], my_time[25], ts[25], ts_4[25], ts_6[20], dt[20];
4134   ulong      d_length, t_length, ts_length, ts4_length, ts6_length,
4135              dt_length, y_length;
4136   MYSQL_BIND my_bind[8];
4137   my_bool    is_null[8];
4138   ulong      length[8];
4139 
4140   myheader("test_fetch_date");
4141 
4142   /* Will not work if sql_mode is NO_ZERO_DATE (implicit if TRADITIONAL) */
4143   rc= mysql_query(mysql, "SET SQL_MODE=''");
4144   myquery(rc);
4145 
4146   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
4147   myquery(rc);
4148 
4149   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \
4150                                                         c3 timestamp, \
4151                                                         c4 year, \
4152                                                         c5 datetime, \
4153                                                         c6 timestamp, \
4154                                                         c7 timestamp)");
4155   myquery(rc);
4156 
4157   rc= mysql_query(mysql, "SET SQL_MODE=''");
4158   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \
4159                                                               '12:49:00', \
4160                                                               '2002-01-02 17:46:59', \
4161                                                               2010, \
4162                                                               '2010-07-10', \
4163                                                               '2020', '1999-12-29')");
4164   myquery(rc);
4165 
4166   rc= mysql_commit(mysql);
4167   myquery(rc);
4168 
4169   bzero((char*) my_bind, sizeof(my_bind));
4170   for (i= 0; i < array_elements(my_bind); i++)
4171   {
4172     my_bind[i].is_null= &is_null[i];
4173     my_bind[i].length= &length[i];
4174   }
4175 
4176   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
4177   my_bind[1]= my_bind[2]= my_bind[0];
4178 
4179   my_bind[0].buffer= (void *)&date;
4180   my_bind[0].buffer_length= sizeof(date);
4181   my_bind[0].length= &d_length;
4182 
4183   my_bind[1].buffer= (void *)&my_time;
4184   my_bind[1].buffer_length= sizeof(my_time);
4185   my_bind[1].length= &t_length;
4186 
4187   my_bind[2].buffer= (void *)&ts;
4188   my_bind[2].buffer_length= sizeof(ts);
4189   my_bind[2].length= &ts_length;
4190 
4191   my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4192   my_bind[3].buffer= (void *)&year;
4193   my_bind[3].length= &y_length;
4194 
4195   my_bind[4].buffer_type= MYSQL_TYPE_STRING;
4196   my_bind[4].buffer= (void *)&dt;
4197   my_bind[4].buffer_length= sizeof(dt);
4198   my_bind[4].length= &dt_length;
4199 
4200   my_bind[5].buffer_type= MYSQL_TYPE_STRING;
4201   my_bind[5].buffer= (void *)&ts_4;
4202   my_bind[5].buffer_length= sizeof(ts_4);
4203   my_bind[5].length= &ts4_length;
4204 
4205   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
4206   my_bind[6].buffer= (void *)&ts_6;
4207   my_bind[6].buffer_length= sizeof(ts_6);
4208   my_bind[6].length= &ts6_length;
4209 
4210   rc= my_stmt_result("SELECT * FROM test_bind_result");
4211   DIE_UNLESS(rc == 1);
4212 
4213   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
4214   check_stmt(stmt);
4215 
4216   rc= mysql_stmt_bind_result(stmt, my_bind);
4217   check_execute(stmt, rc);
4218 
4219   rc= mysql_stmt_execute(stmt);
4220   check_execute(stmt, rc);
4221 
4222   ts_4[0]= '\0';
4223   rc= mysql_stmt_fetch(stmt);
4224   check_execute(stmt, rc);
4225 
4226   if (!opt_silent)
4227   {
4228     fprintf(stdout, "\n date   : %s(%lu)", date, d_length);
4229     fprintf(stdout, "\n time   : %s(%lu)", my_time, t_length);
4230     fprintf(stdout, "\n ts     : %s(%lu)", ts, ts_length);
4231     fprintf(stdout, "\n year   : %d(%lu)", year, y_length);
4232     fprintf(stdout, "\n dt     : %s(%lu)", dt,  dt_length);
4233     fprintf(stdout, "\n ts(4)  : %s(%lu)", ts_4, ts4_length);
4234     fprintf(stdout, "\n ts(6)  : %s(%lu)", ts_6, ts6_length);
4235   }
4236 
4237   DIE_UNLESS(strcmp(date, "2002-01-02") == 0);
4238   DIE_UNLESS(d_length == 10);
4239 
4240   DIE_UNLESS(strcmp(my_time, "12:49:00") == 0);
4241   DIE_UNLESS(t_length == 8);
4242 
4243   DIE_UNLESS(strcmp(ts, "2002-01-02 17:46:59") == 0);
4244   DIE_UNLESS(ts_length == 19);
4245 
4246   DIE_UNLESS(year == 2010);
4247   DIE_UNLESS(y_length == 4);
4248 
4249   DIE_UNLESS(strcmp(dt, "2010-07-10 00:00:00") == 0);
4250   DIE_UNLESS(dt_length == 19);
4251 
4252   DIE_UNLESS(strcmp(ts_4, "0000-00-00 00:00:00") == 0);
4253   DIE_UNLESS(ts4_length == strlen("0000-00-00 00:00:00"));
4254 
4255   DIE_UNLESS(strcmp(ts_6, "1999-12-29 00:00:00") == 0);
4256   DIE_UNLESS(ts6_length == 19);
4257 
4258   rc= mysql_stmt_fetch(stmt);
4259   DIE_UNLESS(rc == MYSQL_NO_DATA);
4260 
4261   mysql_stmt_close(stmt);
4262 }
4263 
4264 
4265 /* Test fetching of str to all types */
4266 
test_fetch_str()4267 static void test_fetch_str()
4268 {
4269   int rc;
4270 
4271   myheader("test_fetch_str");
4272 
4273   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4274   myquery(rc);
4275 
4276   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 char(10), \
4277                                                      c2 char(10), \
4278                                                      c3 char(20), \
4279                                                      c4 char(20), \
4280                                                      c5 char(30), \
4281                                                      c6 char(40), \
4282                                                      c7 char(20))");
4283   myquery(rc);
4284 
4285   bind_fetch(3);
4286 }
4287 
4288 
4289 /* Test fetching of long to all types */
4290 
test_fetch_long()4291 static void test_fetch_long()
4292 {
4293   int rc;
4294 
4295   myheader("test_fetch_long");
4296 
4297   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4298   myquery(rc);
4299 
4300   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 int unsigned, \
4301                                                      c2 int unsigned, \
4302                                                      c3 int, \
4303                                                      c4 int, \
4304                                                      c5 int, \
4305                                                      c6 int unsigned, \
4306                                                      c7 int)");
4307   myquery(rc);
4308 
4309   bind_fetch(4);
4310 }
4311 
4312 
4313 /* Test fetching of short to all types */
4314 
test_fetch_short()4315 static void test_fetch_short()
4316 {
4317   int rc;
4318 
4319   myheader("test_fetch_short");
4320 
4321   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4322   myquery(rc);
4323 
4324   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, \
4325                                                      c2 smallint, \
4326                                                      c3 smallint unsigned, \
4327                                                      c4 smallint, \
4328                                                      c5 smallint, \
4329                                                      c6 smallint, \
4330                                                      c7 smallint unsigned)");
4331   myquery(rc);
4332 
4333   bind_fetch(5);
4334 }
4335 
4336 
4337 /* Test fetching of tiny to all types */
4338 
test_fetch_tiny()4339 static void test_fetch_tiny()
4340 {
4341   int rc;
4342 
4343   myheader("test_fetch_tiny");
4344 
4345   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4346   myquery(rc);
4347 
4348   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 tinyint unsigned, \
4349                                                      c2 tinyint, \
4350                                                      c3 tinyint unsigned, \
4351                                                      c4 tinyint, \
4352                                                      c5 tinyint, \
4353                                                      c6 tinyint, \
4354                                                      c7 tinyint unsigned)");
4355   myquery(rc);
4356 
4357   bind_fetch(3);
4358 
4359 }
4360 
4361 
4362 /* Test fetching of longlong to all types */
4363 
test_fetch_bigint()4364 static void test_fetch_bigint()
4365 {
4366   int rc;
4367 
4368   myheader("test_fetch_bigint");
4369 
4370   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4371   myquery(rc);
4372 
4373   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 bigint, \
4374                                                      c2 bigint, \
4375                                                      c3 bigint unsigned, \
4376                                                      c4 bigint unsigned, \
4377                                                      c5 bigint unsigned, \
4378                                                      c6 bigint unsigned, \
4379                                                      c7 bigint unsigned)");
4380   myquery(rc);
4381 
4382   bind_fetch(2);
4383 
4384 }
4385 
4386 
4387 /* Test fetching of float to all types */
4388 
test_fetch_float()4389 static void test_fetch_float()
4390 {
4391   int rc;
4392 
4393   myheader("test_fetch_float");
4394 
4395   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4396   myquery(rc);
4397 
4398   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 float(3), \
4399                                                      c2 float, \
4400                                                      c3 float unsigned, \
4401                                                      c4 float, \
4402                                                      c5 float, \
4403                                                      c6 float, \
4404                                                      c7 float(10) unsigned)");
4405   myquery(rc);
4406 
4407   bind_fetch(2);
4408 
4409 }
4410 
4411 
4412 /* Test fetching of double to all types */
4413 
test_fetch_double()4414 static void test_fetch_double()
4415 {
4416   int rc;
4417 
4418   myheader("test_fetch_double");
4419 
4420   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4421   myquery(rc);
4422 
4423   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 double(5, 2), "
4424                          "c2 double unsigned, c3 double unsigned, "
4425                          "c4 double unsigned, c5 double unsigned, "
4426                          "c6 double unsigned, c7 double unsigned)");
4427   myquery(rc);
4428 
4429   bind_fetch(3);
4430 
4431 }
4432 
4433 
4434 /* Test simple prepare with all possible types */
4435 
test_prepare_ext()4436 static void test_prepare_ext()
4437 {
4438   MYSQL_STMT *stmt;
4439   int        rc;
4440   char       *sql;
4441   int        nData= 1;
4442   char       tData= 1;
4443   short      sData= 10;
4444   longlong   bData= 20;
4445   MYSQL_BIND my_bind[6];
4446   char query[MAX_TEST_QUERY_LENGTH];
4447   myheader("test_prepare_ext");
4448 
4449   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext");
4450   myquery(rc);
4451 
4452   sql= (char *)"CREATE TABLE test_prepare_ext"
4453                "("
4454                " c1  tinyint,"
4455                " c2  smallint,"
4456                " c3  mediumint,"
4457                " c4  int,"
4458                " c5  integer,"
4459                " c6  bigint,"
4460                " c7  float,"
4461                " c8  double,"
4462                " c9  double precision,"
4463                " c10 real,"
4464                " c11 decimal(7, 4),"
4465                " c12 numeric(8, 4),"
4466                " c13 date,"
4467                " c14 datetime,"
4468                " c15 timestamp,"
4469                " c16 time,"
4470                " c17 year,"
4471                " c18 bit,"
4472                " c19 bool,"
4473                " c20 char,"
4474                " c21 char(10),"
4475                " c22 varchar(30),"
4476                " c23 tinyblob,"
4477                " c24 tinytext,"
4478                " c25 blob,"
4479                " c26 text,"
4480                " c27 mediumblob,"
4481                " c28 mediumtext,"
4482                " c29 longblob,"
4483                " c30 longtext,"
4484                " c31 enum('one', 'two', 'three'),"
4485                " c32 set('monday', 'tuesday', 'wednesday'))";
4486 
4487   rc= mysql_query(mysql, sql);
4488   myquery(rc);
4489 
4490   /* insert by prepare - all integers */
4491   strmov(query, (char *)"INSERT INTO test_prepare_ext(c1, c2, c3, c4, c5, c6) VALUES(?, ?, ?, ?, ?, ?)");
4492   stmt= mysql_simple_prepare(mysql, query);
4493   check_stmt(stmt);
4494 
4495   verify_param_count(stmt, 6);
4496 
4497   /* Always bzero all members of bind parameter */
4498   bzero((char*) my_bind, sizeof(my_bind));
4499 
4500   /*tinyint*/
4501   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4502   my_bind[0].buffer= (void *)&tData;
4503 
4504   /*smallint*/
4505   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
4506   my_bind[1].buffer= (void *)&sData;
4507 
4508   /*mediumint*/
4509   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
4510   my_bind[2].buffer= (void *)&nData;
4511 
4512   /*int*/
4513   my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4514   my_bind[3].buffer= (void *)&nData;
4515 
4516   /*integer*/
4517   my_bind[4].buffer_type= MYSQL_TYPE_LONG;
4518   my_bind[4].buffer= (void *)&nData;
4519 
4520   /*bigint*/
4521   my_bind[5].buffer_type= MYSQL_TYPE_LONGLONG;
4522   my_bind[5].buffer= (void *)&bData;
4523 
4524   rc= mysql_stmt_bind_param(stmt, my_bind);
4525   check_execute(stmt, rc);
4526 
4527   /*
4528   *  integer to integer
4529   */
4530   for (nData= 0; nData<10; nData++, tData++, sData++, bData++)
4531   {
4532     rc= mysql_stmt_execute(stmt);
4533     check_execute(stmt, rc);
4534   }
4535   mysql_stmt_close(stmt);
4536 
4537   /* now fetch the results ..*/
4538 
4539   stmt= mysql_simple_prepare(mysql, "SELECT c1, c2, c3, c4, c5, c6 "
4540                                     "FROM test_prepare_ext");
4541   check_stmt(stmt);
4542 
4543   /* get the result */
4544   rc= mysql_stmt_execute(stmt);
4545   check_execute(stmt, rc);
4546 
4547   rc= my_process_stmt_result(stmt);
4548   DIE_UNLESS(nData == rc);
4549 
4550   mysql_stmt_close(stmt);
4551 }
4552 
4553 
4554 /* Test real and alias names */
4555 
test_field_names()4556 static void test_field_names()
4557 {
4558   int        rc;
4559   MYSQL_RES  *result;
4560 
4561   myheader("test_field_names");
4562 
4563   if (!opt_silent)
4564     fprintf(stdout, "\n %d, %d, %d", MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_ENUM);
4565   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names1");
4566   myquery(rc);
4567 
4568   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names2");
4569   myquery(rc);
4570 
4571   rc= mysql_query(mysql, "CREATE TABLE test_field_names1(id int, name varchar(50))");
4572   myquery(rc);
4573 
4574   rc= mysql_query(mysql, "CREATE TABLE test_field_names2(id int, name varchar(50))");
4575   myquery(rc);
4576 
4577   /* with table name included with TRUE column name */
4578   rc= mysql_query(mysql, "SELECT id as 'id-alias' FROM test_field_names1");
4579   myquery(rc);
4580 
4581   result= mysql_use_result(mysql);
4582   mytest(result);
4583 
4584   rc= my_process_result_set(result);
4585   DIE_UNLESS(rc == 0);
4586   mysql_free_result(result);
4587 
4588   /* with table name included with TRUE column name */
4589   rc= mysql_query(mysql, "SELECT t1.id as 'id-alias', test_field_names2.name FROM test_field_names1 t1, test_field_names2");
4590   myquery(rc);
4591 
4592   result= mysql_use_result(mysql);
4593   mytest(result);
4594 
4595   rc= my_process_result_set(result);
4596   DIE_UNLESS(rc == 0);
4597   mysql_free_result(result);
4598 }
4599 
4600 
4601 /* Test warnings */
4602 
test_warnings()4603 static void test_warnings()
4604 {
4605   int        rc;
4606   MYSQL_RES  *result;
4607 
4608   myheader("test_warnings");
4609 
4610   mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4611 
4612   rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4613   myquery(rc);
4614 
4615   if (!opt_silent)
4616     fprintf(stdout, "\n total warnings: %d", mysql_warning_count(mysql));
4617   rc= mysql_query(mysql, "SHOW WARNINGS");
4618   myquery(rc);
4619 
4620   result= mysql_store_result(mysql);
4621   mytest(result);
4622 
4623   rc= my_process_result_set(result);
4624   DIE_UNLESS(rc == 1);
4625   mysql_free_result(result);
4626 }
4627 
4628 
4629 /* Test errors */
4630 
test_errors()4631 static void test_errors()
4632 {
4633   int        rc;
4634   MYSQL_RES  *result;
4635 
4636   myheader("test_errors");
4637 
4638   mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4639 
4640   rc= mysql_query(mysql, "DROP TABLE test_non_exists");
4641   myquery_r(rc);
4642 
4643   rc= mysql_query(mysql, "SHOW ERRORS");
4644   myquery(rc);
4645 
4646   result= mysql_store_result(mysql);
4647   mytest(result);
4648 
4649   (void) my_process_result_set(result);
4650   mysql_free_result(result);
4651 }
4652 
4653 
4654 /* Test simple prepare-insert */
4655 
test_insert()4656 static void test_insert()
4657 {
4658   MYSQL_STMT *stmt;
4659   int        rc;
4660   char       str_data[50];
4661   char       tiny_data;
4662   MYSQL_RES  *result;
4663   MYSQL_BIND my_bind[2];
4664   ulong      length;
4665 
4666   myheader("test_insert");
4667 
4668   rc= mysql_autocommit(mysql, TRUE);
4669   myquery(rc);
4670 
4671   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_insert");
4672   myquery(rc);
4673 
4674   rc= mysql_query(mysql, "CREATE TABLE test_prep_insert(col1 tinyint, \
4675                                 col2 varchar(50))");
4676   myquery(rc);
4677 
4678   /* insert by prepare */
4679   stmt= mysql_simple_prepare(mysql,
4680                              "INSERT INTO test_prep_insert VALUES(?, ?)");
4681   check_stmt(stmt);
4682 
4683   verify_param_count(stmt, 2);
4684 
4685   /*
4686     We need to bzero bind structure because mysql_stmt_bind_param checks all
4687     its members.
4688   */
4689   bzero((char*) my_bind, sizeof(my_bind));
4690 
4691   /* tinyint */
4692   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4693   my_bind[0].buffer= (void *)&tiny_data;
4694 
4695   /* string */
4696   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
4697   my_bind[1].buffer= str_data;
4698   my_bind[1].buffer_length= sizeof(str_data);;
4699   my_bind[1].length= &length;
4700 
4701   rc= mysql_stmt_bind_param(stmt, my_bind);
4702   check_execute(stmt, rc);
4703 
4704   /* now, execute the prepared statement to insert 10 records.. */
4705   for (tiny_data= 0; tiny_data < 3; tiny_data++)
4706   {
4707     length= sprintf(str_data, "MySQL%d", tiny_data);
4708     rc= mysql_stmt_execute(stmt);
4709     check_execute(stmt, rc);
4710   }
4711 
4712   mysql_stmt_close(stmt);
4713 
4714   /* now fetch the results ..*/
4715   rc= mysql_commit(mysql);
4716   myquery(rc);
4717 
4718   /* test the results now, only one row should exist */
4719   rc= mysql_query(mysql, "SELECT * FROM test_prep_insert");
4720   myquery(rc);
4721 
4722   /* get the result */
4723   result= mysql_store_result(mysql);
4724   mytest(result);
4725 
4726   rc= my_process_result_set(result);
4727   DIE_UNLESS((int) tiny_data == rc);
4728   mysql_free_result(result);
4729 
4730 }
4731 
4732 
4733 /* Test simple prepare-resultset info */
4734 
test_prepare_resultset()4735 static void test_prepare_resultset()
4736 {
4737   MYSQL_STMT *stmt;
4738   int        rc;
4739   MYSQL_RES  *result;
4740 
4741   myheader("test_prepare_resultset");
4742 
4743   rc= mysql_autocommit(mysql, TRUE);
4744   myquery(rc);
4745 
4746   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_resultset");
4747   myquery(rc);
4748 
4749   rc= mysql_query(mysql, "CREATE TABLE test_prepare_resultset(id int, \
4750                                 name varchar(50), extra double)");
4751   myquery(rc);
4752 
4753   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_prepare_resultset");
4754   check_stmt(stmt);
4755 
4756   verify_param_count(stmt, 0);
4757 
4758   result= mysql_stmt_result_metadata(stmt);
4759   mytest(result);
4760   my_print_result_metadata(result);
4761   mysql_free_result(result);
4762   mysql_stmt_close(stmt);
4763 }
4764 
4765 
4766 /* Test field flags (verify .NET provider) */
4767 
test_field_flags()4768 static void test_field_flags()
4769 {
4770   int          rc;
4771   MYSQL_RES    *result;
4772   MYSQL_FIELD  *field;
4773   unsigned int i;
4774 
4775 
4776   myheader("test_field_flags");
4777 
4778   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_flags");
4779   myquery(rc);
4780 
4781   rc= mysql_query(mysql, "CREATE TABLE test_field_flags(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, \
4782                                                         id1 int NOT NULL, \
4783                                                         id2 int UNIQUE, \
4784                                                         id3 int, \
4785                                                         id4 int NOT NULL, \
4786                                                         id5 int, \
4787                                                         KEY(id3, id4))");
4788   myquery(rc);
4789 
4790   /* with table name included with TRUE column name */
4791   rc= mysql_query(mysql, "SELECT * FROM test_field_flags");
4792   myquery(rc);
4793 
4794   result= mysql_use_result(mysql);
4795   mytest(result);
4796 
4797   mysql_field_seek(result, 0);
4798   if (!opt_silent)
4799     fputc('\n', stdout);
4800 
4801   for(i= 0; i< mysql_num_fields(result); i++)
4802   {
4803     field= mysql_fetch_field(result);
4804     if (!opt_silent)
4805     {
4806       fprintf(stdout, "\n field:%d", i);
4807       if (field->flags & NOT_NULL_FLAG)
4808         fprintf(stdout, "\n  NOT_NULL_FLAG");
4809       if (field->flags & PRI_KEY_FLAG)
4810         fprintf(stdout, "\n  PRI_KEY_FLAG");
4811       if (field->flags & UNIQUE_KEY_FLAG)
4812         fprintf(stdout, "\n  UNIQUE_KEY_FLAG");
4813       if (field->flags & MULTIPLE_KEY_FLAG)
4814         fprintf(stdout, "\n  MULTIPLE_KEY_FLAG");
4815       if (field->flags & AUTO_INCREMENT_FLAG)
4816         fprintf(stdout, "\n  AUTO_INCREMENT_FLAG");
4817 
4818     }
4819   }
4820   mysql_free_result(result);
4821 }
4822 
4823 
4824 /* Test mysql_stmt_close for open stmts */
4825 
test_stmt_close()4826 static void test_stmt_close()
4827 {
4828   MYSQL *lmysql;
4829   MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x;
4830   MYSQL_BIND  my_bind[1];
4831   MYSQL_RES   *result;
4832   unsigned int  count;
4833   int   rc;
4834   char query[MAX_TEST_QUERY_LENGTH];
4835 
4836   myheader("test_stmt_close");
4837 
4838   if (!opt_silent)
4839     fprintf(stdout, "\n Establishing a test connection ...");
4840   if (!(lmysql= mysql_client_init(NULL)))
4841   {
4842     myerror("mysql_client_init() failed");
4843     exit(1);
4844   }
4845   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
4846                            opt_password, current_db, opt_port,
4847                            opt_unix_socket, 0)))
4848   {
4849     myerror("connection failed");
4850     exit(1);
4851   }
4852   mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
4853   if (!opt_silent)
4854     fprintf(stdout, "OK");
4855 
4856 
4857   /* set AUTOCOMMIT to ON*/
4858   mysql_autocommit(lmysql, TRUE);
4859 
4860   rc= mysql_query(lmysql, "SET SQL_MODE = ''");
4861   myquery(rc);
4862 
4863   rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close");
4864   myquery(rc);
4865 
4866   rc= mysql_query(lmysql, "CREATE TABLE test_stmt_close(id int)");
4867   myquery(rc);
4868 
4869   strmov(query, "DO \"nothing\"");
4870   stmt1= mysql_simple_prepare(lmysql, query);
4871   check_stmt(stmt1);
4872 
4873   verify_param_count(stmt1, 0);
4874 
4875   strmov(query, "INSERT INTO test_stmt_close(id) VALUES(?)");
4876   stmt_x= mysql_simple_prepare(mysql, query);
4877   check_stmt(stmt_x);
4878 
4879   verify_param_count(stmt_x, 1);
4880 
4881   strmov(query, "UPDATE test_stmt_close SET id= ? WHERE id= ?");
4882   stmt3= mysql_simple_prepare(lmysql, query);
4883   check_stmt(stmt3);
4884 
4885   verify_param_count(stmt3, 2);
4886 
4887   strmov(query, "SELECT * FROM test_stmt_close WHERE id= ?");
4888   stmt2= mysql_simple_prepare(lmysql, query);
4889   check_stmt(stmt2);
4890 
4891   verify_param_count(stmt2, 1);
4892 
4893   rc= mysql_stmt_close(stmt1);
4894   if (!opt_silent)
4895     fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
4896   DIE_UNLESS(rc == 0);
4897 
4898   /*
4899     Originally we were going to close all statements automatically in
4900     mysql_close(). This proved to not work well - users weren't able to
4901     close statements by hand once mysql_close() had been called.
4902     Now mysql_close() doesn't free any statements, so this test doesn't
4903     serve its original designation any more.
4904     Here we free stmt2 and stmt3 by hand to avoid memory leaks.
4905   */
4906   mysql_stmt_close(stmt2);
4907   mysql_stmt_close(stmt3);
4908   mysql_close(lmysql);
4909 
4910   /*
4911     We need to bzero bind structure because mysql_stmt_bind_param checks all
4912     its members.
4913   */
4914   bzero((char*) my_bind, sizeof(my_bind));
4915 
4916   my_bind[0].buffer= (void *)&count;
4917   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
4918   count= 100;
4919 
4920   rc= mysql_stmt_bind_param(stmt_x, my_bind);
4921   check_execute(stmt_x, rc);
4922 
4923   rc= mysql_stmt_execute(stmt_x);
4924   check_execute(stmt_x, rc);
4925 
4926   verify_st_affected_rows(stmt_x, 1);
4927 
4928   rc= mysql_stmt_close(stmt_x);
4929   if (!opt_silent)
4930     fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
4931   DIE_UNLESS( rc == 0);
4932 
4933   rc= mysql_query(mysql, "SELECT id FROM test_stmt_close");
4934   myquery(rc);
4935 
4936   result= mysql_store_result(mysql);
4937   mytest(result);
4938 
4939   rc= my_process_result_set(result);
4940   DIE_UNLESS(rc == 1);
4941   mysql_free_result(result);
4942 }
4943 
4944 
4945 /* Test simple set variable prepare */
4946 
test_set_variable()4947 static void test_set_variable()
4948 {
4949   MYSQL_STMT *stmt, *stmt1;
4950   int        rc;
4951   int        set_count, def_count, get_count;
4952   ulong      length;
4953   char       var[NAME_LEN+1];
4954   MYSQL_BIND set_bind[1], get_bind[2];
4955 
4956   myheader("test_set_variable");
4957 
4958   mysql_autocommit(mysql, TRUE);
4959 
4960   stmt1= mysql_simple_prepare(mysql, "show variables like 'max_error_count'");
4961   check_stmt(stmt1);
4962 
4963   /*
4964     We need to bzero bind structure because mysql_stmt_bind_param checks all
4965     its members.
4966   */
4967   bzero((char*) get_bind, sizeof(get_bind));
4968 
4969   get_bind[0].buffer_type= MYSQL_TYPE_STRING;
4970   get_bind[0].buffer= (void *)var;
4971   get_bind[0].length= &length;
4972   get_bind[0].buffer_length= (int)NAME_LEN;
4973   length= NAME_LEN;
4974 
4975   get_bind[1].buffer_type= MYSQL_TYPE_LONG;
4976   get_bind[1].buffer= (void *)&get_count;
4977 
4978   rc= mysql_stmt_execute(stmt1);
4979   check_execute(stmt1, rc);
4980 
4981   rc= mysql_stmt_bind_result(stmt1, get_bind);
4982   check_execute(stmt1, rc);
4983 
4984   rc= mysql_stmt_fetch(stmt1);
4985   check_execute(stmt1, rc);
4986 
4987   if (!opt_silent)
4988     fprintf(stdout, "\n max_error_count(default): %d", get_count);
4989   def_count= get_count;
4990 
4991   DIE_UNLESS(strcmp(var, "max_error_count") == 0);
4992   rc= mysql_stmt_fetch(stmt1);
4993   DIE_UNLESS(rc == MYSQL_NO_DATA);
4994 
4995   stmt= mysql_simple_prepare(mysql, "set max_error_count= ?");
4996   check_stmt(stmt);
4997 
4998   bzero((char*) set_bind, sizeof(set_bind));
4999 
5000   set_bind[0].buffer_type= MYSQL_TYPE_LONG;
5001   set_bind[0].buffer= (void *)&set_count;
5002 
5003   rc= mysql_stmt_bind_param(stmt, set_bind);
5004   check_execute(stmt, rc);
5005 
5006   set_count= 31;
5007   rc= mysql_stmt_execute(stmt);
5008   check_execute(stmt, rc);
5009 
5010   mysql_commit(mysql);
5011 
5012   rc= mysql_stmt_execute(stmt1);
5013   check_execute(stmt1, rc);
5014 
5015   rc= mysql_stmt_fetch(stmt1);
5016   check_execute(stmt1, rc);
5017 
5018   if (!opt_silent)
5019     fprintf(stdout, "\n max_error_count         : %d", get_count);
5020   DIE_UNLESS(get_count == set_count);
5021 
5022   rc= mysql_stmt_fetch(stmt1);
5023   DIE_UNLESS(rc == MYSQL_NO_DATA);
5024 
5025   /* restore back to default */
5026   set_count= def_count;
5027   rc= mysql_stmt_execute(stmt);
5028   check_execute(stmt, rc);
5029 
5030   rc= mysql_stmt_execute(stmt1);
5031   check_execute(stmt1, rc);
5032 
5033   rc= mysql_stmt_fetch(stmt1);
5034   check_execute(stmt1, rc);
5035 
5036   if (!opt_silent)
5037     fprintf(stdout, "\n max_error_count(default): %d", get_count);
5038   DIE_UNLESS(get_count == set_count);
5039 
5040   rc= mysql_stmt_fetch(stmt1);
5041   DIE_UNLESS(rc == MYSQL_NO_DATA);
5042 
5043   mysql_stmt_close(stmt);
5044   mysql_stmt_close(stmt1);
5045 }
5046 
5047 /* Test FUNCTION field info / DATE_FORMAT() table_name . */
5048 
test_func_fields()5049 static void test_func_fields()
5050 {
5051   int        rc;
5052   MYSQL_RES  *result;
5053   MYSQL_FIELD *field;
5054 
5055   myheader("test_func_fields");
5056 
5057   rc= mysql_autocommit(mysql, TRUE);
5058   myquery(rc);
5059 
5060   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_dateformat");
5061   myquery(rc);
5062 
5063   rc= mysql_query(mysql, "CREATE TABLE test_dateformat(id int, \
5064                                                        ts timestamp)");
5065   myquery(rc);
5066 
5067   rc= mysql_query(mysql, "INSERT INTO test_dateformat(id) values(10)");
5068   myquery(rc);
5069 
5070   rc= mysql_query(mysql, "SELECT ts FROM test_dateformat");
5071   myquery(rc);
5072 
5073   result= mysql_store_result(mysql);
5074   mytest(result);
5075 
5076   field= mysql_fetch_field(result);
5077   mytest(field);
5078   if (!opt_silent)
5079     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table,
5080             "test_dateformat");
5081   DIE_UNLESS(strcmp(field->table, "test_dateformat") == 0);
5082 
5083   field= mysql_fetch_field(result);
5084   mytest_r(field); /* no more fields */
5085 
5086   mysql_free_result(result);
5087 
5088   /* DATE_FORMAT */
5089   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'venu' FROM test_dateformat");
5090   myquery(rc);
5091 
5092   result= mysql_store_result(mysql);
5093   mytest(result);
5094 
5095   field= mysql_fetch_field(result);
5096   mytest(field);
5097   if (!opt_silent)
5098     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table, "");
5099   DIE_UNLESS(field->table[0] == '\0');
5100 
5101   field= mysql_fetch_field(result);
5102   mytest_r(field); /* no more fields */
5103 
5104   mysql_free_result(result);
5105 
5106   /* FIELD ALIAS TEST */
5107   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y')  AS 'YEAR' FROM test_dateformat");
5108   myquery(rc);
5109 
5110   result= mysql_store_result(mysql);
5111   mytest(result);
5112 
5113   field= mysql_fetch_field(result);
5114   mytest(field);
5115   if (!opt_silent)
5116   {
5117     printf("\n field name: `%s` (expected: `%s`)", field->name, "YEAR");
5118     printf("\n field org name: `%s` (expected: `%s`)", field->org_name, "");
5119   }
5120   DIE_UNLESS(strcmp(field->name, "YEAR") == 0);
5121   DIE_UNLESS(field->org_name[0] == '\0');
5122 
5123   field= mysql_fetch_field(result);
5124   mytest_r(field); /* no more fields */
5125 
5126   mysql_free_result(result);
5127 }
5128 
5129 
5130 /* Multiple stmts .. */
5131 
test_multi_stmt()5132 static void test_multi_stmt()
5133 {
5134 
5135   MYSQL_STMT  *stmt, *stmt1, *stmt2;
5136   int         rc;
5137   uint32      id;
5138   char        name[50];
5139   MYSQL_BIND  my_bind[2];
5140   ulong       length[2];
5141   my_bool     is_null[2];
5142   myheader("test_multi_stmt");
5143 
5144   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_multi_table");
5145   myquery(rc);
5146 
5147   rc= mysql_query(mysql, "CREATE TABLE test_multi_table(id int, name char(20))");
5148   myquery(rc);
5149 
5150   rc= mysql_query(mysql, "INSERT INTO test_multi_table values(10, 'mysql')");
5151   myquery(rc);
5152 
5153   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_multi_table "
5154                                     "WHERE id= ?");
5155   check_stmt(stmt);
5156 
5157   stmt2= mysql_simple_prepare(mysql, "UPDATE test_multi_table "
5158                                      "SET name='updated' WHERE id=10");
5159   check_stmt(stmt2);
5160 
5161   verify_param_count(stmt, 1);
5162 
5163   /*
5164     We need to bzero bind structure because mysql_stmt_bind_param checks all
5165     its members.
5166   */
5167   bzero((char*) my_bind, sizeof(my_bind));
5168 
5169   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5170   my_bind[0].buffer= (void *)&id;
5171   my_bind[0].is_null= &is_null[0];
5172   my_bind[0].length= &length[0];
5173   is_null[0]= 0;
5174   length[0]= 0;
5175 
5176   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5177   my_bind[1].buffer= (void *)name;
5178   my_bind[1].buffer_length= sizeof(name);
5179   my_bind[1].length= &length[1];
5180   my_bind[1].is_null= &is_null[1];
5181 
5182   rc= mysql_stmt_bind_param(stmt, my_bind);
5183   check_execute(stmt, rc);
5184 
5185   rc= mysql_stmt_bind_result(stmt, my_bind);
5186   check_execute(stmt, rc);
5187 
5188   id= 10;
5189   rc= mysql_stmt_execute(stmt);
5190   check_execute(stmt, rc);
5191 
5192   id= 999;
5193   rc= mysql_stmt_fetch(stmt);
5194   check_execute(stmt, rc);
5195 
5196   if (!opt_silent)
5197   {
5198     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5199     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5200   }
5201   DIE_UNLESS(id == 10);
5202   DIE_UNLESS(strcmp(name, "mysql") == 0);
5203 
5204   rc= mysql_stmt_fetch(stmt);
5205   DIE_UNLESS(rc == MYSQL_NO_DATA);
5206 
5207   /* alter the table schema now */
5208   stmt1= mysql_simple_prepare(mysql, "DELETE FROM test_multi_table "
5209                                      "WHERE id= ? AND "
5210                                      "CONVERT(name USING utf8)=?");
5211   check_stmt(stmt1);
5212 
5213   verify_param_count(stmt1, 2);
5214 
5215   rc= mysql_stmt_bind_param(stmt1, my_bind);
5216   check_execute(stmt1, rc);
5217 
5218   rc= mysql_stmt_execute(stmt2);
5219   check_execute(stmt2, rc);
5220 
5221   verify_st_affected_rows(stmt2, 1);
5222 
5223   rc= mysql_stmt_execute(stmt);
5224   check_execute(stmt, rc);
5225 
5226   rc= mysql_stmt_fetch(stmt);
5227   check_execute(stmt, rc);
5228 
5229   if (!opt_silent)
5230   {
5231     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5232     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5233   }
5234   DIE_UNLESS(id == 10);
5235   DIE_UNLESS(strcmp(name, "updated") == 0);
5236 
5237   rc= mysql_stmt_fetch(stmt);
5238   DIE_UNLESS(rc == MYSQL_NO_DATA);
5239 
5240   rc= mysql_stmt_execute(stmt1);
5241   check_execute(stmt1, rc);
5242 
5243   verify_st_affected_rows(stmt1, 1);
5244 
5245   mysql_stmt_close(stmt1);
5246 
5247   rc= mysql_stmt_execute(stmt);
5248   check_execute(stmt, rc);
5249 
5250   rc= mysql_stmt_fetch(stmt);
5251   DIE_UNLESS(rc == MYSQL_NO_DATA);
5252 
5253   rc= my_stmt_result("SELECT * FROM test_multi_table");
5254   DIE_UNLESS(rc == 0);
5255 
5256   mysql_stmt_close(stmt);
5257   mysql_stmt_close(stmt2);
5258 
5259 }
5260 
5261 
5262 /* Test simple sample - manual */
5263 
test_manual_sample()5264 static void test_manual_sample()
5265 {
5266   unsigned int param_count;
5267   MYSQL_STMT   *stmt;
5268   short        small_data= 1;
5269   int          int_data= 2;
5270   int          rc;
5271   char         str_data[50]= "std_data";
5272   ulonglong    affected_rows;
5273   MYSQL_BIND   my_bind[3];
5274   my_bool      is_null;
5275   char query[MAX_TEST_QUERY_LENGTH];
5276 
5277   myheader("test_manual_sample");
5278 
5279   /*
5280     Sample which is incorporated directly in the manual under Prepared
5281     statements section (Example from mysql_stmt_execute()
5282   */
5283 
5284   mysql_autocommit(mysql, 1);
5285   if (mysql_query(mysql, "DROP TABLE IF EXISTS test_table"))
5286   {
5287     fprintf(stderr, "\n drop table failed");
5288     fprintf(stderr, "\n %s", mysql_error(mysql));
5289     exit(1);
5290   }
5291   if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \
5292                                                  col3 smallint, \
5293                                                  col4 timestamp)"))
5294   {
5295     fprintf(stderr, "\n create table failed");
5296     fprintf(stderr, "\n %s", mysql_error(mysql));
5297     exit(1);
5298   }
5299 
5300   /* Prepare a insert query with 3 parameters */
5301   strmov(query, "INSERT INTO test_table(col1, col2, col3) values(?, ?, ?)");
5302   if (!(stmt= mysql_simple_prepare(mysql, query)))
5303   {
5304     fprintf(stderr, "\n prepare, insert failed");
5305     fprintf(stderr, "\n %s", mysql_error(mysql));
5306     exit(1);
5307   }
5308   if (!opt_silent)
5309     fprintf(stdout, "\n prepare, insert successful");
5310 
5311   /* Get the parameter count from the statement */
5312   param_count= mysql_stmt_param_count(stmt);
5313 
5314   if (!opt_silent)
5315     fprintf(stdout, "\n total parameters in insert: %d", param_count);
5316   if (param_count != 3) /* validate parameter count */
5317   {
5318     fprintf(stderr, "\n invalid parameter count returned by MySQL");
5319     exit(1);
5320   }
5321 
5322   /* Bind the data for the parameters */
5323 
5324   /*
5325     We need to bzero bind structure because mysql_stmt_bind_param checks all
5326     its members.
5327   */
5328   bzero((char*) my_bind, sizeof(my_bind));
5329 
5330   /* INTEGER PART */
5331   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5332   my_bind[0].buffer= (void *)&int_data;
5333 
5334   /* STRING PART */
5335   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
5336   my_bind[1].buffer= (void *)str_data;
5337   my_bind[1].buffer_length= sizeof(str_data);
5338 
5339   /* SMALLINT PART */
5340   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
5341   my_bind[2].buffer= (void *)&small_data;
5342   my_bind[2].is_null= &is_null;
5343   is_null= 0;
5344 
5345   /* Bind the buffers */
5346   if (mysql_stmt_bind_param(stmt, my_bind))
5347   {
5348     fprintf(stderr, "\n param bind failed");
5349     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5350     exit(1);
5351   }
5352 
5353   /* Specify the data */
5354   int_data= 10;             /* integer */
5355   strmov(str_data, "MySQL"); /* string  */
5356 
5357   /* INSERT SMALLINT data as NULL */
5358   is_null= 1;
5359 
5360   /* Execute the insert statement - 1*/
5361   if (mysql_stmt_execute(stmt))
5362   {
5363     fprintf(stderr, "\n execute 1 failed");
5364     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5365     exit(1);
5366   }
5367 
5368   /* Get the total rows affected */
5369   affected_rows= mysql_stmt_affected_rows(stmt);
5370 
5371   if (!opt_silent)
5372     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5373   if (affected_rows != 1) /* validate affected rows */
5374   {
5375     fprintf(stderr, "\n invalid affected rows by MySQL");
5376     exit(1);
5377   }
5378 
5379   /* Re-execute the insert, by changing the values */
5380   int_data= 1000;
5381   strmov(str_data, "The most popular open source database");
5382   small_data= 1000;         /* smallint */
5383   is_null= 0;               /* reset */
5384 
5385   /* Execute the insert statement - 2*/
5386   if (mysql_stmt_execute(stmt))
5387   {
5388     fprintf(stderr, "\n execute 2 failed");
5389     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5390     exit(1);
5391   }
5392 
5393   /* Get the total rows affected */
5394   affected_rows= mysql_stmt_affected_rows(stmt);
5395 
5396   if (!opt_silent)
5397     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5398   if (affected_rows != 1) /* validate affected rows */
5399   {
5400     fprintf(stderr, "\n invalid affected rows by MySQL");
5401     exit(1);
5402   }
5403 
5404   /* Close the statement */
5405   if (mysql_stmt_close(stmt))
5406   {
5407     fprintf(stderr, "\n failed while closing the statement");
5408     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5409     exit(1);
5410   }
5411   rc= my_stmt_result("SELECT * FROM test_table");
5412   DIE_UNLESS(rc == 2);
5413 
5414   /* DROP THE TABLE */
5415   if (mysql_query(mysql, "DROP TABLE test_table"))
5416   {
5417     fprintf(stderr, "\n drop table failed");
5418     fprintf(stderr, "\n %s", mysql_error(mysql));
5419     exit(1);
5420   }
5421   if (!opt_silent)
5422     fprintf(stdout, "Success !!!");
5423 }
5424 
5425 
5426 /* Test alter table scenario in the middle of prepare */
5427 
test_prepare_alter()5428 static void test_prepare_alter()
5429 {
5430   MYSQL_STMT  *stmt;
5431   int         rc, id;
5432   MYSQL_BIND  my_bind[1];
5433   my_bool     is_null;
5434 
5435   myheader("test_prepare_alter");
5436 
5437   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_alter");
5438   myquery(rc);
5439 
5440   rc= mysql_query(mysql, "CREATE TABLE test_prep_alter(id int, name char(20))");
5441   myquery(rc);
5442 
5443   rc= mysql_query(mysql, "INSERT INTO test_prep_alter values(10, 'venu'), (20, 'mysql')");
5444   myquery(rc);
5445 
5446   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?, 'monty')");
5447   check_stmt(stmt);
5448 
5449   verify_param_count(stmt, 1);
5450 
5451   /*
5452     We need to bzero bind structure because mysql_stmt_bind_param checks all
5453     its members.
5454   */
5455   bzero((char*) my_bind, sizeof(my_bind));
5456 
5457   is_null= 0;
5458   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
5459   my_bind[0].buffer= (void *)&id;
5460   my_bind[0].is_null= &is_null;
5461 
5462   rc= mysql_stmt_bind_param(stmt, my_bind);
5463   check_execute(stmt, rc);
5464 
5465   id= 30;
5466   rc= mysql_stmt_execute(stmt);
5467   check_execute(stmt, rc);
5468 
5469   if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)"))
5470     exit(1);
5471 
5472   is_null= 1;
5473   rc= mysql_stmt_execute(stmt);
5474   check_execute(stmt, rc);
5475 
5476   rc= my_stmt_result("SELECT * FROM test_prep_alter");
5477   DIE_UNLESS(rc == 4);
5478 
5479   mysql_stmt_close(stmt);
5480 }
5481 
5482 
5483 /* Test the support of multi-statement executions */
5484 
test_multi_statements()5485 static void test_multi_statements()
5486 {
5487   MYSQL *mysql_local;
5488   MYSQL_RES *result;
5489   int    rc;
5490 
5491   const char *query= "\
5492 DROP TABLE IF EXISTS test_multi_tab;\
5493 CREATE TABLE test_multi_tab(id int, name char(20));\
5494 INSERT INTO test_multi_tab(id) VALUES(10), (20);\
5495 INSERT INTO test_multi_tab VALUES(20, 'insert;comma');\
5496 SELECT * FROM test_multi_tab;\
5497 UPDATE test_multi_tab SET name='new;name' WHERE id=20;\
5498 DELETE FROM test_multi_tab WHERE name='new;name';\
5499 SELECT * FROM test_multi_tab;\
5500 DELETE FROM test_multi_tab WHERE id=10;\
5501 SELECT * FROM test_multi_tab;\
5502 DROP TABLE test_multi_tab;\
5503 select 1;\
5504 DROP TABLE IF EXISTS test_multi_tab";
5505   uint count, exp_value;
5506   uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0};
5507 
5508   myheader("test_multi_statements");
5509 
5510   /*
5511     First test that we get an error for multi statements
5512     (Because default connection is not opened with CLIENT_MULTI_STATEMENTS)
5513   */
5514   rc= mysql_query(mysql, query); /* syntax error */
5515   myquery_r(rc);
5516 
5517   rc= mysql_next_result(mysql);
5518   DIE_UNLESS(rc == -1);
5519   rc= mysql_more_results(mysql);
5520   DIE_UNLESS(rc == 0);
5521 
5522   if (!(mysql_local= mysql_client_init(NULL)))
5523   {
5524     fprintf(stdout, "\n mysql_client_init() failed");
5525     exit(1);
5526   }
5527 
5528   /* Create connection that supports multi statements */
5529   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5530                            opt_password, current_db, opt_port,
5531                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5532   {
5533     fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local));
5534     exit(1);
5535   }
5536   mysql_options(mysql_local, MYSQL_OPT_RECONNECT, &my_true);
5537 
5538   rc= mysql_query(mysql_local, query);
5539   myquery(rc);
5540 
5541   for (count= 0 ; count < array_elements(rows) ; count++)
5542   {
5543     if (!opt_silent)
5544       fprintf(stdout, "\n Query %d: ", count);
5545     if ((result= mysql_store_result(mysql_local)))
5546     {
5547       (void) my_process_result_set(result);
5548       mysql_free_result(result);
5549     }
5550     else if (!opt_silent)
5551       fprintf(stdout, "OK, %ld row(s) affected, %ld warning(s)\n",
5552               (ulong) mysql_affected_rows(mysql_local),
5553               (ulong) mysql_warning_count(mysql_local));
5554 
5555     exp_value= (uint) mysql_affected_rows(mysql_local);
5556     if (rows[count] !=  exp_value)
5557     {
5558       fprintf(stderr, "row %d  had affected rows: %d, should be %d\n",
5559               count, exp_value, rows[count]);
5560       exit(1);
5561     }
5562     if (count != array_elements(rows) -1)
5563     {
5564       if (!(rc= mysql_more_results(mysql_local)))
5565       {
5566         fprintf(stdout,
5567                 "mysql_more_result returned wrong value: %d for row %d\n",
5568                 rc, count);
5569         exit(1);
5570       }
5571       if ((rc= mysql_next_result(mysql_local)))
5572       {
5573         exp_value= mysql_errno(mysql_local);
5574 
5575         exit(1);
5576       }
5577     }
5578     else
5579     {
5580       rc= mysql_more_results(mysql_local);
5581       DIE_UNLESS(rc == 0);
5582       rc= mysql_next_result(mysql_local);
5583       DIE_UNLESS(rc == -1);
5584     }
5585   }
5586 
5587   /* check that errors abort multi statements */
5588 
5589   rc= mysql_query(mysql_local, "select 1+1+a;select 1+1");
5590   myquery_r(rc);
5591   rc= mysql_more_results(mysql_local);
5592   DIE_UNLESS(rc == 0);
5593   rc= mysql_next_result(mysql_local);
5594   DIE_UNLESS(rc == -1);
5595 
5596   rc= mysql_query(mysql_local, "select 1+1;select 1+1+a;select 1");
5597   myquery(rc);
5598   result= mysql_store_result(mysql_local);
5599   mytest(result);
5600   mysql_free_result(result);
5601   rc= mysql_more_results(mysql_local);
5602   DIE_UNLESS(rc == 1);
5603   rc= mysql_next_result(mysql_local);
5604   DIE_UNLESS(rc > 0);
5605 
5606   /*
5607     Ensure that we can now do a simple query (this checks that the server is
5608     not trying to send us the results for the last 'select 1'
5609   */
5610   rc= mysql_query(mysql_local, "select 1+1+1");
5611   myquery(rc);
5612   result= mysql_store_result(mysql_local);
5613   mytest(result);
5614   (void) my_process_result_set(result);
5615   mysql_free_result(result);
5616 
5617   /*
5618     Check if errors in one of the queries handled properly.
5619   */
5620   rc= mysql_query(mysql_local, "select 1; select * from not_existing_table");
5621   myquery(rc);
5622   result= mysql_store_result(mysql_local);
5623   mysql_free_result(result);
5624 
5625   rc= mysql_next_result(mysql_local);
5626   DIE_UNLESS(rc > 0);
5627 
5628   rc= mysql_next_result(mysql_local);
5629   DIE_UNLESS(rc < 0);
5630 
5631   mysql_close(mysql_local);
5632 }
5633 
5634 
5635 /*
5636   Check that Prepared statement cannot contain several
5637   SQL statements
5638 */
5639 
test_prepare_multi_statements()5640 static void test_prepare_multi_statements()
5641 {
5642   MYSQL *mysql_local;
5643   MYSQL_STMT *stmt;
5644   char query[MAX_TEST_QUERY_LENGTH];
5645   myheader("test_prepare_multi_statements");
5646 
5647   if (!(mysql_local= mysql_client_init(NULL)))
5648   {
5649     fprintf(stderr, "\n mysql_client_init() failed");
5650     exit(1);
5651   }
5652 
5653   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5654                            opt_password, current_db, opt_port,
5655                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5656   {
5657     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
5658     exit(1);
5659   }
5660   mysql_options(mysql_local, MYSQL_OPT_RECONNECT, &my_true);
5661   strmov(query, "select 1; select 'another value'");
5662   stmt= mysql_simple_prepare(mysql_local, query);
5663   check_stmt_r(stmt);
5664   mysql_close(mysql_local);
5665 }
5666 
5667 
5668 /* Test simple bind store result */
5669 
test_store_result()5670 static void test_store_result()
5671 {
5672   MYSQL_STMT *stmt;
5673   int        rc;
5674   int32      nData;
5675   char       szData[100];
5676   MYSQL_BIND my_bind[2];
5677   ulong      length, length1;
5678   my_bool    is_null[2];
5679 
5680   myheader("test_store_result");
5681 
5682   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5683   myquery(rc);
5684 
5685   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5686   myquery(rc);
5687 
5688   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5689   myquery(rc);
5690 
5691   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5692   myquery(rc);
5693 
5694   rc= mysql_commit(mysql);
5695   myquery(rc);
5696 
5697   /* fetch */
5698   bzero((char*) my_bind, sizeof(my_bind));
5699   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5700   my_bind[0].buffer= (void *) &nData;       /* integer data */
5701   my_bind[0].length= &length;
5702   my_bind[0].is_null= &is_null[0];
5703 
5704   length= 0;
5705   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5706   my_bind[1].buffer= szData;                /* string data */
5707   my_bind[1].buffer_length= sizeof(szData);
5708   my_bind[1].length= &length1;
5709   my_bind[1].is_null= &is_null[1];
5710   length1= 0;
5711 
5712   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5713   check_stmt(stmt);
5714 
5715   rc= mysql_stmt_bind_result(stmt, my_bind);
5716   check_execute(stmt, rc);
5717 
5718   rc= mysql_stmt_execute(stmt);
5719   check_execute(stmt, rc);
5720 
5721   rc= mysql_stmt_store_result(stmt);
5722   check_execute(stmt, rc);
5723 
5724   rc= mysql_stmt_fetch(stmt);
5725   check_execute(stmt, rc);
5726 
5727   if (!opt_silent)
5728     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5729   DIE_UNLESS(nData == 10);
5730   DIE_UNLESS(strcmp(szData, "venu") == 0);
5731   DIE_UNLESS(length1 == 4);
5732 
5733   rc= mysql_stmt_fetch(stmt);
5734   check_execute(stmt, rc);
5735 
5736   if (!opt_silent)
5737     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5738   DIE_UNLESS(nData == 20);
5739   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5740   DIE_UNLESS(length1 == 5);
5741 
5742   length= 99;
5743   rc= mysql_stmt_fetch(stmt);
5744   check_execute(stmt, rc);
5745 
5746   if (!opt_silent && is_null[0])
5747     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5748   DIE_UNLESS(is_null[0]);
5749   DIE_UNLESS(strcmp(szData, "monty") == 0);
5750   DIE_UNLESS(length1 == 5);
5751 
5752   rc= mysql_stmt_fetch(stmt);
5753   DIE_UNLESS(rc == MYSQL_NO_DATA);
5754 
5755   rc= mysql_stmt_execute(stmt);
5756   check_execute(stmt, rc);
5757 
5758   rc= mysql_stmt_store_result(stmt);
5759   check_execute(stmt, rc);
5760 
5761   rc= mysql_stmt_fetch(stmt);
5762   check_execute(stmt, rc);
5763 
5764   if (!opt_silent)
5765     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5766   DIE_UNLESS(nData == 10);
5767   DIE_UNLESS(strcmp(szData, "venu") == 0);
5768   DIE_UNLESS(length1 == 4);
5769 
5770   rc= mysql_stmt_fetch(stmt);
5771   check_execute(stmt, rc);
5772 
5773   if (!opt_silent)
5774     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5775   DIE_UNLESS(nData == 20);
5776   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5777   DIE_UNLESS(length1 == 5);
5778 
5779   length= 99;
5780   rc= mysql_stmt_fetch(stmt);
5781   check_execute(stmt, rc);
5782 
5783   if (!opt_silent && is_null[0])
5784     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5785   DIE_UNLESS(is_null[0]);
5786   DIE_UNLESS(strcmp(szData, "monty") == 0);
5787   DIE_UNLESS(length1 == 5);
5788 
5789   rc= mysql_stmt_fetch(stmt);
5790   DIE_UNLESS(rc == MYSQL_NO_DATA);
5791 
5792   mysql_stmt_close(stmt);
5793 }
5794 
5795 
5796 /* Test simple bind store result */
5797 
test_store_result1()5798 static void test_store_result1()
5799 {
5800   MYSQL_STMT *stmt;
5801   int        rc;
5802 
5803   myheader("test_store_result1");
5804 
5805   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5806   myquery(rc);
5807 
5808   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5809   myquery(rc);
5810 
5811   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5812   myquery(rc);
5813 
5814   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5815   myquery(rc);
5816 
5817   rc= mysql_commit(mysql);
5818   myquery(rc);
5819 
5820   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5821   check_stmt(stmt);
5822 
5823   rc= mysql_stmt_execute(stmt);
5824   check_execute(stmt, rc);
5825 
5826   rc= mysql_stmt_store_result(stmt);
5827   check_execute(stmt, rc);
5828 
5829   rc= 0;
5830   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5831     rc++;
5832   if (!opt_silent)
5833     fprintf(stdout, "\n total rows: %d", rc);
5834   DIE_UNLESS(rc == 3);
5835 
5836   rc= mysql_stmt_execute(stmt);
5837   check_execute(stmt, rc);
5838 
5839   rc= mysql_stmt_store_result(stmt);
5840   check_execute(stmt, rc);
5841 
5842   rc= 0;
5843   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5844     rc++;
5845   if (!opt_silent)
5846     fprintf(stdout, "\n total rows: %d", rc);
5847   DIE_UNLESS(rc == 3);
5848 
5849   mysql_stmt_close(stmt);
5850 }
5851 
5852 
5853 /* Another test for bind and store result */
5854 
test_store_result2()5855 static void test_store_result2()
5856 {
5857   MYSQL_STMT *stmt;
5858   int        rc;
5859   int        nData;
5860   ulong      length;
5861   MYSQL_BIND my_bind[1];
5862   char query[MAX_TEST_QUERY_LENGTH];
5863 
5864   myheader("test_store_result2");
5865 
5866   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5867   myquery(rc);
5868 
5869   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5870   myquery(rc);
5871 
5872   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5873   myquery(rc);
5874 
5875   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5876   myquery(rc);
5877 
5878   rc= mysql_commit(mysql);
5879   myquery(rc);
5880 
5881   /*
5882     We need to bzero bind structure because mysql_stmt_bind_param checks all
5883     its members.
5884   */
5885   bzero((char*) my_bind, sizeof(my_bind));
5886 
5887   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5888   my_bind[0].buffer= (void *) &nData;      /* integer data */
5889   my_bind[0].length= &length;
5890   my_bind[0].is_null= 0;
5891 
5892   strmov((char *)query , "SELECT col1 FROM test_store_result where col1= ?");
5893   stmt= mysql_simple_prepare(mysql, query);
5894   check_stmt(stmt);
5895 
5896   rc= mysql_stmt_bind_param(stmt, my_bind);
5897   check_execute(stmt, rc);
5898 
5899   rc= mysql_stmt_bind_result(stmt, my_bind);
5900   check_execute(stmt, rc);
5901 
5902   nData= 10; length= 0;
5903   rc= mysql_stmt_execute(stmt);
5904   check_execute(stmt, rc);
5905 
5906   nData= 0;
5907   rc= mysql_stmt_store_result(stmt);
5908   check_execute(stmt, rc);
5909 
5910   rc= mysql_stmt_fetch(stmt);
5911   check_execute(stmt, rc);
5912 
5913   if (!opt_silent)
5914     fprintf(stdout, "\n row 1: %d", nData);
5915   DIE_UNLESS(nData == 10);
5916 
5917   rc= mysql_stmt_fetch(stmt);
5918   DIE_UNLESS(rc == MYSQL_NO_DATA);
5919 
5920   nData= 20;
5921   rc= mysql_stmt_execute(stmt);
5922   check_execute(stmt, rc);
5923 
5924   nData= 0;
5925   rc= mysql_stmt_store_result(stmt);
5926   check_execute(stmt, rc);
5927 
5928   rc= mysql_stmt_fetch(stmt);
5929   check_execute(stmt, rc);
5930 
5931   if (!opt_silent)
5932     fprintf(stdout, "\n row 1: %d", nData);
5933   DIE_UNLESS(nData == 20);
5934 
5935   rc= mysql_stmt_fetch(stmt);
5936   DIE_UNLESS(rc == MYSQL_NO_DATA);
5937   mysql_stmt_close(stmt);
5938 }
5939 
5940 
5941 /* Test simple subselect prepare */
5942 
test_subselect()5943 static void test_subselect()
5944 {
5945 
5946   MYSQL_STMT *stmt;
5947   int        rc, id;
5948   MYSQL_BIND my_bind[1];
5949   DBUG_ENTER("test_subselect");
5950 
5951   myheader("test_subselect");
5952 
5953   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub1");
5954   myquery(rc);
5955 
5956   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub2");
5957   myquery(rc);
5958 
5959   rc= mysql_query(mysql, "CREATE TABLE test_sub1(id int)");
5960   myquery(rc);
5961 
5962   rc= mysql_query(mysql, "CREATE TABLE test_sub2(id int, id1 int)");
5963   myquery(rc);
5964 
5965   rc= mysql_query(mysql, "INSERT INTO test_sub1 values(2)");
5966   myquery(rc);
5967 
5968   rc= mysql_query(mysql, "INSERT INTO test_sub2 VALUES(1, 7), (2, 7)");
5969   myquery(rc);
5970 
5971   rc= mysql_commit(mysql);
5972   myquery(rc);
5973 
5974   /* fetch */
5975   /*
5976     We need to bzero bind structure because mysql_stmt_bind_param checks all
5977     its members.
5978   */
5979   bzero((char*) my_bind, sizeof(my_bind));
5980 
5981   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5982   my_bind[0].buffer= (void *) &id;
5983   my_bind[0].length= 0;
5984   my_bind[0].is_null= 0;
5985 
5986   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id= ?");
5987   check_stmt(stmt);
5988 
5989   rc= mysql_stmt_bind_param(stmt, my_bind);
5990   check_execute(stmt, rc);
5991 
5992   id= 2;
5993   rc= mysql_stmt_execute(stmt);
5994   check_execute(stmt, rc);
5995 
5996   verify_st_affected_rows(stmt, 1);
5997 
5998   id= 9;
5999   rc= mysql_stmt_execute(stmt);
6000   check_execute(stmt, rc);
6001 
6002   verify_st_affected_rows(stmt, 0);
6003 
6004   mysql_stmt_close(stmt);
6005 
6006   rc= my_stmt_result("SELECT * FROM test_sub2");
6007   DIE_UNLESS(rc == 3);
6008 
6009   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
6010                      "from test_sub2 WHERE id1= 8)");
6011   DIE_UNLESS(rc == 1);
6012   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
6013                      "from test_sub2 WHERE id1= 7)");
6014   DIE_UNLESS(rc == 1);
6015 
6016   stmt= mysql_simple_prepare(mysql, ("SELECT ROW(1, 7) IN (select id, id1 "
6017                                      "from test_sub2 WHERE id1= ?)"));
6018   check_stmt(stmt);
6019 
6020   rc= mysql_stmt_bind_param(stmt, my_bind);
6021   check_execute(stmt, rc);
6022 
6023   rc= mysql_stmt_bind_result(stmt, my_bind);
6024   check_execute(stmt, rc);
6025 
6026   id= 7;
6027   rc= mysql_stmt_execute(stmt);
6028   check_execute(stmt, rc);
6029 
6030   rc= mysql_stmt_fetch(stmt);
6031   check_execute(stmt, rc);
6032 
6033   if (!opt_silent)
6034     fprintf(stdout, "\n row 1: %d", id);
6035   DIE_UNLESS(id == 1);
6036 
6037   rc= mysql_stmt_fetch(stmt);
6038   DIE_UNLESS(rc == MYSQL_NO_DATA);
6039 
6040   id= 8;
6041   rc= mysql_stmt_execute(stmt);
6042   check_execute(stmt, rc);
6043 
6044   rc= mysql_stmt_fetch(stmt);
6045   check_execute(stmt, rc);
6046 
6047   if (!opt_silent)
6048     fprintf(stdout, "\n row 1: %d", id);
6049   DIE_UNLESS(id == 0);
6050 
6051   rc= mysql_stmt_fetch(stmt);
6052   DIE_UNLESS(rc == MYSQL_NO_DATA);
6053 
6054   mysql_stmt_close(stmt);
6055   DBUG_VOID_RETURN;
6056 }
6057 
6058 
6059 /*
6060   Generalized conversion routine to handle DATE, TIME and DATETIME
6061   conversion using MYSQL_TIME structure
6062 */
6063 
test_bind_date_conv(uint row_count)6064 static void test_bind_date_conv(uint row_count)
6065 {
6066   MYSQL_STMT   *stmt= 0;
6067   uint         rc, i, count= row_count;
6068   ulong        length[4];
6069   MYSQL_BIND   my_bind[4];
6070   my_bool      is_null[4]= {0};
6071   MYSQL_TIME   tm[4];
6072   ulong        second_part;
6073   uint         year, month, day, hour, minute, sec;
6074   uint         now_year= 1990, now_month= 3, now_day= 13;
6075 
6076   rc= mysql_query(mysql, "SET timestamp=UNIX_TIMESTAMP('1990-03-13')");
6077   myquery(rc);
6078 
6079   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_date VALUES(?, ?, ?, ?)");
6080   check_stmt(stmt);
6081 
6082   verify_param_count(stmt, 4);
6083 
6084   /*
6085     We need to bzero bind structure because mysql_stmt_bind_param checks all
6086     its members.
6087   */
6088   bzero((char*) my_bind, sizeof(my_bind));
6089 
6090   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
6091   my_bind[1].buffer_type= MYSQL_TYPE_TIME;
6092   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
6093   my_bind[3].buffer_type= MYSQL_TYPE_DATE;
6094 
6095   for (i= 0; i < (int) array_elements(my_bind); i++)
6096   {
6097     my_bind[i].buffer= (void *) &tm[i];
6098     my_bind[i].is_null= &is_null[i];
6099     my_bind[i].length= &length[i];
6100     my_bind[i].buffer_length= 30;
6101     length[i]= 20;
6102   }
6103 
6104   second_part= 0;
6105 
6106   year= 2000;
6107   month= 01;
6108   day= 10;
6109 
6110   hour= 11;
6111   minute= 16;
6112   sec= 20;
6113 
6114   rc= mysql_stmt_bind_param(stmt, my_bind);
6115   check_execute(stmt, rc);
6116 
6117   for (count= 0; count < row_count; count++)
6118   {
6119     for (i= 0; i < (int) array_elements(my_bind); i++)
6120     {
6121       tm[i].neg= 0;
6122       tm[i].second_part= second_part+count;
6123       if (my_bind[i].buffer_type != MYSQL_TYPE_TIME)
6124       {
6125         tm[i].year= year+count;
6126         tm[i].month= month+count;
6127         tm[i].day= day+count;
6128       }
6129       else
6130         tm[i].year= tm[i].month= tm[i].day= 0;
6131       if (my_bind[i].buffer_type != MYSQL_TYPE_DATE)
6132       {
6133         tm[i].hour= hour+count;
6134         tm[i].minute= minute+count;
6135         tm[i].second= sec+count;
6136       }
6137       else
6138         tm[i].hour= tm[i].minute= tm[i].second= 0;
6139     }
6140     rc= mysql_stmt_execute(stmt);
6141     check_execute(stmt, rc);
6142   }
6143 
6144   rc= mysql_commit(mysql);
6145   myquery(rc);
6146 
6147   mysql_stmt_close(stmt);
6148 
6149   rc= my_stmt_result("SELECT * FROM test_date");
6150   DIE_UNLESS(row_count == rc);
6151 
6152   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_date");
6153   check_stmt(stmt);
6154 
6155   rc= mysql_stmt_bind_result(stmt, my_bind);
6156   check_execute(stmt, rc);
6157 
6158   rc= mysql_stmt_execute(stmt);
6159   check_execute(stmt, rc);
6160 
6161   rc= mysql_stmt_store_result(stmt);
6162   check_execute(stmt, rc);
6163 
6164   for (count= 0; count < row_count; count++)
6165   {
6166     rc= mysql_stmt_fetch(stmt);
6167     DIE_UNLESS(rc == 0 || rc == MYSQL_DATA_TRUNCATED);
6168 
6169     if (!opt_silent)
6170       fprintf(stdout, "\n");
6171     for (i= 0; i < array_elements(my_bind); i++)
6172     {
6173       if (!opt_silent)
6174         fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d %02d:%02d:%02d.%02lu",
6175                 i, tm[i].year, tm[i].month, tm[i].day,
6176                 tm[i].hour, tm[i].minute, tm[i].second,
6177                 tm[i].second_part);
6178       DIE_UNLESS(tm[i].year == 0 || tm[i].year == year + count ||
6179                  (tm[i].year == now_year &&
6180                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6181       DIE_UNLESS(tm[i].month == 0 || tm[i].month == month + count ||
6182                  (tm[i].month == now_month &&
6183                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6184       DIE_UNLESS(tm[i].day == 0 || tm[i].day == day + count ||
6185                  (tm[i].day == now_day &&
6186                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6187 
6188       DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count);
6189       DIE_UNLESS(tm[i].minute == 0 || tm[i].minute == minute+count);
6190       DIE_UNLESS(tm[i].second == 0 || tm[i].second == sec+count);
6191       DIE_UNLESS(tm[i].second_part == 0 ||
6192                  tm[i].second_part == second_part+count);
6193     }
6194   }
6195   rc= mysql_stmt_fetch(stmt);
6196   DIE_UNLESS(rc == MYSQL_NO_DATA);
6197 
6198   mysql_stmt_close(stmt);
6199 }
6200 
6201 
6202 /* Test DATE, TIME, DATETIME and TS with MYSQL_TIME conversion */
6203 
test_date()6204 static void test_date()
6205 {
6206   int        rc;
6207 
6208   myheader("test_date");
6209 
6210   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6211   myquery(rc);
6212 
6213   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6214                                                  c2 TIME, \
6215                                                  c3 DATETIME, \
6216                                                  c4 DATE)");
6217 
6218   myquery(rc);
6219 
6220   test_bind_date_conv(5);
6221 }
6222 
6223 
6224 /* Test all time types to DATE and DATE to all types */
6225 
test_date_date()6226 static void test_date_date()
6227 {
6228   int        rc;
6229 
6230   myheader("test_date_date");
6231 
6232   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6233   myquery(rc);
6234 
6235   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 DATE, \
6236                                                  c2 DATE, \
6237                                                  c3 DATE, \
6238                                                  c4 DATE)");
6239 
6240   myquery(rc);
6241 
6242   test_bind_date_conv(3);
6243 }
6244 
6245 
6246 /* Test all time types to TIME and TIME to all types */
6247 
test_date_time()6248 static void test_date_time()
6249 {
6250   int        rc;
6251 
6252   myheader("test_date_time");
6253 
6254   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6255   myquery(rc);
6256 
6257   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIME, \
6258                                                  c2 TIME, \
6259                                                  c3 TIME, \
6260                                                  c4 TIME)");
6261 
6262   myquery(rc);
6263 
6264   test_bind_date_conv(3);
6265 }
6266 
6267 
6268 /* Test all time types to TIMESTAMP and TIMESTAMP to all types */
6269 
test_date_ts()6270 static void test_date_ts()
6271 {
6272   int        rc;
6273 
6274   myheader("test_date_ts");
6275 
6276   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6277   myquery(rc);
6278 
6279   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6280                                                  c2 TIMESTAMP, \
6281                                                  c3 TIMESTAMP, \
6282                                                  c4 TIMESTAMP)");
6283 
6284   myquery(rc);
6285 
6286   test_bind_date_conv(2);
6287 }
6288 
6289 
6290 /* Test all time types to DATETIME and DATETIME to all types */
6291 
test_date_dt()6292 static void test_date_dt()
6293 {
6294   int rc;
6295 
6296   myheader("test_date_dt");
6297 
6298   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6299   myquery(rc);
6300 
6301   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 datetime, "
6302                          " c2 datetime, c3 datetime, c4 date)");
6303   myquery(rc);
6304 
6305   test_bind_date_conv(2);
6306 }
6307 
6308 
6309 /* Misc tests to keep pure coverage happy */
6310 
test_pure_coverage()6311 static void test_pure_coverage()
6312 {
6313   MYSQL_STMT *stmt;
6314   MYSQL_BIND my_bind[2];
6315   int        rc;
6316   ulong      length;
6317 
6318   myheader("test_pure_coverage");
6319 
6320   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_pure");
6321   myquery(rc);
6322 
6323   rc= mysql_query(mysql, "CREATE TABLE test_pure(c1 int, c2 varchar(20))");
6324   myquery(rc);
6325 
6326   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c67788) values(10)");
6327   check_stmt_r(stmt);
6328 
6329   /* Query without params and result should allow to bind 0 arrays */
6330   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(10)");
6331   check_stmt(stmt);
6332 
6333   rc= mysql_stmt_bind_param(stmt, (MYSQL_BIND*)0);
6334   check_execute(stmt, rc);
6335 
6336   rc= mysql_stmt_execute(stmt);
6337   check_execute(stmt, rc);
6338 
6339   rc= mysql_stmt_bind_result(stmt, (MYSQL_BIND*)0);
6340   DIE_UNLESS(rc == 1);
6341 
6342   mysql_stmt_close(stmt);
6343 
6344   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(?)");
6345   check_stmt(stmt);
6346 
6347   /*
6348     We need to bzero bind structure because mysql_stmt_bind_param checks all
6349     its members.
6350   */
6351   bzero((char*) my_bind, sizeof(my_bind));
6352 
6353   my_bind[0].length= &length;
6354   my_bind[0].is_null= 0;
6355   my_bind[0].buffer_length= 0;
6356 
6357   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6358   rc= mysql_stmt_bind_param(stmt, my_bind);
6359   check_execute_r(stmt, rc); /* unsupported buffer type */
6360 
6361   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6362   rc= mysql_stmt_bind_param(stmt, my_bind);
6363   check_execute(stmt, rc);
6364 
6365   rc= mysql_stmt_store_result(stmt);
6366   check_execute(stmt, rc);
6367 
6368   mysql_stmt_close(stmt);
6369 
6370   stmt= mysql_simple_prepare(mysql, "select * from test_pure");
6371   check_execute(stmt, rc);
6372 
6373   rc= mysql_stmt_execute(stmt);
6374   check_execute(stmt, rc);
6375 
6376   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6377   rc= mysql_stmt_bind_result(stmt, my_bind);
6378   check_execute(stmt, rc); /* MariaDB C/C converts geometry to string */
6379 
6380   rc= mysql_stmt_store_result(stmt);
6381   DIE_IF(rc);
6382 
6383   rc= mysql_stmt_store_result(stmt);
6384   DIE_UNLESS(rc); /* Old error must be reset first */
6385 
6386   mysql_stmt_close(stmt);
6387 
6388   mysql_query(mysql, "DROP TABLE test_pure");
6389 }
6390 
6391 
6392 /* Test for string buffer fetch */
6393 
test_buffers()6394 static void test_buffers()
6395 {
6396   MYSQL_STMT *stmt;
6397   MYSQL_BIND my_bind[1];
6398   int        rc;
6399   ulong      length;
6400   my_bool    is_null;
6401   char       buffer[20];
6402 
6403   myheader("test_buffers");
6404 
6405   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_buffer");
6406   myquery(rc);
6407 
6408   rc= mysql_query(mysql, "CREATE TABLE test_buffer(str varchar(20))");
6409   myquery(rc);
6410 
6411   rc= mysql_query(mysql, "insert into test_buffer values('MySQL')\
6412                           , ('Database'), ('Open-Source'), ('Popular')");
6413   myquery(rc);
6414 
6415   stmt= mysql_simple_prepare(mysql, "select str from test_buffer");
6416   check_stmt(stmt);
6417 
6418   rc= mysql_stmt_execute(stmt);
6419   check_execute(stmt, rc);
6420 
6421   bzero(buffer, sizeof(buffer));              /* Avoid overruns in printf() */
6422 
6423   bzero((char*) my_bind, sizeof(my_bind));
6424   my_bind[0].length= &length;
6425   my_bind[0].is_null= &is_null;
6426   my_bind[0].buffer_length= 1;
6427   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6428   my_bind[0].buffer= (void *)buffer;
6429   my_bind[0].error= &my_bind[0].error_value;
6430 
6431   rc= mysql_stmt_bind_result(stmt, my_bind);
6432   check_execute(stmt, rc);
6433 
6434   rc= mysql_stmt_store_result(stmt);
6435   check_execute(stmt, rc);
6436 
6437   buffer[1]= 'X';
6438   rc= mysql_stmt_fetch(stmt);
6439   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6440   DIE_UNLESS(my_bind[0].error_value);
6441   if (!opt_silent)
6442     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6443   DIE_UNLESS(buffer[0] == 'M');
6444   DIE_UNLESS(buffer[1] == 'X');
6445   DIE_UNLESS(length == 5);
6446 
6447   my_bind[0].buffer_length= 8;
6448   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6449   check_execute(stmt, rc);
6450 
6451   rc= mysql_stmt_fetch(stmt);
6452   check_execute(stmt, rc);
6453   if (!opt_silent)
6454     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6455   DIE_UNLESS(strncmp(buffer, "Database", 8) == 0);
6456   DIE_UNLESS(length == 8);
6457 
6458   my_bind[0].buffer_length= 12;
6459   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6460   check_execute(stmt, rc);
6461 
6462   rc= mysql_stmt_fetch(stmt);
6463   check_execute(stmt, rc);
6464   if (!opt_silent)
6465     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6466   DIE_UNLESS(strcmp(buffer, "Open-Source") == 0);
6467   DIE_UNLESS(length == 11);
6468 
6469   my_bind[0].buffer_length= 6;
6470   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6471   check_execute(stmt, rc);
6472 
6473   rc= mysql_stmt_fetch(stmt);
6474   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6475   DIE_UNLESS(my_bind[0].error_value);
6476   if (!opt_silent)
6477     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6478   DIE_UNLESS(strncmp(buffer, "Popula", 6) == 0);
6479   DIE_UNLESS(length == 7);
6480 
6481   mysql_stmt_close(stmt);
6482 }
6483 
6484 
6485 /* Test the direct query execution in the middle of open stmts */
6486 
test_open_direct()6487 static void test_open_direct()
6488 {
6489   MYSQL_STMT  *stmt;
6490   MYSQL_RES   *result;
6491   int         rc;
6492 
6493   myheader("test_open_direct");
6494 
6495   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_open_direct");
6496   myquery(rc);
6497 
6498   rc= mysql_query(mysql, "CREATE TABLE test_open_direct(id int, name char(6))");
6499   myquery(rc);
6500 
6501   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_open_direct values(10, 'mysql')");
6502   check_stmt(stmt);
6503 
6504   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6505   myquery(rc);
6506 
6507   result= mysql_store_result(mysql);
6508   mytest(result);
6509 
6510   rc= my_process_result_set(result);
6511   DIE_UNLESS(rc == 0);
6512   mysql_free_result(result);
6513 
6514   rc= mysql_stmt_execute(stmt);
6515   check_execute(stmt, rc);
6516 
6517   verify_st_affected_rows(stmt, 1);
6518 
6519   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6520   myquery(rc);
6521 
6522   result= mysql_store_result(mysql);
6523   mytest(result);
6524 
6525   rc= my_process_result_set(result);
6526   DIE_UNLESS(rc == 1);
6527   mysql_free_result(result);
6528 
6529   rc= mysql_stmt_execute(stmt);
6530   check_execute(stmt, rc);
6531 
6532   verify_st_affected_rows(stmt, 1);
6533 
6534   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6535   myquery(rc);
6536 
6537   result= mysql_store_result(mysql);
6538   mytest(result);
6539 
6540   rc= my_process_result_set(result);
6541   DIE_UNLESS(rc == 2);
6542   mysql_free_result(result);
6543 
6544   mysql_stmt_close(stmt);
6545 
6546   /* run a direct query in the middle of a fetch */
6547   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6548   check_stmt(stmt);
6549 
6550   rc= mysql_stmt_execute(stmt);
6551   check_execute(stmt, rc);
6552 
6553   rc= mysql_stmt_fetch(stmt);
6554   check_execute(stmt, rc);
6555 
6556   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6557   myquery_r(rc);
6558 
6559   rc= mysql_stmt_close(stmt);
6560   check_execute(stmt, rc);
6561 
6562   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6563   myquery(rc);
6564 
6565   /* run a direct query with store result */
6566   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6567   check_stmt(stmt);
6568 
6569   rc= mysql_stmt_execute(stmt);
6570   check_execute(stmt, rc);
6571 
6572   rc= mysql_stmt_store_result(stmt);
6573   check_execute(stmt, rc);
6574 
6575   rc= mysql_stmt_fetch(stmt);
6576   check_execute(stmt, rc);
6577 
6578   rc= mysql_query(mysql, "drop table test_open_direct");
6579   myquery(rc);
6580 
6581   rc= mysql_stmt_close(stmt);
6582   check_execute(stmt, rc);
6583 }
6584 
6585 
6586 /* Test fetch without prior bound buffers */
6587 
test_fetch_nobuffs()6588 static void test_fetch_nobuffs()
6589 {
6590   MYSQL_STMT *stmt;
6591   MYSQL_BIND my_bind[4];
6592   char       str[4][50];
6593   int        rc;
6594 
6595   myheader("test_fetch_nobuffs");
6596 
6597   stmt= mysql_simple_prepare(mysql, "SELECT DATABASE(), CURRENT_USER(), \
6598                               CURRENT_DATE(), CURRENT_TIME()");
6599   check_stmt(stmt);
6600 
6601   rc= mysql_stmt_execute(stmt);
6602   check_execute(stmt, rc);
6603 
6604   rc= 0;
6605   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6606     rc++;
6607 
6608   if (!opt_silent)
6609     fprintf(stdout, "\n total rows        : %d", rc);
6610   DIE_UNLESS(rc == 1);
6611 
6612   bzero((char*) my_bind, sizeof(MYSQL_BIND));
6613   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6614   my_bind[0].buffer= (void *)str[0];
6615   my_bind[0].buffer_length= sizeof(str[0]);
6616   my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0];
6617   my_bind[1].buffer= (void *)str[1];
6618   my_bind[2].buffer= (void *)str[2];
6619   my_bind[3].buffer= (void *)str[3];
6620 
6621   rc= mysql_stmt_bind_result(stmt, my_bind);
6622   check_execute(stmt, rc);
6623 
6624   rc= mysql_stmt_execute(stmt);
6625   check_execute(stmt, rc);
6626 
6627   rc= 0;
6628   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6629   {
6630     rc++;
6631     if (!opt_silent)
6632     {
6633       fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
6634       fprintf(stdout, "\n CURRENT_USER()    : %s", str[1]);
6635       fprintf(stdout, "\n CURRENT_DATE()    : %s", str[2]);
6636       fprintf(stdout, "\n CURRENT_TIME()    : %s", str[3]);
6637     }
6638   }
6639   if (!opt_silent)
6640     fprintf(stdout, "\n total rows        : %d", rc);
6641   DIE_UNLESS(rc == 1);
6642 
6643   mysql_stmt_close(stmt);
6644 }
6645 
6646 
6647 /* Test a misc bug */
6648 
test_ushort_bug()6649 static void test_ushort_bug()
6650 {
6651   MYSQL_STMT *stmt;
6652   MYSQL_BIND my_bind[4];
6653   ushort     short_value;
6654   uint32     long_value;
6655   ulong      s_length, l_length, ll_length, t_length;
6656   ulonglong  longlong_value;
6657   int        rc;
6658   uchar      tiny_value;
6659   char       llbuf[22];
6660   myheader("test_ushort_bug");
6661 
6662   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ushort");
6663   myquery(rc);
6664 
6665   rc= mysql_query(mysql, "CREATE TABLE test_ushort(a smallint unsigned, \
6666                                                   b smallint unsigned, \
6667                                                   c smallint unsigned, \
6668                                                   d smallint unsigned)");
6669   myquery(rc);
6670 
6671   rc= mysql_query(mysql,
6672                   "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)");
6673   myquery(rc);
6674 
6675 
6676   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ushort");
6677   check_stmt(stmt);
6678 
6679   rc= mysql_stmt_execute(stmt);
6680   check_execute(stmt, rc);
6681 
6682   bzero((char*) my_bind, sizeof(my_bind));
6683   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6684   my_bind[0].buffer= (void *)&short_value;
6685   my_bind[0].is_unsigned= TRUE;
6686   my_bind[0].length= &s_length;
6687 
6688   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6689   my_bind[1].buffer= (void *)&long_value;
6690   my_bind[1].length= &l_length;
6691 
6692   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6693   my_bind[2].buffer= (void *)&longlong_value;
6694   my_bind[2].length= &ll_length;
6695 
6696   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6697   my_bind[3].buffer= (void *)&tiny_value;
6698   my_bind[3].is_unsigned= TRUE;
6699   my_bind[3].length= &t_length;
6700 
6701   rc= mysql_stmt_bind_result(stmt, my_bind);
6702   check_execute(stmt, rc);
6703 
6704   rc= mysql_stmt_fetch(stmt);
6705   check_execute(stmt, rc);
6706 
6707   if (!opt_silent)
6708   {
6709     fprintf(stdout, "\n ushort   : %d (%ld)", short_value, s_length);
6710     fprintf(stdout, "\n ulong    : %lu (%ld)", (ulong) long_value, l_length);
6711     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6712             ll_length);
6713     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, t_length);
6714   }
6715 
6716   DIE_UNLESS(short_value == 35999);
6717   DIE_UNLESS(s_length == 2);
6718 
6719   DIE_UNLESS(long_value == 35999);
6720   DIE_UNLESS(l_length == 4);
6721 
6722   DIE_UNLESS(longlong_value == 35999);
6723   DIE_UNLESS(ll_length == 8);
6724 
6725   DIE_UNLESS(tiny_value == 200);
6726   DIE_UNLESS(t_length == 1);
6727 
6728   rc= mysql_stmt_fetch(stmt);
6729   DIE_UNLESS(rc == MYSQL_NO_DATA);
6730 
6731   mysql_stmt_close(stmt);
6732 }
6733 
6734 
6735 /* Test a misc smallint-signed conversion bug */
6736 
test_sshort_bug()6737 static void test_sshort_bug()
6738 {
6739   MYSQL_STMT *stmt;
6740   MYSQL_BIND my_bind[4];
6741   short      short_value;
6742   int32      long_value;
6743   ulong      s_length, l_length, ll_length, t_length;
6744   ulonglong  longlong_value;
6745   int        rc;
6746   uchar      tiny_value;
6747   char       llbuf[22];
6748 
6749   myheader("test_sshort_bug");
6750 
6751   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sshort");
6752   myquery(rc);
6753 
6754   rc= mysql_query(mysql, "CREATE TABLE test_sshort(a smallint signed, \
6755                                                   b smallint signed, \
6756                                                   c smallint unsigned, \
6757                                                   d smallint unsigned)");
6758   myquery(rc);
6759 
6760   rc= mysql_query(mysql, "INSERT INTO test_sshort VALUES(-5999, -5999, 35999, 200)");
6761   myquery(rc);
6762 
6763 
6764   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_sshort");
6765   check_stmt(stmt);
6766 
6767   rc= mysql_stmt_execute(stmt);
6768   check_execute(stmt, rc);
6769 
6770   bzero((char*) my_bind, sizeof(my_bind));
6771   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6772   my_bind[0].buffer= (void *)&short_value;
6773   my_bind[0].length= &s_length;
6774 
6775   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6776   my_bind[1].buffer= (void *)&long_value;
6777   my_bind[1].length= &l_length;
6778 
6779   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6780   my_bind[2].buffer= (void *)&longlong_value;
6781   my_bind[2].length= &ll_length;
6782 
6783   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6784   my_bind[3].buffer= (void *)&tiny_value;
6785   my_bind[3].is_unsigned= TRUE;
6786   my_bind[3].length= &t_length;
6787 
6788   rc= mysql_stmt_bind_result(stmt, my_bind);
6789   check_execute(stmt, rc);
6790 
6791   rc= mysql_stmt_fetch(stmt);
6792   check_execute(stmt, rc);
6793 
6794   if (!opt_silent)
6795   {
6796     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, s_length);
6797     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, l_length);
6798     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6799             ll_length);
6800     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, t_length);
6801   }
6802 
6803   DIE_UNLESS(short_value == -5999);
6804   DIE_UNLESS(s_length == 2);
6805 
6806   DIE_UNLESS(long_value == -5999);
6807   DIE_UNLESS(l_length == 4);
6808 
6809   DIE_UNLESS(longlong_value == 35999);
6810   DIE_UNLESS(ll_length == 8);
6811 
6812   DIE_UNLESS(tiny_value == 200);
6813   DIE_UNLESS(t_length == 1);
6814 
6815   rc= mysql_stmt_fetch(stmt);
6816   DIE_UNLESS(rc == MYSQL_NO_DATA);
6817 
6818   mysql_stmt_close(stmt);
6819 }
6820 
6821 
6822 /* Test a misc tinyint-signed conversion bug */
6823 
test_stiny_bug()6824 static void test_stiny_bug()
6825 {
6826   MYSQL_STMT *stmt;
6827   MYSQL_BIND my_bind[4];
6828   short      short_value;
6829   int32      long_value;
6830   ulong      s_length, l_length, ll_length, t_length;
6831   ulonglong  longlong_value;
6832   int        rc;
6833   uchar      tiny_value;
6834   char       llbuf[22];
6835 
6836   myheader("test_stiny_bug");
6837 
6838   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_stiny");
6839   myquery(rc);
6840 
6841   rc= mysql_query(mysql, "CREATE TABLE test_stiny(a tinyint signed, \
6842                                                   b tinyint signed, \
6843                                                   c tinyint unsigned, \
6844                                                   d tinyint unsigned)");
6845   myquery(rc);
6846 
6847   rc= mysql_query(mysql, "INSERT INTO test_stiny VALUES(-128, -127, 255, 0)");
6848   myquery(rc);
6849 
6850 
6851   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_stiny");
6852   check_stmt(stmt);
6853 
6854   rc= mysql_stmt_execute(stmt);
6855   check_execute(stmt, rc);
6856 
6857   bzero((char*) my_bind, sizeof(my_bind));
6858   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6859   my_bind[0].buffer= (void *)&short_value;
6860   my_bind[0].length= &s_length;
6861 
6862   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6863   my_bind[1].buffer= (void *)&long_value;
6864   my_bind[1].length= &l_length;
6865 
6866   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6867   my_bind[2].buffer= (void *)&longlong_value;
6868   my_bind[2].length= &ll_length;
6869 
6870   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6871   my_bind[3].buffer= (void *)&tiny_value;
6872   my_bind[3].length= &t_length;
6873 
6874   rc= mysql_stmt_bind_result(stmt, my_bind);
6875   check_execute(stmt, rc);
6876 
6877   rc= mysql_stmt_fetch(stmt);
6878   check_execute(stmt, rc);
6879 
6880   if (!opt_silent)
6881   {
6882     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, s_length);
6883     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, l_length);
6884     fprintf(stdout, "\n longlong : %s  (%ld)", llstr(longlong_value, llbuf),
6885             ll_length);
6886     fprintf(stdout, "\n tinyint  : %d    (%ld)", tiny_value, t_length);
6887   }
6888 
6889   DIE_UNLESS(short_value == -128);
6890   DIE_UNLESS(s_length == 2);
6891 
6892   DIE_UNLESS(long_value == -127);
6893   DIE_UNLESS(l_length == 4);
6894 
6895   DIE_UNLESS(longlong_value == 255);
6896   DIE_UNLESS(ll_length == 8);
6897 
6898   DIE_UNLESS(tiny_value == 0);
6899   DIE_UNLESS(t_length == 1);
6900 
6901   rc= mysql_stmt_fetch(stmt);
6902   DIE_UNLESS(rc == MYSQL_NO_DATA);
6903 
6904   mysql_stmt_close(stmt);
6905 }
6906 
6907 
6908 /* Test misc field information, bug: #74 */
6909 
test_field_misc()6910 static void test_field_misc()
6911 {
6912   MYSQL_STMT  *stmt;
6913   MYSQL_RES   *result;
6914   int         rc;
6915 
6916   myheader("test_field_misc");
6917 
6918   rc= mysql_query(mysql, "SELECT @@autocommit");
6919   myquery(rc);
6920 
6921   result= mysql_store_result(mysql);
6922   mytest(result);
6923 
6924   rc= my_process_result_set(result);
6925   DIE_UNLESS(rc == 1);
6926 
6927   verify_prepare_field(result, 0,
6928                        "@@autocommit", "",  /* field and its org name */
6929                        MYSQL_TYPE_LONGLONG, /* field type */
6930                        "", "",              /* table and its org name */
6931                        "", 1, 0);           /* db name, length(its bool flag)*/
6932 
6933   mysql_free_result(result);
6934 
6935   stmt= mysql_simple_prepare(mysql, "SELECT @@autocommit");
6936   check_stmt(stmt);
6937 
6938   rc= mysql_stmt_execute(stmt);
6939   check_execute(stmt, rc);
6940 
6941   result= mysql_stmt_result_metadata(stmt);
6942   mytest(result);
6943 
6944   rc= my_process_stmt_result(stmt);
6945   DIE_UNLESS(rc == 1);
6946 
6947   verify_prepare_field(result, 0,
6948                        "@@autocommit", "",  /* field and its org name */
6949                        MYSQL_TYPE_LONGLONG, /* field type */
6950                        "", "",              /* table and its org name */
6951                        "", 1, 0);           /* db name, length(its bool flag)*/
6952 
6953   mysql_free_result(result);
6954   mysql_stmt_close(stmt);
6955 
6956   stmt= mysql_simple_prepare(mysql, "SELECT @@max_error_count");
6957   check_stmt(stmt);
6958 
6959   result= mysql_stmt_result_metadata(stmt);
6960   mytest(result);
6961 
6962   rc= mysql_stmt_execute(stmt);
6963   check_execute(stmt, rc);
6964 
6965   rc= my_process_stmt_result(stmt);
6966   DIE_UNLESS(rc == 1);
6967 
6968   verify_prepare_field(result, 0,
6969                        "@@max_error_count", "",   /* field and its org name */
6970                        MYSQL_TYPE_LONGLONG, /* field type */
6971                        "", "",              /* table and its org name */
6972                        /* db name, length */
6973                        "", MY_INT64_NUM_DECIMAL_DIGITS , 0);
6974 
6975   mysql_free_result(result);
6976   mysql_stmt_close(stmt);
6977 
6978   stmt= mysql_simple_prepare(mysql, "SELECT @@max_allowed_packet");
6979   check_stmt(stmt);
6980 
6981   result= mysql_stmt_result_metadata(stmt);
6982   mytest(result);
6983 
6984   rc= mysql_stmt_execute(stmt);
6985   check_execute(stmt, rc);
6986 
6987   DIE_UNLESS(1 == my_process_stmt_result(stmt));
6988 
6989   verify_prepare_field(result, 0,
6990                        "@@max_allowed_packet", "", /* field and its org name */
6991                        MYSQL_TYPE_LONGLONG, /* field type */
6992                        "", "",              /* table and its org name */
6993                        /* db name, length */
6994                        "", MY_INT64_NUM_DECIMAL_DIGITS, 0);
6995 
6996   mysql_free_result(result);
6997   mysql_stmt_close(stmt);
6998 
6999   stmt= mysql_simple_prepare(mysql, "SELECT @@sql_warnings");
7000   check_stmt(stmt);
7001 
7002   result= mysql_stmt_result_metadata(stmt);
7003   mytest(result);
7004 
7005   rc= mysql_stmt_execute(stmt);
7006   check_execute(stmt, rc);
7007 
7008   rc= my_process_stmt_result(stmt);
7009   DIE_UNLESS(rc == 1);
7010 
7011   verify_prepare_field(result, 0,
7012                        "@@sql_warnings", "",  /* field and its org name */
7013                        MYSQL_TYPE_LONGLONG,   /* field type */
7014                        "", "",                /* table and its org name */
7015                        "", 1, 0);             /* db name, length */
7016 
7017   mysql_free_result(result);
7018   mysql_stmt_close(stmt);
7019 }
7020 
7021 
7022 /*
7023   Test SET OPTION feature with prepare stmts
7024   bug #85 (reported by mark@mysql.com)
7025 */
7026 
test_set_option()7027 static void test_set_option()
7028 {
7029   MYSQL_STMT *stmt;
7030   MYSQL_RES  *result;
7031   int        rc;
7032 
7033   myheader("test_set_option");
7034 
7035   mysql_autocommit(mysql, TRUE);
7036 
7037   /* LIMIT the rows count to 2 */
7038   rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT= 2");
7039   myquery(rc);
7040 
7041   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_limit");
7042   myquery(rc);
7043 
7044   rc= mysql_query(mysql, "CREATE TABLE test_limit(a tinyint)");
7045   myquery(rc);
7046 
7047   rc= mysql_query(mysql, "INSERT INTO test_limit VALUES(10), (20), (30), (40)");
7048   myquery(rc);
7049 
7050   if (!opt_silent)
7051     fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)");
7052   rc= mysql_query(mysql, "SELECT * FROM test_limit");
7053   myquery(rc);
7054 
7055   result= mysql_store_result(mysql);
7056   mytest(result);
7057 
7058   rc= my_process_result_set(result);
7059   DIE_UNLESS(rc == 2);
7060 
7061   mysql_free_result(result);
7062 
7063   if (!opt_silent)
7064     fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)");
7065   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7066   check_stmt(stmt);
7067 
7068   rc= mysql_stmt_execute(stmt);
7069   check_execute(stmt, rc);
7070 
7071   rc= my_process_stmt_result(stmt);
7072   DIE_UNLESS(rc == 2);
7073 
7074   mysql_stmt_close(stmt);
7075 
7076   /* RESET the LIMIT the rows count to 0 */
7077   if (!opt_silent)
7078     fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)");
7079   rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT=DEFAULT");
7080   myquery(rc);
7081 
7082   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7083   check_stmt(stmt);
7084 
7085   rc= mysql_stmt_execute(stmt);
7086   check_execute(stmt, rc);
7087 
7088   rc= my_process_stmt_result(stmt);
7089   DIE_UNLESS(rc == 4);
7090 
7091   mysql_stmt_close(stmt);
7092 }
7093 
7094 #ifdef EMBEDDED_LIBRARY
test_embedded_start_stop()7095 static void test_embedded_start_stop()
7096 {
7097   MYSQL *mysql_emb=NULL;
7098   int i, j;
7099   int argc= original_argc;                    // Start with the original args
7100   char **argv, **my_argv;
7101   char test_name[]= "test_embedded_start_stop";
7102 #define EMBEDDED_RESTARTS 64
7103 
7104   myheader("test_embedded_start_stop");
7105 
7106   /* Must stop the main embedded server, since we use the same config. */
7107   client_disconnect(mysql);    /* disconnect from server */
7108   free_defaults(defaults_argv);
7109   mysql_server_end();
7110   /* Free everything allocated by my_once_alloc */
7111   my_end(0);
7112 
7113   /*
7114     Use a copy of the original arguments.
7115     The arguments will be altered when reading the configs and parsing
7116     options.
7117   */
7118   my_argv= malloc((argc + 1) * sizeof(char*));
7119   if (!my_argv)
7120     exit(1);
7121 
7122   /* Test restarting the embedded library many times. */
7123   for (i= 1; i <= EMBEDDED_RESTARTS; i++)
7124   {
7125     argv= my_argv;
7126     argv[0]= test_name;
7127     for (j= 1; j < argc; j++)
7128       argv[j]= original_argv[j];
7129 
7130     /* Initialize everything again. */
7131     MY_INIT(argv[0]);
7132 
7133     /* Load the client defaults from the .cnf file[s]. */
7134     load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv);
7135 
7136     /* Parse the options (including the ones given from defaults files). */
7137     get_options(&argc, &argv);
7138 
7139     /* mysql_library_init is the same as mysql_server_init. */
7140     if (mysql_library_init(embedded_server_arg_count,
7141                            embedded_server_args,
7142                            (char**) embedded_server_groups))
7143     {
7144       myerror("mysql_library_init failed");
7145       exit(1);
7146     }
7147 
7148     /* Create a client connection. */
7149     if (!(mysql_emb= mysql_client_init(NULL)))
7150     {
7151       myerror("mysql_client_init failed");
7152       exit(1);
7153     }
7154 
7155     /* Connect it and see if we can use the database. */
7156     if (!(mysql_real_connect(mysql_emb, opt_host, opt_user,
7157                              opt_password, current_db, 0,
7158                              NULL, 0)))
7159     {
7160       myerror("mysql_real_connect failed");
7161     }
7162 
7163     /* Close the client connection */
7164     mysql_close(mysql_emb);
7165     mysql_emb = NULL;
7166     /* Free arguments allocated for defaults files. */
7167     free_defaults(defaults_argv);
7168     /* mysql_library_end is a define for mysql_server_end. */
7169     mysql_library_end();
7170     /* Free everything allocated by my_once_alloc */
7171     my_end(0);
7172   }
7173 
7174   argc= original_argc;
7175   argv= my_argv;
7176   argv[0]= test_name;
7177   for (j= 1; j < argc; j++)
7178     argv[j]= original_argv[j];
7179 
7180   MY_INIT(argv[0]);
7181 
7182   load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv);
7183   get_options(&argc, &argv);
7184 
7185   /* Must start the main embedded server again after the test. */
7186   if (mysql_server_init(embedded_server_arg_count,
7187                         embedded_server_args,
7188                         (char**) embedded_server_groups))
7189     DIE("Can't initialize MySQL server");
7190 
7191   /* connect to server with no flags, default protocol, auto reconnect true */
7192   mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
7193   free(my_argv);
7194 }
7195 #endif /* EMBEDDED_LIBRARY */
7196 
7197 
7198 /*
7199   Test a misc GRANT option
7200   bug #89 (reported by mark@mysql.com)
7201 */
7202 
7203 #ifndef EMBEDDED_LIBRARY
test_prepare_grant()7204 static void test_prepare_grant()
7205 {
7206   int rc;
7207   char query[MAX_TEST_QUERY_LENGTH];
7208 
7209   myheader("test_prepare_grant");
7210 
7211   mysql_autocommit(mysql, TRUE);
7212 
7213   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_grant");
7214   myquery(rc);
7215 
7216   rc= mysql_query(mysql, "CREATE TABLE test_grant(a tinyint primary key auto_increment)");
7217   myquery(rc);
7218 
7219   strxmov(query, "GRANT INSERT, UPDATE, SELECT ON ", current_db,
7220                 ".test_grant TO 'test_grant'@",
7221                 opt_host ? opt_host : "'localhost'", NullS);
7222 
7223   if (mysql_query(mysql, query))
7224   {
7225     myerror("GRANT failed");
7226 
7227     /*
7228        If server started with --skip-grant-tables, skip this test, else
7229        exit to indicate an error
7230 
7231        ER_UNKNOWN_COM_ERROR= 1047
7232      */
7233     if (mysql_errno(mysql) != 1047)
7234       exit(1);
7235   }
7236   else
7237   {
7238     MYSQL *org_mysql= mysql, *lmysql;
7239     MYSQL_STMT *stmt;
7240 
7241     if (!opt_silent)
7242       fprintf(stdout, "\n Establishing a test connection ...");
7243     if (!(lmysql= mysql_client_init(NULL)))
7244     {
7245       myerror("mysql_client_init() failed");
7246       exit(1);
7247     }
7248     if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
7249                              "", current_db, opt_port,
7250                              opt_unix_socket, 0)))
7251     {
7252       myerror("connection failed");
7253       mysql_close(lmysql);
7254       exit(1);
7255     }
7256     mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
7257     if (!opt_silent)
7258       fprintf(stdout, "OK");
7259 
7260     mysql= lmysql;
7261     rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)");
7262     myquery(rc);
7263 
7264     rc= mysql_query(mysql, "INSERT INTO test_grant(a) VALUES(NULL)");
7265     myquery(rc);
7266 
7267     execute_prepare_query("INSERT INTO test_grant(a) VALUES(NULL)", 1);
7268     execute_prepare_query("INSERT INTO test_grant VALUES(NULL)", 1);
7269     execute_prepare_query("UPDATE test_grant SET a=9 WHERE a=1", 1);
7270     rc= my_stmt_result("SELECT a FROM test_grant");
7271     DIE_UNLESS(rc == 4);
7272 
7273     /* Both DELETE expected to fail as user does not have DELETE privs */
7274 
7275     rc= mysql_query(mysql, "DELETE FROM test_grant");
7276     myquery_r(rc);
7277 
7278     stmt= mysql_simple_prepare(mysql, "DELETE FROM test_grant");
7279     check_stmt_r(stmt);
7280 
7281     rc= my_stmt_result("SELECT * FROM test_grant");
7282     DIE_UNLESS(rc == 4);
7283 
7284     mysql_close(lmysql);
7285     mysql= org_mysql;
7286 
7287     rc= mysql_query(mysql, "delete from mysql.user where User='test_grant'");
7288     myquery(rc);
7289     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7290 
7291     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_grant'");
7292     myquery(rc);
7293     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7294 
7295   }
7296 }
7297 #endif /* EMBEDDED_LIBRARY */
7298 
7299 /*
7300   Test a crash when invalid/corrupted .frm is used in the
7301   SHOW TABLE STATUS
7302   bug #93 (reported by serg@mysql.com).
7303 */
7304 
test_frm_bug()7305 static void test_frm_bug()
7306 {
7307   MYSQL_STMT *stmt;
7308   MYSQL_BIND my_bind[2];
7309   MYSQL_RES  *result;
7310   MYSQL_ROW  row;
7311   FILE       *test_file;
7312   char       data_dir[FN_REFLEN];
7313   char       test_frm[FN_REFLEN];
7314   int        rc;
7315 
7316   myheader("test_frm_bug");
7317 
7318   mysql_autocommit(mysql, TRUE);
7319 
7320   rc= mysql_query(mysql, "drop table if exists test_frm_bug");
7321   myquery(rc);
7322 
7323   rc= mysql_query(mysql, "flush tables");
7324   myquery(rc);
7325 
7326   stmt= mysql_simple_prepare(mysql, "show variables like 'datadir'");
7327   check_stmt(stmt);
7328 
7329   rc= mysql_stmt_execute(stmt);
7330   check_execute(stmt, rc);
7331 
7332   bzero((char*) my_bind, sizeof(my_bind));
7333   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
7334   my_bind[0].buffer= data_dir;
7335   my_bind[0].buffer_length= FN_REFLEN;
7336   my_bind[1]= my_bind[0];
7337 
7338   rc= mysql_stmt_bind_result(stmt, my_bind);
7339   check_execute(stmt, rc);
7340 
7341   rc= mysql_stmt_fetch(stmt);
7342   check_execute(stmt, rc);
7343 
7344   if (!opt_silent)
7345     fprintf(stdout, "\n data directory: %s", data_dir);
7346 
7347   rc= mysql_stmt_fetch(stmt);
7348   DIE_UNLESS(rc == MYSQL_NO_DATA);
7349 
7350   strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS);
7351 
7352   if (!opt_silent)
7353     fprintf(stdout, "\n test_frm: %s", test_frm);
7354 
7355   if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
7356   {
7357     fprintf(stdout, "\n ERROR: my_fopen failed for '%s'", test_frm);
7358     fprintf(stdout, "\n test cancelled");
7359     exit(1);
7360   }
7361   if (!opt_silent)
7362     fprintf(test_file, "this is a junk file for test");
7363 
7364   rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'");
7365   myquery(rc);
7366 
7367   result= mysql_store_result(mysql);
7368   mytest(result);/* It can't be NULL */
7369 
7370   rc= my_process_result_set(result);
7371   DIE_UNLESS(rc == 1);
7372 
7373   mysql_data_seek(result, 0);
7374 
7375   row= mysql_fetch_row(result);
7376   mytest(row);
7377 
7378   if (!opt_silent)
7379     fprintf(stdout, "\n Comment: %s", row[17]);
7380   DIE_UNLESS(row[17] != 0);
7381 
7382   mysql_free_result(result);
7383   mysql_stmt_close(stmt);
7384 
7385   my_fclose(test_file, MYF(0));
7386   mysql_query(mysql, "drop table if exists test_frm_bug");
7387 }
7388 
7389 
7390 /* Test DECIMAL conversion */
7391 
test_decimal_bug()7392 static void test_decimal_bug()
7393 {
7394   MYSQL_STMT *stmt;
7395   MYSQL_BIND my_bind[1];
7396   char       data[30];
7397   int        rc;
7398   my_bool    is_null;
7399 
7400   myheader("test_decimal_bug");
7401 
7402   mysql_autocommit(mysql, TRUE);
7403 
7404   rc= mysql_query(mysql, "drop table if exists test_decimal_bug");
7405   myquery(rc);
7406 
7407   rc= mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10, 2))");
7408   myquery(rc);
7409 
7410   rc= mysql_query(mysql, "insert into test_decimal_bug value(8), (10.22), (5.61)");
7411   myquery(rc);
7412 
7413   stmt= mysql_simple_prepare(mysql, "select c1 from test_decimal_bug where c1= ?");
7414   check_stmt(stmt);
7415 
7416   /*
7417     We need to bzero bind structure because mysql_stmt_bind_param checks all
7418     its members.
7419   */
7420   bzero((char*) my_bind, sizeof(my_bind));
7421 
7422   my_bind[0].buffer_type= MYSQL_TYPE_NEWDECIMAL;
7423   my_bind[0].buffer= (void *)data;
7424   my_bind[0].buffer_length= 25;
7425   my_bind[0].is_null= &is_null;
7426 
7427   is_null= 0;
7428   rc= mysql_stmt_bind_param(stmt, my_bind);
7429   check_execute(stmt, rc);
7430 
7431   memset(data, 0, sizeof data);
7432   strmov(data, "8.0");
7433   rc= mysql_stmt_execute(stmt);
7434   check_execute(stmt, rc);
7435 
7436   data[0]= 0;
7437   rc= mysql_stmt_bind_result(stmt, my_bind);
7438   check_execute(stmt, rc);
7439 
7440   rc= mysql_stmt_fetch(stmt);
7441   check_execute(stmt, rc);
7442 
7443   if (!opt_silent)
7444     fprintf(stdout, "\n data: %s", data);
7445   DIE_UNLESS(strcmp(data, "8.00") == 0);
7446 
7447   rc= mysql_stmt_fetch(stmt);
7448   DIE_UNLESS(rc == MYSQL_NO_DATA);
7449 
7450   strmov(data, "5.61");
7451   rc= mysql_stmt_execute(stmt);
7452   check_execute(stmt, rc);
7453 
7454   data[0]= 0;
7455   rc= mysql_stmt_bind_result(stmt, my_bind);
7456   check_execute(stmt, rc);
7457 
7458   rc= mysql_stmt_fetch(stmt);
7459   check_execute(stmt, rc);
7460 
7461   if (!opt_silent)
7462     fprintf(stdout, "\n data: %s", data);
7463   DIE_UNLESS(strcmp(data, "5.61") == 0);
7464 
7465   rc= mysql_stmt_fetch(stmt);
7466   DIE_UNLESS(rc == MYSQL_NO_DATA);
7467 
7468   is_null= 1;
7469   rc= mysql_stmt_execute(stmt);
7470   check_execute(stmt, rc);
7471 
7472   rc= mysql_stmt_fetch(stmt);
7473   DIE_UNLESS(rc == MYSQL_NO_DATA);
7474 
7475   strmov(data, "10.22"); is_null= 0;
7476   rc= mysql_stmt_execute(stmt);
7477   check_execute(stmt, rc);
7478 
7479   data[0]= 0;
7480   rc= mysql_stmt_bind_result(stmt, my_bind);
7481   check_execute(stmt, rc);
7482 
7483   rc= mysql_stmt_fetch(stmt);
7484   check_execute(stmt, rc);
7485 
7486   if (!opt_silent)
7487     fprintf(stdout, "\n data: %s", data);
7488   DIE_UNLESS(strcmp(data, "10.22") == 0);
7489 
7490   rc= mysql_stmt_fetch(stmt);
7491   DIE_UNLESS(rc == MYSQL_NO_DATA);
7492 
7493   mysql_stmt_close(stmt);
7494 }
7495 
7496 
7497 /* Test EXPLAIN bug (#115, reported by mark@mysql.com & georg@php.net). */
7498 
test_explain_bug()7499 static void test_explain_bug()
7500 {
7501   MYSQL_STMT *stmt;
7502   MYSQL_RES  *result;
7503   int        rc;
7504 
7505   myheader("test_explain_bug");
7506 
7507   mysql_autocommit(mysql, TRUE);
7508 
7509   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_explain");
7510   myquery(rc);
7511 
7512   rc= mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))");
7513   myquery(rc);
7514 
7515   stmt= mysql_simple_prepare(mysql, "explain test_explain");
7516   check_stmt(stmt);
7517 
7518   rc= mysql_stmt_execute(stmt);
7519   check_execute(stmt, rc);
7520 
7521   rc= my_process_stmt_result(stmt);
7522   DIE_UNLESS(rc == 2);
7523 
7524   result= mysql_stmt_result_metadata(stmt);
7525   mytest(result);
7526 
7527   if (!opt_silent)
7528     fprintf(stdout, "\n total fields in the result: %d",
7529             mysql_num_fields(result));
7530   DIE_UNLESS(6 == mysql_num_fields(result));
7531 
7532   verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
7533                        mysql_get_server_version(mysql) <= 50000 ?
7534                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7535                        0, 0, "information_schema", 64, 0);
7536 
7537   verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
7538                        0, 0, "information_schema", 0, 0);
7539 
7540   verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
7541                        mysql_get_server_version(mysql) <= 50000 ?
7542                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7543                        0, 0, "information_schema", 3, 0);
7544 
7545   verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
7546                        mysql_get_server_version(mysql) <= 50000 ?
7547                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7548                        0, 0, "information_schema", 3, 0);
7549 
7550   if ( mysql_get_server_version(mysql) >= 50027 )
7551   {
7552     /*  The patch for bug#23037 changes column type of DEAULT to blob */
7553     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7554                          MYSQL_TYPE_BLOB, 0, 0, "information_schema", 0, 0);
7555   }
7556   else
7557   {
7558     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7559                          mysql_get_server_version(mysql) >= 50027 ?
7560                          MYSQL_TYPE_BLOB :
7561                          mysql_get_server_version(mysql) <= 50000 ?
7562                          MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7563                          0, 0, "information_schema",
7564                          mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
7565   }
7566 
7567   verify_prepare_field(result, 5, "Extra", "EXTRA",
7568                        mysql_get_server_version(mysql) <= 50000 ?
7569                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7570                        0, 0, "information_schema", 30, 0);
7571 
7572   mysql_free_result(result);
7573   mysql_stmt_close(stmt);
7574 
7575   stmt= mysql_simple_prepare(mysql, "explain select id, name FROM test_explain");
7576   check_stmt(stmt);
7577 
7578   rc= mysql_stmt_execute(stmt);
7579   check_execute(stmt, rc);
7580 
7581   rc= my_process_stmt_result(stmt);
7582   DIE_UNLESS(rc == 1);
7583 
7584   result= mysql_stmt_result_metadata(stmt);
7585   mytest(result);
7586 
7587   if (!opt_silent)
7588     fprintf(stdout, "\n total fields in the result: %d",
7589             mysql_num_fields(result));
7590   DIE_UNLESS(10 == mysql_num_fields(result));
7591 
7592   verify_prepare_field(result, 0, "id", "", MYSQL_TYPE_LONGLONG,
7593                        "", "", "", 3, 0);
7594 
7595   verify_prepare_field(result, 1, "select_type", "", MYSQL_TYPE_VAR_STRING,
7596                        "", "", "", 19, 0);
7597 
7598   verify_prepare_field(result, 2, "table", "", MYSQL_TYPE_VAR_STRING,
7599                        "", "", "", NAME_CHAR_LEN, 0);
7600 
7601   verify_prepare_field(result, 3, "type", "", MYSQL_TYPE_VAR_STRING,
7602                        "", "", "", 10, 0);
7603 
7604   verify_prepare_field(result, 4, "possible_keys", "", MYSQL_TYPE_VAR_STRING,
7605                        "", "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7606 
7607   verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
7608                        "", "", "", NAME_CHAR_LEN, 0);
7609 
7610   if (mysql_get_server_version(mysql) <= 50000)
7611   {
7612     verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG, "",
7613                          "", "", 3, 0);
7614   }
7615   else
7616   {
7617     verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
7618                          "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7619   }
7620 
7621   /* The length of this may verify between MariaDB versions (1024 / 2048) */
7622   verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
7623                        "", "", "", NAME_CHAR_LEN * HA_MAX_KEY_SEG, 0);
7624 
7625   verify_prepare_field(result, 8, "rows", "", MYSQL_TYPE_VAR_STRING,
7626                        "", "", "", NAME_CHAR_LEN, 0);
7627 
7628   verify_prepare_field(result, 9, "Extra", "", MYSQL_TYPE_VAR_STRING,
7629                        "", "", "", 255, 0);
7630 
7631   mysql_free_result(result);
7632   mysql_stmt_close(stmt);
7633 }
7634 
7635 #ifdef NOT_YET_WORKING
7636 
7637 /*
7638   Test math functions.
7639   Bug #148 (reported by salle@mysql.com).
7640 */
7641 
7642 #define myerrno(n) check_errcode(n)
7643 
check_errcode(const unsigned int err)7644 static void check_errcode(const unsigned int err)
7645 {
7646   if (!opt_silent || mysql_errno(mysql) != err)
7647   {
7648     if (mysql->server_version)
7649       fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
7650     else
7651       fprintf(stdout, "\n [MySQL]");
7652     fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
7653   }
7654   DIE_UNLESS(mysql_errno(mysql) == err);
7655 }
7656 
7657 
test_drop_temp()7658 static void test_drop_temp()
7659 {
7660   int rc;
7661 
7662   myheader("test_drop_temp");
7663 
7664   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS test_drop_temp_db");
7665   myquery(rc);
7666 
7667   rc= mysql_query(mysql, "CREATE DATABASE test_drop_temp_db");
7668   myquery(rc);
7669 
7670   rc= mysql_query(mysql, "CREATE TABLE test_drop_temp_db.t1(c1 int, c2 char(1))");
7671   myquery(rc);
7672 
7673   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7674   myquery(rc);
7675 
7676   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7677   myquery(rc);
7678 
7679   strxmov(query, "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@",
7680                 opt_host ? opt_host : "localhost", NullS);
7681 
7682   if (mysql_query(mysql, query))
7683   {
7684     myerror("GRANT failed");
7685 
7686     /*
7687        If server started with --skip-grant-tables, skip this test, else
7688        exit to indicate an error
7689 
7690        ER_UNKNOWN_COM_ERROR= 1047
7691      */
7692     if (mysql_errno(mysql) != 1047)
7693       exit(1);
7694   }
7695   else
7696   {
7697     MYSQL *org_mysql= mysql, *lmysql;
7698 
7699     if (!opt_silent)
7700       fprintf(stdout, "\n Establishing a test connection ...");
7701     if (!(lmysql= mysql_client_init(NULL)))
7702     {
7703       myerror("mysql_client_init() failed");
7704       exit(1);
7705     }
7706 
7707     rc= mysql_query(mysql, "flush privileges");
7708     myquery(rc);
7709 
7710     if (!(mysql_real_connect(lmysql, opt_host ? opt_host : "localhost", "test_temp",
7711                              "", "test_drop_temp_db", opt_port,
7712                              opt_unix_socket, 0)))
7713     {
7714       mysql= lmysql;
7715       myerror("connection failed");
7716       mysql_close(lmysql);
7717       exit(1);
7718     }
7719     mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
7720     if (!opt_silent)
7721       fprintf(stdout, "OK");
7722 
7723     mysql= lmysql;
7724     rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')");
7725     myerrno((uint)1142);
7726 
7727     rc= mysql_query(mysql, "DROP TABLE t1");
7728     myerrno((uint)1142);
7729 
7730     mysql= org_mysql;
7731     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t1(c1 int)");
7732     myquery(rc);
7733 
7734     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t2 LIKE test_drop_temp_db.t1");
7735     myquery(rc);
7736 
7737     mysql= lmysql;
7738 
7739     rc= mysql_query(mysql, "DROP TABLE t1, t2");
7740     myquery_r(rc);
7741 
7742     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t1");
7743     myquery_r(rc);
7744 
7745     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t2");
7746     myquery_r(rc);
7747 
7748     mysql_close(lmysql);
7749     mysql= org_mysql;
7750 
7751     rc= mysql_query(mysql, "drop database test_drop_temp_db");
7752     myquery(rc);
7753     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7754 
7755     rc= mysql_query(mysql, "delete from mysql.user where User='test_temp'");
7756     myquery(rc);
7757     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7758 
7759 
7760     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_temp'");
7761     myquery(rc);
7762     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7763   }
7764 }
7765 #endif
7766 
7767 
7768 /* Test warnings for cuted rows */
7769 
test_cuted_rows()7770 static void test_cuted_rows()
7771 {
7772   int        rc, count;
7773   MYSQL_RES  *result;
7774 
7775   myheader("test_cuted_rows");
7776 
7777   mysql_query(mysql, "DROP TABLE if exists t1");
7778   mysql_query(mysql, "DROP TABLE if exists t2");
7779 
7780   rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)");
7781   myquery(rc);
7782 
7783   rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)");
7784   myquery(rc);
7785 
7786   rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)");
7787   myquery(rc);
7788 
7789   count= mysql_warning_count(mysql);
7790   if (!opt_silent)
7791     fprintf(stdout, "\n total warnings: %d", count);
7792   DIE_UNLESS(count == 0);
7793 
7794   rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
7795   myquery(rc);
7796 
7797   count= mysql_warning_count(mysql);
7798   if (!opt_silent)
7799     fprintf(stdout, "\n total warnings: %d", count);
7800   DIE_UNLESS(count == 2);
7801 
7802   rc= mysql_query(mysql, "SHOW WARNINGS");
7803   myquery(rc);
7804 
7805   result= mysql_store_result(mysql);
7806   mytest(result);
7807 
7808   rc= my_process_result_set(result);
7809   DIE_UNLESS(rc == 2);
7810   mysql_free_result(result);
7811 
7812   rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)");
7813   myquery(rc);
7814 
7815   count= mysql_warning_count(mysql);
7816   if (!opt_silent)
7817     fprintf(stdout, "\n total warnings: %d", count);
7818   DIE_UNLESS(count == 2);
7819 
7820   rc= mysql_query(mysql, "SHOW WARNINGS");
7821   myquery(rc);
7822 
7823   result= mysql_store_result(mysql);
7824   mytest(result);
7825 
7826   rc= my_process_result_set(result);
7827   DIE_UNLESS(rc == 2);
7828   mysql_free_result(result);
7829 }
7830 
7831 
7832 /* Test update/binary logs */
7833 
test_logs()7834 static void test_logs()
7835 {
7836   MYSQL_STMT *stmt;
7837   MYSQL_BIND my_bind[2];
7838   char       data[255];
7839   ulong      length;
7840   int        rc;
7841   short      id;
7842 
7843   myheader("test_logs");
7844 
7845 
7846   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs");
7847   myquery(rc);
7848 
7849   rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))");
7850   myquery(rc);
7851 
7852   strmov((char *)data, "INSERT INTO test_logs VALUES(?, ?)");
7853   stmt= mysql_simple_prepare(mysql, data);
7854   check_stmt(stmt);
7855 
7856   /*
7857     We need to bzero bind structure because mysql_stmt_bind_param checks all
7858     its members.
7859   */
7860   bzero((char*) my_bind, sizeof(my_bind));
7861 
7862   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
7863   my_bind[0].buffer= (void *)&id;
7864 
7865   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
7866   my_bind[1].buffer= (void *)&data;
7867   my_bind[1].buffer_length= 255;
7868   my_bind[1].length= &length;
7869 
7870   id= 9876;
7871   length= (ulong)(strmov((char *)data, "MySQL - Open Source Database")- data);
7872 
7873   rc= mysql_stmt_bind_param(stmt, my_bind);
7874   check_execute(stmt, rc);
7875 
7876   rc= mysql_stmt_execute(stmt);
7877   check_execute(stmt, rc);
7878 
7879   strmov((char *)data, "'");
7880   length= 1;
7881 
7882   rc= mysql_stmt_execute(stmt);
7883   check_execute(stmt, rc);
7884 
7885   strmov((char *)data, "\"");
7886   length= 1;
7887 
7888   rc= mysql_stmt_execute(stmt);
7889   check_execute(stmt, rc);
7890 
7891   length= (ulong)(strmov((char *)data, "my\'sql\'")-data);
7892   rc= mysql_stmt_execute(stmt);
7893   check_execute(stmt, rc);
7894 
7895   length= (ulong)(strmov((char *)data, "my\"sql\"")-data);
7896   rc= mysql_stmt_execute(stmt);
7897   check_execute(stmt, rc);
7898 
7899   mysql_stmt_close(stmt);
7900 
7901   strmov((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')");
7902   stmt= mysql_simple_prepare(mysql, data);
7903   check_stmt(stmt);
7904 
7905   rc= mysql_stmt_execute(stmt);
7906   check_execute(stmt, rc);
7907 
7908   rc= mysql_stmt_execute(stmt);
7909   check_execute(stmt, rc);
7910 
7911   mysql_stmt_close(stmt);
7912 
7913   strmov((char *)data, "SELECT * FROM test_logs WHERE id=?");
7914   stmt= mysql_simple_prepare(mysql, data);
7915   check_stmt(stmt);
7916 
7917   rc= mysql_stmt_bind_param(stmt, my_bind);
7918   check_execute(stmt, rc);
7919 
7920   rc= mysql_stmt_execute(stmt);
7921   check_execute(stmt, rc);
7922 
7923   my_bind[1].buffer_length= 255;
7924   rc= mysql_stmt_bind_result(stmt, my_bind);
7925   check_execute(stmt, rc);
7926 
7927   rc= mysql_stmt_fetch(stmt);
7928   check_execute(stmt, rc);
7929 
7930   if (!opt_silent)
7931   {
7932     fprintf(stdout, "id    : %d\n", id);
7933     fprintf(stdout, "name  : %s(%ld)\n", data, length);
7934   }
7935 
7936   DIE_UNLESS(id == 9876);
7937   DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */
7938   DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1);
7939 
7940   rc= mysql_stmt_fetch(stmt);
7941   check_execute(stmt, rc);
7942 
7943   if (!opt_silent)
7944     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7945 
7946   DIE_UNLESS(length == 1);
7947   DIE_UNLESS(strcmp(data, "'") == 0);
7948 
7949   rc= mysql_stmt_fetch(stmt);
7950   check_execute(stmt, rc);
7951 
7952   if (!opt_silent)
7953     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7954 
7955   DIE_UNLESS(length == 1);
7956   DIE_UNLESS(strcmp(data, "\"") == 0);
7957 
7958   rc= mysql_stmt_fetch(stmt);
7959   check_execute(stmt, rc);
7960 
7961   if (!opt_silent)
7962     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7963 
7964   DIE_UNLESS(length == 7);
7965   DIE_UNLESS(strcmp(data, "my\'sql\'") == 0);
7966 
7967   rc= mysql_stmt_fetch(stmt);
7968   check_execute(stmt, rc);
7969 
7970   if (!opt_silent)
7971     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7972 
7973   DIE_UNLESS(length == 7);
7974   /*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */
7975 
7976   rc= mysql_stmt_fetch(stmt);
7977   DIE_UNLESS(rc == MYSQL_NO_DATA);
7978 
7979   mysql_stmt_close(stmt);
7980 
7981   rc= mysql_query(mysql, "DROP TABLE test_logs");
7982   myquery(rc);
7983 }
7984 
7985 
7986 /* Test 'n' statements create and close */
7987 
test_nstmts()7988 static void test_nstmts()
7989 {
7990   MYSQL_STMT  *stmt;
7991   char        query[255];
7992   int         rc;
7993   static uint i, total_stmts= 2000;
7994   MYSQL_BIND  my_bind[1];
7995 
7996   myheader("test_nstmts");
7997 
7998   mysql_autocommit(mysql, TRUE);
7999 
8000   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_nstmts");
8001   myquery(rc);
8002 
8003   rc= mysql_query(mysql, "CREATE TABLE test_nstmts(id int)");
8004   myquery(rc);
8005 
8006   /*
8007     We need to bzero bind structure because mysql_stmt_bind_param checks all
8008     its members.
8009   */
8010   bzero((char*) my_bind, sizeof(my_bind));
8011 
8012   my_bind[0].buffer= (void *)&i;
8013   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8014 
8015   for (i= 0; i < total_stmts; i++)
8016   {
8017     if (!opt_silent)
8018       fprintf(stdout, "\r stmt: %d", i);
8019 
8020     strmov(query, "insert into test_nstmts values(?)");
8021     stmt= mysql_simple_prepare(mysql, query);
8022     check_stmt(stmt);
8023 
8024     rc= mysql_stmt_bind_param(stmt, my_bind);
8025     check_execute(stmt, rc);
8026 
8027     rc= mysql_stmt_execute(stmt);
8028     check_execute(stmt, rc);
8029 
8030     mysql_stmt_close(stmt);
8031   }
8032 
8033   stmt= mysql_simple_prepare(mysql, " select count(*) from test_nstmts");
8034   check_stmt(stmt);
8035 
8036   rc= mysql_stmt_execute(stmt);
8037   check_execute(stmt, rc);
8038 
8039   i= 0;
8040   rc= mysql_stmt_bind_result(stmt, my_bind);
8041   check_execute(stmt, rc);
8042 
8043   rc= mysql_stmt_fetch(stmt);
8044   check_execute(stmt, rc);
8045   if (!opt_silent)
8046     fprintf(stdout, "\n total rows: %d", i);
8047   DIE_UNLESS( i == total_stmts);
8048 
8049   rc= mysql_stmt_fetch(stmt);
8050   DIE_UNLESS(rc == MYSQL_NO_DATA);
8051 
8052   mysql_stmt_close(stmt);
8053 
8054   rc= mysql_query(mysql, "DROP TABLE test_nstmts");
8055   myquery(rc);
8056 }
8057 
8058 
8059 /* Test stmt seek() functions */
8060 
test_fetch_seek()8061 static void test_fetch_seek()
8062 {
8063   MYSQL_STMT *stmt;
8064   MYSQL_BIND my_bind[3];
8065   MYSQL_ROW_OFFSET row;
8066   int        rc;
8067   int32      c1;
8068   char       c2[11], c3[20];
8069 
8070   myheader("test_fetch_seek");
8071   rc= mysql_query(mysql, "drop table if exists t1");
8072 
8073   myquery(rc);
8074 
8075   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
8076   myquery(rc);
8077 
8078   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
8079   myquery(rc);
8080 
8081   stmt= mysql_simple_prepare(mysql, "select * from t1");
8082   check_stmt(stmt);
8083 
8084   bzero((char*) my_bind, sizeof(my_bind));
8085   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8086   my_bind[0].buffer= (void *)&c1;
8087 
8088   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8089   my_bind[1].buffer= (void *)c2;
8090   my_bind[1].buffer_length= sizeof(c2);
8091 
8092   my_bind[2]= my_bind[1];
8093   my_bind[2].buffer= (void *)c3;
8094   my_bind[2].buffer_length= sizeof(c3);
8095 
8096   rc= mysql_stmt_execute(stmt);
8097   check_execute(stmt, rc);
8098 
8099   rc= mysql_stmt_bind_result(stmt, my_bind);
8100   check_execute(stmt, rc);
8101 
8102   rc= mysql_stmt_store_result(stmt);
8103   check_execute(stmt, rc);
8104 
8105   rc= mysql_stmt_fetch(stmt);
8106   check_execute(stmt, rc);
8107 
8108   if (!opt_silent)
8109     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8110 
8111   row= mysql_stmt_row_tell(stmt);
8112 
8113   row= mysql_stmt_row_seek(stmt, row);
8114 
8115   rc= mysql_stmt_fetch(stmt);
8116   check_execute(stmt, rc);
8117 
8118   if (!opt_silent)
8119     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8120 
8121   row= mysql_stmt_row_seek(stmt, row);
8122 
8123   rc= mysql_stmt_fetch(stmt);
8124   check_execute(stmt, rc);
8125 
8126   if (!opt_silent)
8127     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8128 
8129   mysql_stmt_data_seek(stmt, 0);
8130 
8131   rc= mysql_stmt_fetch(stmt);
8132   check_execute(stmt, rc);
8133 
8134   if (!opt_silent)
8135     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8136 
8137   rc= mysql_stmt_fetch(stmt);
8138   check_execute(stmt, rc);
8139 
8140   rc= mysql_stmt_fetch(stmt);
8141   check_execute(stmt, rc);
8142 
8143   rc= mysql_stmt_fetch(stmt);
8144   check_execute(stmt, rc);
8145 
8146   rc= mysql_stmt_fetch(stmt);
8147   DIE_UNLESS(rc == MYSQL_NO_DATA);
8148 
8149   mysql_stmt_close(stmt);
8150   myquery(mysql_query(mysql, "drop table t1"));
8151 }
8152 
8153 
8154 /* Test mysql_stmt_fetch_column() with offset */
8155 
test_fetch_offset()8156 static void test_fetch_offset()
8157 {
8158   MYSQL_STMT *stmt;
8159   MYSQL_BIND my_bind[1];
8160   char       data[11];
8161   ulong      length;
8162   int        rc;
8163   my_bool    is_null;
8164 
8165 
8166   myheader("test_fetch_offset");
8167 
8168   rc= mysql_query(mysql, "drop table if exists t1");
8169   myquery(rc);
8170 
8171   rc= mysql_query(mysql, "create table t1(a char(10))");
8172   myquery(rc);
8173 
8174   rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)");
8175   myquery(rc);
8176 
8177   stmt= mysql_simple_prepare(mysql, "select * from t1");
8178   check_stmt(stmt);
8179 
8180   bzero((char*) my_bind, sizeof(my_bind));
8181   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8182   my_bind[0].buffer= (void *)data;
8183   my_bind[0].buffer_length= 11;
8184   my_bind[0].is_null= &is_null;
8185   my_bind[0].length= &length;
8186 
8187   rc= mysql_stmt_execute(stmt);
8188   check_execute(stmt, rc);
8189 
8190   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8191   check_execute_r(stmt, rc);
8192 
8193   rc= mysql_stmt_execute(stmt);
8194   check_execute(stmt, rc);
8195 
8196   rc= mysql_stmt_bind_result(stmt, my_bind);
8197   check_execute(stmt, rc);
8198 
8199   rc= mysql_stmt_store_result(stmt);
8200   check_execute(stmt, rc);
8201 
8202   rc= mysql_stmt_fetch(stmt);
8203   check_execute(stmt, rc);
8204 
8205   data[0]= '\0';
8206   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8207   check_execute(stmt, rc);
8208   if (!opt_silent)
8209     fprintf(stdout, "\n col 1: %s (%ld)", data, length);
8210   DIE_UNLESS(strncmp(data, "abcd", 4) == 0 && length == 10);
8211 
8212   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5);
8213   check_execute(stmt, rc);
8214   if (!opt_silent)
8215     fprintf(stdout, "\n col 1: %s (%ld)", data, length);
8216   DIE_UNLESS(strncmp(data, "fg", 2) == 0 && length == 10);
8217 
8218   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9);
8219   check_execute(stmt, rc);
8220   if (!opt_silent)
8221     fprintf(stdout, "\n col 0: %s (%ld)", data, length);
8222   DIE_UNLESS(strncmp(data, "j", 1) == 0 && length == 10);
8223 
8224   rc= mysql_stmt_fetch(stmt);
8225   check_execute(stmt, rc);
8226 
8227   is_null= 0;
8228 
8229   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8230   check_execute(stmt, rc);
8231 
8232   DIE_UNLESS(is_null == 1);
8233 
8234   rc= mysql_stmt_fetch(stmt);
8235   DIE_UNLESS(rc == MYSQL_NO_DATA);
8236 
8237   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8238   check_execute_r(stmt, rc);
8239 
8240   mysql_stmt_close(stmt);
8241 
8242   myquery(mysql_query(mysql, "drop table t1"));
8243 }
8244 
8245 
8246 /* Test mysql_stmt_fetch_column() */
8247 
test_fetch_column()8248 static void test_fetch_column()
8249 {
8250   MYSQL_STMT *stmt;
8251   MYSQL_BIND my_bind[2];
8252   char       c2[20], bc2[20];
8253   ulong      l1, l2, bl1, bl2;
8254   int        rc, c1, bc1;
8255 
8256   myheader("test_fetch_column");
8257 
8258   rc= mysql_query(mysql, "drop table if exists t1");
8259   myquery(rc);
8260 
8261   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
8262   myquery(rc);
8263 
8264   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
8265   myquery(rc);
8266 
8267   stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc");
8268   check_stmt(stmt);
8269 
8270   bzero((char*) my_bind, sizeof(my_bind));
8271   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8272   my_bind[0].buffer= (void *)&bc1;
8273   my_bind[0].buffer_length= 0;
8274   my_bind[0].is_null= 0;
8275   my_bind[0].length= &bl1;
8276   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8277   my_bind[1].buffer= (void *)bc2;
8278   my_bind[1].buffer_length= 7;
8279   my_bind[1].is_null= 0;
8280   my_bind[1].length= &bl2;
8281 
8282   rc= mysql_stmt_execute(stmt);
8283   check_execute(stmt, rc);
8284 
8285   rc= mysql_stmt_bind_result(stmt, my_bind);
8286   check_execute(stmt, rc);
8287 
8288   rc= mysql_stmt_store_result(stmt);
8289   check_execute(stmt, rc);
8290 
8291   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */
8292   check_execute_r(stmt, rc);
8293 
8294   rc= mysql_stmt_fetch(stmt);
8295   check_execute(stmt, rc);
8296 
8297   if (!opt_silent)
8298     fprintf(stdout, "\n row 0: %d, %s", bc1, bc2);
8299 
8300   c2[0]= '\0'; l2= 0;
8301   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8302   my_bind[0].buffer= (void *)c2;
8303   my_bind[0].buffer_length= 7;
8304   my_bind[0].is_null= 0;
8305   my_bind[0].length= &l2;
8306 
8307   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8308   check_execute(stmt, rc);
8309   if (!opt_silent)
8310     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8311   DIE_UNLESS(strncmp(c2, "venu", 4) == 0 && l2 == 4);
8312 
8313   c2[0]= '\0'; l2= 0;
8314   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8315   check_execute(stmt, rc);
8316   if (!opt_silent)
8317     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8318   DIE_UNLESS(strcmp(c2, "venu") == 0 && l2 == 4);
8319 
8320   c1= 0;
8321   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8322   my_bind[0].buffer= (void *)&c1;
8323   my_bind[0].buffer_length= 0;
8324   my_bind[0].is_null= 0;
8325   my_bind[0].length= &l1;
8326 
8327   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8328   check_execute(stmt, rc);
8329   if (!opt_silent)
8330     fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
8331   DIE_UNLESS(c1 == 1 && l1 == 4);
8332 
8333   rc= mysql_stmt_fetch(stmt);
8334   check_execute(stmt, rc);
8335 
8336   if (!opt_silent)
8337     fprintf(stdout, "\n row 1: %d, %s", bc1, bc2);
8338 
8339   c2[0]= '\0'; l2= 0;
8340   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8341   my_bind[0].buffer= (void *)c2;
8342   my_bind[0].buffer_length= 7;
8343   my_bind[0].is_null= 0;
8344   my_bind[0].length= &l2;
8345 
8346   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8347   check_execute(stmt, rc);
8348   if (!opt_silent)
8349     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8350   DIE_UNLESS(strncmp(c2, "mysq", 4) == 0 && l2 == 5);
8351 
8352   c2[0]= '\0'; l2= 0;
8353   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8354   check_execute(stmt, rc);
8355   if (!opt_silent)
8356     fprintf(stdout, "\n col 1: %si(%ld)", c2, l2);
8357   DIE_UNLESS(strcmp(c2, "mysql") == 0 && l2 == 5);
8358 
8359   c1= 0;
8360   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8361   my_bind[0].buffer= (void *)&c1;
8362   my_bind[0].buffer_length= 0;
8363   my_bind[0].is_null= 0;
8364   my_bind[0].length= &l1;
8365 
8366   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8367   check_execute(stmt, rc);
8368   if (!opt_silent)
8369     fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
8370   DIE_UNLESS(c1 == 2 && l1 == 4);
8371 
8372   rc= mysql_stmt_fetch(stmt);
8373   DIE_UNLESS(rc == MYSQL_NO_DATA);
8374 
8375   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8376   check_execute_r(stmt, rc);
8377 
8378   mysql_stmt_close(stmt);
8379   myquery(mysql_query(mysql, "drop table t1"));
8380 }
8381 
8382 
8383 /* Test mysql_list_fields() */
8384 
test_list_fields()8385 static void test_list_fields()
8386 {
8387   MYSQL_RES *result;
8388   int rc;
8389   myheader("test_list_fields");
8390 
8391   rc= mysql_query(mysql, "drop table if exists t1");
8392   myquery(rc);
8393 
8394   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10) default 'mysql')");
8395   myquery(rc);
8396 
8397   result= mysql_list_fields(mysql, "t1", NULL);
8398   mytest(result);
8399 
8400   rc= my_process_result_set(result);
8401   DIE_UNLESS(rc == 0);
8402 
8403   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_LONG,
8404                        "t1", "t1",
8405                        current_db, 11, "0");
8406 
8407   verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_STRING,
8408                        "t1", "t1",
8409                        current_db, 10, "mysql");
8410 
8411   mysql_free_result(result);
8412   myquery(mysql_query(mysql, "drop table t1"));
8413 }
8414 
8415 
8416 /* Test mysql_list_fields() with information_schema */
8417 
test_list_information_schema_fields()8418 static void test_list_information_schema_fields()
8419 {
8420   MYSQL_RES *result;
8421   int rc;
8422   myheader("test_list_information_schema_fields");
8423 
8424   rc= mysql_select_db(mysql, "information_schema");
8425   myquery(rc);
8426   result= mysql_list_fields(mysql, "all_plugins", NULL);
8427   mytest(result);
8428   rc= my_process_result_set(result);
8429   DIE_UNLESS(rc == 0);
8430   mysql_free_result(result);
8431   rc= mysql_select_db(mysql, current_db);
8432   myquery(rc);
8433 }
8434 
8435 
test_list_fields_blob()8436 static void test_list_fields_blob()
8437 {
8438   MYSQL_RES *result;
8439   int rc;
8440   myheader("test_list_fields_blob");
8441 
8442   rc= mysql_query(mysql, "drop table if exists t1");
8443   myquery(rc);
8444 
8445   rc= mysql_query(mysql, "create table t1(c1 tinyblob, c2 blob, c3 mediumblob, c4 longblob)");
8446   myquery(rc);
8447 
8448   result= mysql_list_fields(mysql, "t1", NULL);
8449   mytest(result);
8450 
8451   rc= my_process_result_set(result);
8452   DIE_UNLESS(rc == 0);
8453 
8454   /*
8455     All BLOB variant Fields are displayed as MYSQL_TYPE_BLOB in
8456     the result set metadata. Note, some Items display the exact
8457     BLOB type. This inconsistency should be fixed eventually.
8458   */
8459   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_BLOB,
8460                        "t1", "t1",
8461                        current_db, 255, NULL);
8462 
8463   verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_BLOB,
8464                        "t1", "t1",
8465                        current_db, 65535, NULL);
8466 
8467   verify_prepare_field(result, 2, "c3", "c3", MYSQL_TYPE_BLOB,
8468                        "t1", "t1",
8469                        current_db, 16777215, NULL);
8470 
8471   verify_prepare_field(result, 3, "c4", "c4", MYSQL_TYPE_BLOB,
8472                        "t1", "t1",
8473                        current_db, 4294967295ULL, NULL);
8474 
8475   mysql_free_result(result);
8476   myquery(mysql_query(mysql, "drop table t1"));
8477 }
8478 
8479 
test_list_fields_default()8480 static void test_list_fields_default()
8481 {
8482   int rc, i;
8483   myheader("test_list_fields_default");
8484 
8485   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
8486   myquery(rc);
8487 
8488   rc= mysql_query(mysql,
8489                   "CREATE TABLE t1 ("
8490                   " i1 INT NOT NULL DEFAULT 0,"
8491                   " i3 BIGINT UNSIGNED NOT NULL DEFAULT 0xFFFFFFFFFFFFFFFF,"
8492                   " s1 VARCHAR(10) CHARACTER SET latin1 NOT NULL DEFAULT 's1def',"
8493                   " d1 DECIMAL(31,1) NOT NULL DEFAULT 111111111122222222223333333333.9,"
8494                   " t1 DATETIME(6) NOT NULL DEFAULT '2001-01-01 10:20:30.123456',"
8495                   " e1 ENUM('a','b') NOT NULL DEFAULT 'a'"
8496                   ")");
8497   myquery(rc);
8498 
8499   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1");
8500   myquery(rc);
8501 
8502   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
8503   myquery(rc);
8504 
8505   /*
8506     Checking that mysql_list_fields() returns the same result
8507     for a TABLE and a VIEW on the same table.
8508   */
8509   for (i= 0; i < 2; i++)
8510   {
8511     const char *table_name= i == 0 ? "t1" : "v1";
8512     MYSQL_RES *result= mysql_list_fields(mysql, table_name, NULL);
8513     mytest(result);
8514 
8515     rc= my_process_result_set(result);
8516     DIE_UNLESS(rc == 0);
8517 
8518     verify_prepare_field(result, 0, "i1", "i1", MYSQL_TYPE_LONG,
8519                          table_name, table_name, current_db,
8520                          11, "0");
8521 
8522     verify_prepare_field(result, 1, "i3", "i3", MYSQL_TYPE_LONGLONG,
8523                          table_name, table_name, current_db,
8524                          20, "18446744073709551615");
8525 
8526     verify_prepare_field(result, 2, "s1", "s1", MYSQL_TYPE_VAR_STRING,
8527                          table_name, table_name, current_db,
8528                          10, "s1def");
8529 
8530     verify_prepare_field(result, 3, "d1", "d1", MYSQL_TYPE_NEWDECIMAL,
8531                          table_name, table_name, current_db,
8532                          33, "111111111122222222223333333333.9");
8533 
8534     verify_prepare_field(result, 4, "t1", "t1", MYSQL_TYPE_DATETIME,
8535                          table_name, table_name, current_db,
8536                          26, "2001-01-01 10:20:30.123456");
8537 
8538     verify_prepare_field(result, 5, "e1", "e1", MYSQL_TYPE_STRING,
8539                          table_name, table_name, current_db,
8540                          1, "a");
8541 
8542     mysql_free_result(result);
8543   }
8544 
8545   myquery(mysql_query(mysql, "DROP VIEW v1"));
8546   myquery(mysql_query(mysql, "DROP TABLE t1"));
8547 }
8548 
8549 
8550 /**
8551   Note, this test covers MDEV-18408 and MDEV-18685
8552 */
8553 
test_mdev18408()8554 static void test_mdev18408()
8555 {
8556   MYSQL_RES *result;
8557   int rc;
8558   myheader("test_mdev18408s");
8559 
8560   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
8561   myquery(rc);
8562 
8563   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1");
8564   myquery(rc);
8565 
8566   rc= mysql_query(mysql, "CREATE TABLE t1 (c1 TIMESTAMP NULL DEFAULT NULL)");
8567   myquery(rc);
8568 
8569   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT c1 FROM t1");
8570   myquery(rc);
8571 
8572   result= mysql_list_fields(mysql, "v1", NULL);
8573   mytest(result);
8574 
8575   rc= my_process_result_set(result);
8576   DIE_UNLESS(rc == 0);
8577 
8578   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_TIMESTAMP,
8579                        "v1", "v1",  current_db, 19, 0);
8580 
8581   mysql_free_result(result);
8582   myquery(mysql_query(mysql, "DROP VIEW v1"));
8583   myquery(mysql_query(mysql, "DROP TABLE t1"));
8584 }
8585 
8586 
test_bug19671()8587 static void test_bug19671()
8588 {
8589   MYSQL_RES *result;
8590   int rc;
8591   myheader("test_bug19671");
8592 
8593   mysql_query(mysql, "set sql_mode=''");
8594   rc= mysql_query(mysql, "drop table if exists t1");
8595   myquery(rc);
8596 
8597   rc= mysql_query(mysql, "drop view if exists v1");
8598   myquery(rc);
8599 
8600   rc= mysql_query(mysql, "create table t1(f1 int)");
8601   myquery(rc);
8602 
8603   rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
8604   myquery(rc);
8605 
8606   result= mysql_list_fields(mysql, "v1", NULL);
8607   mytest(result);
8608 
8609   rc= my_process_result_set(result);
8610   DIE_UNLESS(rc == 0);
8611 
8612   verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
8613                        "v1", "v1", current_db, 11, NULL);
8614 
8615   mysql_free_result(result);
8616   myquery(mysql_query(mysql, "drop view v1"));
8617   myquery(mysql_query(mysql, "drop table t1"));
8618 }
8619 
8620 
8621 /* Test a memory ovverun bug */
8622 
test_mem_overun()8623 static void test_mem_overun()
8624 {
8625   char       buffer[10000], field[10];
8626   MYSQL_STMT *stmt;
8627   MYSQL_RES  *field_res;
8628   int        rc, length;
8629   unsigned   i;
8630 
8631   myheader("test_mem_overun");
8632 
8633   /*
8634     Test a memory ovverun bug when a table had 1000 fields with
8635     a row of data
8636   */
8637   rc= mysql_query(mysql, "drop table if exists t_mem_overun");
8638   myquery(rc);
8639 
8640   strxmov(buffer, "create table t_mem_overun(", NullS);
8641   for (i= 0; i < 1000; i++)
8642   {
8643     sprintf(field, "c%u int", i);
8644     strxmov(buffer, buffer, field, ", ", NullS);
8645   }
8646   length= strlen(buffer);
8647   buffer[length-2]= ')';
8648   buffer[--length]= '\0';
8649 
8650   rc= mysql_real_query(mysql, buffer, length);
8651   myquery(rc);
8652 
8653   strxmov(buffer, "insert into t_mem_overun values(", NullS);
8654   for (i= 0; i < 1000; i++)
8655   {
8656     strxmov(buffer, buffer, "1, ", NullS);
8657   }
8658   length= strlen(buffer);
8659   buffer[length-2]= ')';
8660   buffer[--length]= '\0';
8661 
8662   rc= mysql_real_query(mysql, buffer, length);
8663   myquery(rc);
8664 
8665   rc= mysql_query(mysql, "select * from t_mem_overun");
8666   myquery(rc);
8667 
8668   rc= my_process_result(mysql);
8669   DIE_UNLESS(rc == 1);
8670 
8671   stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun");
8672   check_stmt(stmt);
8673 
8674   rc= mysql_stmt_execute(stmt);
8675   check_execute(stmt, rc);
8676 
8677   field_res= mysql_stmt_result_metadata(stmt);
8678   mytest(field_res);
8679 
8680   if (!opt_silent)
8681     fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
8682   DIE_UNLESS( 1000 == mysql_num_fields(field_res));
8683 
8684   rc= mysql_stmt_store_result(stmt);
8685   check_execute(stmt, rc);
8686 
8687   rc= mysql_stmt_fetch(stmt);
8688   check_execute(stmt, rc);
8689 
8690   rc= mysql_stmt_fetch(stmt);
8691   DIE_UNLESS(rc == MYSQL_NO_DATA);
8692 
8693   mysql_free_result(field_res);
8694 
8695   mysql_stmt_close(stmt);
8696 }
8697 
8698 
8699 /* Test mysql_stmt_free_result() */
8700 
test_free_result()8701 static void test_free_result()
8702 {
8703   MYSQL_STMT *stmt;
8704   MYSQL_BIND my_bind[1];
8705   char       c2[5];
8706   ulong      bl1, l2;
8707   int        rc, c1, bc1;
8708 
8709   myheader("test_free_result");
8710 
8711   rc= mysql_query(mysql, "drop table if exists test_free_result");
8712   myquery(rc);
8713 
8714   rc= mysql_query(mysql, "create table test_free_result("
8715                          "c1 int primary key auto_increment)");
8716   myquery(rc);
8717 
8718   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8719   myquery(rc);
8720 
8721   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8722   check_stmt(stmt);
8723 
8724   bzero((char*) my_bind, sizeof(my_bind));
8725   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8726   my_bind[0].buffer= (void *)&bc1;
8727   my_bind[0].length= &bl1;
8728 
8729   rc= mysql_stmt_execute(stmt);
8730   check_execute(stmt, rc);
8731 
8732   rc= mysql_stmt_bind_result(stmt, my_bind);
8733   check_execute(stmt, rc);
8734 
8735   rc= mysql_stmt_fetch(stmt);
8736   check_execute(stmt, rc);
8737 
8738   c2[0]= '\0'; l2= 0;
8739   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8740   my_bind[0].buffer= (void *)c2;
8741   my_bind[0].buffer_length= 7;
8742   my_bind[0].is_null= 0;
8743   my_bind[0].length= &l2;
8744 
8745   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8746   check_execute(stmt, rc);
8747   if (!opt_silent)
8748     fprintf(stdout, "\n col 0: %s(%ld)", c2, l2);
8749   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8750 
8751   rc= mysql_stmt_fetch(stmt);
8752   check_execute(stmt, rc);
8753 
8754   c1= 0, l2= 0;
8755   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8756   my_bind[0].buffer= (void *)&c1;
8757   my_bind[0].buffer_length= 0;
8758   my_bind[0].is_null= 0;
8759   my_bind[0].length= &l2;
8760 
8761   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8762   check_execute(stmt, rc);
8763   if (!opt_silent)
8764     fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8765   DIE_UNLESS(c1 == 2 && l2 == 4);
8766 
8767   rc= mysql_query(mysql, "drop table test_free_result");
8768   myquery_r(rc); /* error should be, COMMANDS OUT OF SYNC */
8769 
8770   rc= mysql_stmt_free_result(stmt);
8771   check_execute(stmt, rc);
8772 
8773   rc= mysql_query(mysql, "drop table test_free_result");
8774   myquery(rc);  /* should be successful */
8775 
8776   mysql_stmt_close(stmt);
8777 }
8778 
8779 
8780 /* Test mysql_stmt_store_result() */
8781 
test_free_store_result()8782 static void test_free_store_result()
8783 {
8784   MYSQL_STMT *stmt;
8785   MYSQL_BIND my_bind[1];
8786   char       c2[5];
8787   ulong      bl1, l2;
8788   int        rc, c1, bc1;
8789 
8790   myheader("test_free_store_result");
8791 
8792   rc= mysql_query(mysql, "drop table if exists test_free_result");
8793   myquery(rc);
8794 
8795   rc= mysql_query(mysql, "create table test_free_result(c1 int primary key auto_increment)");
8796   myquery(rc);
8797 
8798   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8799   myquery(rc);
8800 
8801   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8802   check_stmt(stmt);
8803 
8804   bzero((char*) my_bind, sizeof(my_bind));
8805   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8806   my_bind[0].buffer= (void *)&bc1;
8807   my_bind[0].buffer_length= 0;
8808   my_bind[0].is_null= 0;
8809   my_bind[0].length= &bl1;
8810 
8811   rc= mysql_stmt_execute(stmt);
8812   check_execute(stmt, rc);
8813 
8814   rc= mysql_stmt_bind_result(stmt, my_bind);
8815   check_execute(stmt, rc);
8816 
8817   rc= mysql_stmt_store_result(stmt);
8818   check_execute(stmt, rc);
8819 
8820   rc= mysql_stmt_fetch(stmt);
8821   check_execute(stmt, rc);
8822 
8823   c2[0]= '\0'; l2= 0;
8824   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8825   my_bind[0].buffer= (void *)c2;
8826   my_bind[0].buffer_length= 7;
8827   my_bind[0].is_null= 0;
8828   my_bind[0].length= &l2;
8829 
8830   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8831   check_execute(stmt, rc);
8832   if (!opt_silent)
8833     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8834   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8835 
8836   rc= mysql_stmt_fetch(stmt);
8837   check_execute(stmt, rc);
8838 
8839   c1= 0, l2= 0;
8840   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8841   my_bind[0].buffer= (void *)&c1;
8842   my_bind[0].buffer_length= 0;
8843   my_bind[0].is_null= 0;
8844   my_bind[0].length= &l2;
8845 
8846   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8847   check_execute(stmt, rc);
8848   if (!opt_silent)
8849     fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8850   DIE_UNLESS(c1 == 2 && l2 == 4);
8851 
8852   rc= mysql_stmt_free_result(stmt);
8853   check_execute(stmt, rc);
8854 
8855   rc= mysql_query(mysql, "drop table test_free_result");
8856   myquery(rc);
8857 
8858   mysql_stmt_close(stmt);
8859 }
8860 
8861 
8862 /* Test SQLmode */
8863 
test_sqlmode()8864 static void test_sqlmode()
8865 {
8866   MYSQL_STMT *stmt;
8867   MYSQL_BIND my_bind[2];
8868   char       c1[5], c2[5];
8869   int        rc;
8870   char query[MAX_TEST_QUERY_LENGTH];
8871 
8872   myheader("test_sqlmode");
8873 
8874   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping");
8875   myquery(rc);
8876 
8877   rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))");
8878   myquery(rc);
8879 
8880   /* PIPES_AS_CONCAT */
8881   strmov(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
8882   if (!opt_silent)
8883     fprintf(stdout, "\n With %s", query);
8884   rc= mysql_query(mysql, query);
8885   myquery(rc);
8886 
8887   strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8888   if (!opt_silent)
8889     fprintf(stdout, "\n  query: %s", query);
8890   stmt= mysql_simple_prepare(mysql, query);
8891   check_stmt(stmt);
8892 
8893   if (!opt_silent)
8894     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8895 
8896   /*
8897     We need to bzero bind structure because mysql_stmt_bind_param checks all
8898     its members.
8899   */
8900   bzero((char*) my_bind, sizeof(my_bind));
8901 
8902   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8903   my_bind[0].buffer= (void *)c1;
8904   my_bind[0].buffer_length= 2;
8905 
8906   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8907   my_bind[1].buffer= (void *)c2;
8908   my_bind[1].buffer_length= 3;
8909 
8910   rc= mysql_stmt_bind_param(stmt, my_bind);
8911   check_execute(stmt, rc);
8912 
8913   strmov(c1, "My"); strmov(c2, "SQL");
8914   rc= mysql_stmt_execute(stmt);
8915   check_execute(stmt, rc);
8916   mysql_stmt_close(stmt);
8917 
8918   verify_col_data("test_piping", "name", "MySQL");
8919 
8920   rc= mysql_query(mysql, "DELETE FROM test_piping");
8921   myquery(rc);
8922 
8923   strmov(query, "SELECT connection_id    ()");
8924   if (!opt_silent)
8925     fprintf(stdout, "\n  query: %s", query);
8926   stmt= mysql_simple_prepare(mysql, query);
8927   check_stmt(stmt);
8928   mysql_stmt_close(stmt);
8929 
8930   /* ANSI */
8931   strmov(query, "SET SQL_MODE= \"ANSI\"");
8932   if (!opt_silent)
8933     fprintf(stdout, "\n With %s", query);
8934   rc= mysql_query(mysql, query);
8935   myquery(rc);
8936 
8937   strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8938   if (!opt_silent)
8939     fprintf(stdout, "\n  query: %s", query);
8940   stmt= mysql_simple_prepare(mysql, query);
8941   check_stmt(stmt);
8942   if (!opt_silent)
8943     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8944 
8945   rc= mysql_stmt_bind_param(stmt, my_bind);
8946   check_execute(stmt, rc);
8947 
8948   strmov(c1, "My"); strmov(c2, "SQL");
8949   rc= mysql_stmt_execute(stmt);
8950   check_execute(stmt, rc);
8951 
8952   mysql_stmt_close(stmt);
8953   verify_col_data("test_piping", "name", "MySQL");
8954 
8955   /* ANSI mode spaces ... */
8956   strmov(query, "SELECT connection_id    ()");
8957   if (!opt_silent)
8958     fprintf(stdout, "\n  query: %s", query);
8959   stmt= mysql_simple_prepare(mysql, query);
8960   check_stmt(stmt);
8961 
8962   rc= mysql_stmt_execute(stmt);
8963   check_execute(stmt, rc);
8964 
8965   rc= mysql_stmt_fetch(stmt);
8966   check_execute(stmt, rc);
8967 
8968   rc= mysql_stmt_fetch(stmt);
8969   DIE_UNLESS(rc == MYSQL_NO_DATA);
8970   if (!opt_silent)
8971     fprintf(stdout, "\n  returned 1 row\n");
8972 
8973   mysql_stmt_close(stmt);
8974 
8975   /* IGNORE SPACE MODE */
8976   strmov(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
8977   if (!opt_silent)
8978     fprintf(stdout, "\n With %s", query);
8979   rc= mysql_query(mysql, query);
8980   myquery(rc);
8981 
8982   strmov(query, "SELECT connection_id    ()");
8983   if (!opt_silent)
8984     fprintf(stdout, "\n  query: %s", query);
8985   stmt= mysql_simple_prepare(mysql, query);
8986   check_stmt(stmt);
8987 
8988   rc= mysql_stmt_execute(stmt);
8989   check_execute(stmt, rc);
8990 
8991   rc= mysql_stmt_fetch(stmt);
8992   check_execute(stmt, rc);
8993 
8994   rc= mysql_stmt_fetch(stmt);
8995   DIE_UNLESS(rc == MYSQL_NO_DATA);
8996   if (!opt_silent)
8997     fprintf(stdout, "\n  returned 1 row");
8998 
8999   mysql_stmt_close(stmt);
9000 }
9001 
9002 
9003 /* Test for timestamp handling */
9004 
test_ts()9005 static void test_ts()
9006 {
9007   MYSQL_STMT *stmt;
9008   MYSQL_BIND my_bind[6];
9009   MYSQL_TIME ts;
9010   MYSQL_RES  *prep_res;
9011   char       strts[30];
9012   ulong      length;
9013   int        rc, field_count;
9014   char       name;
9015   char query[MAX_TEST_QUERY_LENGTH];
9016   const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
9017                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS TIME)",
9018                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
9019   myheader("test_ts");
9020 
9021   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts");
9022   myquery(rc);
9023 
9024   rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)");
9025   myquery(rc);
9026 
9027   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)");
9028   check_stmt(stmt);
9029 
9030   ts.year= 2003;
9031   ts.month= 07;
9032   ts.day= 12;
9033   ts.hour= 21;
9034   ts.minute= 07;
9035   ts.second= 46;
9036   ts.second_part= 0;
9037   length= (long)(strmov(strts, "2003-07-12 21:07:46") - strts);
9038 
9039   /*
9040     We need to bzero bind structure because mysql_stmt_bind_param checks all
9041     its members.
9042   */
9043   bzero((char*) my_bind, sizeof(my_bind));
9044 
9045   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
9046   my_bind[0].buffer= (void *)&ts;
9047   my_bind[0].buffer_length= sizeof(ts);
9048 
9049   my_bind[2]= my_bind[1]= my_bind[0];
9050 
9051   my_bind[3].buffer_type= MYSQL_TYPE_STRING;
9052   my_bind[3].buffer= (void *)strts;
9053   my_bind[3].buffer_length= sizeof(strts);
9054   my_bind[3].length= &length;
9055 
9056   my_bind[5]= my_bind[4]= my_bind[3];
9057 
9058   rc= mysql_stmt_bind_param(stmt, my_bind);
9059   check_execute(stmt, rc);
9060 
9061   rc= mysql_stmt_execute(stmt);
9062   check_execute(stmt, rc);
9063 
9064   mysql_stmt_close(stmt);
9065 
9066   verify_col_data("test_ts", "a", "2003-07-12");
9067   verify_col_data("test_ts", "b", "21:07:46");
9068   verify_col_data("test_ts", "c", "2003-07-12 21:07:46");
9069 
9070   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts");
9071   check_stmt(stmt);
9072 
9073   prep_res= mysql_stmt_result_metadata(stmt);
9074   mytest(prep_res);
9075 
9076   rc= mysql_stmt_execute(stmt);
9077   check_execute(stmt, rc);
9078 
9079   rc= my_process_stmt_result(stmt);
9080   DIE_UNLESS(rc == 2);
9081   field_count= mysql_num_fields(prep_res);
9082 
9083   mysql_free_result(prep_res);
9084   mysql_stmt_close(stmt);
9085 
9086   for (name= 'a'; field_count--; name++)
9087   {
9088     int row_count= 0;
9089 
9090     sprintf(query, queries[field_count], name);
9091 
9092     if (!opt_silent)
9093       fprintf(stdout, "\n  %s", query);
9094     stmt= mysql_simple_prepare(mysql, query);
9095     check_stmt(stmt);
9096 
9097     rc= mysql_stmt_bind_param(stmt, my_bind);
9098     check_execute(stmt, rc);
9099 
9100     rc= mysql_stmt_execute(stmt);
9101     check_execute(stmt, rc);
9102 
9103     while (mysql_stmt_fetch(stmt) == 0)
9104       row_count++;
9105 
9106     if (!opt_silent)
9107       fprintf(stdout, "\n   returned '%d' rows", row_count);
9108     DIE_UNLESS(row_count == 2);
9109     mysql_stmt_close(stmt);
9110   }
9111 }
9112 
9113 
9114 /* Test for bug #1500. */
9115 
test_bug1500()9116 static void test_bug1500()
9117 {
9118   MYSQL_STMT *stmt;
9119   MYSQL_BIND my_bind[3];
9120   int        rc;
9121   int32 int_data[3]= {2, 3, 4};
9122   const char *data;
9123 
9124   myheader("test_bug1500");
9125 
9126   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
9127   myquery(rc);
9128 
9129   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (i INT)");
9130   myquery(rc);
9131 
9132   rc= mysql_query(mysql, "INSERT INTO test_bg1500 VALUES (1), (2)");
9133   myquery(rc);
9134 
9135   rc= mysql_commit(mysql);
9136   myquery(rc);
9137 
9138   stmt= mysql_simple_prepare(mysql, "SELECT i FROM test_bg1500 WHERE i IN (?, ?, ?)");
9139   check_stmt(stmt);
9140   verify_param_count(stmt, 3);
9141 
9142   /*
9143     We need to bzero bind structure because mysql_stmt_bind_param checks all
9144     its members.
9145   */
9146   bzero((char*) my_bind, sizeof(my_bind));
9147 
9148   my_bind[0].buffer= (void *)int_data;
9149   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9150   my_bind[2]= my_bind[1]= my_bind[0];
9151   my_bind[1].buffer= (void *)(int_data + 1);
9152   my_bind[2].buffer= (void *)(int_data + 2);
9153 
9154   rc= mysql_stmt_bind_param(stmt, my_bind);
9155   check_execute(stmt, rc);
9156 
9157   rc= mysql_stmt_execute(stmt);
9158   check_execute(stmt, rc);
9159 
9160   rc= my_process_stmt_result(stmt);
9161   DIE_UNLESS(rc == 1);
9162 
9163   mysql_stmt_close(stmt);
9164 
9165   rc= mysql_query(mysql, "DROP TABLE test_bg1500");
9166   myquery(rc);
9167 
9168   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM");
9169   myquery(rc);
9170 
9171   rc= mysql_query(mysql,
9172         "INSERT INTO test_bg1500 VALUES ('Gravedigger'), ('Greed'), ('Hollow Dogs')");
9173   myquery(rc);
9174 
9175   rc= mysql_commit(mysql);
9176   myquery(rc);
9177 
9178   stmt= mysql_simple_prepare(mysql,
9179           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)");
9180   check_stmt(stmt);
9181 
9182   verify_param_count(stmt, 1);
9183 
9184   data= "Dogs";
9185   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9186   my_bind[0].buffer= (void *) data;
9187   my_bind[0].buffer_length= strlen(data);
9188   my_bind[0].is_null= 0;
9189   my_bind[0].length= 0;
9190 
9191   rc= mysql_stmt_bind_param(stmt, my_bind);
9192   check_execute(stmt, rc);
9193 
9194   rc= mysql_stmt_execute(stmt);
9195   check_execute(stmt, rc);
9196 
9197   rc= my_process_stmt_result(stmt);
9198   DIE_UNLESS(rc == 1);
9199 
9200   mysql_stmt_close(stmt);
9201 
9202   /* This should work too */
9203   stmt= mysql_simple_prepare(mysql,
9204           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?, 'digger'))");
9205   check_stmt(stmt);
9206 
9207   verify_param_count(stmt, 1);
9208 
9209   data= "Grave";
9210   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9211   my_bind[0].buffer= (void *) data;
9212   my_bind[0].buffer_length= strlen(data);
9213 
9214   rc= mysql_stmt_bind_param(stmt, my_bind);
9215   check_execute(stmt, rc);
9216 
9217   rc= mysql_stmt_execute(stmt);
9218   check_execute(stmt, rc);
9219 
9220   rc= my_process_stmt_result(stmt);
9221   DIE_UNLESS(rc == 1);
9222 
9223   mysql_stmt_close(stmt);
9224 }
9225 
9226 
test_bug1946()9227 static void test_bug1946()
9228 {
9229   MYSQL_STMT *stmt;
9230   int rc;
9231   const char *query= "INSERT INTO prepare_command VALUES (?)";
9232 
9233   myheader("test_bug1946");
9234 
9235   rc= mysql_query(mysql, "DROP TABLE IF EXISTS prepare_command");
9236   myquery(rc);
9237 
9238   rc= mysql_query(mysql, "CREATE TABLE prepare_command(ID INT)");
9239   myquery(rc);
9240 
9241   stmt= mysql_simple_prepare(mysql, query);
9242   check_stmt(stmt);
9243   rc= mysql_real_query(mysql, query, strlen(query));
9244   DIE_UNLESS(rc != 0);
9245   if (!opt_silent)
9246     fprintf(stdout, "Got error (as expected):\n");
9247   myerror(NULL);
9248 
9249   mysql_stmt_close(stmt);
9250   rc= mysql_query(mysql, "DROP TABLE prepare_command");
9251 }
9252 
9253 
test_parse_error_and_bad_length()9254 static void test_parse_error_and_bad_length()
9255 {
9256   MYSQL_STMT *stmt;
9257   int rc;
9258 
9259   /* check that we get 4 syntax errors over the 4 calls */
9260   myheader("test_parse_error_and_bad_length");
9261 
9262   rc= mysql_query(mysql, "SHOW DATABAAAA");
9263   DIE_UNLESS(rc);
9264   if (!opt_silent)
9265     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9266   rc= mysql_real_query(mysql, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAAA"));
9267   DIE_UNLESS(rc);
9268   if (!opt_silent)
9269     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9270 
9271   stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA");
9272   DIE_UNLESS(!stmt);
9273   if (!opt_silent)
9274     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9275   stmt= mysql_stmt_init(mysql);
9276   DIE_UNLESS(stmt);
9277   rc= mysql_stmt_prepare(stmt, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAA"));
9278   DIE_UNLESS(rc != 0);
9279   if (!opt_silent)
9280     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
9281   mysql_stmt_close(stmt);
9282 }
9283 
9284 
test_bug2247()9285 static void test_bug2247()
9286 {
9287   MYSQL_STMT *stmt;
9288   MYSQL_RES *res;
9289   int rc;
9290   int i;
9291   const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)";
9292   const char *insert= "INSERT INTO bug2247 VALUES (NULL)";
9293   const char *SELECT= "SELECT id FROM bug2247";
9294   const char *update= "UPDATE bug2247 SET id=id+10";
9295   const char *drop= "DROP TABLE IF EXISTS bug2247";
9296   ulonglong exp_count;
9297   enum { NUM_ROWS= 5 };
9298 
9299   myheader("test_bug2247");
9300 
9301   if (!opt_silent)
9302     fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
9303                   "mysql_query ... ");
9304   /* create table and insert few rows */
9305   rc= mysql_query(mysql, drop);
9306   myquery(rc);
9307 
9308   rc= mysql_query(mysql, create);
9309   myquery(rc);
9310 
9311   stmt= mysql_simple_prepare(mysql, insert);
9312   check_stmt(stmt);
9313   for (i= 0; i < NUM_ROWS; ++i)
9314   {
9315     rc= mysql_stmt_execute(stmt);
9316     check_execute(stmt, rc);
9317   }
9318   exp_count= mysql_stmt_affected_rows(stmt);
9319   DIE_UNLESS(exp_count == 1);
9320 
9321   rc= mysql_query(mysql, SELECT);
9322   myquery(rc);
9323   /*
9324     mysql_store_result overwrites mysql->affected_rows. Check that
9325     mysql_stmt_affected_rows() returns the same value, whereas
9326     mysql_affected_rows() value is correct.
9327   */
9328   res= mysql_store_result(mysql);
9329   mytest(res);
9330 
9331   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9332   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9333 
9334   rc= mysql_query(mysql, update);
9335   myquery(rc);
9336   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9337   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9338 
9339   mysql_free_result(res);
9340   mysql_stmt_close(stmt);
9341 
9342   /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */
9343   stmt= mysql_simple_prepare(mysql, SELECT);
9344   check_stmt(stmt);
9345 
9346   rc= mysql_stmt_execute(stmt);
9347   check_execute(stmt, rc);
9348   rc= mysql_stmt_store_result(stmt);
9349   check_execute(stmt, rc);
9350   exp_count= mysql_stmt_affected_rows(stmt);
9351   DIE_UNLESS(exp_count == NUM_ROWS);
9352 
9353   rc= mysql_query(mysql, insert);
9354   myquery(rc);
9355   DIE_UNLESS(mysql_affected_rows(mysql) == 1);
9356   DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count);
9357 
9358   mysql_stmt_close(stmt);
9359   if (!opt_silent)
9360     fprintf(stdout, "OK");
9361 }
9362 
9363 
test_subqueries()9364 static void test_subqueries()
9365 {
9366   MYSQL_STMT *stmt;
9367   int rc, i;
9368   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";
9369 
9370   myheader("test_subqueries");
9371 
9372   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9373   myquery(rc);
9374 
9375   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9376   myquery(rc);
9377 
9378   rc= mysql_query(mysql,
9379                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9380   myquery(rc);
9381 
9382   rc= mysql_query(mysql, "create table t2 select * from t1;");
9383   myquery(rc);
9384 
9385   stmt= mysql_simple_prepare(mysql, query);
9386   check_stmt(stmt);
9387   for (i= 0; i < 3; i++)
9388   {
9389     rc= mysql_stmt_execute(stmt);
9390     check_execute(stmt, rc);
9391     rc= my_process_stmt_result(stmt);
9392     DIE_UNLESS(rc == 5);
9393   }
9394   mysql_stmt_close(stmt);
9395 
9396   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9397   myquery(rc);
9398 }
9399 
9400 
test_bad_union()9401 static void test_bad_union()
9402 {
9403   MYSQL_STMT *stmt;
9404   const char *query= "SELECT 1, 2 union SELECT 1";
9405 
9406   myheader("test_bad_union");
9407 
9408   stmt= mysql_simple_prepare(mysql, query);
9409   DIE_UNLESS(stmt == 0);
9410   myerror(NULL);
9411 }
9412 
9413 
test_distinct()9414 static void test_distinct()
9415 {
9416   MYSQL_STMT *stmt;
9417   int rc, i;
9418   const char *query=
9419     "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a";
9420 
9421   myheader("test_distinct");
9422 
9423   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9424   myquery(rc);
9425 
9426   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9427   myquery(rc);
9428 
9429   rc= mysql_query(mysql,
9430                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), \
9431 (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);");
9432   myquery(rc);
9433 
9434   for (i= 0; i < 3; i++)
9435   {
9436     stmt= mysql_simple_prepare(mysql, query);
9437     check_stmt(stmt);
9438     rc= mysql_stmt_execute(stmt);
9439     check_execute(stmt, rc);
9440     rc= my_process_stmt_result(stmt);
9441     DIE_UNLESS(rc == 5);
9442     mysql_stmt_close(stmt);
9443   }
9444 
9445   rc= mysql_query(mysql, "DROP TABLE t1");
9446   myquery(rc);
9447 }
9448 
9449 
9450 /*
9451   Test for bug#2248 "mysql_fetch without prior mysql_stmt_execute hangs"
9452 */
9453 
test_bug2248()9454 static void test_bug2248()
9455 {
9456   MYSQL_STMT *stmt;
9457   int rc;
9458   const char *query1= "SELECT DATABASE()";
9459   const char *query2= "INSERT INTO test_bug2248 VALUES (10)";
9460 
9461   myheader("test_bug2248");
9462 
9463   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248");
9464   myquery(rc);
9465 
9466   rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)");
9467   myquery(rc);
9468 
9469   stmt= mysql_simple_prepare(mysql, query1);
9470   check_stmt(stmt);
9471 
9472   /* This should not hang */
9473   rc= mysql_stmt_fetch(stmt);
9474   check_execute_r(stmt, rc);
9475 
9476   /* And this too */
9477   rc= mysql_stmt_store_result(stmt);
9478   check_execute_r(stmt, rc);
9479 
9480   mysql_stmt_close(stmt);
9481 
9482   stmt= mysql_simple_prepare(mysql, query2);
9483   check_stmt(stmt);
9484 
9485   rc= mysql_stmt_execute(stmt);
9486   check_execute(stmt, rc);
9487 
9488   /* This too should not hang but should return proper error */
9489   rc= mysql_stmt_fetch(stmt);
9490   DIE_UNLESS(rc == 1);
9491 
9492   /* This too should not hang but should not bark */
9493   rc= mysql_stmt_store_result(stmt);
9494   check_execute(stmt, rc);
9495 
9496   /* This should return proper error */
9497   rc= mysql_stmt_fetch(stmt);
9498   check_execute_r(stmt, rc);
9499   DIE_UNLESS(rc == 1);
9500 
9501   mysql_stmt_close(stmt);
9502 
9503   rc= mysql_query(mysql, "DROP TABLE test_bug2248");
9504   myquery(rc);
9505 }
9506 
9507 
test_subqueries_ref()9508 static void test_subqueries_ref()
9509 {
9510   MYSQL_STMT *stmt;
9511   int rc, i;
9512   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)";
9513 
9514   myheader("test_subqueries_ref");
9515 
9516   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9517   myquery(rc);
9518 
9519   rc= mysql_query(mysql, "CREATE TABLE t1 (a int);");
9520   myquery(rc);
9521 
9522   rc= mysql_query(mysql,
9523                   "insert into t1 values (1), (2), (3), (4), (5);");
9524   myquery(rc);
9525 
9526   stmt= mysql_simple_prepare(mysql, query);
9527   check_stmt(stmt);
9528   for (i= 0; i < 3; i++)
9529   {
9530     rc= mysql_stmt_execute(stmt);
9531     check_execute(stmt, rc);
9532     rc= my_process_stmt_result(stmt);
9533     DIE_UNLESS(rc == 1);
9534   }
9535   mysql_stmt_close(stmt);
9536 
9537   rc= mysql_query(mysql, "DROP TABLE t1");
9538   myquery(rc);
9539 }
9540 
9541 
test_union()9542 static void test_union()
9543 {
9544   MYSQL_STMT *stmt;
9545   int rc;
9546 
9547   myheader("test_union");
9548 
9549   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9550   myquery(rc);
9551 
9552   rc= mysql_query(mysql,
9553                   "CREATE TABLE t1 "
9554                   "(id INTEGER NOT NULL PRIMARY KEY, "
9555                   " name VARCHAR(20) NOT NULL)");
9556   myquery(rc);
9557   rc= mysql_query(mysql,
9558                   "INSERT INTO t1 (id, name) VALUES "
9559                   "(2, 'Ja'), (3, 'Ede'), "
9560                   "(4, 'Haag'), (5, 'Kabul'), "
9561                   "(6, 'Almere'), (7, 'Utrecht'), "
9562                   "(8, 'Qandahar'), (9, 'Amsterdam'), "
9563                   "(10, 'Amersfoort'), (11, 'Constantine')");
9564   myquery(rc);
9565   rc= mysql_query(mysql,
9566                   "CREATE TABLE t2 "
9567                   "(id INTEGER NOT NULL PRIMARY KEY, "
9568                   " name VARCHAR(20) NOT NULL)");
9569   myquery(rc);
9570   rc= mysql_query(mysql,
9571                   "INSERT INTO t2 (id, name) VALUES "
9572                   "(4, 'Guam'), (5, 'Aruba'), "
9573                   "(6, 'Angola'), (7, 'Albania'), "
9574                   "(8, 'Anguilla'), (9, 'Argentina'), "
9575                   "(10, 'Azerbaijan'), (11, 'Afghanistan'), "
9576                   "(12, 'Burkina Faso'), (13, 'Faroe Islands')");
9577   myquery(rc);
9578 
9579   stmt= mysql_simple_prepare(mysql,
9580                              "SELECT t1.name FROM t1 UNION "
9581                              "SELECT t2.name FROM t2");
9582   check_stmt(stmt);
9583 
9584   rc= mysql_stmt_execute(stmt);
9585   check_execute(stmt, rc);
9586   rc= my_process_stmt_result(stmt);
9587   DIE_UNLESS(rc == 20);
9588   mysql_stmt_close(stmt);
9589 
9590   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9591   myquery(rc);
9592 }
9593 
9594 
test_bug3117()9595 static void test_bug3117()
9596 {
9597   MYSQL_STMT *stmt;
9598   MYSQL_BIND buffer;
9599   longlong lii;
9600   ulong length;
9601   my_bool is_null;
9602   int rc;
9603 
9604   myheader("test_bug3117");
9605 
9606   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9607   myquery(rc);
9608 
9609   rc= mysql_query(mysql, "CREATE TABLE t1 (id int auto_increment primary key)");
9610   myquery(rc);
9611 
9612   stmt= mysql_simple_prepare(mysql, "SELECT LAST_INSERT_ID()");
9613   check_stmt(stmt);
9614 
9615   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9616   myquery(rc);
9617 
9618   rc= mysql_stmt_execute(stmt);
9619   check_execute(stmt, rc);
9620 
9621   bzero((char*) &buffer, sizeof(buffer));
9622   buffer.buffer_type= MYSQL_TYPE_LONGLONG;
9623   buffer.buffer_length= sizeof(lii);
9624   buffer.buffer= (void *)&lii;
9625   buffer.length= &length;
9626   buffer.is_null= &is_null;
9627 
9628   rc= mysql_stmt_bind_result(stmt, &buffer);
9629   check_execute(stmt, rc);
9630 
9631   rc= mysql_stmt_store_result(stmt);
9632   check_execute(stmt, rc);
9633 
9634   rc= mysql_stmt_fetch(stmt);
9635   check_execute(stmt, rc);
9636 
9637   DIE_UNLESS(is_null == 0 && lii == 1);
9638   if (!opt_silent)
9639     fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
9640 
9641   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9642   myquery(rc);
9643 
9644   rc= mysql_stmt_execute(stmt);
9645   check_execute(stmt, rc);
9646 
9647   rc= mysql_stmt_fetch(stmt);
9648   check_execute(stmt, rc);
9649 
9650   DIE_UNLESS(is_null == 0 && lii == 2);
9651   if (!opt_silent)
9652     fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
9653 
9654   mysql_stmt_close(stmt);
9655 
9656   rc= mysql_query(mysql, "DROP TABLE t1");
9657   myquery(rc);
9658 }
9659 
9660 
test_join()9661 static void test_join()
9662 {
9663   MYSQL_STMT *stmt;
9664   int rc, i, j;
9665   const char *query[]= {"SELECT * FROM t2 join t1 on (t1.a=t2.a)",
9666                         "SELECT * FROM t2 natural join t1",
9667                         "SELECT * FROM t2 join t1 using(a)",
9668                         "SELECT * FROM t2 left join t1 on(t1.a=t2.a)",
9669                         "SELECT * FROM t2 natural left join t1",
9670                         "SELECT * FROM t2 left join t1 using(a)",
9671                         "SELECT * FROM t2 right join t1 on(t1.a=t2.a)",
9672                         "SELECT * FROM t2 natural right join t1",
9673                         "SELECT * FROM t2 right join t1 using(a)"};
9674 
9675   myheader("test_join");
9676 
9677   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9678   myquery(rc);
9679 
9680   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9681   myquery(rc);
9682 
9683   rc= mysql_query(mysql,
9684                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9685   myquery(rc);
9686 
9687   rc= mysql_query(mysql, "CREATE TABLE t2 (a int , c int);");
9688   myquery(rc);
9689 
9690   rc= mysql_query(mysql,
9691                   "insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9692   myquery(rc);
9693 
9694   for (j= 0; j < 9; j++)
9695   {
9696     stmt= mysql_simple_prepare(mysql, query[j]);
9697     check_stmt(stmt);
9698     for (i= 0; i < 3; i++)
9699     {
9700       rc= mysql_stmt_execute(stmt);
9701       check_execute(stmt, rc);
9702       rc= my_process_stmt_result(stmt);
9703       DIE_UNLESS(rc == 5);
9704     }
9705     mysql_stmt_close(stmt);
9706   }
9707 
9708   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9709   myquery(rc);
9710 }
9711 
9712 
test_selecttmp()9713 static void test_selecttmp()
9714 {
9715   MYSQL_STMT *stmt;
9716   int rc, i;
9717   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";
9718 
9719   myheader("test_select_tmp");
9720 
9721   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3");
9722   myquery(rc);
9723 
9724   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9725   myquery(rc);
9726 
9727   rc= mysql_query(mysql, "create table t2 (a int, b int);");
9728   myquery(rc);
9729 
9730   rc= mysql_query(mysql, "create table t3 (a int, b int);");
9731   myquery(rc);
9732 
9733   rc= mysql_query(mysql,
9734                   "insert into t1 values (0, 100), (1, 2), (1, 3), (2, 2), (2, 7), \
9735 (2, -1), (3, 10);");
9736   myquery(rc);
9737   rc= mysql_query(mysql,
9738                   "insert into t2 values (0, 0), (1, 1), (2, 1), (3, 1), (4, 1);");
9739   myquery(rc);
9740   rc= mysql_query(mysql,
9741                   "insert into t3 values (3, 3), (2, 2), (1, 1);");
9742   myquery(rc);
9743 
9744   stmt= mysql_simple_prepare(mysql, query);
9745   check_stmt(stmt);
9746   for (i= 0; i < 3; i++)
9747   {
9748     rc= mysql_stmt_execute(stmt);
9749     check_execute(stmt, rc);
9750     rc= my_process_stmt_result(stmt);
9751     DIE_UNLESS(rc == 3);
9752   }
9753   mysql_stmt_close(stmt);
9754 
9755   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3");
9756   myquery(rc);
9757 }
9758 
9759 
test_create_drop()9760 static void test_create_drop()
9761 {
9762   MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select;
9763   char *query;
9764   int rc, i;
9765   myheader("test_table_manipulation");
9766 
9767   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9768   myquery(rc);
9769 
9770   rc= mysql_query(mysql, "create table t2 (a int);");
9771   myquery(rc);
9772 
9773   rc= mysql_query(mysql, "create table t1 (a int);");
9774   myquery(rc);
9775 
9776   rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);");
9777   myquery(rc);
9778 
9779   query= (char*)"create table t1 (a int)";
9780   stmt_create= mysql_simple_prepare(mysql, query);
9781   check_stmt(stmt_create);
9782 
9783   query= (char*)"drop table t1";
9784   stmt_drop= mysql_simple_prepare(mysql, query);
9785   check_stmt(stmt_drop);
9786 
9787   query= (char*)"select a in (select a from t2) from t1";
9788   stmt_select= mysql_simple_prepare(mysql, query);
9789   check_stmt(stmt_select);
9790 
9791   rc= mysql_query(mysql, "DROP TABLE t1");
9792   myquery(rc);
9793 
9794   query= (char*)"create table t1 select a from t2";
9795   stmt_create_select= mysql_simple_prepare(mysql, query);
9796   check_stmt(stmt_create_select);
9797 
9798   for (i= 0; i < 3; i++)
9799   {
9800     rc= mysql_stmt_execute(stmt_create);
9801     check_execute(stmt_create, rc);
9802     if (!opt_silent)
9803       fprintf(stdout, "created %i\n", i);
9804 
9805     rc= mysql_stmt_execute(stmt_select);
9806     check_execute(stmt_select, rc);
9807     rc= my_process_stmt_result(stmt_select);
9808     DIE_UNLESS(rc == 0);
9809 
9810     rc= mysql_stmt_execute(stmt_drop);
9811     check_execute(stmt_drop, rc);
9812     if (!opt_silent)
9813       fprintf(stdout, "dropped %i\n", i);
9814 
9815     rc= mysql_stmt_execute(stmt_create_select);
9816     check_execute(stmt_create, rc);
9817     if (!opt_silent)
9818       fprintf(stdout, "created select %i\n", i);
9819 
9820     rc= mysql_stmt_execute(stmt_select);
9821     check_execute(stmt_select, rc);
9822     rc= my_process_stmt_result(stmt_select);
9823     DIE_UNLESS(rc == 3);
9824 
9825     rc= mysql_stmt_execute(stmt_drop);
9826     check_execute(stmt_drop, rc);
9827     if (!opt_silent)
9828       fprintf(stdout, "dropped %i\n", i);
9829   }
9830 
9831   mysql_stmt_close(stmt_create);
9832   mysql_stmt_close(stmt_drop);
9833   mysql_stmt_close(stmt_select);
9834   mysql_stmt_close(stmt_create_select);
9835 
9836   rc= mysql_query(mysql, "DROP TABLE t2");
9837   myquery(rc);
9838 }
9839 
9840 
test_rename()9841 static void test_rename()
9842 {
9843   MYSQL_STMT *stmt;
9844   const char *query= "rename table t1 to t2, t3 to t4";
9845   int rc;
9846   myheader("test_table_rename");
9847 
9848   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
9849   myquery(rc);
9850 
9851   stmt= mysql_simple_prepare(mysql, query);
9852   check_stmt(stmt);
9853 
9854   rc= mysql_query(mysql, "create table t1 (a int)");
9855   myquery(rc);
9856 
9857   rc= mysql_stmt_execute(stmt);
9858   check_execute_r(stmt, rc);
9859   if (!opt_silent)
9860     fprintf(stdout, "rename without t3\n");
9861 
9862   rc= mysql_query(mysql, "create table t3 (a int)");
9863   myquery(rc);
9864 
9865   rc= mysql_stmt_execute(stmt);
9866   check_execute(stmt, rc);
9867   if (!opt_silent)
9868     fprintf(stdout, "rename with t3\n");
9869 
9870   rc= mysql_stmt_execute(stmt);
9871   check_execute_r(stmt, rc);
9872   if (!opt_silent)
9873     fprintf(stdout, "rename renamed\n");
9874 
9875   rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3");
9876   myquery(rc);
9877 
9878   rc= mysql_stmt_execute(stmt);
9879   check_execute(stmt, rc);
9880   if (!opt_silent)
9881     fprintf(stdout, "rename reverted\n");
9882 
9883   mysql_stmt_close(stmt);
9884 
9885   rc= mysql_query(mysql, "DROP TABLE t2, t4");
9886   myquery(rc);
9887 }
9888 
9889 
test_do_set()9890 static void test_do_set()
9891 {
9892   MYSQL_STMT *stmt_do, *stmt_set;
9893   char *query;
9894   int rc, i;
9895   myheader("test_do_set");
9896 
9897   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9898   myquery(rc);
9899 
9900   rc= mysql_query(mysql, "create table t1 (a int)");
9901   myquery(rc);
9902 
9903   query= (char*)"do @var:=(1 in (select * from t1))";
9904   stmt_do= mysql_simple_prepare(mysql, query);
9905   check_stmt(stmt_do);
9906 
9907   query= (char*)"set @var=(1 in (select * from t1))";
9908   stmt_set= mysql_simple_prepare(mysql, query);
9909   check_stmt(stmt_set);
9910 
9911   for (i= 0; i < 3; i++)
9912   {
9913     rc= mysql_stmt_execute(stmt_do);
9914     check_execute(stmt_do, rc);
9915     if (!opt_silent)
9916       fprintf(stdout, "do %i\n", i);
9917     rc= mysql_stmt_execute(stmt_set);
9918     check_execute(stmt_set, rc);
9919     if (!opt_silent)
9920       fprintf(stdout, "set %i\n", i);
9921   }
9922 
9923   mysql_stmt_close(stmt_do);
9924   mysql_stmt_close(stmt_set);
9925 }
9926 
9927 
test_multi()9928 static void test_multi()
9929 {
9930   MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2;
9931   char *query;
9932   MYSQL_BIND my_bind[1];
9933   int rc, i;
9934   int32 param= 1;
9935   ulong length= 1;
9936   myheader("test_multi");
9937 
9938   /*
9939     We need to bzero bind structure because mysql_stmt_bind_param checks all
9940     its members.
9941   */
9942   bzero((char*) my_bind, sizeof(my_bind));
9943 
9944   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9945   my_bind[0].buffer= (void *)&param;
9946   my_bind[0].length= &length;
9947 
9948   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9949   myquery(rc);
9950 
9951   rc= mysql_query(mysql, "create table t1 (a int, b int)");
9952   myquery(rc);
9953 
9954   rc= mysql_query(mysql, "create table t2 (a int, b int)");
9955   myquery(rc);
9956 
9957   rc= mysql_query(mysql, "insert into t1 values (3, 3), (2, 2), (1, 1)");
9958   myquery(rc);
9959 
9960   rc= mysql_query(mysql, "insert into t2 values (3, 3), (2, 2), (1, 1)");
9961   myquery(rc);
9962 
9963   query= (char*)"delete t1, t2 from t1, t2 where t1.a=t2.a and t1.b=10";
9964   stmt_delete= mysql_simple_prepare(mysql, query);
9965   check_stmt(stmt_delete);
9966 
9967   query= (char*)"update t1, t2 set t1.b=10, t2.b=10 where t1.a=t2.a and t1.b=?";
9968   stmt_update= mysql_simple_prepare(mysql, query);
9969   check_stmt(stmt_update);
9970 
9971   query= (char*)"select * from t1";
9972   stmt_select1= mysql_simple_prepare(mysql, query);
9973   check_stmt(stmt_select1);
9974 
9975   query= (char*)"select * from t2";
9976   stmt_select2= mysql_simple_prepare(mysql, query);
9977   check_stmt(stmt_select2);
9978 
9979   for(i= 0; i < 3; i++)
9980   {
9981     rc= mysql_stmt_bind_param(stmt_update, my_bind);
9982     check_execute(stmt_update, rc);
9983 
9984     rc= mysql_stmt_execute(stmt_update);
9985     check_execute(stmt_update, rc);
9986     if (!opt_silent)
9987       fprintf(stdout, "update %ld\n", (long) param);
9988 
9989     rc= mysql_stmt_execute(stmt_delete);
9990     check_execute(stmt_delete, rc);
9991     if (!opt_silent)
9992       fprintf(stdout, "delete %ld\n", (long) param);
9993 
9994     rc= mysql_stmt_execute(stmt_select1);
9995     check_execute(stmt_select1, rc);
9996     rc= my_process_stmt_result(stmt_select1);
9997     DIE_UNLESS(rc == 3-param);
9998 
9999     rc= mysql_stmt_execute(stmt_select2);
10000     check_execute(stmt_select2, rc);
10001     rc= my_process_stmt_result(stmt_select2);
10002     DIE_UNLESS(rc == 3-param);
10003 
10004     param++;
10005   }
10006 
10007   mysql_stmt_close(stmt_delete);
10008   mysql_stmt_close(stmt_update);
10009   mysql_stmt_close(stmt_select1);
10010   mysql_stmt_close(stmt_select2);
10011   rc= mysql_query(mysql, "drop table t1, t2");
10012   myquery(rc);
10013 }
10014 
10015 
test_insert_select()10016 static void test_insert_select()
10017 {
10018   MYSQL_STMT *stmt_insert, *stmt_select;
10019   char *query;
10020   int rc;
10021   uint i;
10022   myheader("test_insert_select");
10023 
10024   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
10025   myquery(rc);
10026 
10027   rc= mysql_query(mysql, "create table t1 (a int)");
10028   myquery(rc);
10029 
10030   rc= mysql_query(mysql, "create table t2 (a int)");
10031   myquery(rc);
10032 
10033   rc= mysql_query(mysql, "insert into t2 values (1)");
10034   myquery(rc);
10035 
10036   query= (char*)"insert into t1 select a from t2";
10037   stmt_insert= mysql_simple_prepare(mysql, query);
10038   check_stmt(stmt_insert);
10039 
10040   query= (char*)"select * from t1";
10041   stmt_select= mysql_simple_prepare(mysql, query);
10042   check_stmt(stmt_select);
10043 
10044   for(i= 0; i < 3; i++)
10045   {
10046     rc= mysql_stmt_execute(stmt_insert);
10047     check_execute(stmt_insert, rc);
10048     if (!opt_silent)
10049       fprintf(stdout, "insert %u\n", i);
10050 
10051     rc= mysql_stmt_execute(stmt_select);
10052     check_execute(stmt_select, rc);
10053     rc= my_process_stmt_result(stmt_select);
10054     DIE_UNLESS(rc == (int)(i+1));
10055   }
10056 
10057   mysql_stmt_close(stmt_insert);
10058   mysql_stmt_close(stmt_select);
10059   rc= mysql_query(mysql, "drop table t1, t2");
10060   myquery(rc);
10061 }
10062 
10063 
test_bind_nagative()10064 static void test_bind_nagative()
10065 {
10066   MYSQL_STMT *stmt_insert;
10067   char *query;
10068   int rc;
10069   MYSQL_BIND      my_bind[1];
10070   int32           my_val= 0;
10071   ulong           my_length= 0L;
10072   my_bool         my_null= FALSE;
10073   myheader("test_insert_select");
10074 
10075   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10076   myquery(rc);
10077 
10078   rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)");
10079   myquery(rc);
10080 
10081   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)");
10082   myquery(rc);
10083 
10084   query= (char*)"INSERT INTO t1 VALUES (?)";
10085   stmt_insert= mysql_simple_prepare(mysql, query);
10086   check_stmt(stmt_insert);
10087 
10088   /* bind parameters */
10089   bzero((char*) my_bind, sizeof(my_bind));
10090 
10091   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10092   my_bind[0].buffer= (void *)&my_val;
10093   my_bind[0].length= &my_length;
10094   my_bind[0].is_null= (char*)&my_null;
10095 
10096   rc= mysql_stmt_bind_param(stmt_insert, my_bind);
10097   check_execute(stmt_insert, rc);
10098 
10099   my_val= -1;
10100   rc= mysql_stmt_execute(stmt_insert);
10101   check_execute(stmt_insert, rc);
10102 
10103   mysql_stmt_close(stmt_insert);
10104   rc= mysql_query(mysql, "drop table t1");
10105   myquery(rc);
10106 }
10107 
10108 
test_derived()10109 static void test_derived()
10110 {
10111   MYSQL_STMT *stmt;
10112   int rc, i;
10113   MYSQL_BIND      my_bind[1];
10114   int32           my_val= 0;
10115   ulong           my_length= 0L;
10116   my_bool         my_null= FALSE;
10117   const char *query=
10118     "select count(1) from (select f.id from t1 f where f.id=?) as x";
10119 
10120   myheader("test_derived");
10121 
10122   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10123   myquery(rc);
10124 
10125   rc= mysql_query(mysql, "create table t1 (id  int(8), primary key (id)) \
10126 ENGINE=InnoDB DEFAULT CHARSET=utf8");
10127   myquery(rc);
10128 
10129   rc= mysql_query(mysql, "insert into t1 values (1)");
10130   myquery(rc);
10131 
10132   stmt= mysql_simple_prepare(mysql, query);
10133   check_stmt(stmt);
10134   /*
10135     We need to bzero bind structure because mysql_stmt_bind_param checks all
10136     its members.
10137   */
10138   bzero((char*) my_bind, sizeof(my_bind));
10139 
10140   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10141   my_bind[0].buffer= (void *)&my_val;
10142   my_bind[0].length= &my_length;
10143   my_bind[0].is_null= (char*)&my_null;
10144   my_val= 1;
10145   rc= mysql_stmt_bind_param(stmt, my_bind);
10146   check_execute(stmt, rc);
10147 
10148   for (i= 0; i < 3; i++)
10149   {
10150     rc= mysql_stmt_execute(stmt);
10151     check_execute(stmt, rc);
10152     rc= my_process_stmt_result(stmt);
10153     DIE_UNLESS(rc == 1);
10154   }
10155   mysql_stmt_close(stmt);
10156 
10157   rc= mysql_query(mysql, "DROP TABLE t1");
10158   myquery(rc);
10159 }
10160 
10161 
test_xjoin()10162 static void test_xjoin()
10163 {
10164   MYSQL_STMT *stmt;
10165   int rc, i;
10166   const char *query=
10167     "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";
10168 
10169   myheader("test_xjoin");
10170 
10171   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
10172   myquery(rc);
10173 
10174   rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10175   myquery(rc);
10176 
10177   rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10178   myquery(rc);
10179 
10180   rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
10181   myquery(rc);
10182 
10183   rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10184   myquery(rc);
10185 
10186   rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)");
10187   myquery(rc);
10188 
10189   rc= mysql_query(mysql, "insert into t1 values (1, 1, 'aaa'), (2, null, 'bbb')");
10190   myquery(rc);
10191 
10192   rc= mysql_query(mysql, "insert into t2 values (1, 2, 'ccc')");
10193   myquery(rc);
10194 
10195   rc= mysql_query(mysql, "insert into t4 values (1, 'Name1'), (2, null)");
10196   myquery(rc);
10197 
10198   stmt= mysql_simple_prepare(mysql, query);
10199   check_stmt(stmt);
10200 
10201   for (i= 0; i < 3; i++)
10202   {
10203     rc= mysql_stmt_execute(stmt);
10204     check_execute(stmt, rc);
10205     rc= my_process_stmt_result(stmt);
10206     DIE_UNLESS(rc == 1);
10207   }
10208   mysql_stmt_close(stmt);
10209 
10210   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3, t4");
10211   myquery(rc);
10212 }
10213 
10214 
test_bug3035()10215 static void test_bug3035()
10216 {
10217   MYSQL_STMT *stmt;
10218   int rc;
10219   MYSQL_BIND bind_array[12], *my_bind= bind_array, *bind_end= my_bind + 12;
10220   int8 int8_val;
10221   uint8 uint8_val;
10222   int16 int16_val;
10223   uint16 uint16_val;
10224   int32 int32_val;
10225   uint32 uint32_val;
10226   longlong int64_val;
10227   ulonglong uint64_val;
10228   double double_val, udouble_val, double_tmp;
10229   char longlong_as_string[22], ulonglong_as_string[22];
10230 
10231   /* mins and maxes */
10232   const int8 int8_min= -128;
10233   const int8 int8_max= 127;
10234   const uint8 uint8_min= 0;
10235   const uint8 uint8_max= 255;
10236 
10237   const int16 int16_min= -32768;
10238   const int16 int16_max= 32767;
10239   const uint16 uint16_min= 0;
10240   const uint16 uint16_max= 65535;
10241 
10242   const int32 int32_max= 2147483647L;
10243   const int32 int32_min= -int32_max - 1;
10244   const uint32 uint32_min= 0;
10245   const uint32 uint32_max= 4294967295U;
10246 
10247   /* it might not work okay everyplace */
10248   const longlong int64_max= 9223372036854775807LL;
10249   const longlong int64_min= -int64_max - 1;
10250 
10251   const ulonglong uint64_min= 0U;
10252   const ulonglong uint64_max= 18446744073709551615ULL;
10253 
10254   const char *stmt_text;
10255 
10256   myheader("test_bug3035");
10257 
10258   stmt_text= "DROP TABLE IF EXISTS t1";
10259   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10260   myquery(rc);
10261 
10262   stmt_text= "CREATE TABLE t1 (i8 TINYINT, ui8 TINYINT UNSIGNED, "
10263                               "i16 SMALLINT, ui16 SMALLINT UNSIGNED, "
10264                               "i32 INT, ui32 INT UNSIGNED, "
10265                               "i64 BIGINT, ui64 BIGINT UNSIGNED, "
10266                               "id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT)";
10267   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10268   myquery(rc);
10269 
10270   bzero((char*) bind_array, sizeof(bind_array));
10271 
10272   for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10273     my_bind->error= &my_bind->error_value;
10274 
10275   bind_array[0].buffer_type= MYSQL_TYPE_TINY;
10276   bind_array[0].buffer= (void *) &int8_val;
10277 
10278   bind_array[1].buffer_type= MYSQL_TYPE_TINY;
10279   bind_array[1].buffer= (void *) &uint8_val;
10280   bind_array[1].is_unsigned= 1;
10281 
10282   bind_array[2].buffer_type= MYSQL_TYPE_SHORT;
10283   bind_array[2].buffer= (void *) &int16_val;
10284 
10285   bind_array[3].buffer_type= MYSQL_TYPE_SHORT;
10286   bind_array[3].buffer= (void *) &uint16_val;
10287   bind_array[3].is_unsigned= 1;
10288 
10289   bind_array[4].buffer_type= MYSQL_TYPE_LONG;
10290   bind_array[4].buffer= (void *) &int32_val;
10291 
10292   bind_array[5].buffer_type= MYSQL_TYPE_LONG;
10293   bind_array[5].buffer= (void *) &uint32_val;
10294   bind_array[5].is_unsigned= 1;
10295 
10296   bind_array[6].buffer_type= MYSQL_TYPE_LONGLONG;
10297   bind_array[6].buffer= (void *) &int64_val;
10298 
10299   bind_array[7].buffer_type= MYSQL_TYPE_LONGLONG;
10300   bind_array[7].buffer= (void *) &uint64_val;
10301   bind_array[7].is_unsigned= 1;
10302 
10303   stmt= mysql_stmt_init(mysql);
10304   check_stmt(stmt);
10305 
10306   stmt_text= "INSERT INTO t1 (i8, ui8, i16, ui16, i32, ui32, i64, ui64) "
10307                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
10308   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10309   check_execute(stmt, rc);
10310 
10311   mysql_stmt_bind_param(stmt, bind_array);
10312 
10313   int8_val= int8_min;
10314   uint8_val= uint8_min;
10315   int16_val= int16_min;
10316   uint16_val= uint16_min;
10317   int32_val= int32_min;
10318   uint32_val= uint32_min;
10319   int64_val= int64_min;
10320   uint64_val= uint64_min;
10321 
10322   rc= mysql_stmt_execute(stmt);
10323   check_execute(stmt, rc);
10324 
10325   int8_val= int8_max;
10326   uint8_val= uint8_max;
10327   int16_val= int16_max;
10328   uint16_val= uint16_max;
10329   int32_val= int32_max;
10330   uint32_val= uint32_max;
10331   int64_val= int64_max;
10332   uint64_val= uint64_max;
10333 
10334   rc= mysql_stmt_execute(stmt);
10335   check_execute(stmt, rc);
10336 
10337   stmt_text= "SELECT i8, ui8, i16, ui16, i32, ui32, i64, ui64, ui64, "
10338              "cast(ui64 as signed), ui64, cast(ui64 as signed)"
10339              "FROM t1 ORDER BY id ASC";
10340 
10341   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10342   check_execute(stmt, rc);
10343 
10344   rc= mysql_stmt_execute(stmt);
10345   check_execute(stmt, rc);
10346 
10347   bind_array[8].buffer_type= MYSQL_TYPE_DOUBLE;
10348   bind_array[8].buffer= (void *) &udouble_val;
10349 
10350   bind_array[9].buffer_type= MYSQL_TYPE_DOUBLE;
10351   bind_array[9].buffer= (void *) &double_val;
10352 
10353   bind_array[10].buffer_type= MYSQL_TYPE_STRING;
10354   bind_array[10].buffer= (void *) &ulonglong_as_string;
10355   bind_array[10].buffer_length= sizeof(ulonglong_as_string);
10356 
10357   bind_array[11].buffer_type= MYSQL_TYPE_STRING;
10358   bind_array[11].buffer= (void *) &longlong_as_string;
10359   bind_array[11].buffer_length= sizeof(longlong_as_string);
10360 
10361   mysql_stmt_bind_result(stmt, bind_array);
10362 
10363   rc= mysql_stmt_fetch(stmt);
10364   check_execute(stmt, rc);
10365 
10366   DIE_UNLESS(int8_val == int8_min);
10367   DIE_UNLESS(uint8_val == uint8_min);
10368   DIE_UNLESS(int16_val == int16_min);
10369   DIE_UNLESS(uint16_val == uint16_min);
10370   DIE_UNLESS(int32_val == int32_min);
10371   DIE_UNLESS(uint32_val == uint32_min);
10372   DIE_UNLESS(int64_val == int64_min);
10373   DIE_UNLESS(uint64_val == uint64_min);
10374   DIE_UNLESS(double_val == (longlong) uint64_min);
10375   double_tmp= ulonglong2double(uint64_val);
10376   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10377   DIE_UNLESS(!strcmp(longlong_as_string, "0"));
10378   DIE_UNLESS(!strcmp(ulonglong_as_string, "0"));
10379 
10380   rc= mysql_stmt_fetch(stmt);
10381 
10382   if (!opt_silent)
10383   {
10384     printf("Truncation mask: ");
10385     for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10386       printf("%d", (int) my_bind->error_value);
10387     printf("\n");
10388   }
10389   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0);
10390 
10391   DIE_UNLESS(int8_val == int8_max);
10392   DIE_UNLESS(uint8_val == uint8_max);
10393   DIE_UNLESS(int16_val == int16_max);
10394   DIE_UNLESS(uint16_val == uint16_max);
10395   DIE_UNLESS(int32_val == int32_max);
10396   DIE_UNLESS(uint32_val == uint32_max);
10397   DIE_UNLESS(int64_val == int64_max);
10398   DIE_UNLESS(uint64_val == uint64_max);
10399   DIE_UNLESS(double_val == (longlong) uint64_val);
10400   double_tmp= ulonglong2double(uint64_val);
10401   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10402   DIE_UNLESS(!strcmp(longlong_as_string, "-1"));
10403   DIE_UNLESS(!strcmp(ulonglong_as_string, "18446744073709551615"));
10404 
10405   rc= mysql_stmt_fetch(stmt);
10406   DIE_UNLESS(rc == MYSQL_NO_DATA);
10407 
10408   mysql_stmt_close(stmt);
10409 
10410   stmt_text= "DROP TABLE t1";
10411   mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10412 }
10413 
10414 
test_union2()10415 static void test_union2()
10416 {
10417   MYSQL_STMT *stmt;
10418   int rc, i;
10419 
10420   myheader("test_union2");
10421 
10422   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10423   myquery(rc);
10424 
10425   rc= mysql_query(mysql, "CREATE TABLE t1(col1 INT, \
10426                                          col2 VARCHAR(40),      \
10427                                          col3 SMALLINT, \
10428                                          col4 TIMESTAMP)");
10429   myquery(rc);
10430 
10431   stmt= mysql_simple_prepare(mysql,
10432                              "select col1 FROM t1 where col1=1 union distinct "
10433                              "select col1 FROM t1 where col1=2");
10434   check_stmt(stmt);
10435 
10436   for (i= 0; i < 3; i++)
10437   {
10438     rc= mysql_stmt_execute(stmt);
10439     check_execute(stmt, rc);
10440     rc= my_process_stmt_result(stmt);
10441     DIE_UNLESS(rc == 0);
10442   }
10443 
10444   mysql_stmt_close(stmt);
10445 
10446   rc= mysql_query(mysql, "DROP TABLE t1");
10447   myquery(rc);
10448 }
10449 
10450 
10451 /*
10452   This tests for various mysql_stmt_send_long_data bugs described in #1664
10453 */
10454 
test_bug1664()10455 static void test_bug1664()
10456 {
10457     MYSQL_STMT *stmt;
10458     int        rc, int_data;
10459     const char *data;
10460     const char *str_data= "Simple string";
10461     MYSQL_BIND my_bind[2];
10462     const char *query= "INSERT INTO test_long_data(col2, col1) VALUES(?, ?)";
10463 
10464     myheader("test_bug1664");
10465 
10466     rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
10467     myquery(rc);
10468 
10469     rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, col2 long varchar)");
10470     myquery(rc);
10471 
10472     stmt= mysql_stmt_init(mysql);
10473     check_stmt(stmt);
10474     rc= mysql_stmt_prepare(stmt, query, strlen(query));
10475     check_execute(stmt, rc);
10476 
10477     verify_param_count(stmt, 2);
10478 
10479     bzero((char*) my_bind, sizeof(my_bind));
10480 
10481     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10482     my_bind[0].buffer= (void *)str_data;
10483     my_bind[0].buffer_length= strlen(str_data);
10484 
10485     my_bind[1].buffer= (void *)&int_data;
10486     my_bind[1].buffer_type= MYSQL_TYPE_LONG;
10487 
10488     rc= mysql_stmt_bind_param(stmt, my_bind);
10489     check_execute(stmt, rc);
10490 
10491     int_data= 1;
10492 
10493     /*
10494       Let us supply empty long_data. This should work and should
10495       not break following execution.
10496     */
10497     data= "";
10498     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10499     check_execute(stmt, rc);
10500 
10501     rc= mysql_stmt_execute(stmt);
10502     check_execute(stmt, rc);
10503 
10504     verify_col_data("test_long_data", "col1", "1");
10505     verify_col_data("test_long_data", "col2", "");
10506 
10507     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10508     myquery(rc);
10509 
10510     /* This should pass OK */
10511     data= (char *)"Data";
10512     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10513     check_execute(stmt, rc);
10514 
10515     rc= mysql_stmt_execute(stmt);
10516     check_execute(stmt, rc);
10517 
10518     verify_col_data("test_long_data", "col1", "1");
10519     verify_col_data("test_long_data", "col2", "Data");
10520 
10521     /* clean up */
10522     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10523     myquery(rc);
10524 
10525     /*
10526       Now we are changing int parameter and don't do anything
10527       with first parameter. Second mysql_stmt_execute() should run
10528       OK treating this first parameter as string parameter.
10529     */
10530 
10531     int_data= 2;
10532     /* execute */
10533     rc= mysql_stmt_execute(stmt);
10534     check_execute(stmt, rc);
10535 
10536     verify_col_data("test_long_data", "col1", "2");
10537     verify_col_data("test_long_data", "col2", str_data);
10538 
10539     /* clean up */
10540     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10541     myquery(rc);
10542 
10543     /*
10544       Now we are sending other long data. It should not be
10545       concatened to previous.
10546     */
10547 
10548     data= (char *)"SomeOtherData";
10549     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10550     check_execute(stmt, rc);
10551 
10552     rc= mysql_stmt_execute(stmt);
10553     check_execute(stmt, rc);
10554 
10555     verify_col_data("test_long_data", "col1", "2");
10556     verify_col_data("test_long_data", "col2", "SomeOtherData");
10557 
10558     mysql_stmt_close(stmt);
10559 
10560     /* clean up */
10561     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10562     myquery(rc);
10563 
10564     /* Now let us test how mysql_stmt_reset works. */
10565     stmt= mysql_stmt_init(mysql);
10566     check_stmt(stmt);
10567     rc= mysql_stmt_prepare(stmt, query, strlen(query));
10568     check_execute(stmt, rc);
10569     rc= mysql_stmt_bind_param(stmt, my_bind);
10570     check_execute(stmt, rc);
10571 
10572     data= (char *)"SomeData";
10573     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10574     check_execute(stmt, rc);
10575 
10576     rc= mysql_stmt_reset(stmt);
10577     check_execute(stmt, rc);
10578 
10579     rc= mysql_stmt_execute(stmt);
10580     check_execute(stmt, rc);
10581 
10582     verify_col_data("test_long_data", "col1", "2");
10583     verify_col_data("test_long_data", "col2", str_data);
10584 
10585     mysql_stmt_close(stmt);
10586 
10587     /* Final clean up */
10588     rc= mysql_query(mysql, "DROP TABLE test_long_data");
10589     myquery(rc);
10590 }
10591 
10592 
test_order_param()10593 static void test_order_param()
10594 {
10595   MYSQL_STMT *stmt;
10596   int rc;
10597 
10598   myheader("test_order_param");
10599 
10600   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10601   myquery(rc);
10602 
10603   rc= mysql_query(mysql, "CREATE TABLE t1(a INT, b char(10))");
10604   myquery(rc);
10605 
10606   stmt= mysql_simple_prepare(mysql,
10607                              "select sum(a) + 200, 1 from t1 "
10608                              " union distinct "
10609                              "select sum(a) + 200, 1 from t1 group by b ");
10610   check_stmt(stmt);
10611   mysql_stmt_close(stmt);
10612 
10613   stmt= mysql_simple_prepare(mysql,
10614                              "select sum(a) + 200, ? from t1 group by b "
10615                              " union distinct "
10616                              "select sum(a) + 200, 1 from t1 group by b ");
10617   check_stmt(stmt);
10618   mysql_stmt_close(stmt);
10619 
10620   stmt= mysql_simple_prepare(mysql,
10621                              "select sum(a) + 200, ? from t1 "
10622                              " union distinct "
10623                              "select sum(a) + 200, 1 from t1 group by b ");
10624   check_stmt(stmt);
10625   mysql_stmt_close(stmt);
10626 
10627   rc= mysql_query(mysql, "DROP TABLE t1");
10628   myquery(rc);
10629 }
10630 
10631 
test_union_param()10632 static void test_union_param()
10633 {
10634   MYSQL_STMT *stmt;
10635   char *query;
10636   int rc, i;
10637   MYSQL_BIND      my_bind[2];
10638   char            my_val[4];
10639   ulong           my_length= 3L;
10640   my_bool         my_null= FALSE;
10641   myheader("test_union_param");
10642 
10643   strmov(my_val, "abc");
10644 
10645   query= (char*)"select ? as my_col union distinct select ?";
10646   stmt= mysql_simple_prepare(mysql, query);
10647   check_stmt(stmt);
10648 
10649   /*
10650     We need to bzero bind structure because mysql_stmt_bind_param checks all
10651     its members.
10652   */
10653   bzero((char*) my_bind, sizeof(my_bind));
10654 
10655   /* bind parameters */
10656   my_bind[0].buffer_type=    MYSQL_TYPE_STRING;
10657   my_bind[0].buffer=         (char*) &my_val;
10658   my_bind[0].buffer_length=  4;
10659   my_bind[0].length=         &my_length;
10660   my_bind[0].is_null=        (char*)&my_null;
10661   my_bind[1].buffer_type=    MYSQL_TYPE_STRING;
10662   my_bind[1].buffer=         (char*) &my_val;
10663   my_bind[1].buffer_length=  4;
10664   my_bind[1].length=         &my_length;
10665   my_bind[1].is_null=        (char*)&my_null;
10666 
10667   rc= mysql_stmt_bind_param(stmt, my_bind);
10668   check_execute(stmt, rc);
10669 
10670   for (i= 0; i < 3; i++)
10671   {
10672     rc= mysql_stmt_execute(stmt);
10673     check_execute(stmt, rc);
10674     rc= my_process_stmt_result(stmt);
10675     DIE_UNLESS(rc == 1);
10676   }
10677 
10678   mysql_stmt_close(stmt);
10679 }
10680 
10681 
test_ps_i18n()10682 static void test_ps_i18n()
10683 {
10684   MYSQL_STMT *stmt;
10685   int rc;
10686   const char *stmt_text;
10687   MYSQL_BIND bind_array[2];
10688 
10689   /* Represented as numbers to keep UTF8 tools from clobbering them. */
10690   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
10691   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
10692   char buf1[16], buf2[16];
10693   ulong buf1_len, buf2_len;
10694 
10695 
10696   myheader("test_ps_i18n");
10697 
10698   stmt_text= "DROP TABLE IF EXISTS t1";
10699   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10700   myquery(rc);
10701 
10702   /*
10703     Create table with binary columns, set session character set to cp1251,
10704     client character set to koi8, and make sure that there is conversion
10705     on insert and no conversion on select
10706   */
10707 
10708   stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
10709 
10710   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10711   myquery(rc);
10712 
10713   stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
10714                  "CHARACTER_SET_CONNECTION=cp1251, "
10715                  "CHARACTER_SET_RESULTS=koi8r";
10716 
10717   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10718   myquery(rc);
10719 
10720   bzero((char*) bind_array, sizeof(bind_array));
10721 
10722   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10723   bind_array[0].buffer= (void *) koi8;
10724   bind_array[0].buffer_length= strlen(koi8);
10725 
10726   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10727   bind_array[1].buffer= (void *) koi8;
10728   bind_array[1].buffer_length= strlen(koi8);
10729 
10730   stmt= mysql_stmt_init(mysql);
10731   check_stmt(stmt);
10732 
10733   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10734 
10735   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10736   check_execute(stmt, rc);
10737 
10738   mysql_stmt_bind_param(stmt, bind_array);
10739 
10740   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10741 
10742   rc= mysql_stmt_execute(stmt);
10743   check_execute(stmt, rc);
10744 
10745   stmt_text= "SELECT c1, c2 FROM t1";
10746 
10747   /* c1 and c2 are binary so no conversion will be done on select */
10748   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10749   check_execute(stmt, rc);
10750 
10751   rc= mysql_stmt_execute(stmt);
10752   check_execute(stmt, rc);
10753 
10754   bind_array[0].buffer= buf1;
10755   bind_array[0].buffer_length= sizeof(buf1);
10756   bind_array[0].length= &buf1_len;
10757 
10758   bind_array[1].buffer= buf2;
10759   bind_array[1].buffer_length= sizeof(buf2);
10760   bind_array[1].length= &buf2_len;
10761 
10762   mysql_stmt_bind_result(stmt, bind_array);
10763 
10764   rc= mysql_stmt_fetch(stmt);
10765   check_execute(stmt, rc);
10766 
10767   DIE_UNLESS(buf1_len == strlen(cp1251));
10768   DIE_UNLESS(buf2_len == strlen(cp1251));
10769   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
10770   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
10771 
10772   rc= mysql_stmt_fetch(stmt);
10773   DIE_UNLESS(rc == MYSQL_NO_DATA);
10774 
10775   stmt_text= "DROP TABLE IF EXISTS t1";
10776   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10777   myquery(rc);
10778 
10779   /*
10780     Now create table with two cp1251 columns, set client character
10781     set to koi8 and supply columns of one row as string and another as
10782     binary data. Binary data must not be converted on insert, and both
10783     columns must be converted to client character set on select.
10784   */
10785 
10786   stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
10787                               "c2 VARCHAR(255) CHARACTER SET cp1251)";
10788 
10789   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10790   myquery(rc);
10791 
10792   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10793 
10794   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10795   check_execute(stmt, rc);
10796 
10797   /* this data must be converted */
10798   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10799   bind_array[0].buffer= (void *) koi8;
10800   bind_array[0].buffer_length= strlen(koi8);
10801 
10802   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10803   bind_array[1].buffer= (void *) koi8;
10804   bind_array[1].buffer_length= strlen(koi8);
10805 
10806   mysql_stmt_bind_param(stmt, bind_array);
10807 
10808   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10809 
10810   rc= mysql_stmt_execute(stmt);
10811   check_execute(stmt, rc);
10812 
10813   /* this data must not be converted */
10814   bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
10815   bind_array[0].buffer= (void *) cp1251;
10816   bind_array[0].buffer_length= strlen(cp1251);
10817 
10818   bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
10819   bind_array[1].buffer= (void *) cp1251;
10820   bind_array[1].buffer_length= strlen(cp1251);
10821 
10822   mysql_stmt_bind_param(stmt, bind_array);
10823 
10824   mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251));
10825 
10826   rc= mysql_stmt_execute(stmt);
10827   check_execute(stmt, rc);
10828 
10829   /* Fetch data and verify that rows are in koi8 */
10830 
10831   stmt_text= "SELECT c1, c2 FROM t1";
10832 
10833   /* c1 and c2 are binary so no conversion will be done on select */
10834   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10835   check_execute(stmt, rc);
10836 
10837   rc= mysql_stmt_execute(stmt);
10838   check_execute(stmt, rc);
10839 
10840   bind_array[0].buffer= buf1;
10841   bind_array[0].buffer_length= sizeof(buf1);
10842   bind_array[0].length= &buf1_len;
10843 
10844   bind_array[1].buffer= buf2;
10845   bind_array[1].buffer_length= sizeof(buf2);
10846   bind_array[1].length= &buf2_len;
10847 
10848   mysql_stmt_bind_result(stmt, bind_array);
10849 
10850   while ((rc= mysql_stmt_fetch(stmt)) == 0)
10851   {
10852     DIE_UNLESS(buf1_len == strlen(koi8));
10853     DIE_UNLESS(buf2_len == strlen(koi8));
10854     DIE_UNLESS(!memcmp(buf1, koi8, buf1_len));
10855     DIE_UNLESS(!memcmp(buf2, koi8, buf1_len));
10856   }
10857   DIE_UNLESS(rc == MYSQL_NO_DATA);
10858   mysql_stmt_close(stmt);
10859 
10860   stmt_text= "DROP TABLE t1";
10861   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10862   myquery(rc);
10863   stmt_text= "SET NAMES DEFAULT";
10864   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10865   myquery(rc);
10866 }
10867 
10868 
test_bug3796()10869 static void test_bug3796()
10870 {
10871   MYSQL_STMT *stmt;
10872   MYSQL_BIND my_bind[1];
10873   const char *concat_arg0= "concat_with_";
10874   enum { OUT_BUFF_SIZE= 30 };
10875   char out_buff[OUT_BUFF_SIZE];
10876   char canonical_buff[OUT_BUFF_SIZE];
10877   ulong out_length;
10878   const char *stmt_text;
10879   int rc;
10880 
10881   myheader("test_bug3796");
10882 
10883   /* Create and fill test table */
10884   stmt_text= "DROP TABLE IF EXISTS t1";
10885   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10886   myquery(rc);
10887 
10888   stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))";
10889   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10890   myquery(rc);
10891 
10892   stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')";
10893   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10894   myquery(rc);
10895 
10896   /* Create statement handle and prepare it with select */
10897   stmt= mysql_stmt_init(mysql);
10898   stmt_text= "SELECT concat(?, b) FROM t1";
10899 
10900   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10901   check_execute(stmt, rc);
10902 
10903   /* Bind input buffers */
10904   bzero((char*) my_bind, sizeof(my_bind));
10905 
10906   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10907   my_bind[0].buffer= (void *) concat_arg0;
10908   my_bind[0].buffer_length= strlen(concat_arg0);
10909 
10910   mysql_stmt_bind_param(stmt, my_bind);
10911 
10912   /* Execute the select statement */
10913   rc= mysql_stmt_execute(stmt);
10914   check_execute(stmt, rc);
10915 
10916   my_bind[0].buffer= (void *) out_buff;
10917   my_bind[0].buffer_length= OUT_BUFF_SIZE;
10918   my_bind[0].length= &out_length;
10919 
10920   mysql_stmt_bind_result(stmt, my_bind);
10921 
10922   rc= mysql_stmt_fetch(stmt);
10923   if (!opt_silent)
10924     printf("Concat result: '%s'\n", out_buff);
10925   check_execute(stmt, rc);
10926   strmov(canonical_buff, concat_arg0);
10927   strcat(canonical_buff, "ONE");
10928   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10929          strncmp(out_buff, canonical_buff, out_length) == 0);
10930 
10931   rc= mysql_stmt_fetch(stmt);
10932   check_execute(stmt, rc);
10933   strmov(canonical_buff + strlen(concat_arg0), "TWO");
10934   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10935          strncmp(out_buff, canonical_buff, out_length) == 0);
10936   if (!opt_silent)
10937     printf("Concat result: '%s'\n", out_buff);
10938 
10939   rc= mysql_stmt_fetch(stmt);
10940   DIE_UNLESS(rc == MYSQL_NO_DATA);
10941 
10942   mysql_stmt_close(stmt);
10943 
10944   stmt_text= "DROP TABLE IF EXISTS t1";
10945   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10946   myquery(rc);
10947 }
10948 
10949 
test_bug4026()10950 static void test_bug4026()
10951 {
10952   MYSQL_STMT *stmt;
10953   MYSQL_BIND my_bind[2];
10954   MYSQL_TIME time_in, time_out;
10955   MYSQL_TIME datetime_in, datetime_out;
10956   const char *stmt_text;
10957   int rc;
10958 
10959   myheader("test_bug4026");
10960 
10961   /* Check that microseconds are inserted and selected successfully */
10962 
10963   /* Create a statement handle and prepare it with select */
10964   stmt= mysql_stmt_init(mysql);
10965   stmt_text= "SELECT ?, ?";
10966 
10967   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10968   check_execute(stmt, rc);
10969 
10970   /* Bind input buffers */
10971   bzero((char*) my_bind, sizeof(my_bind));
10972   bzero((char*) &time_in, sizeof(time_in));
10973   bzero((char*) &time_out, sizeof(time_out));
10974   bzero((char*) &datetime_in, sizeof(datetime_in));
10975   bzero((char*) &datetime_out, sizeof(datetime_out));
10976 
10977   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
10978   my_bind[0].buffer= (void *) &time_in;
10979   my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
10980   my_bind[1].buffer= (void *) &datetime_in;
10981 
10982   time_in.hour= 23;
10983   time_in.minute= 59;
10984   time_in.second= 59;
10985   time_in.second_part= 123456;
10986   /*
10987     This is not necessary, just to make DIE_UNLESS below work: this field
10988     is filled in when time is received from server
10989   */
10990   time_in.time_type= MYSQL_TIMESTAMP_TIME;
10991 
10992   datetime_in= time_in;
10993   datetime_in.year= 2003;
10994   datetime_in.month= 12;
10995   datetime_in.day= 31;
10996   datetime_in.time_type= MYSQL_TIMESTAMP_DATETIME;
10997 
10998   mysql_stmt_bind_param(stmt, my_bind);
10999 
11000   /* Execute the select statement */
11001   rc= mysql_stmt_execute(stmt);
11002   check_execute(stmt, rc);
11003 
11004   my_bind[0].buffer= (void *) &time_out;
11005   my_bind[1].buffer= (void *) &datetime_out;
11006 
11007   mysql_stmt_bind_result(stmt, my_bind);
11008 
11009   rc= mysql_stmt_fetch(stmt);
11010   DIE_UNLESS(rc == 0);
11011   if (!opt_silent)
11012   {
11013     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
11014            time_out.second_part);
11015     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
11016            datetime_out.day, datetime_out.hour,
11017            datetime_out.minute, datetime_out.second,
11018            datetime_out.second_part);
11019   }
11020   DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0);
11021   DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0);
11022   mysql_stmt_close(stmt);
11023 }
11024 
11025 
test_bug4079()11026 static void test_bug4079()
11027 {
11028   MYSQL_STMT *stmt;
11029   MYSQL_BIND my_bind[1];
11030   const char *stmt_text;
11031   uint32 res;
11032   int rc;
11033 
11034   myheader("test_bug4079");
11035 
11036   /* Create and fill table */
11037   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
11038   mysql_query(mysql, "CREATE TABLE t1 (a int)");
11039   mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2)");
11040 
11041   /* Prepare erroneous statement */
11042   stmt= mysql_stmt_init(mysql);
11043   stmt_text= "SELECT 1 < (SELECT a FROM t1)";
11044 
11045   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11046   check_execute(stmt, rc);
11047 
11048   /* Execute the select statement */
11049   rc= mysql_stmt_execute(stmt);
11050   check_execute(stmt, rc);
11051 
11052   /* Bind input buffers */
11053   bzero((char*) my_bind, sizeof(my_bind));
11054 
11055   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11056   my_bind[0].buffer= (void *) &res;
11057 
11058   mysql_stmt_bind_result(stmt, my_bind);
11059 
11060   rc= mysql_stmt_fetch(stmt);
11061   DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA);
11062   if (!opt_silent)
11063     printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
11064            mysql_stmt_error(stmt));
11065   /* buggy version of libmysql hanged up here */
11066   mysql_stmt_close(stmt);
11067 }
11068 
11069 
test_bug4236()11070 static void test_bug4236()
11071 {
11072   MYSQL_STMT *stmt;
11073   const char *stmt_text;
11074   int rc;
11075   MYSQL_STMT backup;
11076 
11077   myheader("test_bug4236");
11078 
11079   stmt= mysql_stmt_init(mysql);
11080 
11081   /* mysql_stmt_execute() of statement with statement id= 0 crashed server */
11082   stmt_text= "SELECT 1";
11083   /* We need to prepare statement to pass by possible check in libmysql */
11084   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11085   check_execute(stmt, rc);
11086   /* Hack to check that server works OK if statement wasn't found */
11087   backup.stmt_id= stmt->stmt_id;
11088   stmt->stmt_id= 0;
11089   rc= mysql_stmt_execute(stmt);
11090   DIE_UNLESS(rc);
11091   /* Restore original statement id to be able to reprepare it */
11092   stmt->stmt_id= backup.stmt_id;
11093 
11094   mysql_stmt_close(stmt);
11095 }
11096 
11097 
test_bug4030()11098 static void test_bug4030()
11099 {
11100   MYSQL_STMT *stmt;
11101   MYSQL_BIND my_bind[3];
11102   MYSQL_TIME time_canonical, time_out;
11103   MYSQL_TIME date_canonical, date_out;
11104   MYSQL_TIME datetime_canonical, datetime_out;
11105   const char *stmt_text;
11106   int rc;
11107 
11108   myheader("test_bug4030");
11109 
11110   /* Check that microseconds are inserted and selected successfully */
11111 
11112   /* Execute a query with time values in prepared mode */
11113   stmt= mysql_stmt_init(mysql);
11114   stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
11115              "'2003-12-31 23:59:59.123456'";
11116   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11117   check_execute(stmt, rc);
11118   rc= mysql_stmt_execute(stmt);
11119   check_execute(stmt, rc);
11120 
11121   /* Bind output buffers */
11122   bzero((char*) my_bind, sizeof(my_bind));
11123   bzero((char*) &time_canonical, sizeof(time_canonical));
11124   bzero((char*) &time_out, sizeof(time_out));
11125   bzero((char*) &date_canonical, sizeof(date_canonical));
11126   bzero((char*) &date_out, sizeof(date_out));
11127   bzero((char*) &datetime_canonical, sizeof(datetime_canonical));
11128   bzero((char*) &datetime_out, sizeof(datetime_out));
11129 
11130   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
11131   my_bind[0].buffer= (void *) &time_out;
11132   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11133   my_bind[1].buffer= (void *) &date_out;
11134   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
11135   my_bind[2].buffer= (void *) &datetime_out;
11136 
11137   time_canonical.hour= 23;
11138   time_canonical.minute= 59;
11139   time_canonical.second= 59;
11140   time_canonical.second_part= 123456;
11141   time_canonical.time_type= MYSQL_TIMESTAMP_TIME;
11142 
11143   date_canonical.year= 2003;
11144   date_canonical.month= 12;
11145   date_canonical.day= 31;
11146   date_canonical.time_type= MYSQL_TIMESTAMP_DATE;
11147 
11148   datetime_canonical= time_canonical;
11149   datetime_canonical.year= 2003;
11150   datetime_canonical.month= 12;
11151   datetime_canonical.day= 31;
11152   datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME;
11153 
11154   mysql_stmt_bind_result(stmt, my_bind);
11155 
11156   rc= mysql_stmt_fetch(stmt);
11157   DIE_UNLESS(rc == 0);
11158   if (!opt_silent)
11159   {
11160     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
11161            time_out.second_part);
11162     printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
11163     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
11164            datetime_out.day, datetime_out.hour,
11165            datetime_out.minute, datetime_out.second,
11166            datetime_out.second_part);
11167   }
11168   DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
11169   DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
11170   DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
11171   mysql_stmt_close(stmt);
11172 }
11173 
test_view()11174 static void test_view()
11175 {
11176   MYSQL_STMT *stmt;
11177   int rc, i;
11178   MYSQL_BIND      my_bind[1];
11179   char            str_data[50];
11180   ulong           length = 0L;
11181   long            is_null = 0L;
11182   const char *query=
11183     "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
11184 
11185   myheader("test_view");
11186 
11187   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
11188   myquery(rc);
11189 
11190   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
11191   myquery(rc);
11192   rc= mysql_query(mysql,"CREATE TABLE t1 ("
11193                         " SERVERGRP varchar(20) NOT NULL default '', "
11194                         " DBINSTANCE varchar(20) NOT NULL default '', "
11195                         " PRIMARY KEY  (SERVERGRP)) "
11196                         " CHARSET=latin1 collate=latin1_bin");
11197   myquery(rc);
11198   rc= mysql_query(mysql,"CREATE TABLE t2 ("
11199                         " SERVERNAME varchar(20) NOT NULL, "
11200                         " SERVERGRP varchar(20) NOT NULL, "
11201                         " PRIMARY KEY (SERVERNAME)) "
11202                         " CHARSET=latin1 COLLATE latin1_bin");
11203   myquery(rc);
11204   rc= mysql_query(mysql,
11205                   "CREATE TABLE t3 ("
11206                   " SERVERGRP varchar(20) BINARY NOT NULL, "
11207                   " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
11208                   " ACTSTATE char(1) NOT NULL , "
11209                   " LOCAL_NAME varchar(30) NOT NULL, "
11210                   " CHG_DATE varchar(8) NOT NULL default '00000000', "
11211                   " CHG_TIME varchar(6) NOT NULL default '000000', "
11212                   " MXUSER varchar(12) NOT NULL default '', "
11213                   " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
11214                   " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
11215   myquery(rc);
11216   rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
11217                   " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
11218                   " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
11219                   " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
11220                   " ((T0002.SERVERGRP = T0001.SERVERGRP) and"
11221                   " (T0002.SERVERGRP = T0003.SERVERGRP)"
11222                   " and (T0003.MAPSTATE = _latin1'A') and"
11223                   " (T0003.ACTSTATE = _latin1' '))");
11224   myquery(rc);
11225 
11226   stmt= mysql_stmt_init(mysql);
11227   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11228   check_execute(stmt, rc);
11229 
11230   strmov(str_data, "TEST");
11231   bzero((char*) my_bind, sizeof(my_bind));
11232   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
11233   my_bind[0].buffer= (char *)&str_data;
11234   my_bind[0].buffer_length= 50;
11235   my_bind[0].length= &length;
11236   length= 4;
11237   my_bind[0].is_null= (char*)&is_null;
11238   rc= mysql_stmt_bind_param(stmt, my_bind);
11239   check_execute(stmt,rc);
11240 
11241   for (i= 0; i < 3; i++)
11242   {
11243     rc= mysql_stmt_execute(stmt);
11244     check_execute(stmt, rc);
11245     rc= my_process_stmt_result(stmt);
11246     DIE_UNLESS(1 == rc);
11247   }
11248   mysql_stmt_close(stmt);
11249 
11250   rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
11251   myquery(rc);
11252   rc= mysql_query(mysql, "DROP VIEW v1");
11253   myquery(rc);
11254 }
11255 
11256 
test_view_where()11257 static void test_view_where()
11258 {
11259   MYSQL_STMT *stmt;
11260   int rc, i;
11261   const char *query=
11262     "select v1.c,v2.c from v1, v2";
11263 
11264   myheader("test_view_where");
11265 
11266   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2");
11267   myquery(rc);
11268 
11269   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1");
11270   myquery(rc);
11271   rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)");
11272   myquery(rc);
11273   rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)");
11274   myquery(rc);
11275   rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3");
11276   myquery(rc);
11277   rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3");
11278   myquery(rc);
11279 
11280   stmt= mysql_stmt_init(mysql);
11281   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11282   check_execute(stmt, rc);
11283 
11284   for (i= 0; i < 3; i++)
11285   {
11286     rc= mysql_stmt_execute(stmt);
11287     check_execute(stmt, rc);
11288     rc= my_process_stmt_result(stmt);
11289     DIE_UNLESS(4 == rc);
11290   }
11291   mysql_stmt_close(stmt);
11292 
11293   rc= mysql_query(mysql, "DROP TABLE t1");
11294   myquery(rc);
11295   rc= mysql_query(mysql, "DROP VIEW v1, v2");
11296   myquery(rc);
11297 }
11298 
11299 
test_view_2where()11300 static void test_view_2where()
11301 {
11302   MYSQL_STMT *stmt;
11303   int rc, i;
11304   MYSQL_BIND      my_bind[8];
11305   char            parms[8][100];
11306   ulong           length[8];
11307   const char *query=
11308     "select relid, report, handle, log_group, username, variant, type, "
11309     "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
11310     "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
11311     "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";
11312 
11313   myheader("test_view_2where");
11314 
11315   rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
11316   myquery(rc);
11317   rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
11318   myquery(rc);
11319   rc= mysql_query(mysql,
11320                   "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
11321                   " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
11322                   " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
11323                   " USERNAME varchar(12) NOT NULL,"
11324                   " VARIANT varchar(12) NOT NULL,"
11325                   " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
11326                   " VERSION varchar(6) NOT NULL default '000000',"
11327                   " ERFDAT varchar(8) NOT NULL default '00000000',"
11328                   " ERFTIME varchar(6) NOT NULL default '000000',"
11329                   " ERFNAME varchar(12) NOT NULL,"
11330                   " AEDAT varchar(8) NOT NULL default '00000000',"
11331                   " AETIME varchar(6) NOT NULL default '000000',"
11332                   " AENAME varchar(12) NOT NULL,"
11333                   " DEPENDVARS varchar(10) NOT NULL,"
11334                   " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
11335                   " CLUSTD blob,"
11336                   " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
11337                                 "USERNAME, VARIANT, TYPE, SRTF2))"
11338                  " CHARSET=latin1 COLLATE latin1_bin");
11339   myquery(rc);
11340   rc= mysql_query(mysql,
11341                   "CREATE VIEW V_LTDX AS select T0001.MANDT AS "
11342                   " MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
11343                   " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
11344                   " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
11345                   " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
11346                   " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
11347                   " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
11348                   " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
11349                   " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
11350                   " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
11351   myquery(rc);
11352   bzero((char*) my_bind, sizeof(my_bind));
11353   for (i=0; i < 8; i++) {
11354     strmov(parms[i], "1");
11355     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11356     my_bind[i].buffer = (char *)&parms[i];
11357     my_bind[i].buffer_length = 100;
11358     my_bind[i].is_null = 0;
11359     my_bind[i].length = &length[i];
11360     length[i] = 1;
11361   }
11362   stmt= mysql_stmt_init(mysql);
11363   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11364   check_execute(stmt, rc);
11365 
11366   rc= mysql_stmt_bind_param(stmt, my_bind);
11367   check_execute(stmt,rc);
11368 
11369   rc= mysql_stmt_execute(stmt);
11370   check_execute(stmt, rc);
11371   rc= my_process_stmt_result(stmt);
11372   DIE_UNLESS(0 == rc);
11373 
11374   mysql_stmt_close(stmt);
11375 
11376   rc= mysql_query(mysql, "DROP VIEW V_LTDX");
11377   myquery(rc);
11378   rc= mysql_query(mysql, "DROP TABLE LTDX");
11379   myquery(rc);
11380 }
11381 
11382 
test_view_star()11383 static void test_view_star()
11384 {
11385   MYSQL_STMT *stmt;
11386   int rc, i;
11387   MYSQL_BIND      my_bind[8];
11388   char            parms[8][100];
11389   ulong           length[8];
11390   const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)";
11391 
11392   myheader("test_view_star");
11393 
11394   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1");
11395   myquery(rc);
11396   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1");
11397   myquery(rc);
11398   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
11399   myquery(rc);
11400   rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1");
11401   myquery(rc);
11402   bzero((char*) my_bind, sizeof(my_bind));
11403   for (i= 0; i < 2; i++) {
11404     sprintf((char *)&parms[i], "%d", i);
11405     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11406     my_bind[i].buffer = (char *)&parms[i];
11407     my_bind[i].buffer_length = 100;
11408     my_bind[i].is_null = 0;
11409     my_bind[i].length = &length[i];
11410     length[i] = 1;
11411   }
11412 
11413   stmt= mysql_stmt_init(mysql);
11414   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11415   check_execute(stmt, rc);
11416 
11417   rc= mysql_stmt_bind_param(stmt, my_bind);
11418   check_execute(stmt,rc);
11419 
11420   for (i= 0; i < 3; i++)
11421   {
11422     rc= mysql_stmt_execute(stmt);
11423     check_execute(stmt, rc);
11424     rc= my_process_stmt_result(stmt);
11425     DIE_UNLESS(0 == rc);
11426   }
11427 
11428   mysql_stmt_close(stmt);
11429 
11430   rc= mysql_query(mysql, "DROP TABLE t1");
11431   myquery(rc);
11432   rc= mysql_query(mysql, "DROP VIEW vt1");
11433   myquery(rc);
11434 }
11435 
11436 
test_view_insert()11437 static void test_view_insert()
11438 {
11439   MYSQL_STMT *insert_stmt, *select_stmt;
11440   int rc, i;
11441   MYSQL_BIND      my_bind[1];
11442   int             my_val = 0;
11443   ulong           my_length = 0L;
11444   long            my_null = 0L;
11445   const char *query=
11446     "insert into v1 values (?)";
11447 
11448   myheader("test_view_insert");
11449 
11450   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11451   myquery(rc);
11452   rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1");
11453   myquery(rc);
11454 
11455   rc= mysql_query(mysql,"create table t1 (a int, primary key (a))");
11456   myquery(rc);
11457 
11458   rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1");
11459   myquery(rc);
11460 
11461   insert_stmt= mysql_stmt_init(mysql);
11462   rc= mysql_stmt_prepare(insert_stmt, query, strlen(query));
11463   check_execute(insert_stmt, rc);
11464   query= "select * from t1";
11465   select_stmt= mysql_stmt_init(mysql);
11466   rc= mysql_stmt_prepare(select_stmt, query, strlen(query));
11467   check_execute(select_stmt, rc);
11468 
11469   bzero((char*) my_bind, sizeof(my_bind));
11470   my_bind[0].buffer_type = MYSQL_TYPE_LONG;
11471   my_bind[0].buffer = (char *)&my_val;
11472   my_bind[0].length = &my_length;
11473   my_bind[0].is_null = (char*)&my_null;
11474   rc= mysql_stmt_bind_param(insert_stmt, my_bind);
11475   check_execute(insert_stmt, rc);
11476 
11477   for (i= 0; i < 3; i++)
11478   {
11479     int rowcount= 0;
11480     my_val= i;
11481 
11482     rc= mysql_stmt_execute(insert_stmt);
11483     check_execute(insert_stmt, rc);
11484 
11485     rc= mysql_stmt_execute(select_stmt);
11486     check_execute(select_stmt, rc);
11487     rowcount= (int)my_process_stmt_result(select_stmt);
11488     DIE_UNLESS((i+1) == rowcount);
11489   }
11490   mysql_stmt_close(insert_stmt);
11491   mysql_stmt_close(select_stmt);
11492 
11493   rc= mysql_query(mysql, "DROP VIEW v1");
11494   myquery(rc);
11495   rc= mysql_query(mysql, "DROP TABLE t1");
11496   myquery(rc);
11497 }
11498 
11499 
test_left_join_view()11500 static void test_left_join_view()
11501 {
11502   MYSQL_STMT *stmt;
11503   int rc, i;
11504   const char *query=
11505     "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);";
11506 
11507   myheader("test_left_join_view");
11508 
11509   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11510   myquery(rc);
11511 
11512   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1");
11513   myquery(rc);
11514   rc= mysql_query(mysql,"CREATE TABLE t1 (a int)");
11515   myquery(rc);
11516   rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)");
11517   myquery(rc);
11518   rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1");
11519   myquery(rc);
11520   stmt= mysql_stmt_init(mysql);
11521   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11522   check_execute(stmt, rc);
11523 
11524   for (i= 0; i < 3; i++)
11525   {
11526     rc= mysql_stmt_execute(stmt);
11527     check_execute(stmt, rc);
11528     rc= my_process_stmt_result(stmt);
11529     DIE_UNLESS(3 == rc);
11530   }
11531   mysql_stmt_close(stmt);
11532 
11533   rc= mysql_query(mysql, "DROP VIEW v1");
11534   myquery(rc);
11535   rc= mysql_query(mysql, "DROP TABLE t1");
11536   myquery(rc);
11537 }
11538 
11539 
test_view_insert_fields()11540 static void test_view_insert_fields()
11541 {
11542   MYSQL_STMT	*stmt;
11543   char		parm[11][1000];
11544   ulong         l[11];
11545   int		rc, i;
11546   MYSQL_BIND	my_bind[11];
11547   const char    *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";
11548 
11549   myheader("test_view_insert_fields");
11550 
11551   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
11552   myquery(rc);
11553   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
11554   myquery(rc);
11555   rc= mysql_query(mysql,
11556                   "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
11557                   "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
11558                   "K4N4 varchar(4) NOT NULL default '0000',"
11559                   "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
11560                   "F3N5 varchar(5) NOT NULL default '00000',"
11561                   "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
11562                   "F6N4 varchar(4) NOT NULL default '0000',"
11563                   "F7F8 double NOT NULL default '0',"
11564                   "F8F8 double NOT NULL default '0',"
11565                   "F9D8 decimal(8,2) NOT NULL default '0.00',"
11566                   "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
11567                   "CHARSET=latin1 COLLATE latin1_bin");
11568   myquery(rc);
11569   rc= mysql_query(mysql,
11570                   "CREATE VIEW v1 AS select sql_no_cache "
11571                   " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
11572                   " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
11573                   " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
11574                   " from t1 T0001");
11575 
11576   bzero((char*) my_bind, sizeof(my_bind));
11577   for (i= 0; i < 11; i++)
11578   {
11579     l[i]= 20;
11580     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
11581     my_bind[i].is_null= 0;
11582     my_bind[i].buffer= (char *)&parm[i];
11583 
11584     memset(parm[i], 0, sizeof parm[i]);
11585     strmov(parm[i], "1");
11586     my_bind[i].buffer_length= 2;
11587     my_bind[i].length= &l[i];
11588   }
11589   stmt= mysql_stmt_init(mysql);
11590   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11591   check_execute(stmt, rc);
11592   rc= mysql_stmt_bind_param(stmt, my_bind);
11593   check_execute(stmt, rc);
11594 
11595   rc= mysql_stmt_execute(stmt);
11596   check_execute(stmt, rc);
11597   mysql_stmt_close(stmt);
11598 
11599   query= "select * from t1";
11600   stmt= mysql_stmt_init(mysql);
11601   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11602   check_execute(stmt, rc);
11603   rc= mysql_stmt_execute(stmt);
11604   check_execute(stmt, rc);
11605   rc= my_process_stmt_result(stmt);
11606   DIE_UNLESS(1 == rc);
11607 
11608   mysql_stmt_close(stmt);
11609   rc= mysql_query(mysql, "DROP VIEW v1");
11610   myquery(rc);
11611   rc= mysql_query(mysql, "DROP TABLE t1");
11612   myquery(rc);
11613 
11614 }
11615 
test_bug5126()11616 static void test_bug5126()
11617 {
11618   MYSQL_STMT *stmt;
11619   MYSQL_BIND my_bind[2];
11620   int32 c1, c2;
11621   const char *stmt_text;
11622   int rc;
11623 
11624   myheader("test_bug5126");
11625 
11626   stmt_text= "DROP TABLE IF EXISTS t1";
11627   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11628   myquery(rc);
11629 
11630   stmt_text= "CREATE TABLE t1 (a mediumint, b int)";
11631   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11632   myquery(rc);
11633 
11634   stmt_text= "INSERT INTO t1 VALUES (8386608, 1)";
11635   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11636   myquery(rc);
11637 
11638   stmt= mysql_stmt_init(mysql);
11639   stmt_text= "SELECT a, b FROM t1";
11640   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11641   check_execute(stmt, rc);
11642   rc= mysql_stmt_execute(stmt);
11643   check_execute(stmt, rc);
11644 
11645   /* Bind output buffers */
11646   bzero((char*) my_bind, sizeof(my_bind));
11647 
11648   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11649   my_bind[0].buffer= &c1;
11650   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
11651   my_bind[1].buffer= &c2;
11652 
11653   mysql_stmt_bind_result(stmt, my_bind);
11654 
11655   rc= mysql_stmt_fetch(stmt);
11656   DIE_UNLESS(rc == 0);
11657   DIE_UNLESS(c1 == 8386608 && c2 == 1);
11658   if (!opt_silent)
11659     printf("%ld, %ld\n", (long) c1, (long) c2);
11660   mysql_stmt_close(stmt);
11661 }
11662 
11663 
test_bug4231()11664 static void test_bug4231()
11665 {
11666   MYSQL_STMT *stmt;
11667   MYSQL_BIND my_bind[2];
11668   MYSQL_TIME tm[2];
11669   const char *stmt_text;
11670   int rc;
11671 
11672   myheader("test_bug4231");
11673 
11674   stmt_text= "DROP TABLE IF EXISTS t1";
11675   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11676   myquery(rc);
11677 
11678   stmt_text= "CREATE TABLE t1 (a int)";
11679   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11680   myquery(rc);
11681 
11682   stmt_text= "INSERT INTO t1 VALUES (1)";
11683   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11684   myquery(rc);
11685 
11686   stmt= mysql_stmt_init(mysql);
11687   stmt_text= "SELECT a FROM t1 WHERE ? = ?";
11688   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11689   check_execute(stmt, rc);
11690 
11691   /* Bind input buffers */
11692   bzero((char*) my_bind, sizeof(my_bind));
11693   bzero((char*) tm, sizeof(tm));
11694 
11695   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
11696   my_bind[0].buffer= &tm[0];
11697   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11698   my_bind[1].buffer= &tm[1];
11699 
11700   mysql_stmt_bind_param(stmt, my_bind);
11701   check_execute(stmt, rc);
11702 
11703   /*
11704     First set server-side params to some non-zero non-equal values:
11705     then we will check that they are not used when client sends
11706     new (zero) times.
11707   */
11708   tm[0].time_type = MYSQL_TIMESTAMP_DATE;
11709   tm[0].year = 2000;
11710   tm[0].month = 1;
11711   tm[0].day = 1;
11712   tm[1]= tm[0];
11713   --tm[1].year;                                 /* tm[0] != tm[1] */
11714 
11715   rc= mysql_stmt_execute(stmt);
11716   check_execute(stmt, rc);
11717 
11718   rc= mysql_stmt_fetch(stmt);
11719 
11720   /* binds are unequal, no rows should be returned */
11721   DIE_UNLESS(rc == MYSQL_NO_DATA);
11722 
11723   /* Set one of the dates to zero */
11724   tm[0].year= tm[0].month= tm[0].day= 0;
11725   tm[1]= tm[0];
11726   mysql_stmt_execute(stmt);
11727   rc= mysql_stmt_fetch(stmt);
11728   DIE_UNLESS(rc == 0);
11729 
11730   mysql_stmt_close(stmt);
11731   stmt_text= "DROP TABLE t1";
11732   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11733   myquery(rc);
11734 }
11735 
11736 
test_bug5399()11737 static void test_bug5399()
11738 {
11739   /*
11740     Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
11741     statement id hash in the server uses binary collation.
11742   */
11743 #define NUM_OF_USED_STMT 97
11744   MYSQL_STMT *stmt_list[NUM_OF_USED_STMT];
11745   MYSQL_STMT **stmt;
11746   MYSQL_BIND my_bind[1];
11747   char buff[600];
11748   int rc;
11749   int32 no;
11750 
11751   myheader("test_bug5399");
11752 
11753   bzero((char*) my_bind, sizeof(my_bind));
11754   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11755   my_bind[0].buffer= &no;
11756 
11757   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11758   {
11759     sprintf(buff, "select %d", (int) (stmt - stmt_list));
11760     *stmt= mysql_stmt_init(mysql);
11761     rc= mysql_stmt_prepare(*stmt, buff, strlen(buff));
11762     check_execute(*stmt, rc);
11763     mysql_stmt_bind_result(*stmt, my_bind);
11764   }
11765   if (!opt_silent)
11766     printf("%d statements prepared.\n", NUM_OF_USED_STMT);
11767 
11768   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11769   {
11770     rc= mysql_stmt_execute(*stmt);
11771     check_execute(*stmt, rc);
11772     rc= mysql_stmt_store_result(*stmt);
11773     check_execute(*stmt, rc);
11774     rc= mysql_stmt_fetch(*stmt);
11775     DIE_UNLESS(rc == 0);
11776     DIE_UNLESS((int32) (stmt - stmt_list) == no);
11777   }
11778 
11779   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11780     mysql_stmt_close(*stmt);
11781 #undef NUM_OF_USED_STMT
11782 }
11783 
11784 
test_bug5194()11785 static void test_bug5194()
11786 {
11787   MYSQL_STMT *stmt;
11788   MYSQL_BIND *my_bind;
11789   char *query;
11790   char *param_str;
11791   int param_str_length;
11792   const char *stmt_text;
11793   int rc;
11794   float float_array[250] =
11795   {
11796     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11797     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11798     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11799     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11800     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11801     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11802     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11803     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11804     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11805     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11806     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11807     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11808     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11809     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11810     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11811     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11812     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11813     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11814     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11815     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11816     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11817     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11818     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11819     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11820     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25
11821   };
11822   float *fa_ptr= float_array;
11823   /* Number of columns per row */
11824   const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array);
11825   /* Number of rows per bulk insert to start with */
11826   const int MIN_ROWS_PER_INSERT= 262;
11827   /* Max number of rows per bulk insert to end with */
11828   const int MAX_ROWS_PER_INSERT= 300;
11829   const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT;
11830   const char *query_template= "insert into t1 values %s";
11831   const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */
11832   const int uint16_max= 65535;
11833   int nrows, i;
11834 
11835   myheader("test_bug5194");
11836 
11837   stmt_text= "drop table if exists t1";
11838   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11839 
11840   stmt_text= "create table if not exists t1"
11841    "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, "
11842    "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, "
11843    "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, "
11844    "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, "
11845    "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, "
11846    "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, "
11847    "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, "
11848    "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, "
11849    "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, "
11850    "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, "
11851    "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, "
11852    "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, "
11853    "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, "
11854    "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, "
11855    "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, "
11856    "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, "
11857    "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, "
11858    "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, "
11859    "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, "
11860    "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, "
11861    "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, "
11862    "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, "
11863    "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, "
11864    "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, "
11865    "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, "
11866    "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, "
11867    "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, "
11868    "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, "
11869    "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, "
11870    "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, "
11871    "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, "
11872    "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, "
11873    "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, "
11874    "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, "
11875    "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, "
11876    "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, "
11877    "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, "
11878    "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, "
11879    "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, "
11880    "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, "
11881    "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, "
11882    "c247 float, c248 float, c249 float, c250 float)";
11883   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11884   myquery(rc);
11885 
11886   my_bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11887   query= (char*) malloc(strlen(query_template) +
11888                         MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
11889   param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
11890 
11891   if (my_bind == 0 || query == 0 || param_str == 0)
11892   {
11893     fprintf(stderr, "Can't allocate enough memory for query structs\n");
11894     if (my_bind)
11895       free(my_bind);
11896     if (query)
11897       free(query);
11898     if (param_str)
11899       free(param_str);
11900     return;
11901   }
11902 
11903   stmt= mysql_stmt_init(mysql);
11904 
11905   /* setup a template for one row of parameters */
11906   sprintf(param_str, "(");
11907   for (i= 1; i < COLUMN_COUNT; ++i)
11908     strcat(param_str, "?, ");
11909   strcat(param_str, "?)");
11910   param_str_length= strlen(param_str);
11911 
11912   /* setup bind array */
11913   bzero((char*) my_bind, MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11914   for (i= 0; i < MAX_PARAM_COUNT; ++i)
11915   {
11916     my_bind[i].buffer_type= MYSQL_TYPE_FLOAT;
11917     my_bind[i].buffer= fa_ptr;
11918     if (++fa_ptr == float_array + COLUMN_COUNT)
11919       fa_ptr= float_array;
11920   }
11921 
11922   /*
11923     Test each number of rows per bulk insert, so that we can see where
11924     MySQL fails.
11925   */
11926   for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows)
11927   {
11928     char *query_ptr;
11929     /* Create statement text for current number of rows */
11930     sprintf(query, query_template, param_str);
11931     query_ptr= query + strlen(query);
11932     for (i= 1; i < nrows; ++i)
11933     {
11934       memcpy(query_ptr, ", ", 2);
11935       query_ptr+= 2;
11936       memcpy(query_ptr, param_str, param_str_length);
11937       query_ptr+= param_str_length;
11938     }
11939     *query_ptr= '\0';
11940 
11941     rc= mysql_stmt_prepare(stmt, query, (ulong)(query_ptr - query));
11942     if (rc && nrows * COLUMN_COUNT > uint16_max)
11943     {
11944       if (!opt_silent)
11945         printf("Failed to prepare a statement with %d placeholders "
11946                "(as expected).\n", nrows * COLUMN_COUNT);
11947       break;
11948     }
11949     else
11950       check_execute(stmt, rc);
11951 
11952     if (!opt_silent)
11953       printf("Insert: query length= %d, row count= %d, param count= %lu\n",
11954              (int) strlen(query), nrows, mysql_stmt_param_count(stmt));
11955 
11956     /* bind the parameter array and execute the query */
11957     rc= mysql_stmt_bind_param(stmt, my_bind);
11958     check_execute(stmt, rc);
11959 
11960     rc= mysql_stmt_execute(stmt);
11961     check_execute(stmt, rc);
11962     mysql_stmt_reset(stmt);
11963   }
11964 
11965   mysql_stmt_close(stmt);
11966   free(my_bind);
11967   free(query);
11968   free(param_str);
11969   stmt_text= "drop table t1";
11970   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11971   myquery(rc);
11972 }
11973 
11974 
test_bug5315()11975 static void test_bug5315()
11976 {
11977   MYSQL_STMT *stmt;
11978   const char *stmt_text;
11979   int rc;
11980 
11981   myheader("test_bug5315");
11982 
11983   stmt_text= "SELECT 1";
11984   stmt= mysql_stmt_init(mysql);
11985   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11986   DIE_UNLESS(rc == 0);
11987   if (!opt_silent)
11988     printf("Executing mysql_change_user\n");
11989   mysql_change_user(mysql, opt_user, opt_password, current_db);
11990   if (!opt_silent)
11991     printf("Executing mysql_stmt_execute\n");
11992   rc= mysql_stmt_execute(stmt);
11993   DIE_UNLESS(rc != 0);
11994   if (rc)
11995   {
11996     if (!opt_silent)
11997       printf("Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
11998   }
11999   /* check that connection is OK */
12000   if (!opt_silent)
12001     printf("Executing mysql_stmt_close\n");
12002   mysql_stmt_close(stmt);
12003   if (!opt_silent)
12004     printf("Executing mysql_stmt_init\n");
12005   stmt= mysql_stmt_init(mysql);
12006   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12007   DIE_UNLESS(rc == 0);
12008   rc= mysql_stmt_execute(stmt);
12009   DIE_UNLESS(rc == 0);
12010   mysql_stmt_close(stmt);
12011 }
12012 
12013 
test_bug6049()12014 static void test_bug6049()
12015 {
12016   MYSQL_STMT *stmt;
12017   MYSQL_BIND my_bind[1];
12018   MYSQL_RES *res;
12019   MYSQL_ROW row;
12020   const char *stmt_text;
12021   char buffer[30];
12022   ulong length;
12023   int rc;
12024 
12025   myheader("test_bug6049");
12026 
12027   stmt_text= "SELECT MAKETIME(-25, 12, 12)";
12028 
12029   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12030   myquery(rc);
12031   res= mysql_store_result(mysql);
12032   row= mysql_fetch_row(res);
12033 
12034   stmt= mysql_stmt_init(mysql);
12035   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12036   check_execute(stmt, rc);
12037   rc= mysql_stmt_execute(stmt);
12038   check_execute(stmt, rc);
12039 
12040   bzero((char*) my_bind, sizeof(my_bind));
12041   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
12042   my_bind[0].buffer         = &buffer;
12043   my_bind[0].buffer_length  = sizeof(buffer);
12044   my_bind[0].length         = &length;
12045 
12046   mysql_stmt_bind_result(stmt, my_bind);
12047   rc= mysql_stmt_fetch(stmt);
12048   DIE_UNLESS(rc == 0);
12049 
12050   if (!opt_silent)
12051   {
12052     printf("Result from query: %s\n", row[0]);
12053     printf("Result from prepared statement: %s\n", (char*) buffer);
12054   }
12055 
12056   DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);
12057 
12058   mysql_free_result(res);
12059   mysql_stmt_close(stmt);
12060 }
12061 
12062 
test_bug6058()12063 static void test_bug6058()
12064 {
12065   MYSQL_STMT *stmt;
12066   MYSQL_BIND my_bind[1];
12067   MYSQL_RES *res;
12068   MYSQL_ROW row;
12069   const char *stmt_text;
12070   char buffer[30];
12071   ulong length;
12072   int rc;
12073 
12074   myheader("test_bug6058");
12075 
12076   rc= mysql_query(mysql, "SET SQL_MODE=''");
12077   myquery(rc);
12078 
12079   stmt_text= "SELECT CAST('0000-00-00' AS DATE)";
12080 
12081   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12082   myquery(rc);
12083   res= mysql_store_result(mysql);
12084   row= mysql_fetch_row(res);
12085 
12086   stmt= mysql_stmt_init(mysql);
12087   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12088   check_execute(stmt, rc);
12089   rc= mysql_stmt_execute(stmt);
12090   check_execute(stmt, rc);
12091 
12092   bzero((char*) my_bind, sizeof(my_bind));
12093   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
12094   my_bind[0].buffer         = &buffer;
12095   my_bind[0].buffer_length  = sizeof(buffer);
12096   my_bind[0].length         = &length;
12097 
12098   mysql_stmt_bind_result(stmt, my_bind);
12099   rc= mysql_stmt_fetch(stmt);
12100   DIE_UNLESS(rc == 0);
12101 
12102   if (!opt_silent)
12103   {
12104     printf("Result from query: %s\n", row[0]);
12105     printf("Result from prepared statement: %s\n", buffer);
12106   }
12107 
12108   DIE_UNLESS(strcmp(row[0], buffer) == 0);
12109 
12110   mysql_free_result(res);
12111   mysql_stmt_close(stmt);
12112 }
12113 
12114 
test_bug6059()12115 static void test_bug6059()
12116 {
12117   MYSQL_STMT *stmt;
12118   const char *stmt_text;
12119 
12120   myheader("test_bug6059");
12121 
12122   stmt_text= "SELECT 'foo' INTO OUTFILE 'x.3'";
12123 
12124   stmt= mysql_stmt_init(mysql);
12125   (void) mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12126   DIE_UNLESS(mysql_stmt_field_count(stmt) == 0);
12127   mysql_stmt_close(stmt);
12128 }
12129 
12130 
test_bug6046()12131 static void test_bug6046()
12132 {
12133   MYSQL_STMT *stmt;
12134   const char *stmt_text;
12135   int rc;
12136   short b= 1;
12137   MYSQL_BIND my_bind[1];
12138 
12139   myheader("test_bug6046");
12140 
12141   stmt_text= "DROP TABLE IF EXISTS t1";
12142   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12143   myquery(rc);
12144   stmt_text= "CREATE TABLE t1 (a int, b int)";
12145   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12146   myquery(rc);
12147   stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)";
12148   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12149   myquery(rc);
12150 
12151   stmt= mysql_stmt_init(mysql);
12152 
12153   stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 "
12154              "WHERE t1.b > ? ORDER BY t1.a";
12155 
12156   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12157   check_execute(stmt, rc);
12158 
12159   b= 1;
12160   bzero((char*) my_bind, sizeof(my_bind));
12161   my_bind[0].buffer= &b;
12162   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
12163 
12164   mysql_stmt_bind_param(stmt, my_bind);
12165 
12166   rc= mysql_stmt_execute(stmt);
12167   check_execute(stmt, rc);
12168   mysql_stmt_store_result(stmt);
12169 
12170   rc= mysql_stmt_execute(stmt);
12171   check_execute(stmt, rc);
12172 
12173   mysql_stmt_close(stmt);
12174 }
12175 
12176 
12177 
test_basic_cursors()12178 static void test_basic_cursors()
12179 {
12180   const char *basic_tables[]=
12181   {
12182     "DROP TABLE IF EXISTS t1, t2",
12183 
12184     "CREATE TABLE t1 "
12185     "(id INTEGER NOT NULL PRIMARY KEY, "
12186     " name VARCHAR(20) NOT NULL)",
12187 
12188     "INSERT INTO t1 (id, name) VALUES "
12189     "  (2, 'Ja'), (3, 'Ede'), "
12190     "  (4, 'Haag'), (5, 'Kabul'), "
12191     "  (6, 'Almere'), (7, 'Utrecht'), "
12192     "  (8, 'Qandahar'), (9, 'Amsterdam'), "
12193     "  (10, 'Amersfoort'), (11, 'Constantine')",
12194 
12195     "CREATE TABLE t2 "
12196     "(id INTEGER NOT NULL PRIMARY KEY, "
12197     " name VARCHAR(20) NOT NULL)",
12198 
12199     "INSERT INTO t2 (id, name) VALUES "
12200     "  (4, 'Guam'), (5, 'Aruba'), "
12201     "  (6, 'Angola'), (7, 'Albania'), "
12202     "  (8, 'Anguilla'), (9, 'Argentina'), "
12203     "  (10, 'Azerbaijan'), (11, 'Afghanistan'), "
12204     "  (12, 'Burkina Faso'), (13, 'Faroe Islands')"
12205   };
12206   const char *queries[]=
12207   {
12208     "SELECT * FROM t1",
12209     "SELECT * FROM t2"
12210   };
12211 
12212   DBUG_ENTER("test_basic_cursors");
12213   myheader("test_basic_cursors");
12214 
12215   fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
12216 
12217   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12218   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12219   DBUG_VOID_RETURN;
12220 }
12221 
12222 
test_cursors_with_union()12223 static void test_cursors_with_union()
12224 {
12225   const char *queries[]=
12226   {
12227     "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2",
12228     "SELECT t1.id FROM t1 WHERE t1.id < 5"
12229   };
12230   myheader("test_cursors_with_union");
12231   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12232   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12233 }
12234 
12235 
test_cursors_with_procedure()12236 static void test_cursors_with_procedure()
12237 {
12238   const char *queries[]=
12239   {
12240     "SELECT * FROM t1 procedure analyse()"
12241   };
12242   myheader("test_cursors_with_procedure");
12243   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12244   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12245 }
12246 
12247 
12248 /*
12249   Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
12250   should not crash server and should not hang in case of errors.
12251 
12252   Since those functions can't be seen in modern API (unless client library
12253   was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro.
12254 */
test_bug6081()12255 static void test_bug6081()
12256 {
12257   int rc;
12258   myheader("test_bug6081");
12259 
12260   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12261                      (ulong)strlen(current_db), 0);
12262   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12263   {
12264     myerror(NULL);                                   /* purecov: inspected */
12265     die(__FILE__, __LINE__, "COM_DROP_DB failed");   /* purecov: inspected */
12266   }
12267   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12268                      (ulong)strlen(current_db), 0);
12269   myquery_r(rc);
12270   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12271                      (ulong)strlen(current_db), 0);
12272   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12273   {
12274     myerror(NULL);                                   /* purecov: inspected */
12275     die(__FILE__, __LINE__, "COM_CREATE_DB failed"); /* purecov: inspected */
12276   }
12277   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12278                      (ulong)strlen(current_db), 0);
12279   myquery_r(rc);
12280   rc= mysql_select_db(mysql, current_db);
12281   myquery(rc);
12282 }
12283 
12284 
test_bug6096()12285 static void test_bug6096()
12286 {
12287   MYSQL_STMT *stmt;
12288   MYSQL_RES *query_result, *stmt_metadata;
12289   const char *stmt_text;
12290   MYSQL_BIND my_bind[12];
12291   MYSQL_FIELD *query_field_list, *stmt_field_list;
12292   ulong query_field_count, stmt_field_count;
12293   int rc;
12294   my_bool update_max_length= TRUE;
12295   uint i;
12296 
12297   myheader("test_bug6096");
12298 
12299   stmt_text= "drop table if exists t1";
12300   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12301   myquery(rc);
12302 
12303   mysql_query(mysql, "set sql_mode=''");
12304   stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, "
12305                              " c_mediumint mediumint, c_int int, "
12306                              " c_bigint bigint, c_float float, "
12307                              " c_double double, c_varchar varchar(20), "
12308                              " c_char char(20), c_time time, c_date date, "
12309                              " c_datetime datetime)";
12310   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12311   myquery(rc);
12312   stmt_text= "insert into t1  values (-100, -20000, 30000000, 4, 8, 1.0, "
12313                                      "2.0, 'abc', 'def', now(), now(), now())";
12314   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12315   myquery(rc);
12316 
12317   stmt_text= "select * from t1";
12318 
12319   /* Run select in prepared and non-prepared mode and compare metadata */
12320   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12321   myquery(rc);
12322   query_result= mysql_store_result(mysql);
12323   query_field_list= mysql_fetch_fields(query_result);
12324   query_field_count= mysql_num_fields(query_result);
12325 
12326   stmt= mysql_stmt_init(mysql);
12327   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12328   check_execute(stmt, rc);
12329   rc= mysql_stmt_execute(stmt);
12330   check_execute(stmt, rc);
12331   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
12332                       (void*) &update_max_length);
12333   mysql_stmt_store_result(stmt);
12334   stmt_metadata= mysql_stmt_result_metadata(stmt);
12335   stmt_field_list= mysql_fetch_fields(stmt_metadata);
12336   stmt_field_count= mysql_num_fields(stmt_metadata);
12337   DIE_UNLESS(stmt_field_count == query_field_count);
12338 
12339   /* Print out and check the metadata */
12340 
12341   if (!opt_silent)
12342   {
12343     printf(" ------------------------------------------------------------\n");
12344     printf("             |                     Metadata \n");
12345     printf(" ------------------------------------------------------------\n");
12346     printf("             |         Query          |   Prepared statement \n");
12347     printf(" ------------------------------------------------------------\n");
12348     printf(" field name  |  length   | max_length |  length   |  max_length\n");
12349     printf(" ------------------------------------------------------------\n");
12350 
12351     for (i= 0; i < query_field_count; ++i)
12352     {
12353       MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
12354       printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
12355              f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
12356       DIE_UNLESS(f1->length == f2->length);
12357     }
12358     printf(" ---------------------------------------------------------------\n");
12359   }
12360 
12361   /* Bind and fetch the data */
12362 
12363   bzero((char*) my_bind, sizeof(my_bind));
12364   for (i= 0; i < stmt_field_count; ++i)
12365   {
12366     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
12367     my_bind[i].buffer_length= stmt_field_list[i].max_length + 1;
12368     my_bind[i].buffer= malloc(my_bind[i].buffer_length);
12369   }
12370   mysql_stmt_bind_result(stmt, my_bind);
12371   rc= mysql_stmt_fetch(stmt);
12372   check_execute(stmt, rc);
12373   rc= mysql_stmt_fetch(stmt);
12374   DIE_UNLESS(rc == MYSQL_NO_DATA);
12375 
12376   /* Clean up */
12377 
12378   for (i= 0; i < stmt_field_count; ++i)
12379     free(my_bind[i].buffer);
12380   mysql_stmt_close(stmt);
12381   mysql_free_result(query_result);
12382   mysql_free_result(stmt_metadata);
12383   stmt_text= "drop table t1";
12384   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12385   myquery(rc);
12386 }
12387 
12388 
12389 /*
12390   Test of basic checks that are performed in server for components
12391   of MYSQL_TIME parameters.
12392 */
12393 
test_datetime_ranges()12394 static void test_datetime_ranges()
12395 {
12396   const char *stmt_text;
12397   int rc, i;
12398   MYSQL_STMT *stmt;
12399   MYSQL_BIND my_bind[6];
12400   MYSQL_TIME tm[6];
12401 
12402   myheader("test_datetime_ranges");
12403 
12404   stmt_text= "drop table if exists t1";
12405   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12406   myquery(rc);
12407 
12408   stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
12409                               "hour datetime, min datetime, sec datetime)";
12410   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12411   myquery(rc);
12412 
12413   stmt= mysql_simple_prepare(mysql,
12414                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
12415   check_stmt(stmt);
12416   verify_param_count(stmt, 6);
12417 
12418   bzero((char*) my_bind, sizeof(my_bind));
12419   for (i= 0; i < 6; i++)
12420   {
12421     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12422     my_bind[i].buffer= &tm[i];
12423   }
12424   rc= mysql_stmt_bind_param(stmt, my_bind);
12425   check_execute(stmt, rc);
12426 
12427   tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
12428   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12429   tm[0].second_part= 0; tm[0].neg= 0;
12430 
12431   tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12432   tm[0].year= 10000;  tm[1].month= 13; tm[2].day= 32;
12433   tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;
12434 
12435   rc= mysql_stmt_execute(stmt);
12436   check_execute(stmt, rc);
12437   my_process_warnings(mysql, 6);
12438 
12439   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12440   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12441   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12442   verify_col_data("t1", "hour", "0000-00-00 00:00:00");
12443   verify_col_data("t1", "min", "0000-00-00 00:00:00");
12444   verify_col_data("t1", "sec", "0000-00-00 00:00:00");
12445 
12446   mysql_stmt_close(stmt);
12447 
12448   stmt_text= "delete from t1";
12449   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12450   myquery(rc);
12451 
12452   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
12453                                     "VALUES (?, ?, ?)");
12454   check_stmt(stmt);
12455   verify_param_count(stmt, 3);
12456 
12457   /*
12458     We reuse contents of bind and tm arrays left from previous part of test.
12459   */
12460   for (i= 0; i < 3; i++)
12461     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12462 
12463   rc= mysql_stmt_bind_param(stmt, my_bind);
12464   check_execute(stmt, rc);
12465 
12466   rc= mysql_stmt_execute(stmt);
12467   check_execute(stmt, rc);
12468   my_process_warnings(mysql, 3);
12469 
12470   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12471   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12472   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12473 
12474   mysql_stmt_close(stmt);
12475 
12476   stmt_text= "drop table t1";
12477   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12478   myquery(rc);
12479 
12480   stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
12481   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12482   myquery(rc);
12483 
12484   stmt= mysql_simple_prepare(mysql,
12485                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
12486   check_stmt(stmt);
12487   verify_param_count(stmt, 5);
12488 
12489   /*
12490     Again we reuse what we can from previous part of test.
12491   */
12492   for (i= 0; i < 5; i++)
12493     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12494 
12495   rc= mysql_stmt_bind_param(stmt, my_bind);
12496   check_execute(stmt, rc);
12497 
12498   tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
12499   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12500   tm[0].second_part= 0; tm[0].neg= 0;
12501 
12502   tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12503   tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;
12504 
12505   rc= mysql_stmt_execute(stmt);
12506   check_execute(stmt, rc);
12507   my_process_warnings(mysql, 2);
12508 
12509   verify_col_data("t1", "day_ovfl", "838:59:59");
12510   verify_col_data("t1", "day", "828:30:30");
12511   verify_col_data("t1", "hour", "270:30:30");
12512   verify_col_data("t1", "min", "00:00:00");
12513   verify_col_data("t1", "sec", "00:00:00");
12514 
12515   mysql_stmt_close(stmt);
12516 
12517   stmt_text= "drop table t1";
12518   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12519   myquery(rc);
12520 }
12521 
12522 
12523 /*
12524   This test is used in:
12525   mysql-test/suite/binlog/binlog_stm_datetime_ranges_mdev15289.test
12526 */
test_datetime_ranges_mdev15289()12527 static void test_datetime_ranges_mdev15289()
12528 {
12529   const char *stmt_text;
12530   int rc, i;
12531   MYSQL_STMT *stmt;
12532   MYSQL_BIND my_bind[4];
12533   MYSQL_TIME tm[4];
12534 
12535   myheader("test_datetime_ranges_mdev15289");
12536 
12537   stmt_text= "SET sql_mode=''";
12538   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12539   myquery(rc);
12540 
12541   stmt_text= "create or replace table t1 "
12542              "(t time, d date, dt datetime,ts timestamp)";
12543   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12544   myquery(rc);
12545 
12546   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?, ?, ?, ?)");
12547   check_stmt(stmt);
12548   verify_param_count(stmt, 4);
12549 
12550   /*** Testing DATETIME ***/
12551   bzero((char*) my_bind, sizeof(my_bind));
12552   for (i= 0; i < 4; i++)
12553   {
12554     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12555     my_bind[i].buffer= &tm[i];
12556   }
12557   rc= mysql_stmt_bind_param(stmt, my_bind);
12558   check_execute(stmt, rc);
12559 
12560   /* Notice bad year */
12561   tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2;
12562   tm[0].hour= 03; tm[0].minute= 04; tm[0].second= 05;
12563   tm[0].second_part= 0; tm[0].neg= 0;
12564   tm[0].time_type= MYSQL_TIMESTAMP_DATETIME;
12565   tm[3]= tm[2]= tm[1]= tm[0];
12566 
12567   rc= mysql_stmt_execute(stmt);
12568   check_execute(stmt, rc);
12569   my_process_warnings(mysql, 4);
12570 
12571   verify_col_data("t1", "t", "00:00:00");
12572   verify_col_data("t1", "d", "0000-00-00");
12573   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12574   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12575 
12576   /*** Testing DATE ***/
12577   bzero((char*) my_bind, sizeof(my_bind));
12578   for (i= 0; i < 4; i++)
12579   {
12580     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12581     my_bind[i].buffer= &tm[i];
12582   }
12583   rc= mysql_stmt_bind_param(stmt, my_bind);
12584   check_execute(stmt, rc);
12585 
12586   /* Notice bad year */
12587   tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2;
12588   tm[0].hour= 00; tm[0].minute= 00; tm[0].second= 00;
12589   tm[0].second_part= 0; tm[0].neg= 0;
12590   tm[0].time_type= MYSQL_TIMESTAMP_DATE;
12591   tm[3]= tm[2]= tm[1]= tm[0];
12592 
12593   rc= mysql_stmt_execute(stmt);
12594   check_execute(stmt, rc);
12595   my_process_warnings(mysql, 4);
12596 
12597   verify_col_data("t1", "t", "00:00:00");
12598   verify_col_data("t1", "d", "0000-00-00");
12599   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12600   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12601 
12602   /*** Testing TIME ***/
12603   bzero((char*) my_bind, sizeof(my_bind));
12604   for (i= 0; i < 4; i++)
12605   {
12606     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12607     my_bind[i].buffer= &tm[i];
12608   }
12609   rc= mysql_stmt_bind_param(stmt, my_bind);
12610   check_execute(stmt, rc);
12611 
12612   /* Notice bad hour */
12613   tm[0].year= 0; tm[0].month= 0; tm[0].day= 0;
12614   tm[0].hour= 100; tm[0].minute= 64; tm[0].second= 05;
12615   tm[0].second_part= 0; tm[0].neg= 0;
12616   tm[0].time_type= MYSQL_TIMESTAMP_TIME;
12617   tm[3]= tm[2]= tm[1]= tm[0];
12618 
12619   rc= mysql_stmt_execute(stmt);
12620   check_execute(stmt, rc);
12621   my_process_warnings(mysql, 4);
12622 
12623   verify_col_data("t1", "t", "00:00:00");
12624   verify_col_data("t1", "d", "0000-00-00");
12625   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12626   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12627 
12628   mysql_stmt_close(stmt);
12629 
12630   stmt_text= "drop table t1";
12631   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12632   myquery(rc);
12633 }
12634 
12635 
test_bug4172()12636 static void test_bug4172()
12637 {
12638   MYSQL_STMT *stmt;
12639   MYSQL_BIND my_bind[3];
12640   const char *stmt_text;
12641   MYSQL_RES *res;
12642   MYSQL_ROW row;
12643   int rc;
12644   char f[100], d[100], e[100];
12645   ulong f_len, d_len, e_len;
12646 
12647   myheader("test_bug4172");
12648 
12649   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
12650   mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))");
12651   mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, "
12652                                             "123456.1234)");
12653 
12654   stmt= mysql_stmt_init(mysql);
12655   stmt_text= "SELECT f, d, e FROM t1";
12656 
12657   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12658   check_execute(stmt, rc);
12659   rc= mysql_stmt_execute(stmt);
12660   check_execute(stmt, rc);
12661 
12662   bzero((char*) my_bind, sizeof(my_bind));
12663   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12664   my_bind[0].buffer= f;
12665   my_bind[0].buffer_length= sizeof(f);
12666   my_bind[0].length= &f_len;
12667   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
12668   my_bind[1].buffer= d;
12669   my_bind[1].buffer_length= sizeof(d);
12670   my_bind[1].length= &d_len;
12671   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
12672   my_bind[2].buffer= e;
12673   my_bind[2].buffer_length= sizeof(e);
12674   my_bind[2].length= &e_len;
12675 
12676   mysql_stmt_bind_result(stmt, my_bind);
12677 
12678   mysql_stmt_store_result(stmt);
12679   rc= mysql_stmt_fetch(stmt);
12680   check_execute(stmt, rc);
12681 
12682   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12683   myquery(rc);
12684   res= mysql_store_result(mysql);
12685   row= mysql_fetch_row(res);
12686 
12687   if (!opt_silent)
12688   {
12689     printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n",
12690            f, d, e);
12691     printf("Text protocol:   float=%s, double=%s, decimal(10,4)=%s\n",
12692            row[0], row[1], row[2]);
12693   }
12694   DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]));
12695 
12696   mysql_free_result(res);
12697   mysql_stmt_close(stmt);
12698 }
12699 
12700 
test_conversion()12701 static void test_conversion()
12702 {
12703   MYSQL_STMT *stmt;
12704   const char *stmt_text;
12705   int rc;
12706   MYSQL_BIND my_bind[1];
12707   uchar buff[4];
12708   ulong length;
12709 
12710   myheader("test_conversion");
12711 
12712   stmt_text= "DROP TABLE IF EXISTS t1";
12713   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12714   myquery(rc);
12715   stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
12716   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12717   myquery(rc);
12718   stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
12719              " character_set_results=latin1";
12720   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12721   myquery(rc);
12722 
12723   stmt= mysql_stmt_init(mysql);
12724 
12725   stmt_text= "INSERT INTO t1 (a) VALUES (?)";
12726   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12727   check_execute(stmt, rc);
12728 
12729   bzero((char*) my_bind, sizeof(my_bind));
12730   my_bind[0].buffer= (char*) buff;
12731   my_bind[0].length= &length;
12732   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12733 
12734   mysql_stmt_bind_param(stmt, my_bind);
12735 
12736   buff[0]= (uchar) 0xC3;
12737   buff[1]= (uchar) 0xA0;
12738   length= 2;
12739 
12740   rc= mysql_stmt_execute(stmt);
12741   check_execute(stmt, rc);
12742 
12743   stmt_text= "SELECT a FROM t1";
12744   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12745   check_execute(stmt, rc);
12746   rc= mysql_stmt_execute(stmt);
12747   check_execute(stmt, rc);
12748 
12749   my_bind[0].buffer_length= sizeof(buff);
12750   mysql_stmt_bind_result(stmt, my_bind);
12751 
12752   rc= mysql_stmt_fetch(stmt);
12753   DIE_UNLESS(rc == 0);
12754   DIE_UNLESS(length == 1);
12755   DIE_UNLESS(buff[0] == 0xE0);
12756   rc= mysql_stmt_fetch(stmt);
12757   DIE_UNLESS(rc == MYSQL_NO_DATA);
12758 
12759   mysql_stmt_close(stmt);
12760   stmt_text= "DROP TABLE t1";
12761   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12762   myquery(rc);
12763   stmt_text= "SET NAMES DEFAULT";
12764   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12765   myquery(rc);
12766 }
12767 
test_rewind(void)12768 static void test_rewind(void)
12769 {
12770   MYSQL_STMT *stmt;
12771   MYSQL_BIND my_bind;
12772   int rc = 0;
12773   const char *stmt_text;
12774   long unsigned int length=4, Data=0;
12775   my_bool isnull=0;
12776 
12777   myheader("test_rewind");
12778 
12779   stmt_text= "CREATE TABLE t1 (a int)";
12780   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12781   myquery(rc);
12782   stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)";
12783   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12784   myquery(rc);
12785 
12786   stmt= mysql_stmt_init(mysql);
12787 
12788   stmt_text= "SELECT * FROM t1";
12789   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12790   check_execute(stmt, rc);
12791 
12792   bzero((char*) &my_bind, sizeof(MYSQL_BIND));
12793   my_bind.buffer_type= MYSQL_TYPE_LONG;
12794   my_bind.buffer= (void *)&Data; /* this buffer won't be altered */
12795   my_bind.length= &length;
12796   my_bind.is_null= &isnull;
12797 
12798   rc= mysql_stmt_execute(stmt);
12799   check_execute(stmt, rc);
12800 
12801   rc= mysql_stmt_store_result(stmt);
12802   DIE_UNLESS(rc == 0);
12803 
12804   rc= mysql_stmt_bind_result(stmt, &my_bind);
12805   DIE_UNLESS(rc == 0);
12806 
12807   /* retreive all result sets till we are at the end */
12808   while(!mysql_stmt_fetch(stmt))
12809     if (!opt_silent)
12810       printf("fetched result:%ld\n", Data);
12811 
12812   DIE_UNLESS(rc != MYSQL_NO_DATA);
12813 
12814   /* seek to the first row */
12815   mysql_stmt_data_seek(stmt, 0);
12816 
12817   /* now we should be able to fetch the results again */
12818   /* but mysql_stmt_fetch returns MYSQL_NO_DATA */
12819   while(!(rc= mysql_stmt_fetch(stmt)))
12820     if (!opt_silent)
12821       printf("fetched result after seek:%ld\n", Data);
12822 
12823   DIE_UNLESS(rc == MYSQL_NO_DATA);
12824 
12825   stmt_text= "DROP TABLE t1";
12826   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12827   myquery(rc);
12828   rc= mysql_stmt_free_result(stmt);
12829   rc= mysql_stmt_close(stmt);
12830 }
12831 
12832 
test_truncation()12833 static void test_truncation()
12834 {
12835   MYSQL_STMT *stmt;
12836   const char *stmt_text;
12837   int rc;
12838   uint bind_count;
12839   MYSQL_BIND *bind_array, *my_bind;
12840 
12841   myheader("test_truncation");
12842 
12843   /* Prepare the test table */
12844   rc= mysql_query(mysql, "drop table if exists t1");
12845   myquery(rc);
12846 
12847   stmt_text= "create table t1 ("
12848              "i8 tinyint, ui8 tinyint unsigned, "
12849              "i16 smallint, i16_1 smallint, "
12850              "ui16 smallint unsigned, i32 int, i32_1 int, "
12851              "d double, d_1 double, ch char(30), ch_1 char(30), "
12852              "tx text, tx_1 text, ch_2 char(30) "
12853              ")";
12854   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12855   myquery(rc);
12856 
12857   {
12858     const char insert_text[]=
12859              "insert into t1 VALUES ("
12860              "-10, "                            /* i8 */
12861              "200, "                            /* ui8 */
12862              "32000, "                          /* i16 */
12863              "-32767, "                         /* i16_1 */
12864              "64000, "                          /* ui16 */
12865              "1073741824, "                     /* i32 */
12866              "1073741825, "                     /* i32_1 */
12867              "123.456, "                        /* d */
12868              "-12345678910, "                   /* d_1 */
12869              "'111111111111111111111111111111',"/* ch */
12870              "'abcdef', "                       /* ch_1 */
12871              "'12345 	      ', "              /* tx */
12872              "'12345.67 	      ', "      /* tx_1 */
12873              "'12345.67abc'"                    /* ch_2 */
12874              ")";
12875     rc= mysql_real_query(mysql, insert_text, strlen(insert_text));
12876     myquery(rc);
12877   }
12878 
12879   stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, "
12880              "       i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, "
12881              "       d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, "
12882              "       tx_1 c17, ch_2 c18 "
12883              "from t1";
12884 
12885   stmt= mysql_stmt_init(mysql);
12886   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12887   check_execute(stmt, rc);
12888   rc= mysql_stmt_execute(stmt);
12889   check_execute(stmt, rc);
12890   bind_count= (uint) mysql_stmt_field_count(stmt);
12891 
12892   /*************** Fill in the bind structure and bind it **************/
12893   bind_array= malloc(sizeof(MYSQL_BIND) * bind_count);
12894   bzero((char*) bind_array, sizeof(MYSQL_BIND) * bind_count);
12895   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12896     my_bind->error= &my_bind->error_value;
12897   my_bind= bind_array;
12898 
12899   my_bind->buffer= malloc(sizeof(uint8));
12900   my_bind->buffer_type= MYSQL_TYPE_TINY;
12901   my_bind->is_unsigned= TRUE;
12902 
12903   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12904   my_bind->buffer= malloc(sizeof(uint32));
12905   my_bind->buffer_type= MYSQL_TYPE_LONG;
12906   my_bind->is_unsigned= TRUE;
12907 
12908   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12909   my_bind->buffer= malloc(sizeof(int8));
12910   my_bind->buffer_type= MYSQL_TYPE_TINY;
12911 
12912   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12913   my_bind->buffer= malloc(sizeof(uint16));
12914   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12915   my_bind->is_unsigned= TRUE;
12916 
12917   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12918   my_bind->buffer= malloc(sizeof(int16));
12919   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12920 
12921   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12922   my_bind->buffer= malloc(sizeof(uint16));
12923   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12924   my_bind->is_unsigned= TRUE;
12925 
12926   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12927   my_bind->buffer= malloc(sizeof(int8));
12928   my_bind->buffer_type= MYSQL_TYPE_TINY;
12929   my_bind->is_unsigned= TRUE;
12930 
12931   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12932   my_bind->buffer= malloc(sizeof(float));
12933   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12934 
12935   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12936   my_bind->buffer= malloc(sizeof(float));
12937   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12938 
12939   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12940   my_bind->buffer= malloc(sizeof(double));
12941   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12942 
12943   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12944   my_bind->buffer= malloc(sizeof(longlong));
12945   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12946 
12947   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12948   my_bind->buffer= malloc(sizeof(ulonglong));
12949   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12950   my_bind->is_unsigned= TRUE;
12951 
12952   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12953   my_bind->buffer= malloc(sizeof(longlong));
12954   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12955 
12956   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12957   my_bind->buffer= malloc(sizeof(longlong));
12958   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12959 
12960   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12961   my_bind->buffer= malloc(sizeof(longlong));
12962   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12963 
12964   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12965   my_bind->buffer= malloc(sizeof(longlong));
12966   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12967 
12968   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12969   my_bind->buffer= malloc(sizeof(double));
12970   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12971 
12972   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12973   my_bind->buffer= malloc(sizeof(double));
12974   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12975 
12976   rc= mysql_stmt_bind_result(stmt, bind_array);
12977   check_execute(stmt, rc);
12978   rc= mysql_stmt_fetch(stmt);
12979   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12980 
12981   /*************** Verify truncation results ***************************/
12982   my_bind= bind_array;
12983 
12984   /* signed tiny -> tiny */
12985   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == -10);
12986 
12987   /* signed tiny -> uint32 */
12988   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12989   DIE_UNLESS(*my_bind->error && * (int32*) my_bind->buffer == -10);
12990 
12991   /* unsigned tiny -> tiny */
12992   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12993   DIE_UNLESS(*my_bind->error && * (uint8*) my_bind->buffer == 200);
12994 
12995   /* short -> ushort */
12996   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12997   DIE_UNLESS(*my_bind->error && * (int16*) my_bind->buffer == -32767);
12998 
12999   /* ushort -> short */
13000   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13001   DIE_UNLESS(*my_bind->error && * (uint16*) my_bind->buffer == 64000);
13002 
13003   /* short -> ushort (no truncation, data is in the range of target type) */
13004   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13005   DIE_UNLESS(! *my_bind->error && * (uint16*) my_bind->buffer == 32000);
13006 
13007   /* ushort -> utiny */
13008   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13009   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == 0);
13010 
13011   /* int -> float: no truncation, the number is a power of two */
13012   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13013   DIE_UNLESS(! *my_bind->error && * (float*) my_bind->buffer == 1073741824);
13014 
13015   /* int -> float: truncation, not enough bits in float */
13016   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13017   DIE_UNLESS(*my_bind->error);
13018 
13019   /* int -> double: no truncation */
13020   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13021   DIE_UNLESS(! *my_bind->error && * (double*) my_bind->buffer == 1073741825);
13022 
13023   /* double -> longlong: fractional part is lost */
13024   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13025 
13026   /* double -> ulonglong, negative fp number to unsigned integer */
13027   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13028   /* Value in the buffer is not defined: don't test it */
13029   DIE_UNLESS(*my_bind->error);
13030 
13031   /* double -> longlong, negative fp number to signed integer: no loss */
13032   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13033   DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == -12345678910LL);
13034 
13035   /* big numeric string -> number */
13036   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13037   DIE_UNLESS(*my_bind->error);
13038 
13039   /* junk string -> number */
13040   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13041   DIE_UNLESS(*my_bind->error && *(longlong*) my_bind->buffer == 0);
13042 
13043   /* string with trailing spaces -> number */
13044   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13045   DIE_UNLESS(! *my_bind->error && *(longlong*) my_bind->buffer == 12345);
13046 
13047   /* string with trailing spaces -> double */
13048   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13049   DIE_UNLESS(! *my_bind->error && *(double*) my_bind->buffer == 12345.67);
13050 
13051   /* string with trailing junk -> double */
13052   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13053   /*
13054     XXX: There must be a truncation error: but it's not the way the server
13055     behaves, so let's leave it for now.
13056   */
13057   DIE_UNLESS(*(double*) my_bind->buffer == 12345.67);
13058   /*
13059     TODO: string -> double,  double -> time, double -> string (truncation
13060           errors are not supported here yet)
13061           longlong -> time/date/datetime
13062           date -> time, date -> timestamp, date -> number
13063           time -> string, time -> date, time -> timestamp,
13064           number -> date string -> date
13065   */
13066   /*************** Cleanup *********************************************/
13067 
13068   mysql_stmt_close(stmt);
13069 
13070   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
13071     free(my_bind->buffer);
13072   free(bind_array);
13073 
13074   rc= mysql_query(mysql, "drop table t1");
13075   myquery(rc);
13076 }
13077 
test_truncation_option()13078 static void test_truncation_option()
13079 {
13080   MYSQL_STMT *stmt;
13081   const char *stmt_text;
13082   int rc;
13083   uint8 buf;
13084   my_bool option= 0;
13085   my_bool error;
13086   MYSQL_BIND my_bind;
13087 
13088   myheader("test_truncation_option");
13089 
13090   /* Prepare the test table */
13091   stmt_text= "select -1";
13092 
13093   stmt= mysql_stmt_init(mysql);
13094   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13095   check_execute(stmt, rc);
13096   rc= mysql_stmt_execute(stmt);
13097   check_execute(stmt, rc);
13098 
13099   bzero((char*) &my_bind, sizeof(my_bind));
13100 
13101   my_bind.buffer= (void*) &buf;
13102   my_bind.buffer_type= MYSQL_TYPE_TINY;
13103   my_bind.is_unsigned= TRUE;
13104   my_bind.error= &error;
13105 
13106   rc= mysql_stmt_bind_result(stmt, &my_bind);
13107   check_execute(stmt, rc);
13108   rc= mysql_stmt_fetch(stmt);
13109   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
13110   DIE_UNLESS(error);
13111   rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
13112   myquery(rc);
13113   /* need to rebind for the new setting to take effect */
13114   rc= mysql_stmt_bind_result(stmt, &my_bind);
13115   check_execute(stmt, rc);
13116   rc= mysql_stmt_execute(stmt);
13117   check_execute(stmt, rc);
13118   rc= mysql_stmt_fetch(stmt);
13119   check_execute(stmt, rc);
13120   /* The only change is rc - error pointers are still filled in */
13121   DIE_UNLESS(error == 1);
13122   /* restore back the defaults */
13123   option= 1;
13124   mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
13125 
13126   mysql_stmt_close(stmt);
13127 }
13128 
13129 
13130 /* Bug#6761 - mysql_list_fields doesn't work */
13131 
test_bug6761(void)13132 static void test_bug6761(void)
13133 {
13134   const char *stmt_text;
13135   MYSQL_RES *res;
13136   int rc;
13137   myheader("test_bug6761");
13138 
13139   stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
13140   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13141   myquery(rc);
13142 
13143   res= mysql_list_fields(mysql, "t1", "%");
13144   DIE_UNLESS(res && mysql_num_fields(res) == 3);
13145   mysql_free_result(res);
13146 
13147   stmt_text= "DROP TABLE t1";
13148   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13149   myquery(rc);
13150 }
13151 
13152 
13153 /* Bug#8330 - mysql_stmt_execute crashes (libmysql) */
13154 
test_bug8330()13155 static void test_bug8330()
13156 {
13157   const char *stmt_text;
13158   MYSQL_STMT *stmt[2];
13159   int i, rc;
13160   const char *query= "select a,b from t1 where a=?";
13161   MYSQL_BIND my_bind[2];
13162   long lval[2];
13163 
13164   myheader("test_bug8330");
13165 
13166   stmt_text= "drop table if exists t1";
13167   /* in case some previos test failed */
13168   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13169   myquery(rc);
13170   stmt_text= "create table t1 (a int, b int)";
13171   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13172   myquery(rc);
13173 
13174   bzero((char*) my_bind, sizeof(my_bind));
13175   for (i=0; i < 2; i++)
13176   {
13177     stmt[i]= mysql_stmt_init(mysql);
13178     rc= mysql_stmt_prepare(stmt[i], query, strlen(query));
13179     check_execute(stmt[i], rc);
13180 
13181     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
13182     lval[i]= 0;
13183     my_bind[i].buffer= (void*) &lval[i];
13184     my_bind[i].is_null= 0;
13185     mysql_stmt_bind_param(stmt[i], &my_bind[i]);
13186   }
13187 
13188   rc= mysql_stmt_execute(stmt[0]);
13189   check_execute(stmt[0], rc);
13190 
13191   rc= mysql_stmt_execute(stmt[1]);
13192   DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
13193   rc= mysql_stmt_execute(stmt[0]);
13194   check_execute(stmt[0], rc);
13195 
13196   mysql_stmt_close(stmt[0]);
13197   mysql_stmt_close(stmt[1]);
13198 
13199   stmt_text= "drop table t1";
13200   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13201   myquery(rc);
13202 }
13203 
13204 
13205 /* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */
13206 
test_bug7990()13207 static void test_bug7990()
13208 {
13209   MYSQL_STMT *stmt;
13210   int rc;
13211   myheader("test_bug7990");
13212 
13213   stmt= mysql_stmt_init(mysql);
13214   rc= mysql_stmt_prepare(stmt, "foo", 3);
13215   /*
13216     XXX: the fact that we store errno both in STMT and in
13217     MYSQL is not documented and is subject to change in 5.0
13218   */
13219   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql));
13220   mysql_stmt_close(stmt);
13221   DIE_UNLESS(!mysql_errno(mysql));
13222 }
13223 
13224 /*
13225   Bug #15518 - Reusing a stmt that has failed during prepare
13226   does not clear error
13227 */
13228 
test_bug15518()13229 static void test_bug15518()
13230 {
13231   MYSQL_STMT *stmt;
13232   MYSQL* mysql1;
13233   int rc;
13234   myheader("test_bug15518");
13235 
13236   mysql1= mysql_client_init(NULL);
13237 
13238   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13239                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13240                           CLIENT_MULTI_STATEMENTS))
13241   {
13242     fprintf(stderr, "Failed to connect to the database\n");
13243     DIE_UNLESS(0);
13244   }
13245 
13246   stmt= mysql_stmt_init(mysql1);
13247 
13248   /*
13249     The prepare of foo should fail with errno 1064 since
13250     it's not a valid query
13251   */
13252   rc= mysql_stmt_prepare(stmt, "foo", 3);
13253   if (!opt_silent)
13254     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13255             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13256   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13257 
13258   /*
13259     Use the same stmt and reprepare with another query that
13260     suceeds
13261   */
13262   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13263   if (!opt_silent)
13264     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13265             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13266   DIE_UNLESS(!rc || mysql_stmt_errno(stmt) || mysql_errno(mysql1));
13267 
13268   mysql_stmt_close(stmt);
13269   DIE_UNLESS(!mysql_errno(mysql1));
13270 
13271   /*
13272     part2, when connection to server has been closed
13273     after first prepare
13274   */
13275   stmt= mysql_stmt_init(mysql1);
13276   rc= mysql_stmt_prepare(stmt, "foo", 3);
13277   if (!opt_silent)
13278     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13279             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13280   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13281 
13282   /* Close connection to server */
13283   mysql_close(mysql1);
13284 
13285   /*
13286     Use the same stmt and reprepare with another query that
13287     suceeds. The prepare should fail with error 2013 since
13288     connection to server has been closed.
13289   */
13290   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13291   if (!opt_silent)
13292     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d\n",
13293             rc, mysql_stmt_errno(stmt));
13294   DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13295 
13296   mysql_stmt_close(stmt);
13297 }
13298 
13299 
disable_query_logs()13300 static void disable_query_logs()
13301 {
13302   int rc;
13303   rc= mysql_query(mysql, "set @@global.general_log=off");
13304   myquery(rc);
13305   rc= mysql_query(mysql, "set @@global.slow_query_log=off");
13306   myquery(rc);
13307 }
13308 
13309 
enable_query_logs(int truncate)13310 static void enable_query_logs(int truncate)
13311 {
13312   int rc;
13313 
13314   rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
13315   myquery(rc);
13316 
13317   rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log");
13318   myquery(rc);
13319 
13320   rc= mysql_query(mysql, "set @@global.general_log=on");
13321   myquery(rc);
13322 
13323   rc= mysql_query(mysql, "set @@global.slow_query_log=on");
13324   myquery(rc);
13325 
13326 
13327   if (truncate)
13328   {
13329     rc= mysql_query(mysql, "truncate mysql.general_log");
13330     myquery(rc);
13331 
13332     rc= mysql_query(mysql, "truncate mysql.slow_log");
13333     myquery(rc);
13334   }
13335 }
13336 
13337 
restore_query_logs()13338 static void restore_query_logs()
13339 {
13340   int rc;
13341   rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
13342   myquery(rc);
13343 
13344   rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log");
13345   myquery(rc);
13346 }
13347 
13348 
test_view_sp_list_fields()13349 static void test_view_sp_list_fields()
13350 {
13351   int		rc;
13352   MYSQL_RES     *res;
13353 
13354   myheader("test_view_sp_list_fields");
13355 
13356   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
13357   myquery(rc);
13358   rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
13359   myquery(rc);
13360   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
13361   myquery(rc);
13362   rc= mysql_query(mysql, "create function f1 () returns int return 5");
13363   myquery(rc);
13364   rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
13365   myquery(rc);
13366   rc= mysql_query(mysql, "create table t2 (s1 int);");
13367   myquery(rc);
13368   rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
13369 count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
13370 from t2);");
13371   myquery(rc);
13372   res= mysql_list_fields(mysql, "v1", NullS);
13373   DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0);
13374   rc= mysql_query(mysql, "DROP FUNCTION f1");
13375   myquery(rc);
13376   rc= mysql_query(mysql, "DROP VIEW v1");
13377   myquery(rc);
13378   rc= mysql_query(mysql, "DROP TABLE t1, t2");
13379   mysql_free_result(res);
13380   myquery(rc);
13381 
13382 }
13383 
13384 
13385 /*
13386  Test mysql_real_escape_string() with gbk charset
13387 
13388  The important part is that 0x27 (') is the second-byte in a invalid
13389  two-byte GBK character here. But 0xbf5c is a valid GBK character, so
13390  it needs to be escaped as 0x5cbf27
13391 */
13392 #define TEST_BUG8378_IN  "\xef\xbb\xbf\x27\xbf\x10"
13393 #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
13394 
test_bug8378()13395 static void test_bug8378()
13396 {
13397 #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
13398   MYSQL *lmysql;
13399   char out[9]; /* strlen(TEST_BUG8378)*2+1 */
13400   char buf[256];
13401   int len, rc;
13402 
13403   myheader("test_bug8378");
13404 
13405   if (!opt_silent)
13406     fprintf(stdout, "\n Establishing a test connection ...");
13407   if (!(lmysql= mysql_client_init(NULL)))
13408   {
13409     myerror("mysql_client_init() failed");
13410     exit(1);
13411   }
13412   if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
13413   {
13414     myerror("mysql_options() failed");
13415     exit(1);
13416   }
13417   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
13418                            opt_password, current_db, opt_port,
13419                            opt_unix_socket, 0)))
13420   {
13421     myerror("connection failed");
13422     exit(1);
13423   }
13424   if (!opt_silent)
13425     fprintf(stdout, "OK");
13426 
13427   rc= mysql_query(lmysql, "SET SQL_MODE=''");
13428   myquery(rc);
13429 
13430   len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4);
13431 
13432   /* No escaping should have actually happened. */
13433   DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
13434 
13435   sprintf(buf, "SELECT '%s'", out);
13436 
13437   rc=mysql_real_query(lmysql, buf, strlen(buf));
13438   myquery(rc);
13439 
13440   mysql_close(lmysql);
13441 #endif
13442 }
13443 
13444 
test_bug8722()13445 static void test_bug8722()
13446 {
13447   MYSQL_STMT *stmt;
13448   int rc;
13449   const char *stmt_text;
13450 
13451   myheader("test_bug8722");
13452   /* Prepare test data */
13453   stmt_text= "drop table if exists t1, v1";
13454   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13455   myquery(rc);
13456   stmt_text= "CREATE TABLE t1 (c1 varchar(10), c2 varchar(10), c3 varchar(10),"
13457                              " c4 varchar(10), c5 varchar(10), c6 varchar(10),"
13458                              " c7 varchar(10), c8 varchar(10), c9 varchar(10),"
13459                              "c10 varchar(10))";
13460   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13461   myquery(rc);
13462   stmt_text= "INSERT INTO t1 VALUES (1,2,3,4,5,6,7,8,9,10)";
13463   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13464   myquery(rc);
13465   stmt_text= "CREATE VIEW v1 AS SELECT * FROM t1";
13466   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13467   myquery(rc);
13468   /* Note: if you uncomment following block everything works fine */
13469 /*
13470   rc= mysql_query(mysql, "sellect * from v1");
13471   myquery(rc);
13472   mysql_free_result(mysql_store_result(mysql));
13473 */
13474 
13475   stmt= mysql_stmt_init(mysql);
13476   stmt_text= "select * from v1";
13477   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13478   check_execute(stmt, rc);
13479   mysql_stmt_close(stmt);
13480   stmt_text= "drop table if exists t1, v1";
13481   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13482   myquery(rc);
13483 }
13484 
13485 
open_cursor(const char * query)13486 MYSQL_STMT *open_cursor(const char *query)
13487 {
13488   int rc;
13489   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
13490 
13491   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
13492   rc= mysql_stmt_prepare(stmt, query, strlen(query));
13493   check_execute(stmt, rc);
13494 
13495   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13496   return stmt;
13497 }
13498 
13499 
test_bug8880()13500 static void test_bug8880()
13501 {
13502   MYSQL_STMT *stmt_list[2], **stmt;
13503   MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
13504   int rc;
13505 
13506   myheader("test_bug8880");
13507 
13508   mysql_query(mysql, "drop table if exists t1");
13509   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13510   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13511   myquery(rc);                                  /* one check is enough */
13512   /*
13513     when inserting 2 rows everything works well
13514     mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
13515   */
13516   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13517     *stmt= open_cursor("select a from t1");
13518   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13519   {
13520     rc= mysql_stmt_execute(*stmt);
13521     check_execute(*stmt, rc);
13522   }
13523   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13524     mysql_stmt_close(*stmt);
13525 }
13526 
13527 /*
13528   Test executing a query with prepared statements while query cache is active
13529 */
13530 
test_open_cursor_prepared_statement_query_cache()13531 static void test_open_cursor_prepared_statement_query_cache()
13532 {
13533   MYSQL_STMT *stmt;
13534   int rc;
13535   MYSQL_RES *result;
13536 
13537   myheader("test_open_cursor_prepared_statement_query_cache");
13538   if (! is_query_cache_available())
13539   {
13540     fprintf(stdout, "Skipping test_open_cursor_prepared_statement_query_cache: Query cache not available.\n");
13541     return;
13542   }
13543 
13544   rc= mysql_query(mysql,
13545                   "set @save_query_cache_type="
13546                   "@@global.query_cache_type,"
13547                   "@save_query_cache_size="
13548                   "@@global.query_cache_size");
13549   myquery(rc);
13550   rc= mysql_query(mysql, "set global query_cache_type=ON");
13551   myquery(rc);
13552   rc= mysql_query(mysql, "set local query_cache_type=ON");
13553   myquery(rc);
13554   rc= mysql_query(mysql, "set global query_cache_size=1000000");
13555   myquery(rc);
13556 
13557   mysql_query(mysql, "drop table if exists t1");
13558   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13559   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13560   myquery(rc);                                  /* one check is enough */
13561 
13562   /* Store query in query cache */
13563   rc= mysql_query(mysql, "SELECT * FROM t1");
13564   myquery(rc);
13565   result= mysql_store_result(mysql);
13566   mytest(result);
13567   (void) my_process_result_set(result);
13568   mysql_free_result(result);
13569 
13570   /* Test using a cursor */
13571   stmt= open_cursor("select a from t1");
13572   rc= mysql_stmt_execute(stmt);
13573   check_execute(stmt, rc);
13574   mysql_stmt_close(stmt);
13575 
13576   rc= mysql_query(mysql, "set global query_cache_type=@save_query_cache_type");
13577   myquery(rc);
13578   rc= mysql_query(mysql, "set global query_cache_size=@save_query_cache_size");
13579   myquery(rc);
13580 }
13581 
13582 
test_bug9159()13583 static void test_bug9159()
13584 {
13585   MYSQL_STMT *stmt;
13586   int rc;
13587   const char *stmt_text= "select a, b from t1";
13588   const unsigned long type= CURSOR_TYPE_READ_ONLY;
13589 
13590   myheader("test_bug9159");
13591 
13592   mysql_query(mysql, "drop table if exists t1");
13593   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13594   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13595   myquery(rc);
13596 
13597   stmt= mysql_stmt_init(mysql);
13598   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13599   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
13600 
13601   mysql_stmt_execute(stmt);
13602   mysql_stmt_close(stmt);
13603   rc= mysql_query(mysql, "drop table if exists t1");
13604   myquery(rc);
13605 }
13606 
13607 
13608 /* Crash when opening a cursor to a query with DISTICNT and no key */
13609 
test_bug9520()13610 static void test_bug9520()
13611 {
13612   MYSQL_STMT *stmt;
13613   MYSQL_BIND my_bind[1];
13614   char a[6];
13615   ulong a_len;
13616   int rc, row_count= 0;
13617 
13618   myheader("test_bug9520");
13619 
13620   mysql_query(mysql, "drop table if exists t1");
13621   mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
13622                      " primary key (a, b, c))");
13623   rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
13624                   " ('a', 'b', 'c'), ('k', 'l', 'm')");
13625   myquery(rc);
13626 
13627   stmt= open_cursor("select distinct b from t1");
13628 
13629   /*
13630     Not crashes with:
13631     stmt= open_cursor("select distinct a from t1");
13632   */
13633 
13634   rc= mysql_stmt_execute(stmt);
13635   check_execute(stmt, rc);
13636 
13637   bzero((char*) my_bind, sizeof(my_bind));
13638   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13639   my_bind[0].buffer= (char*) a;
13640   my_bind[0].buffer_length= sizeof(a);
13641   my_bind[0].length= &a_len;
13642 
13643   mysql_stmt_bind_result(stmt, my_bind);
13644 
13645   while (!(rc= mysql_stmt_fetch(stmt)))
13646     row_count++;
13647 
13648   DIE_UNLESS(rc == MYSQL_NO_DATA);
13649 
13650   if (!opt_silent)
13651     printf("Fetched %d rows\n", row_count);
13652   DBUG_ASSERT(row_count == 3);
13653 
13654   mysql_stmt_close(stmt);
13655 
13656   rc= mysql_query(mysql, "drop table t1");
13657   myquery(rc);
13658 }
13659 
13660 
13661 /*
13662   We can't have more than one cursor open for a prepared statement.
13663   Test re-executions of a PS with cursor; mysql_stmt_reset must close
13664   the cursor attached to the statement, if there is one.
13665 */
13666 
test_bug9478()13667 static void test_bug9478()
13668 {
13669   MYSQL_STMT *stmt;
13670   MYSQL_BIND my_bind[1];
13671   char a[6];
13672   ulong a_len;
13673   int rc, i;
13674   DBUG_ENTER("test_bug9478");
13675 
13676   myheader("test_bug9478");
13677 
13678   mysql_query(mysql, "drop table if exists t1");
13679   mysql_query(mysql, "create table t1 (id integer not null primary key, "
13680                      " name varchar(20) not null)");
13681   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13682                          " (1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13683   myquery(rc);
13684 
13685   stmt= open_cursor("select name from t1 where id=2");
13686 
13687   bzero((char*) my_bind, sizeof(my_bind));
13688   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13689   my_bind[0].buffer= (char*) a;
13690   my_bind[0].buffer_length= sizeof(a);
13691   my_bind[0].length= &a_len;
13692   mysql_stmt_bind_result(stmt, my_bind);
13693 
13694   for (i= 0; i < 5; i++)
13695   {
13696     rc= mysql_stmt_execute(stmt);
13697     check_execute(stmt, rc);
13698     rc= mysql_stmt_fetch(stmt);
13699     check_execute(stmt, rc);
13700     if (!opt_silent && i == 0)
13701       printf("Fetched row: %s\n", a);
13702 
13703     /*
13704       The query above is a one-row result set. Therefore, there is no
13705       cursor associated with it, as the server won't bother with opening
13706       a cursor for a one-row result set. The first row was read from the
13707       server in the fetch above. But there is eof packet pending in the
13708       network. mysql_stmt_execute will flush the packet and successfully
13709       execute the statement.
13710     */
13711 
13712     rc= mysql_stmt_execute(stmt);
13713     check_execute(stmt, rc);
13714 
13715     rc= mysql_stmt_fetch(stmt);
13716     check_execute(stmt, rc);
13717     if (!opt_silent && i == 0)
13718       printf("Fetched row: %s\n", a);
13719     rc= mysql_stmt_fetch(stmt);
13720     DIE_UNLESS(rc == MYSQL_NO_DATA);
13721 
13722     {
13723       char buff[8];
13724       /* Fill in the fetch packet */
13725       int4store(buff, stmt->stmt_id);
13726       buff[4]= 1;                               /* prefetch rows */
13727       rc= mysql_stmt_fetch(stmt);
13728       DIE_UNLESS(rc);
13729       if (!opt_silent && i == 0)
13730         printf("Got error (as expected): %s\n", mysql_error(mysql));
13731     }
13732 
13733     rc= mysql_stmt_execute(stmt);
13734     check_execute(stmt, rc);
13735 
13736     rc= mysql_stmt_fetch(stmt);
13737     check_execute(stmt, rc);
13738     if (!opt_silent && i == 0)
13739       printf("Fetched row: %s\n", a);
13740 
13741     rc= mysql_stmt_reset(stmt);
13742     check_execute(stmt, rc);
13743     rc= mysql_stmt_fetch(stmt);
13744     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13745     if (!opt_silent && i == 0)
13746       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13747   }
13748   rc= mysql_stmt_close(stmt);
13749   DIE_UNLESS(rc == 0);
13750 
13751   /* Test the case with a server side cursor */
13752   stmt= open_cursor("select name from t1");
13753 
13754   mysql_stmt_bind_result(stmt, my_bind);
13755 
13756   for (i= 0; i < 5; i++)
13757   {
13758     DBUG_PRINT("loop",("i: %d", i));
13759     rc= mysql_stmt_execute(stmt);
13760     check_execute(stmt, rc);
13761     rc= mysql_stmt_fetch(stmt);
13762     check_execute(stmt, rc);
13763     if (!opt_silent && i == 0)
13764       printf("Fetched row: %s\n", a);
13765     rc= mysql_stmt_execute(stmt);
13766     check_execute(stmt, rc);
13767 
13768     while (! (rc= mysql_stmt_fetch(stmt)))
13769     {
13770       if (!opt_silent && i == 0)
13771         printf("Fetched row: %s\n", a);
13772     }
13773     DIE_UNLESS(rc == MYSQL_NO_DATA);
13774 
13775     rc= mysql_stmt_execute(stmt);
13776     check_execute(stmt, rc);
13777 
13778     rc= mysql_stmt_fetch(stmt);
13779     check_execute(stmt, rc);
13780     if (!opt_silent && i == 0)
13781       printf("Fetched row: %s\n", a);
13782 
13783     rc= mysql_stmt_reset(stmt);
13784     check_execute(stmt, rc);
13785     rc= mysql_stmt_fetch(stmt);
13786     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13787     if (!opt_silent && i == 0)
13788       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13789   }
13790 
13791   rc= mysql_stmt_close(stmt);
13792   DIE_UNLESS(rc == 0);
13793 
13794   rc= mysql_query(mysql, "drop table t1");
13795   myquery(rc);
13796   DBUG_VOID_RETURN;
13797 }
13798 
13799 
13800 /*
13801   Error message is returned for unsupported features.
13802   Test also cursors with non-default PREFETCH_ROWS
13803 */
13804 
test_bug9643()13805 static void test_bug9643()
13806 {
13807   MYSQL_STMT *stmt;
13808   MYSQL_BIND my_bind[1];
13809   int32 a;
13810   int rc;
13811   const char *stmt_text;
13812   int num_rows= 0;
13813   ulong type;
13814   ulong prefetch_rows= 5;
13815 
13816   myheader("test_bug9643");
13817 
13818   mysql_query(mysql, "drop table if exists t1");
13819   mysql_query(mysql, "create table t1 (id integer not null primary key)");
13820   rc= mysql_query(mysql, "insert into t1 (id) values "
13821                          " (1), (2), (3), (4), (5), (6), (7), (8), (9)");
13822   myquery(rc);
13823 
13824   stmt= mysql_stmt_init(mysql);
13825   /* Not implemented in 5.0 */
13826   type= (ulong) CURSOR_TYPE_SCROLLABLE;
13827   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13828   DIE_UNLESS(rc);
13829   if (! opt_silent)
13830     printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13831 
13832   type= (ulong) CURSOR_TYPE_READ_ONLY;
13833   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13834   check_execute(stmt, rc);
13835   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
13836                           (void*) &prefetch_rows);
13837   check_execute(stmt, rc);
13838   stmt_text= "select * from t1";
13839   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13840   check_execute(stmt, rc);
13841 
13842   bzero((char*) my_bind, sizeof(my_bind));
13843   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13844   my_bind[0].buffer= (void*) &a;
13845   my_bind[0].buffer_length= sizeof(a);
13846   mysql_stmt_bind_result(stmt, my_bind);
13847 
13848   rc= mysql_stmt_execute(stmt);
13849   check_execute(stmt, rc);
13850 
13851   while ((rc= mysql_stmt_fetch(stmt)) == 0)
13852     ++num_rows;
13853   DIE_UNLESS(num_rows == 9);
13854 
13855   rc= mysql_stmt_close(stmt);
13856   DIE_UNLESS(rc == 0);
13857 
13858   rc= mysql_query(mysql, "drop table t1");
13859   myquery(rc);
13860 }
13861 
13862 /*
13863   Bug#11111: fetch from view returns wrong data
13864 */
13865 
test_bug11111()13866 static void test_bug11111()
13867 {
13868   MYSQL_STMT    *stmt;
13869   MYSQL_BIND    my_bind[2];
13870   char          buf[2][20];
13871   ulong         len[2];
13872   int i;
13873   int rc;
13874   const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
13875 
13876   myheader("test_bug11111");
13877 
13878   rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
13879   myquery(rc);
13880   rc= mysql_query(mysql, "drop view if exists t1, t2, v1");
13881   myquery(rc);
13882   rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)");
13883   myquery(rc);
13884   rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)");
13885   myquery(rc);
13886   rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1");
13887   myquery(rc);
13888   rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)");
13889   myquery(rc);
13890   rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
13891   myquery(rc);
13892 
13893   stmt= mysql_stmt_init(mysql);
13894 
13895   mysql_stmt_prepare(stmt, query, strlen(query));
13896   mysql_stmt_execute(stmt);
13897 
13898   bzero((char*) my_bind, sizeof(my_bind));
13899   for (i=0; i < 2; i++)
13900   {
13901     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
13902     my_bind[i].buffer= (uchar* *)&buf[i];
13903     my_bind[i].buffer_length= 20;
13904     my_bind[i].length= &len[i];
13905   }
13906 
13907   rc= mysql_stmt_bind_result(stmt, my_bind);
13908   check_execute(stmt, rc);
13909 
13910   rc= mysql_stmt_fetch(stmt);
13911   check_execute(stmt, rc);
13912   if (!opt_silent)
13913     printf("return: %s", buf[1]);
13914   DIE_UNLESS(!strcmp(buf[1],"1"));
13915   mysql_stmt_close(stmt);
13916   rc= mysql_query(mysql, "drop view v1");
13917   myquery(rc);
13918   rc= mysql_query(mysql, "drop table t1, t2");
13919   myquery(rc);
13920 }
13921 
13922 /*
13923   Check that proper cleanups are done for prepared statement when
13924   fetching thorugh a cursor.
13925 */
13926 
test_bug10729()13927 static void test_bug10729()
13928 {
13929   MYSQL_STMT *stmt;
13930   MYSQL_BIND my_bind[1];
13931   char a[21];
13932   int rc;
13933   const char *stmt_text;
13934   int i= 0;
13935   const char *name_array[3]= { "aaa", "bbb", "ccc" };
13936   ulong type;
13937 
13938   myheader("test_bug10729");
13939 
13940   mysql_query(mysql, "drop table if exists t1");
13941   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13942                                       "name VARCHAR(20) NOT NULL)");
13943   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13944                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13945   myquery(rc);
13946 
13947   stmt= mysql_stmt_init(mysql);
13948 
13949   type= (ulong) CURSOR_TYPE_READ_ONLY;
13950   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13951   check_execute(stmt, rc);
13952   stmt_text= "select name from t1";
13953   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13954   check_execute(stmt, rc);
13955 
13956   bzero((char*) my_bind, sizeof(my_bind));
13957   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13958   my_bind[0].buffer= (void*) a;
13959   my_bind[0].buffer_length= sizeof(a);
13960   mysql_stmt_bind_result(stmt, my_bind);
13961 
13962   for (i= 0; i < 3; i++)
13963   {
13964     int row_no= 0;
13965     rc= mysql_stmt_execute(stmt);
13966     check_execute(stmt, rc);
13967     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13968     {
13969       DIE_UNLESS(strcmp(a, name_array[row_no]) == 0);
13970       if (!opt_silent)
13971         printf("%d: %s\n", row_no, a);
13972       ++row_no;
13973     }
13974     DIE_UNLESS(rc == MYSQL_NO_DATA);
13975   }
13976   rc= mysql_stmt_close(stmt);
13977   DIE_UNLESS(rc == 0);
13978 
13979   rc= mysql_query(mysql, "drop table t1");
13980   myquery(rc);
13981 }
13982 
13983 
13984 /*
13985   Check that mysql_next_result works properly in case when one of
13986   the statements used in a multi-statement query is erroneous
13987 */
13988 
test_bug9992()13989 static void test_bug9992()
13990 {
13991   MYSQL *mysql1;
13992   MYSQL_RES* res ;
13993   int   rc;
13994 
13995   myheader("test_bug9992");
13996 
13997   if (!opt_silent)
13998     printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
13999 
14000   mysql1= mysql_client_init(NULL);
14001 
14002   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
14003                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
14004                           CLIENT_MULTI_STATEMENTS))
14005   {
14006     fprintf(stderr, "Failed to connect to the database\n");
14007     DIE_UNLESS(0);
14008   }
14009 
14010 
14011   /* Sic: SHOW DATABASE is incorrect syntax. */
14012   rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;");
14013 
14014   if (rc)
14015   {
14016     fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1));
14017     DIE_UNLESS(0);
14018   }
14019 
14020   if (!opt_silent)
14021     printf("Testing mysql_store_result/mysql_next_result..\n");
14022 
14023   res= mysql_store_result(mysql1);
14024   DIE_UNLESS(res);
14025   mysql_free_result(res);
14026   rc= mysql_next_result(mysql1);
14027   DIE_UNLESS(rc == 1);                         /* Got errors, as expected */
14028 
14029   if (!opt_silent)
14030     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
14031             mysql_errno(mysql1), mysql_error(mysql1));
14032 
14033   mysql_close(mysql1);
14034 }
14035 
14036 /* Bug#10736: cursors and subqueries, memroot management */
14037 
test_bug10736()14038 static void test_bug10736()
14039 {
14040   MYSQL_STMT *stmt;
14041   MYSQL_BIND my_bind[1];
14042   char a[21];
14043   int rc;
14044   const char *stmt_text;
14045   int i= 0;
14046   ulong type;
14047 
14048   myheader("test_bug10736");
14049 
14050   mysql_query(mysql, "drop table if exists t1");
14051   mysql_query(mysql, "create table t1 (id integer not null primary key,"
14052                                       "name VARCHAR(20) NOT NULL)");
14053   rc= mysql_query(mysql, "insert into t1 (id, name) values "
14054                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
14055   myquery(rc);
14056 
14057   stmt= mysql_stmt_init(mysql);
14058 
14059   type= (ulong) CURSOR_TYPE_READ_ONLY;
14060   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
14061   check_execute(stmt, rc);
14062   stmt_text= "select name from t1 where name=(select name from t1 where id=2)";
14063   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14064   check_execute(stmt, rc);
14065 
14066   bzero((char*) my_bind, sizeof(my_bind));
14067   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14068   my_bind[0].buffer= (void*) a;
14069   my_bind[0].buffer_length= sizeof(a);
14070   mysql_stmt_bind_result(stmt, my_bind);
14071 
14072   for (i= 0; i < 3; i++)
14073   {
14074     int row_no= 0;
14075     rc= mysql_stmt_execute(stmt);
14076     check_execute(stmt, rc);
14077     while ((rc= mysql_stmt_fetch(stmt)) == 0)
14078     {
14079       if (!opt_silent)
14080         printf("%d: %s\n", row_no, a);
14081       ++row_no;
14082     }
14083     DIE_UNLESS(rc == MYSQL_NO_DATA);
14084   }
14085   rc= mysql_stmt_close(stmt);
14086   DIE_UNLESS(rc == 0);
14087 
14088   rc= mysql_query(mysql, "drop table t1");
14089   myquery(rc);
14090 }
14091 
14092 /* Bug#10794: cursors, packets out of order */
14093 
test_bug10794()14094 static void test_bug10794()
14095 {
14096   MYSQL_STMT *stmt, *stmt1;
14097   MYSQL_BIND my_bind[2];
14098   char a[21];
14099   int id_val;
14100   ulong a_len;
14101   int rc;
14102   const char *stmt_text;
14103   int i= 0;
14104   ulong type;
14105 
14106   myheader("test_bug10794");
14107 
14108   mysql_query(mysql, "drop table if exists t1");
14109   mysql_query(mysql, "create table t1 (id integer not null primary key,"
14110                                       "name varchar(20) not null)");
14111   stmt= mysql_stmt_init(mysql);
14112   stmt_text= "insert into t1 (id, name) values (?, ?)";
14113   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14114   check_execute(stmt, rc);
14115   bzero((char*) my_bind, sizeof(my_bind));
14116   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14117   my_bind[0].buffer= (void*) &id_val;
14118   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14119   my_bind[1].buffer= (void*) a;
14120   my_bind[1].length= &a_len;
14121   rc= mysql_stmt_bind_param(stmt, my_bind);
14122   check_execute(stmt, rc);
14123   for (i= 0; i < 42; i++)
14124   {
14125     id_val= (i+1)*10;
14126     sprintf(a, "a%d", i);
14127     a_len= strlen(a); /* safety against broken sprintf */
14128     rc= mysql_stmt_execute(stmt);
14129     check_execute(stmt, rc);
14130   }
14131   stmt_text= "select name from t1";
14132   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14133   type= (ulong) CURSOR_TYPE_READ_ONLY;
14134   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14135   stmt1= mysql_stmt_init(mysql);
14136   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14137   bzero((char*) my_bind, sizeof(my_bind));
14138   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14139   my_bind[0].buffer= (void*) a;
14140   my_bind[0].buffer_length= sizeof(a);
14141   my_bind[0].length= &a_len;
14142   rc= mysql_stmt_bind_result(stmt, my_bind);
14143   check_execute(stmt, rc);
14144   rc= mysql_stmt_execute(stmt);
14145   check_execute(stmt, rc);
14146   rc= mysql_stmt_fetch(stmt);
14147   check_execute(stmt, rc);
14148   if (!opt_silent)
14149     printf("Fetched row from stmt: %s\n", a);
14150   /* Don't optimize: an attribute of the original test case */
14151   mysql_stmt_free_result(stmt);
14152   mysql_stmt_reset(stmt);
14153   stmt_text= "select name from t1 where id=10";
14154   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14155   check_execute(stmt1, rc);
14156   rc= mysql_stmt_bind_result(stmt1, my_bind);
14157   check_execute(stmt1, rc);
14158   rc= mysql_stmt_execute(stmt1);
14159   while (1)
14160   {
14161     rc= mysql_stmt_fetch(stmt1);
14162     if (rc == MYSQL_NO_DATA)
14163     {
14164       if (!opt_silent)
14165         printf("End of data in stmt1\n");
14166       break;
14167     }
14168     check_execute(stmt1, rc);
14169     if (!opt_silent)
14170       printf("Fetched row from stmt1: %s\n", a);
14171   }
14172   mysql_stmt_close(stmt);
14173   mysql_stmt_close(stmt1);
14174 
14175   rc= mysql_query(mysql, "drop table t1");
14176   myquery(rc);
14177 }
14178 
14179 
14180 /* Bug#11172: cursors, crash on a fetch from a datetime column */
14181 
test_bug11172()14182 static void test_bug11172()
14183 {
14184   MYSQL_STMT *stmt;
14185   MYSQL_BIND bind_in[1], bind_out[2];
14186   MYSQL_TIME hired;
14187   int rc;
14188   const char *stmt_text;
14189   int i= 0, id;
14190   ulong type;
14191 
14192   myheader("test_bug11172");
14193 
14194   mysql_query(mysql, "drop table if exists t1");
14195   mysql_query(mysql, "create table t1 (id integer not null primary key,"
14196                                       "hired date not null)");
14197   rc= mysql_query(mysql,
14198                   "insert into t1 (id, hired) values (1, '1933-08-24'), "
14199                   "(2, '1965-01-01'), (3, '1949-08-17'), (4, '1945-07-07'), "
14200                   "(5, '1941-05-15'), (6, '1978-09-15'), (7, '1936-03-28')");
14201   myquery(rc);
14202   stmt= mysql_stmt_init(mysql);
14203   stmt_text= "SELECT id, hired FROM t1 WHERE hired=?";
14204   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14205   check_execute(stmt, rc);
14206 
14207   type= (ulong) CURSOR_TYPE_READ_ONLY;
14208   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14209 
14210   bzero((char*) bind_in, sizeof(bind_in));
14211   bzero((char*) bind_out, sizeof(bind_out));
14212   bzero((char*) &hired, sizeof(hired));
14213   hired.year= 1965;
14214   hired.month= 1;
14215   hired.day= 1;
14216   bind_in[0].buffer_type= MYSQL_TYPE_DATE;
14217   bind_in[0].buffer= (void*) &hired;
14218   bind_in[0].buffer_length= sizeof(hired);
14219   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
14220   bind_out[0].buffer= (void*) &id;
14221   bind_out[1]= bind_in[0];
14222 
14223   for (i= 0; i < 3; i++)
14224   {
14225     rc= mysql_stmt_bind_param(stmt, bind_in);
14226     check_execute(stmt, rc);
14227     rc= mysql_stmt_bind_result(stmt, bind_out);
14228     check_execute(stmt, rc);
14229     rc= mysql_stmt_execute(stmt);
14230     check_execute(stmt, rc);
14231     while ((rc= mysql_stmt_fetch(stmt)) == 0)
14232     {
14233       if (!opt_silent)
14234         printf("fetched data %d:%d-%d-%d\n", id,
14235                hired.year, hired.month, hired.day);
14236     }
14237     DIE_UNLESS(rc == MYSQL_NO_DATA);
14238     if (!mysql_stmt_free_result(stmt))
14239       mysql_stmt_reset(stmt);
14240   }
14241   mysql_stmt_close(stmt);
14242   mysql_rollback(mysql);
14243   mysql_rollback(mysql);
14244 
14245   rc= mysql_query(mysql, "drop table t1");
14246   myquery(rc);
14247 }
14248 
14249 
14250 /* Bug#11656: cursors, crash on a fetch from a query with distinct. */
14251 
test_bug11656()14252 static void test_bug11656()
14253 {
14254   MYSQL_STMT *stmt;
14255   MYSQL_BIND my_bind[2];
14256   int rc;
14257   const char *stmt_text;
14258   char buf[2][20];
14259   int i= 0;
14260   ulong type;
14261 
14262   myheader("test_bug11656");
14263 
14264   mysql_query(mysql, "drop table if exists t1");
14265 
14266   rc= mysql_query(mysql, "create table t1 ("
14267                   "server varchar(40) not null, "
14268                   "test_kind varchar(1) not null, "
14269                   "test_id varchar(30) not null , "
14270                   "primary key (server,test_kind,test_id))");
14271   myquery(rc);
14272 
14273   stmt_text= "select distinct test_kind, test_id from t1 "
14274              "where server in (?, ?)";
14275   stmt= mysql_stmt_init(mysql);
14276   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14277   check_execute(stmt, rc);
14278   type= (ulong) CURSOR_TYPE_READ_ONLY;
14279   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14280 
14281   bzero((char*) my_bind, sizeof(my_bind));
14282   strmov(buf[0], "pcint502_MY2");
14283   strmov(buf[1], "*");
14284   for (i=0; i < 2; i++)
14285   {
14286     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
14287     my_bind[i].buffer= (uchar* *)&buf[i];
14288     my_bind[i].buffer_length= strlen(buf[i]);
14289   }
14290   mysql_stmt_bind_param(stmt, my_bind);
14291 
14292   rc= mysql_stmt_execute(stmt);
14293   check_execute(stmt, rc);
14294 
14295   rc= mysql_stmt_fetch(stmt);
14296   DIE_UNLESS(rc == MYSQL_NO_DATA);
14297 
14298   mysql_stmt_close(stmt);
14299   rc= mysql_query(mysql, "drop table t1");
14300   myquery(rc);
14301 }
14302 
14303 
14304 /*
14305   Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
14306   and mysql_real_escape_string() does the right thing as a result.
14307 */
14308 
test_bug10214()14309 static void test_bug10214()
14310 {
14311   int   len;
14312   char  out[8];
14313 
14314   myheader("test_bug10214");
14315 
14316   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
14317 
14318   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14319   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14320 
14321   mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
14322   DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
14323 
14324   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14325   DIE_UNLESS(memcmp(out, "a''b\\c", len) == 0);
14326 
14327   mysql_query(mysql, "set sql_mode=''");
14328 }
14329 
test_client_character_set()14330 static void test_client_character_set()
14331 {
14332   MY_CHARSET_INFO cs;
14333   char *csname= (char*) "utf8";
14334   char *csdefault= (char*)mysql_character_set_name(mysql);
14335   int rc;
14336 
14337   myheader("test_client_character_set");
14338 
14339   rc= mysql_set_character_set(mysql, csname);
14340   DIE_UNLESS(rc == 0);
14341 
14342   mysql_get_character_set_info(mysql, &cs);
14343   DIE_UNLESS(!strcmp(cs.csname, "utf8"));
14344   DIE_UNLESS(!strcmp(cs.name, "utf8_general_ci"));
14345   /* Restore the default character set */
14346   rc= mysql_set_character_set(mysql, csdefault);
14347   myquery(rc);
14348 }
14349 
14350 /* Test correct max length for MEDIUMTEXT and LONGTEXT columns */
14351 
test_bug9735()14352 static void test_bug9735()
14353 {
14354   MYSQL_RES *res;
14355   int rc;
14356 
14357   myheader("test_bug9735");
14358 
14359   rc= mysql_query(mysql, "drop table if exists t1");
14360   myquery(rc);
14361   rc= mysql_query(mysql, "create table t1 (a mediumtext, b longtext) "
14362                          "character set latin1");
14363   myquery(rc);
14364   rc= mysql_query(mysql, "select * from t1");
14365   myquery(rc);
14366   res= mysql_store_result(mysql);
14367   verify_prepare_field(res, 0, "a", "a", MYSQL_TYPE_BLOB,
14368                        "t1", "t1", current_db, (1U << 24)-1, 0);
14369   verify_prepare_field(res, 1, "b", "b", MYSQL_TYPE_BLOB,
14370                        "t1", "t1", current_db, ~0U, 0);
14371   mysql_free_result(res);
14372   rc= mysql_query(mysql, "drop table t1");
14373   myquery(rc);
14374 }
14375 
14376 
14377 /* Bug#11183 "mysql_stmt_reset() doesn't reset information about error" */
14378 
test_bug11183()14379 static void test_bug11183()
14380 {
14381   int rc;
14382   MYSQL_STMT *stmt;
14383   char bug_statement[]= "insert into t1 values (1)";
14384 
14385   myheader("test_bug11183");
14386 
14387   mysql_query(mysql, "drop table t1 if exists");
14388   mysql_query(mysql, "create table t1 (a int)");
14389 
14390   stmt= mysql_stmt_init(mysql);
14391   DIE_UNLESS(stmt != 0);
14392 
14393   rc= mysql_stmt_prepare(stmt, bug_statement, strlen(bug_statement));
14394   check_execute(stmt, rc);
14395 
14396   rc= mysql_query(mysql, "drop table t1");
14397   myquery(rc);
14398 
14399   /* Trying to execute statement that should fail on execute stage */
14400   rc= mysql_stmt_execute(stmt);
14401   DIE_UNLESS(rc);
14402 
14403   mysql_stmt_reset(stmt);
14404   DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14405 
14406   mysql_query(mysql, "create table t1 (a int)");
14407 
14408   /* Trying to execute statement that should pass ok */
14409   if (mysql_stmt_execute(stmt))
14410   {
14411     mysql_stmt_reset(stmt);
14412     DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14413   }
14414 
14415   mysql_stmt_close(stmt);
14416 
14417   rc= mysql_query(mysql, "drop table t1");
14418   myquery(rc);
14419 }
14420 
test_bug11037()14421 static void test_bug11037()
14422 {
14423   MYSQL_STMT *stmt;
14424   int rc;
14425   const char *stmt_text;
14426 
14427   myheader("test_bug11037");
14428 
14429   mysql_query(mysql, "drop table if exists t1");
14430 
14431   rc= mysql_query(mysql, "create table t1 (id int not null)");
14432   myquery(rc);
14433 
14434   rc= mysql_query(mysql, "insert into t1 values (1)");
14435   myquery(rc);
14436 
14437   stmt_text= "select id FROM t1";
14438   stmt= mysql_stmt_init(mysql);
14439   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14440 
14441   /* expected error */
14442   rc = mysql_stmt_fetch(stmt);
14443   DIE_UNLESS(rc==1);
14444   if (!opt_silent)
14445     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
14446             mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
14447 
14448   rc= mysql_stmt_execute(stmt);
14449   check_execute(stmt, rc);
14450 
14451   rc= mysql_stmt_fetch(stmt);
14452   DIE_UNLESS(rc==0);
14453 
14454   rc= mysql_stmt_fetch(stmt);
14455   DIE_UNLESS(rc==MYSQL_NO_DATA);
14456 
14457   rc= mysql_stmt_fetch(stmt);
14458   DIE_UNLESS(rc==MYSQL_NO_DATA);
14459 
14460   mysql_stmt_close(stmt);
14461   rc= mysql_query(mysql, "drop table t1");
14462   myquery(rc);
14463 }
14464 
14465 /* Bug#10760: cursors, crash in a fetch after rollback. */
14466 
test_bug10760()14467 static void test_bug10760()
14468 {
14469   MYSQL_STMT *stmt;
14470   MYSQL_BIND my_bind[1];
14471   int rc;
14472   const char *stmt_text;
14473   char id_buf[20];
14474   ulong id_len;
14475   int i= 0;
14476   ulong type;
14477 
14478   myheader("test_bug10760");
14479 
14480   mysql_query(mysql, "drop table if exists t1, t2");
14481 
14482   /* create tables */
14483   rc= mysql_query(mysql, "create table t1 (id integer not null primary key)"
14484                          " engine=MyISAM");
14485   myquery(rc);
14486   for (; i < 42; ++i)
14487   {
14488     char buf[100];
14489     sprintf(buf, "insert into t1 (id) values (%d)", i+1);
14490     rc= mysql_query(mysql, buf);
14491     myquery(rc);
14492   }
14493   mysql_autocommit(mysql, FALSE);
14494   /* create statement */
14495   stmt= mysql_stmt_init(mysql);
14496   type= (ulong) CURSOR_TYPE_READ_ONLY;
14497   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14498 
14499   /*
14500     1: check that a deadlock within the same connection
14501     is resolved and an error is returned. The deadlock is modelled
14502     as follows:
14503     con1: open cursor for select * from t1;
14504     con1: insert into t1 (id) values (1)
14505   */
14506   stmt_text= "select id from t1 order by 1";
14507   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14508   check_execute(stmt, rc);
14509   rc= mysql_stmt_execute(stmt);
14510   check_execute(stmt, rc);
14511   rc= mysql_query(mysql, "update t1 set id=id+100");
14512   /*
14513     If cursors are not materialized, the update will return an error;
14514     we mainly test that it won't deadlock.
14515   */
14516   if (rc && !opt_silent)
14517     printf("Got error (as expected): %s\n", mysql_error(mysql));
14518   /*
14519     2: check that MyISAM tables used in cursors survive
14520     COMMIT/ROLLBACK.
14521   */
14522   rc= mysql_rollback(mysql);                  /* should not close the cursor */
14523   myquery(rc);
14524   rc= mysql_stmt_fetch(stmt);
14525   check_execute(stmt, rc);
14526 
14527   /*
14528     3: check that cursors to InnoDB tables are closed (for now) by
14529     COMMIT/ROLLBACK.
14530   */
14531   if (! have_innodb)
14532   {
14533     if (!opt_silent)
14534       printf("Testing that cursors are closed at COMMIT/ROLLBACK requires "
14535              "InnoDB.\n");
14536   }
14537   else
14538   {
14539     stmt_text= "select id from t1 order by 1";
14540     rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14541     check_execute(stmt, rc);
14542 
14543     rc= mysql_query(mysql, "alter table t1 engine=InnoDB");
14544     myquery(rc);
14545 
14546     bzero(my_bind, sizeof(my_bind));
14547     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14548     my_bind[0].buffer= (void*) id_buf;
14549     my_bind[0].buffer_length= sizeof(id_buf);
14550     my_bind[0].length= &id_len;
14551     check_execute(stmt, rc);
14552     mysql_stmt_bind_result(stmt, my_bind);
14553 
14554     rc= mysql_stmt_execute(stmt);
14555     rc= mysql_stmt_fetch(stmt);
14556     DIE_UNLESS(rc == 0);
14557     if (!opt_silent)
14558       printf("Fetched row %s\n", id_buf);
14559     rc= mysql_rollback(mysql);                  /* should close the cursor */
14560     myquery(rc);
14561 #if 0
14562     rc= mysql_stmt_fetch(stmt);
14563     DIE_UNLESS(rc);
14564     if (!opt_silent)
14565       printf("Got error (as expected): %s\n", mysql_error(mysql));
14566 #endif
14567   }
14568 
14569   mysql_stmt_close(stmt);
14570   rc= mysql_query(mysql, "drop table t1");
14571   myquery(rc);
14572   mysql_autocommit(mysql, TRUE);                /* restore default */
14573 }
14574 
test_bug12001()14575 static void test_bug12001()
14576 {
14577   MYSQL *mysql_local;
14578   MYSQL_RES *result;
14579   const char *query= "DROP TABLE IF EXISTS test_table;"
14580                      "CREATE TABLE test_table(id INT);"
14581                      "INSERT INTO test_table VALUES(10);"
14582                      "UPDATE test_table SET id=20 WHERE id=10;"
14583                      "SELECT * FROM test_table;"
14584                      "INSERT INTO non_existent_table VALUES(11);";
14585   int rc, res;
14586 
14587   myheader("test_bug12001");
14588 
14589   if (!(mysql_local= mysql_client_init(NULL)))
14590   {
14591     fprintf(stdout, "\n mysql_client_init() failed");
14592     exit(1);
14593   }
14594 
14595   /* Create connection that supports multi statements */
14596   if (!mysql_real_connect(mysql_local, opt_host, opt_user,
14597                           opt_password, current_db, opt_port,
14598                           opt_unix_socket, CLIENT_MULTI_STATEMENTS))
14599   {
14600     fprintf(stdout, "\n mysql_real_connect() failed");
14601     exit(1);
14602   }
14603 
14604   rc= mysql_query(mysql_local, query);
14605   myquery(rc);
14606 
14607   do
14608   {
14609     if (mysql_field_count(mysql_local) &&
14610         (result= mysql_use_result(mysql_local)))
14611     {
14612       mysql_free_result(result);
14613     }
14614   }
14615   while (!(res= mysql_next_result(mysql_local)));
14616 
14617   rc= mysql_query(mysql_local, "DROP TABLE IF EXISTS test_table");
14618   myquery(rc);
14619 
14620   mysql_close(mysql_local);
14621   DIE_UNLESS(res==1);
14622 }
14623 
14624 
14625 /* Bug#11909: wrong metadata if fetching from two cursors */
14626 
test_bug11909()14627 static void test_bug11909()
14628 {
14629   MYSQL_STMT *stmt1, *stmt2;
14630   MYSQL_BIND my_bind[7];
14631   int rc;
14632   char firstname[20], midinit[20], lastname[20], workdept[20];
14633   ulong firstname_len, midinit_len, lastname_len, workdept_len;
14634   uint32 empno;
14635   double salary;
14636   float bonus;
14637   const char *stmt_text;
14638 
14639   myheader("test_bug11909");
14640 
14641   stmt_text= "drop table if exists t1";
14642   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14643   myquery(rc);
14644 
14645   stmt_text= "create table t1 ("
14646     "  empno int(11) not null, firstname varchar(20) not null,"
14647     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14648     "  workdept varchar(6) not null, salary double not null,"
14649     "  bonus float not null, primary key (empno)"
14650     ") default charset=latin1 collate=latin1_bin";
14651   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14652   myquery(rc);
14653 
14654   stmt_text= "insert into t1 values "
14655     "(10, 'CHRISTINE', 'I', 'HAAS',     'A00', 52750, 1000), "
14656     "(20, 'MICHAEL',   'L', 'THOMPSON', 'B01', 41250, 800),"
14657     "(30, 'SALLY',     'A', 'KWAN',     'C01', 38250, 800),"
14658     "(50, 'JOHN',      'B', 'GEYER',    'E01', 40175, 800), "
14659     "(60, 'IRVING',    'F', 'STERN',    'D11', 32250, 500)";
14660   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14661   myquery(rc);
14662 
14663   /* ****** Begin of trace ****** */
14664 
14665   stmt1= open_cursor("SELECT empno, firstname, midinit, lastname,"
14666                      "workdept, salary, bonus FROM t1");
14667 
14668   bzero(my_bind, sizeof(my_bind));
14669   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14670   my_bind[0].buffer= (void*) &empno;
14671 
14672   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14673   my_bind[1].buffer= (void*) firstname;
14674   my_bind[1].buffer_length= sizeof(firstname);
14675   my_bind[1].length= &firstname_len;
14676 
14677   my_bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;
14678   my_bind[2].buffer= (void*) midinit;
14679   my_bind[2].buffer_length= sizeof(midinit);
14680   my_bind[2].length= &midinit_len;
14681 
14682   my_bind[3].buffer_type= MYSQL_TYPE_VAR_STRING;
14683   my_bind[3].buffer= (void*) lastname;
14684   my_bind[3].buffer_length= sizeof(lastname);
14685   my_bind[3].length= &lastname_len;
14686 
14687   my_bind[4].buffer_type= MYSQL_TYPE_VAR_STRING;
14688   my_bind[4].buffer= (void*) workdept;
14689   my_bind[4].buffer_length= sizeof(workdept);
14690   my_bind[4].length= &workdept_len;
14691 
14692   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
14693   my_bind[5].buffer= (void*) &salary;
14694 
14695   my_bind[6].buffer_type= MYSQL_TYPE_FLOAT;
14696   my_bind[6].buffer= (void*) &bonus;
14697   rc= mysql_stmt_bind_result(stmt1, my_bind);
14698   check_execute(stmt1, rc);
14699 
14700   rc= mysql_stmt_execute(stmt1);
14701   check_execute(stmt1, rc);
14702 
14703   rc= mysql_stmt_fetch(stmt1);
14704   DIE_UNLESS(rc == 0);
14705   DIE_UNLESS(empno == 10);
14706   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14707   DIE_UNLESS(strcmp(midinit, "I") == 0);
14708   DIE_UNLESS(strcmp(lastname, "HAAS") == 0);
14709   DIE_UNLESS(strcmp(workdept, "A00") == 0);
14710   DIE_UNLESS(salary == (double) 52750.0);
14711   DIE_UNLESS(bonus == (float) 1000.0);
14712 
14713   stmt2= open_cursor("SELECT empno, firstname FROM t1");
14714   rc= mysql_stmt_bind_result(stmt2, my_bind);
14715   check_execute(stmt2, rc);
14716 
14717   rc= mysql_stmt_execute(stmt2);
14718   check_execute(stmt2, rc);
14719 
14720   rc= mysql_stmt_fetch(stmt2);
14721   DIE_UNLESS(rc == 0);
14722 
14723   DIE_UNLESS(empno == 10);
14724   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14725 
14726   rc= mysql_stmt_reset(stmt2);
14727   check_execute(stmt2, rc);
14728 
14729   /* ERROR: next statement should return 0 */
14730 
14731   rc= mysql_stmt_fetch(stmt1);
14732   DIE_UNLESS(rc == 0);
14733 
14734   mysql_stmt_close(stmt1);
14735   mysql_stmt_close(stmt2);
14736   rc= mysql_rollback(mysql);
14737   myquery(rc);
14738 
14739   rc= mysql_query(mysql, "drop table t1");
14740   myquery(rc);
14741 }
14742 
14743 /* Cursors: opening a cursor to a compilicated query with ORDER BY */
14744 
test_bug11901()14745 static void test_bug11901()
14746 {
14747   MYSQL_STMT *stmt;
14748   MYSQL_BIND my_bind[2];
14749   int rc;
14750   char workdept[20];
14751   ulong workdept_len;
14752   uint32 empno;
14753   const char *stmt_text;
14754 
14755   myheader("test_bug11901");
14756 
14757   stmt_text= "drop table if exists t1, t2";
14758   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14759   myquery(rc);
14760 
14761   stmt_text= "create table t1 ("
14762     "  empno int(11) not null, firstname varchar(20) not null,"
14763     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14764     "  workdept varchar(6) not null, salary double not null,"
14765     "  bonus float not null, primary key (empno), "
14766     " unique key (workdept, empno) "
14767     ") default charset=latin1 collate=latin1_bin";
14768   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14769   myquery(rc);
14770 
14771   stmt_text= "insert into t1 values "
14772      "(10,  'CHRISTINE', 'I', 'HAAS',      'A00', 52750, 1000),"
14773      "(20,  'MICHAEL',   'L', 'THOMPSON',  'B01', 41250, 800), "
14774      "(30,  'SALLY',     'A', 'KWAN',      'C01', 38250, 800), "
14775      "(50,  'JOHN',      'B', 'GEYER',     'E01', 40175, 800), "
14776      "(60,  'IRVING',    'F', 'STERN',     'D11', 32250, 500), "
14777      "(70,  'EVA',       'D', 'PULASKI',   'D21', 36170, 700), "
14778      "(90,  'EILEEN',    'W', 'HENDERSON', 'E11', 29750, 600), "
14779      "(100, 'THEODORE',  'Q', 'SPENSER',   'E21', 26150, 500), "
14780      "(110, 'VINCENZO',  'G', 'LUCCHESSI', 'A00', 46500, 900), "
14781      "(120, 'SEAN',      '',  'O\\'CONNELL', 'A00', 29250, 600), "
14782      "(130, 'DOLORES',   'M', 'QUINTANA',  'C01', 23800, 500), "
14783      "(140, 'HEATHER',   'A', 'NICHOLLS',  'C01', 28420, 600), "
14784      "(150, 'BRUCE',     '',  'ADAMSON',   'D11', 25280, 500), "
14785      "(160, 'ELIZABETH', 'R', 'PIANKA',    'D11', 22250, 400), "
14786      "(170, 'MASATOSHI', 'J', 'YOSHIMURA', 'D11', 24680, 500), "
14787      "(180, 'MARILYN',   'S', 'SCOUTTEN',  'D11', 21340, 500), "
14788      "(190, 'JAMES',     'H', 'WALKER',    'D11', 20450, 400), "
14789      "(200, 'DAVID',     '',  'BROWN',     'D11', 27740, 600), "
14790      "(210, 'WILLIAM',   'T', 'JONES',     'D11', 18270, 400), "
14791      "(220, 'JENNIFER',  'K', 'LUTZ',      'D11', 29840, 600), "
14792      "(230, 'JAMES',     'J', 'JEFFERSON', 'D21', 22180, 400), "
14793      "(240, 'SALVATORE', 'M', 'MARINO',    'D21', 28760, 600), "
14794      "(250, 'DANIEL',    'S', 'SMITH',     'D21', 19180, 400), "
14795      "(260, 'SYBIL',     'P', 'JOHNSON',   'D21', 17250, 300), "
14796      "(270, 'MARIA',     'L', 'PEREZ',     'D21', 27380, 500), "
14797      "(280, 'ETHEL',     'R', 'SCHNEIDER', 'E11', 26250, 500), "
14798      "(290, 'JOHN',      'R', 'PARKER',    'E11', 15340, 300), "
14799      "(300, 'PHILIP',    'X', 'SMITH',     'E11', 17750, 400), "
14800      "(310, 'MAUDE',     'F', 'SETRIGHT',  'E11', 15900, 300), "
14801      "(320, 'RAMLAL',    'V', 'MEHTA',     'E21', 19950, 400), "
14802      "(330, 'WING',      '',  'LEE',       'E21', 25370, 500), "
14803      "(340, 'JASON',     'R', 'GOUNOT',    'E21', 23840, 500)";
14804 
14805   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14806   myquery(rc);
14807 
14808   stmt_text= "create table t2 ("
14809     " deptno varchar(6) not null, deptname varchar(20) not null,"
14810     " mgrno int(11) not null, location varchar(20) not null,"
14811     " admrdept varchar(6) not null, refcntd int(11) not null,"
14812     " refcntu int(11) not null, primary key (deptno)"
14813     ") default charset=latin1 collate=latin1_bin";
14814   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14815   myquery(rc);
14816 
14817   stmt_text= "insert into t2 values "
14818     "('A00', 'SPIFFY COMPUTER SERV', 10, '', 'A00', 0, 0), "
14819     "('B01', 'PLANNING',             20, '', 'A00', 0, 0), "
14820     "('C01', 'INFORMATION CENTER',   30, '', 'A00', 0, 0), "
14821     "('D01', 'DEVELOPMENT CENTER',   0,  '', 'A00', 0, 0),"
14822     "('D11', 'MANUFACTURING SYSTEM', 60, '', 'D01', 0, 0), "
14823     "('D21', 'ADMINISTRATION SYSTE', 70, '', 'D01', 0, 0), "
14824     "('E01', 'SUPPORT SERVICES',     50, '', 'A00', 0, 0), "
14825     "('E11', 'OPERATIONS',           90, '', 'E01', 0, 0), "
14826     "('E21', 'SOFTWARE SUPPORT',     100,'', 'E01', 0, 0)";
14827   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14828   myquery(rc);
14829 
14830   /* ****** Begin of trace ****** */
14831 
14832   stmt= open_cursor("select t1.empno, t1.workdept "
14833                     "from (t1 left join t2 on t2.deptno = t1.workdept) "
14834                     "where t2.deptno in "
14835                     "   (select t2.deptno "
14836                     "    from (t1 left join t2 on t2.deptno = t1.workdept) "
14837                     "    where t1.empno = ?) "
14838                     "order by 1");
14839   bzero(my_bind, sizeof(my_bind));
14840 
14841   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14842   my_bind[0].buffer= &empno;
14843   rc= mysql_stmt_bind_param(stmt, my_bind);
14844   check_execute(stmt, rc);
14845 
14846   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14847   my_bind[1].buffer= (void*) workdept;
14848   my_bind[1].buffer_length= sizeof(workdept);
14849   my_bind[1].length= &workdept_len;
14850 
14851   rc= mysql_stmt_bind_result(stmt, my_bind);
14852   check_execute(stmt, rc);
14853 
14854   empno= 10;
14855   /* ERROR: next statement causes a server crash */
14856   rc= mysql_stmt_execute(stmt);
14857   check_execute(stmt, rc);
14858 
14859   mysql_stmt_close(stmt);
14860 
14861   rc= mysql_query(mysql, "drop table t1, t2");
14862   myquery(rc);
14863 }
14864 
14865 /* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */
14866 
test_bug11904()14867 static void test_bug11904()
14868 {
14869   MYSQL_STMT *stmt1;
14870   int rc;
14871   const char *stmt_text;
14872   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
14873   MYSQL_BIND my_bind[2];
14874   int country_id=0;
14875   char row_data[11]= {0};
14876 
14877   myheader("test_bug11904");
14878 
14879   /* create tables */
14880   rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b");
14881   myquery(rc);
14882   rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))");
14883   myquery(rc);
14884 
14885   rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv'),"
14886                           " (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg'),"
14887                           " (3,'berlin'), (3, 'frankfurt')");
14888 
14889   myquery(rc);
14890   mysql_commit(mysql);
14891   /* create statement */
14892   stmt1= mysql_stmt_init(mysql);
14893   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14894 
14895   stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id";
14896 
14897   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14898   check_execute(stmt1, rc);
14899 
14900   memset(my_bind, 0, sizeof(my_bind));
14901   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14902   my_bind[0].buffer=& country_id;
14903   my_bind[0].buffer_length= 0;
14904   my_bind[0].length= 0;
14905 
14906   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14907   my_bind[1].buffer=& row_data;
14908   my_bind[1].buffer_length= sizeof(row_data) - 1;
14909   my_bind[1].length= 0;
14910 
14911   rc= mysql_stmt_bind_result(stmt1, my_bind);
14912   check_execute(stmt1, rc);
14913 
14914   rc= mysql_stmt_execute(stmt1);
14915   check_execute(stmt1, rc);
14916 
14917   rc= mysql_stmt_fetch(stmt1);
14918   check_execute(stmt1, rc);
14919   DIE_UNLESS(country_id == 1);
14920   DIE_UNLESS(memcmp(row_data, "plovdiv", 7) == 0);
14921 
14922   rc= mysql_stmt_fetch(stmt1);
14923   check_execute(stmt1, rc);
14924   DIE_UNLESS(country_id == 2);
14925   DIE_UNLESS(memcmp(row_data, "LA", 2) == 0);
14926 
14927   rc= mysql_stmt_fetch(stmt1);
14928   check_execute(stmt1, rc);
14929   DIE_UNLESS(country_id == 3);
14930   DIE_UNLESS(memcmp(row_data, "berlin", 6) == 0);
14931 
14932   rc= mysql_stmt_close(stmt1);
14933   check_execute(stmt1, rc);
14934 
14935   rc= mysql_query(mysql, "drop table bug11904b");
14936   myquery(rc);
14937 }
14938 
14939 
14940 /* Bug#12243: multiple cursors, crash in a fetch after commit. */
14941 
test_bug12243()14942 static void test_bug12243()
14943 {
14944   MYSQL_STMT *stmt1, *stmt2;
14945   int rc;
14946   const char *stmt_text;
14947   ulong type;
14948 
14949   myheader("test_bug12243");
14950 
14951   if (! have_innodb)
14952   {
14953     if (!opt_silent)
14954       printf("This test requires InnoDB.\n");
14955     return;
14956   }
14957 
14958   /* create tables */
14959   mysql_query(mysql, "drop table if exists t1");
14960   mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
14961   rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
14962   myquery(rc);
14963   mysql_autocommit(mysql, FALSE);
14964   /* create statement */
14965   stmt1= mysql_stmt_init(mysql);
14966   stmt2= mysql_stmt_init(mysql);
14967   type= (ulong) CURSOR_TYPE_READ_ONLY;
14968   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14969   mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14970 
14971   stmt_text= "select a from t1";
14972 
14973   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14974   check_execute(stmt1, rc);
14975   rc= mysql_stmt_execute(stmt1);
14976   check_execute(stmt1, rc);
14977   rc= mysql_stmt_fetch(stmt1);
14978   check_execute(stmt1, rc);
14979 
14980   rc= mysql_stmt_prepare(stmt2, stmt_text, strlen(stmt_text));
14981   check_execute(stmt2, rc);
14982   rc= mysql_stmt_execute(stmt2);
14983   check_execute(stmt2, rc);
14984   rc= mysql_stmt_fetch(stmt2);
14985   check_execute(stmt2, rc);
14986 
14987   rc= mysql_stmt_close(stmt1);
14988   check_execute(stmt1, rc);
14989   rc= mysql_commit(mysql);
14990   myquery(rc);
14991   rc= mysql_stmt_fetch(stmt2);
14992   check_execute(stmt2, rc);
14993 
14994   mysql_stmt_close(stmt2);
14995   rc= mysql_query(mysql, "drop table t1");
14996   myquery(rc);
14997   mysql_autocommit(mysql, TRUE);                /* restore default */
14998 }
14999 
15000 
15001 /*
15002   Bug#11718: query with function, join and order by returns wrong type
15003 */
15004 
test_bug11718()15005 static void test_bug11718()
15006 {
15007   MYSQL_RES	*res;
15008   int rc;
15009   const char *query= "select str_to_date(concat(f3),'%Y%m%d') from t1,t2 "
15010                      "where f1=f2 order by f1";
15011 
15012   myheader("test_bug11718");
15013 
15014   rc= mysql_query(mysql, "drop table if exists t1, t2");
15015   myquery(rc);
15016   rc= mysql_query(mysql, "create table t1 (f1 int)");
15017   myquery(rc);
15018   rc= mysql_query(mysql, "create table t2 (f2 int, f3 numeric(8))");
15019   myquery(rc);
15020   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
15021   myquery(rc);
15022   rc= mysql_query(mysql, "insert into t2 values (1,20050101), (2,20050202)");
15023   myquery(rc);
15024   rc= mysql_query(mysql, query);
15025   myquery(rc);
15026   res = mysql_store_result(mysql);
15027 
15028   if (!opt_silent)
15029     printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
15030            "not DATE");
15031   DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
15032   mysql_free_result(res);
15033   rc= mysql_query(mysql, "drop table t1, t2");
15034   myquery(rc);
15035 }
15036 
15037 
15038 /*
15039   Bug #12925: Bad handling of maximum values in getopt
15040 */
test_bug12925()15041 static void test_bug12925()
15042 {
15043   myheader("test_bug12925");
15044   if (opt_getopt_ll_test)
15045     DIE_UNLESS(opt_getopt_ll_test == 25600LL*1024*1024);
15046 }
15047 
15048 
15049 /*
15050   Bug#14210 "Simple query with > operator on large table gives server
15051   crash"
15052 */
15053 
test_bug14210()15054 static void test_bug14210()
15055 {
15056   MYSQL_STMT *stmt;
15057   int rc, i;
15058   const char *stmt_text;
15059   ulong type;
15060 
15061   myheader("test_bug14210");
15062 
15063   mysql_query(mysql, "drop table if exists t1");
15064   /*
15065     To trigger the problem the table must be InnoDB, although the problem
15066     itself is not InnoDB related. In case the table is MyISAM this test
15067     is harmless.
15068   */
15069   mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB");
15070   rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
15071   myquery(rc);
15072   rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
15073   /* Create a big enough table (more than max_heap_table_size) */
15074   for (i= 0; i < 8; i++)
15075   {
15076     rc= mysql_query(mysql, "insert into t1 (a) select a from t1");
15077     myquery(rc);
15078   }
15079   /* create statement */
15080   stmt= mysql_stmt_init(mysql);
15081   type= (ulong) CURSOR_TYPE_READ_ONLY;
15082   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15083 
15084   stmt_text= "select a from t1";
15085 
15086   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15087   check_execute(stmt, rc);
15088   rc= mysql_stmt_execute(stmt);
15089   while ((rc= mysql_stmt_fetch(stmt)) == 0)
15090     ;
15091   DIE_UNLESS(rc == MYSQL_NO_DATA);
15092 
15093   rc= mysql_stmt_close(stmt);
15094 
15095   rc= mysql_query(mysql, "drop table t1");
15096   myquery(rc);
15097   rc= mysql_query(mysql, "set @@session.max_heap_table_size=default");
15098   myquery(rc);
15099 }
15100 
15101 /* Bug#13488: wrong column metadata when fetching from cursor */
15102 
test_bug13488()15103 static void test_bug13488()
15104 {
15105   MYSQL_BIND my_bind[3];
15106   MYSQL_STMT *stmt1;
15107   int rc, f1, f2, f3, i;
15108   const ulong type= CURSOR_TYPE_READ_ONLY;
15109   const char *query= "select * from t1 left join t2 on f1=f2 where f1=1";
15110 
15111   myheader("test_bug13488");
15112 
15113   rc= mysql_query(mysql, "drop table if exists t1, t2");
15114   myquery(rc);
15115   rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)");
15116   myquery(rc);
15117   rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, "
15118                   "f3 int not null)");
15119   myquery(rc);
15120   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
15121   myquery(rc);
15122   rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)");
15123   myquery(rc);
15124 
15125   memset(my_bind, 0, sizeof(my_bind));
15126   for (i= 0; i < 3; i++)
15127   {
15128     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
15129     my_bind[i].buffer_length= 4;
15130     my_bind[i].length= 0;
15131   }
15132   my_bind[0].buffer=&f1;
15133   my_bind[1].buffer=&f2;
15134   my_bind[2].buffer=&f3;
15135 
15136   stmt1= mysql_stmt_init(mysql);
15137   rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type);
15138   check_execute(stmt1, rc);
15139 
15140   rc= mysql_stmt_prepare(stmt1, query, strlen(query));
15141   check_execute(stmt1, rc);
15142 
15143   rc= mysql_stmt_execute(stmt1);
15144   check_execute(stmt1, rc);
15145 
15146   rc= mysql_stmt_bind_result(stmt1, my_bind);
15147   check_execute(stmt1, rc);
15148 
15149   rc= mysql_stmt_fetch(stmt1);
15150   check_execute(stmt1, rc);
15151 
15152   rc= mysql_stmt_free_result(stmt1);
15153   check_execute(stmt1, rc);
15154 
15155   rc= mysql_stmt_reset(stmt1);
15156   check_execute(stmt1, rc);
15157 
15158   rc= mysql_stmt_close(stmt1);
15159   check_execute(stmt1, rc);
15160 
15161   if (!opt_silent)
15162   {
15163     printf("data: f1: %d; f2: %d; f3: %d\n", f1, f2, f3);
15164     printf("data is: %s\n",
15165            (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong");
15166   }
15167   DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
15168   rc= mysql_query(mysql, "drop table t1, t2");
15169   myquery(rc);
15170 }
15171 
15172 /*
15173   Bug#13524: warnings of a previous command are not reset when fetching
15174   from a cursor.
15175 */
15176 
test_bug13524()15177 static void test_bug13524()
15178 {
15179   MYSQL_STMT *stmt;
15180   int rc;
15181   unsigned int warning_count;
15182   const ulong type= CURSOR_TYPE_READ_ONLY;
15183   const char *query= "select * from t1";
15184 
15185   myheader("test_bug13524");
15186 
15187   rc= mysql_query(mysql, "drop table if exists t1, t2");
15188   myquery(rc);
15189   rc= mysql_query(mysql, "create table t1 (a int not null primary key)");
15190   myquery(rc);
15191   rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
15192   myquery(rc);
15193 
15194   stmt= mysql_stmt_init(mysql);
15195   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15196   check_execute(stmt, rc);
15197 
15198   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15199   check_execute(stmt, rc);
15200 
15201   rc= mysql_stmt_execute(stmt);
15202   check_execute(stmt, rc);
15203 
15204   rc= mysql_stmt_fetch(stmt);
15205   check_execute(stmt, rc);
15206 
15207   warning_count= mysql_warning_count(mysql);
15208   DIE_UNLESS(warning_count == 0);
15209 
15210   /* Check that DROP TABLE produced a warning (no such table) */
15211   rc= mysql_query(mysql, "drop table if exists t2");
15212   myquery(rc);
15213   warning_count= mysql_warning_count(mysql);
15214   DIE_UNLESS(warning_count == 1);
15215 
15216   /*
15217     Check that fetch from a cursor cleared the warning from the previous
15218     command.
15219   */
15220   rc= mysql_stmt_fetch(stmt);
15221   check_execute(stmt, rc);
15222   warning_count= mysql_warning_count(mysql);
15223   DIE_UNLESS(warning_count == 0);
15224 
15225   /* Cleanup */
15226   mysql_stmt_close(stmt);
15227   rc= mysql_query(mysql, "drop table t1");
15228   myquery(rc);
15229 }
15230 
15231 /*
15232   Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
15233 */
15234 
test_bug14845()15235 static void test_bug14845()
15236 {
15237   MYSQL_STMT *stmt;
15238   int rc;
15239   const ulong type= CURSOR_TYPE_READ_ONLY;
15240   const char *query= "select count(*) from t1 where 1 = 0";
15241 
15242   myheader("test_bug14845");
15243 
15244   rc= mysql_query(mysql, "drop table if exists t1");
15245   myquery(rc);
15246   rc= mysql_query(mysql, "create table t1 (id int(11) default null, "
15247                          "name varchar(20) default null)"
15248                          "engine=MyISAM DEFAULT CHARSET=utf8");
15249   myquery(rc);
15250   rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')");
15251   myquery(rc);
15252 
15253   stmt= mysql_stmt_init(mysql);
15254   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15255   check_execute(stmt, rc);
15256 
15257   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15258   check_execute(stmt, rc);
15259 
15260   rc= mysql_stmt_execute(stmt);
15261   check_execute(stmt, rc);
15262 
15263   rc= mysql_stmt_fetch(stmt);
15264   DIE_UNLESS(rc == 0);
15265 
15266   rc= mysql_stmt_fetch(stmt);
15267   DIE_UNLESS(rc == MYSQL_NO_DATA);
15268 
15269   /* Cleanup */
15270   mysql_stmt_close(stmt);
15271   rc= mysql_query(mysql, "drop table t1");
15272   myquery(rc);
15273 }
15274 
15275 
15276 /*
15277   Bug #15510: mysql_warning_count returns 0 after mysql_stmt_fetch which
15278   should warn
15279 */
test_bug15510()15280 static void test_bug15510()
15281 {
15282   MYSQL_STMT *stmt;
15283   int rc;
15284   const char *query= "select 1 from dual where 1/0";
15285 
15286   myheader("test_bug15510");
15287 
15288   rc= mysql_query(mysql, "set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'");
15289   myquery(rc);
15290 
15291   stmt= mysql_stmt_init(mysql);
15292 
15293   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15294   check_execute(stmt, rc);
15295 
15296   rc= mysql_stmt_execute(stmt);
15297   check_execute(stmt, rc);
15298 
15299   rc= mysql_stmt_fetch(stmt);
15300   DIE_UNLESS(mysql_warning_count(mysql));
15301 
15302   /* Cleanup */
15303   mysql_stmt_close(stmt);
15304   rc= mysql_query(mysql, "set @@sql_mode=''");
15305   myquery(rc);
15306 }
15307 
15308 
15309 /* Test MYSQL_OPT_RECONNECT, Bug#15719 */
15310 
test_opt_reconnect()15311 static void test_opt_reconnect()
15312 {
15313   MYSQL *lmysql;
15314 
15315 
15316   myheader("test_opt_reconnect");
15317 
15318   if (!(lmysql= mysql_client_init(NULL)))
15319   {
15320     myerror("mysql_client_init() failed");
15321     exit(1);
15322   }
15323 
15324   if (!opt_silent)
15325     fprintf(stdout, "reconnect before mysql_options: %d\n", get_reconnect(lmysql));
15326   DIE_UNLESS(get_reconnect(lmysql) == 0);
15327 
15328   if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
15329   {
15330     myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
15331     DIE_UNLESS(0);
15332   }
15333 
15334   /* reconnect should be 1 */
15335   if (!opt_silent)
15336     fprintf(stdout, "reconnect after mysql_options: %d\n", get_reconnect(lmysql));
15337   DIE_UNLESS(get_reconnect(lmysql) == 1);
15338 
15339   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15340                            opt_password, current_db, opt_port,
15341                            opt_unix_socket, 0)))
15342   {
15343     myerror("connection failed");
15344     DIE_UNLESS(0);
15345   }
15346 
15347   /* reconnect should still be 1 */
15348   if (!opt_silent)
15349     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15350 	    get_reconnect(lmysql));
15351   DIE_UNLESS(get_reconnect(lmysql) == 1);
15352 
15353   mysql_close(lmysql);
15354 
15355   if (!(lmysql= mysql_client_init(NULL)))
15356   {
15357     myerror("mysql_client_init() failed");
15358     DIE_UNLESS(0);
15359   }
15360 
15361   if (!opt_silent)
15362     fprintf(stdout, "reconnect before mysql_real_connect: %d\n", get_reconnect(lmysql));
15363   DIE_UNLESS(get_reconnect(lmysql) == 0);
15364 
15365   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15366                            opt_password, current_db, opt_port,
15367                            opt_unix_socket, 0)))
15368   {
15369     myerror("connection failed");
15370     DIE_UNLESS(0);
15371   }
15372 
15373   /* reconnect should still be 0 */
15374   if (!opt_silent)
15375     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15376 	    get_reconnect(lmysql));
15377   DIE_UNLESS(get_reconnect(lmysql) == 0);
15378 
15379   mysql_close(lmysql);
15380 }
15381 
15382 
15383 #ifndef EMBEDDED_LIBRARY
15384 
test_bug12744()15385 static void test_bug12744()
15386 {
15387   MYSQL_STMT *prep_stmt = NULL;
15388   MYSQL *lmysql;
15389   int rc;
15390   myheader("test_bug12744");
15391 
15392   lmysql= mysql_client_init(NULL);
15393   DIE_UNLESS(lmysql);
15394 
15395   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
15396                           current_db, opt_port, opt_unix_socket, 0))
15397   {
15398     fprintf(stderr, "Failed to connect to the database\n");
15399     DIE_UNLESS(0);
15400   }
15401 
15402   prep_stmt= mysql_stmt_init(lmysql);
15403   rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
15404   DIE_UNLESS(rc == 0);
15405 
15406   mysql_close(lmysql);
15407 
15408   rc= mysql_stmt_execute(prep_stmt);
15409   DIE_UNLESS(rc);
15410   rc= mysql_stmt_reset(prep_stmt);
15411   DIE_UNLESS(rc);
15412   rc= mysql_stmt_close(prep_stmt);
15413   DIE_UNLESS(rc == 0);
15414 }
15415 
15416 #endif /* EMBEDDED_LIBRARY */
15417 
15418 /* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
15419 
test_bug16143()15420 static void test_bug16143()
15421 {
15422   MYSQL_STMT *stmt;
15423   myheader("test_bug16143");
15424 
15425   stmt= mysql_stmt_init(mysql);
15426   /* Check mysql_stmt_sqlstate return "no error" */
15427   DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0);
15428 
15429   mysql_stmt_close(stmt);
15430 }
15431 
15432 
15433 /* Bug #16144: mysql_stmt_attr_get type error */
15434 
test_bug16144()15435 static void test_bug16144()
15436 {
15437   const my_bool flag_orig= (my_bool) 0xde;
15438   my_bool flag= flag_orig;
15439   MYSQL_STMT *stmt;
15440   myheader("test_bug16144");
15441 
15442   /* Check that attr_get returns correct data on little and big endian CPUs */
15443   stmt= mysql_stmt_init(mysql);
15444   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
15445   mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
15446   DIE_UNLESS(flag == flag_orig);
15447 
15448   mysql_stmt_close(stmt);
15449 }
15450 
15451 /*
15452   Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
15453   field length"
15454 */
15455 
test_bug15613()15456 static void test_bug15613()
15457 {
15458   MYSQL_STMT *stmt;
15459   const char *stmt_text;
15460   MYSQL_RES *metadata;
15461   MYSQL_FIELD *field;
15462   int rc;
15463   myheader("test_bug15613");
15464 
15465   /* I. Prepare the table */
15466   rc= mysql_query(mysql, "set names latin1");
15467   myquery(rc);
15468   mysql_query(mysql, "drop table if exists t1");
15469   rc= mysql_query(mysql,
15470                   "create table t1 (t text character set utf8, "
15471                                    "tt tinytext character set utf8, "
15472                                    "mt mediumtext character set utf8, "
15473                                    "lt longtext character set utf8, "
15474                                    "vl varchar(255) character set latin1,"
15475                                    "vb varchar(255) character set binary,"
15476                                    "vu varchar(255) character set utf8)");
15477   myquery(rc);
15478 
15479   stmt= mysql_stmt_init(mysql);
15480 
15481   /* II. Check SELECT metadata */
15482   stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
15483   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15484   metadata= mysql_stmt_result_metadata(stmt);
15485   field= mysql_fetch_fields(metadata);
15486   if (!opt_silent)
15487   {
15488     printf("Field lengths (client character set is latin1):\n"
15489            "text character set utf8:\t\t%lu\n"
15490            "tinytext character set utf8:\t\t%lu\n"
15491            "mediumtext character set utf8:\t\t%lu\n"
15492            "longtext character set utf8:\t\t%lu\n"
15493            "varchar(255) character set latin1:\t%lu\n"
15494            "varchar(255) character set binary:\t%lu\n"
15495            "varchar(255) character set utf8:\t%lu\n",
15496            field[0].length, field[1].length, field[2].length, field[3].length,
15497            field[4].length, field[5].length, field[6].length);
15498   }
15499   DIE_UNLESS(field[0].length == 65535);
15500   DIE_UNLESS(field[1].length == 255);
15501   DIE_UNLESS(field[2].length == 16777215);
15502   DIE_UNLESS(field[3].length == 4294967295UL);
15503   DIE_UNLESS(field[4].length == 255);
15504   DIE_UNLESS(field[5].length == 255);
15505   DIE_UNLESS(field[6].length == 255);
15506   mysql_free_result(metadata);
15507   mysql_stmt_free_result(stmt);
15508 
15509   /* III. Cleanup */
15510   rc= mysql_query(mysql, "drop table t1");
15511   myquery(rc);
15512   rc= mysql_query(mysql, "set names default");
15513   myquery(rc);
15514   mysql_stmt_close(stmt);
15515 }
15516 
15517 /*
15518   Bug#17667: An attacker has the opportunity to bypass query logging.
15519 
15520   Note! Also tests Bug#21813, where prepared statements are used to
15521   run queries
15522 */
test_bug17667()15523 static void test_bug17667()
15524 {
15525   int rc;
15526   MYSQL_STMT *stmt;
15527   enum query_type { QT_NORMAL, QT_PREPARED};
15528   struct buffer_and_length {
15529     enum query_type qt;
15530     const char *buffer;
15531     const uint length;
15532   } statements[]= {
15533     { QT_NORMAL, "drop table if exists bug17667", 29 },
15534     { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
15535     { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
15536     { QT_PREPARED,
15537       "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
15538     { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
15539     { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
15540     { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
15541     { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
15542     { QT_NORMAL, "drop table bug17667", 19 },
15543     { QT_NORMAL, NULL, 0 } };
15544 
15545   struct buffer_and_length *statement_cursor;
15546   FILE *log_file;
15547   char *master_log_filename;
15548 
15549   myheader("test_bug17667");
15550 
15551   master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1);
15552   strxmov(master_log_filename, opt_vardir, "/log/master.log", NullS);
15553   if (!opt_silent)
15554     printf("Opening '%s'\n", master_log_filename);
15555   log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0));
15556   free(master_log_filename);
15557 
15558   if (log_file == NULL)
15559   {
15560     if (!opt_silent)
15561     {
15562       printf("Could not find the log file, VARDIR/log/master.log, so "
15563              "test_bug17667 is not run.\n"
15564              "Run test from the mysql-test/mysql-test-run* program to set up "
15565              "correct environment for this test.\n\n");
15566     }
15567     return;
15568   }
15569 
15570   enable_query_logs(1);
15571 
15572   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15573        statement_cursor++)
15574   {
15575     if (statement_cursor->qt == QT_NORMAL)
15576     {
15577       /* Run statement as normal query */
15578       rc= mysql_real_query(mysql, statement_cursor->buffer,
15579                            statement_cursor->length);
15580       myquery(rc);
15581     }
15582     else if (statement_cursor->qt == QT_PREPARED)
15583     {
15584       /*
15585         Run as prepared statement
15586 
15587         NOTE! All these queries should be in the log twice,
15588         one time for prepare and one time for execute
15589       */
15590       stmt= mysql_stmt_init(mysql);
15591 
15592       rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
15593                              statement_cursor->length);
15594       check_execute(stmt, rc);
15595 
15596       rc= mysql_stmt_execute(stmt);
15597       check_execute(stmt, rc);
15598 
15599       mysql_stmt_close(stmt);
15600     }
15601     else
15602     {
15603       DIE_UNLESS(0==1);
15604     }
15605   }
15606 
15607   /* Make sure the server has written the logs to disk before reading it */
15608   rc= mysql_query(mysql, "flush logs");
15609   myquery(rc);
15610 
15611   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15612        statement_cursor++)
15613   {
15614     int expected_hits= 1, hits= 0;
15615     char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15616     /* more than enough room for the query and some marginalia. */
15617 
15618     /* Prepared statments always occurs twice in log */
15619     if (statement_cursor->qt == QT_PREPARED)
15620       expected_hits++;
15621 
15622     /* Loop until we found expected number of log entries */
15623     do {
15624       /* Loop until statement is found in log */
15625       do {
15626         memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15627 
15628         if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15629         {
15630           /* If fgets returned NULL, it indicates either error or EOF */
15631           if (feof(log_file))
15632             DIE("Found EOF before all statements where found");
15633 
15634           fprintf(stderr, "Got error %d while reading from file\n",
15635                   ferror(log_file));
15636           DIE("Read error");
15637         }
15638 
15639       } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15640                          statement_cursor->buffer,
15641                          statement_cursor->length) == NULL);
15642       hits++;
15643     } while (hits < expected_hits);
15644 
15645     if (!opt_silent)
15646       printf("Found statement starting with \"%s\"\n",
15647              statement_cursor->buffer);
15648   }
15649 
15650   restore_query_logs();
15651 
15652   if (!opt_silent)
15653     printf("success.  All queries found intact in the log.\n");
15654 
15655   my_fclose(log_file, MYF(0));
15656 }
15657 
15658 
15659 /*
15660   Bug#14169: type of group_concat() result changed to blob if tmp_table was
15661   used
15662 */
test_bug14169()15663 static void test_bug14169()
15664 {
15665   MYSQL_STMT *stmt;
15666   const char *stmt_text;
15667   MYSQL_RES *res;
15668   MYSQL_FIELD *field;
15669   int rc;
15670 
15671   myheader("test_bug14169");
15672 
15673   rc= mysql_query(mysql, "drop table if exists t1");
15674   myquery(rc);
15675   rc= mysql_query(mysql, "set session group_concat_max_len=1024");
15676   myquery(rc);
15677   rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))");
15678   myquery(rc);
15679   rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255)),"
15680                          "(2,repeat('b',255))");
15681   myquery(rc);
15682   stmt= mysql_stmt_init(mysql);
15683   stmt_text= "select f2,group_concat(f1) from t1 group by f2";
15684   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15685   myquery(rc);
15686   res= mysql_stmt_result_metadata(stmt);
15687   field= mysql_fetch_fields(res);
15688   if (!opt_silent)
15689     printf("GROUP_CONCAT() result type %i", field[1].type);
15690   DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
15691   mysql_free_result(res);
15692   mysql_stmt_free_result(stmt);
15693   mysql_stmt_close(stmt);
15694 
15695   rc= mysql_query(mysql, "drop table t1");
15696   myquery(rc);
15697 
15698   rc= mysql_query(mysql, "set session group_concat_max_len=@@global.group_concat_max_len");
15699   myquery(rc);
15700 }
15701 
15702 /*
15703    Test that mysql_insert_id() behaves as documented in our manual
15704 */
test_mysql_insert_id()15705 static void test_mysql_insert_id()
15706 {
15707   my_ulonglong res;
15708   int rc;
15709 
15710   myheader("test_mysql_insert_id");
15711 
15712   rc= mysql_query(mysql, "drop table if exists t1,t2");
15713   myquery(rc);
15714   /* table without auto_increment column */
15715   rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
15716   myquery(rc);
15717   rc= mysql_query(mysql, "insert into t1 values (1,'a')");
15718   myquery(rc);
15719   res= mysql_insert_id(mysql);
15720   DIE_UNLESS(res == 0);
15721   rc= mysql_query(mysql, "insert into t1 values (null,'b')");
15722   myquery(rc);
15723   res= mysql_insert_id(mysql);
15724   DIE_UNLESS(res == 0);
15725   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15726   myquery(rc);
15727   res= mysql_insert_id(mysql);
15728   DIE_UNLESS(res == 0);
15729 
15730   /*
15731     Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
15732     sporadically
15733   */
15734   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15735   myquery(rc);
15736   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15737   myquery(rc);
15738   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15739   myquery(rc);
15740   res= mysql_insert_id(mysql);
15741   DIE_UNLESS(res == 0);
15742   rc= mysql_query(mysql, "drop table t2");
15743   myquery(rc);
15744 
15745   rc= mysql_query(mysql, "insert into t1 select null,'d'");
15746   myquery(rc);
15747   res= mysql_insert_id(mysql);
15748   DIE_UNLESS(res == 0);
15749   rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
15750   myquery(rc);
15751   res= mysql_insert_id(mysql);
15752   DIE_UNLESS(res == 300);
15753   rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
15754   myquery(rc);
15755   res= mysql_insert_id(mysql);
15756   /*
15757     Behaviour change: old code used to return 0; but 400 is consistent
15758     with INSERT VALUES, and the manual's section of mysql_insert_id() does not
15759     say INSERT SELECT should be different.
15760   */
15761   DIE_UNLESS(res == 400);
15762 
15763   /* table with auto_increment column */
15764   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15765   myquery(rc);
15766   rc= mysql_query(mysql, "insert into t2 values (1,'a')");
15767   myquery(rc);
15768   res= mysql_insert_id(mysql);
15769   DIE_UNLESS(res == 1);
15770   /* this should not influence next INSERT if it doesn't have auto_inc */
15771   rc= mysql_query(mysql, "insert into t1 values (10,'e')");
15772   myquery(rc);
15773   res= mysql_insert_id(mysql);
15774   DIE_UNLESS(res == 0);
15775 
15776   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15777   myquery(rc);
15778   res= mysql_insert_id(mysql);
15779   DIE_UNLESS(res == 2);
15780   rc= mysql_query(mysql, "insert into t2 select 5,'c'");
15781   myquery(rc);
15782   res= mysql_insert_id(mysql);
15783   /*
15784     Manual says that for multirow insert this should have been 5, but does not
15785     say for INSERT SELECT. This is a behaviour change: old code used to return
15786     0. We try to be consistent with INSERT VALUES.
15787   */
15788   DIE_UNLESS(res == 5);
15789   rc= mysql_query(mysql, "insert into t2 select null,'d'");
15790   myquery(rc);
15791   res= mysql_insert_id(mysql);
15792   DIE_UNLESS(res == 6);
15793   /* with more than one row */
15794   rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
15795   myquery(rc);
15796   res= mysql_insert_id(mysql);
15797   DIE_UNLESS(res == 11);
15798   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15799   myquery(rc);
15800   res= mysql_insert_id(mysql);
15801   /*
15802     Manual says that for multirow insert this should have been 13, but does
15803     not say for INSERT SELECT. This is a behaviour change: old code used to
15804     return 0. We try to be consistent with INSERT VALUES.
15805   */
15806   DIE_UNLESS(res == 13);
15807   rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
15808   myquery(rc);
15809   res= mysql_insert_id(mysql);
15810   DIE_UNLESS(res == 14);
15811   rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
15812   myquery(rc);
15813   res= mysql_insert_id(mysql);
15814   DIE_UNLESS(res == 16);
15815   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15816   myquery_r(rc);
15817   rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
15818   myquery(rc);
15819   res= mysql_insert_id(mysql);
15820   DIE_UNLESS(res == 0);
15821   rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
15822   myquery_r(rc);
15823   res= mysql_insert_id(mysql);
15824   DIE_UNLESS(res == 0);
15825   rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
15826   myquery(rc);
15827   res= mysql_insert_id(mysql);
15828   DIE_UNLESS(res == 0);
15829   /* mixing autogenerated and explicit values */
15830   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
15831   myquery_r(rc);
15832   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
15833   myquery_r(rc);
15834   rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
15835   myquery(rc);
15836   res= mysql_insert_id(mysql);
15837   /*
15838     according to the manual, this might be 20 or 300, but it looks like
15839     auto_increment column takes priority over last_insert_id().
15840   */
15841   DIE_UNLESS(res == 20);
15842   /* If first autogenerated number fails and 2nd works: */
15843   rc= mysql_query(mysql, "drop table t2");
15844   myquery(rc);
15845   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
15846                   "auto_increment, f2 varchar(255), unique (f2))");
15847   myquery(rc);
15848   rc= mysql_query(mysql, "insert into t2 values (null,'e')");
15849   res= mysql_insert_id(mysql);
15850   DIE_UNLESS(res == 1);
15851   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
15852   myquery(rc);
15853   res= mysql_insert_id(mysql);
15854   DIE_UNLESS(res == 2);
15855   /* If autogenerated fails and explicit works: */
15856   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
15857   myquery(rc);
15858   res= mysql_insert_id(mysql);
15859   /*
15860     Behaviour change: old code returned 3 (first autogenerated, even if it
15861     fails); we now return first successful autogenerated.
15862   */
15863   DIE_UNLESS(res == 13);
15864   /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
15865   rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
15866   myquery(rc);
15867   res= mysql_insert_id(mysql);
15868   DIE_UNLESS(res == 0);
15869   rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
15870   myquery(rc);
15871   res= mysql_insert_id(mysql);
15872   DIE_UNLESS(res == 0);
15873   rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
15874   myquery(rc);
15875   res= mysql_insert_id(mysql);
15876   DIE_UNLESS(res == 372);
15877   /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
15878   rc= mysql_query(mysql, "insert into t2 values (null,'g')");
15879   myquery(rc);
15880   res= mysql_insert_id(mysql);
15881   DIE_UNLESS(res == 15);
15882   rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
15883   myquery(rc);
15884   res= mysql_insert_id(mysql);
15885   DIE_UNLESS(res == 0);
15886   /*
15887     Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
15888     mysql_insert_id() returns the id of the row, instead of not being
15889     affected.
15890   */
15891   rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
15892                   "update f2=concat('we updated ',f2)");
15893   myquery(rc);
15894   res= mysql_insert_id(mysql);
15895   DIE_UNLESS(res == 15);
15896 
15897   rc= mysql_query(mysql, "drop table t1,t2");
15898   myquery(rc);
15899 }
15900 
15901 /*
15902   Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
15903 */
15904 
test_bug20152()15905 static void test_bug20152()
15906 {
15907   MYSQL_BIND my_bind[1];
15908   MYSQL_STMT *stmt;
15909   MYSQL_TIME tm;
15910   int rc;
15911   const char *query= "INSERT INTO t1 (f1) VALUES (?)";
15912 
15913   myheader("test_bug20152");
15914 
15915   memset(my_bind, 0, sizeof(my_bind));
15916   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
15917   my_bind[0].buffer= (void*)&tm;
15918 
15919   memset(&tm, 0, sizeof tm);
15920   tm.year = 2006;
15921   tm.month = 6;
15922   tm.day = 18;
15923   tm.hour = 14;
15924   tm.minute = 9;
15925   tm.second = 42;
15926 
15927   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15928   myquery(rc);
15929   rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)");
15930   myquery(rc);
15931 
15932   stmt= mysql_stmt_init(mysql);
15933   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15934   check_execute(stmt, rc);
15935   rc= mysql_stmt_bind_param(stmt, my_bind);
15936   check_execute(stmt, rc);
15937   rc= mysql_stmt_execute(stmt);
15938   check_execute(stmt, rc);
15939   rc= mysql_stmt_close(stmt);
15940   check_execute(stmt, rc);
15941   rc= mysql_query(mysql, "DROP TABLE t1");
15942   myquery(rc);
15943 
15944   if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) {
15945     if (!opt_silent)
15946       printf("OK!");
15947   } else {
15948     printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second);
15949     DIE_UNLESS(0==1);
15950   }
15951 }
15952 
15953 /* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
15954 
test_bug15752()15955 static void test_bug15752()
15956 {
15957   MYSQL mysql_local;
15958   int rc, i;
15959   const int ITERATION_COUNT= 100;
15960   const char *query= "CALL p1()";
15961 
15962   myheader("test_bug15752");
15963 
15964   rc= mysql_query(mysql, "drop procedure if exists p1");
15965   myquery(rc);
15966   rc= mysql_query(mysql, "create procedure p1() select 1");
15967   myquery(rc);
15968 
15969   mysql_client_init(&mysql_local);
15970   if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
15971                            opt_password, current_db, opt_port,
15972                            opt_unix_socket,
15973                            CLIENT_MULTI_STATEMENTS))
15974   {
15975     printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
15976     DIE_UNLESS(0);
15977   }
15978   rc= mysql_real_query(&mysql_local, query, strlen(query));
15979   myquery(rc);
15980   mysql_free_result(mysql_store_result(&mysql_local));
15981 
15982   rc= mysql_real_query(&mysql_local, query, strlen(query));
15983   DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
15984 
15985   if (! opt_silent)
15986     printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
15987 
15988   /* Check some other commands too */
15989 
15990   DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15991   mysql_free_result(mysql_store_result(&mysql_local));
15992   DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15993 
15994   /* The second problem is not reproducible: add the test case */
15995   for (i = 0; i < ITERATION_COUNT; i++)
15996   {
15997     if (mysql_real_query(&mysql_local, query, strlen(query)))
15998     {
15999       printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
16000       break;
16001     }
16002     mysql_free_result(mysql_store_result(&mysql_local));
16003     DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
16004     mysql_free_result(mysql_store_result(&mysql_local));
16005     DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
16006 
16007   }
16008   mysql_close(&mysql_local);
16009   rc= mysql_query(mysql, "drop procedure p1");
16010   myquery(rc);
16011 }
16012 
16013 /*
16014   Bug#21206: memory corruption when too many cursors are opened at once
16015 
16016   Memory corruption happens when more than 1024 cursors are open
16017   simultaneously.
16018 */
test_bug21206()16019 static void test_bug21206()
16020 {
16021   const size_t cursor_count= 1025;
16022 
16023   const char *create_table[]=
16024   {
16025     "DROP TABLE IF EXISTS t1",
16026     "CREATE TABLE t1 (i INT)",
16027     "INSERT INTO t1 VALUES (1), (2), (3)"
16028   };
16029   const char *query= "SELECT * FROM t1";
16030 
16031   Stmt_fetch *fetch_array=
16032     (Stmt_fetch*) calloc(cursor_count, sizeof(Stmt_fetch));
16033 
16034   Stmt_fetch *fetch;
16035 
16036   DBUG_ENTER("test_bug21206");
16037   myheader("test_bug21206");
16038 
16039   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
16040 
16041   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
16042   {
16043     /* Init will exit(1) in case of error */
16044     stmt_fetch_init(fetch, (uint)(fetch - fetch_array), query);
16045   }
16046 
16047   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
16048     stmt_fetch_close(fetch);
16049 
16050   free(fetch_array);
16051 
16052   DBUG_VOID_RETURN;
16053 }
16054 
16055 /*
16056   Ensure we execute the status code while testing
16057 */
16058 
test_status()16059 static void test_status()
16060 {
16061   DBUG_ENTER("test_status");
16062   myheader("test_status");
16063 
16064   if (!mysql_stat(mysql))
16065   {
16066     myerror("mysql_stat failed");                 /* purecov: inspected */
16067     die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
16068   }
16069   DBUG_VOID_RETURN;
16070 }
16071 
16072 /*
16073   Bug#21726: Incorrect result with multiple invocations of
16074   LAST_INSERT_ID
16075 
16076   Test that client gets updated value of insert_id on UPDATE that uses
16077   LAST_INSERT_ID(expr).
16078   select_query added to test for bug
16079     #26921 Problem in mysql_insert_id() Embedded C API function
16080 */
test_bug21726()16081 static void test_bug21726()
16082 {
16083   const char *create_table[]=
16084   {
16085     "DROP TABLE IF EXISTS t1",
16086     "CREATE TABLE t1 (i INT)",
16087     "INSERT INTO t1 VALUES (1)",
16088   };
16089   const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
16090   int rc;
16091   my_ulonglong insert_id;
16092   const char *select_query= "SELECT * FROM t1";
16093   MYSQL_RES  *result;
16094 
16095   DBUG_ENTER("test_bug21726");
16096   myheader("test_bug21726");
16097 
16098   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
16099 
16100   rc= mysql_query(mysql, update_query);
16101   myquery(rc);
16102   insert_id= mysql_insert_id(mysql);
16103   DIE_UNLESS(insert_id == 2);
16104 
16105   rc= mysql_query(mysql, update_query);
16106   myquery(rc);
16107   insert_id= mysql_insert_id(mysql);
16108   DIE_UNLESS(insert_id == 3);
16109 
16110   rc= mysql_query(mysql, select_query);
16111   myquery(rc);
16112   insert_id= mysql_insert_id(mysql);
16113   DIE_UNLESS(insert_id == 3);
16114   result= mysql_store_result(mysql);
16115   mysql_free_result(result);
16116 
16117   DBUG_VOID_RETURN;
16118 }
16119 
16120 
16121 /*
16122   BUG#23383: mysql_affected_rows() returns different values than
16123   mysql_stmt_affected_rows()
16124 
16125   Test that both mysql_affected_rows() and mysql_stmt_affected_rows()
16126   return -1 on error, 0 when no rows were affected, and (positive) row
16127   count when some rows were affected.
16128 */
test_bug23383()16129 static void test_bug23383()
16130 {
16131   const char *insert_query= "INSERT INTO t1 VALUES (1), (2)";
16132   const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3";
16133   MYSQL_STMT *stmt;
16134   my_ulonglong row_count;
16135   int rc;
16136 
16137   DBUG_ENTER("test_bug23383");
16138   myheader("test_bug23383");
16139 
16140   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16141   myquery(rc);
16142 
16143   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)");
16144   myquery(rc);
16145 
16146   rc= mysql_query(mysql, insert_query);
16147   myquery(rc);
16148   row_count= mysql_affected_rows(mysql);
16149   DIE_UNLESS(row_count == 2);
16150 
16151   rc= mysql_query(mysql, insert_query);
16152   DIE_UNLESS(rc != 0);
16153   row_count= mysql_affected_rows(mysql);
16154   DIE_UNLESS(row_count == (my_ulonglong)-1);
16155 
16156   rc= mysql_query(mysql, update_query);
16157   myquery(rc);
16158   row_count= mysql_affected_rows(mysql);
16159   DIE_UNLESS(row_count == 0);
16160 
16161   rc= mysql_query(mysql, "DELETE FROM t1");
16162   myquery(rc);
16163 
16164   stmt= mysql_stmt_init(mysql);
16165   DIE_UNLESS(stmt != 0);
16166 
16167   rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query));
16168   check_execute(stmt, rc);
16169 
16170   rc= mysql_stmt_execute(stmt);
16171   check_execute(stmt, rc);
16172   row_count= mysql_stmt_affected_rows(stmt);
16173   DIE_UNLESS(row_count == 2);
16174 
16175   rc= mysql_stmt_execute(stmt);
16176   DIE_UNLESS(rc != 0);
16177   row_count= mysql_stmt_affected_rows(stmt);
16178   DIE_UNLESS(row_count == (my_ulonglong)-1);
16179 
16180   rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query));
16181   check_execute(stmt, rc);
16182 
16183   rc= mysql_stmt_execute(stmt);
16184   check_execute(stmt, rc);
16185   row_count= mysql_stmt_affected_rows(stmt);
16186   DIE_UNLESS(row_count == 0);
16187 
16188   rc= mysql_stmt_close(stmt);
16189   check_execute(stmt, rc);
16190 
16191   rc= mysql_query(mysql, "DROP TABLE t1");
16192   myquery(rc);
16193 
16194   DBUG_VOID_RETURN;
16195 }
16196 
16197 
16198 /*
16199   BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for
16200   expression cols
16201 
16202   Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set
16203   to either expression or its alias, and db, org_table, table,
16204   org_name fields are empty strings.
16205 */
test_bug21635()16206 static void test_bug21635()
16207 {
16208   const char *expr[]=
16209   {
16210     "MIN(i)", "MIN(i)",
16211     "MIN(i) AS A1", "A1",
16212     "MAX(i)", "MAX(i)",
16213     "MAX(i) AS A2", "A2",
16214     "COUNT(i)", "COUNT(i)",
16215     "COUNT(i) AS A3", "A3",
16216   };
16217   char query[MAX_TEST_QUERY_LENGTH];
16218   char *query_end;
16219   MYSQL_RES *result;
16220   MYSQL_FIELD *field;
16221   unsigned int field_count, i, j;
16222   int rc;
16223 
16224   DBUG_ENTER("test_bug21635");
16225   myheader("test_bug21635");
16226 
16227   query_end= strxmov(query, "SELECT ", NullS);
16228   for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i)
16229     query_end= strxmov(query_end, expr[i * 2], ", ", NullS);
16230   query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS);
16231   DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH);
16232 
16233   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16234   myquery(rc);
16235   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)");
16236   myquery(rc);
16237   /*
16238     We need this loop to ensure correct behavior with both constant and
16239     non-constant tables.
16240   */
16241   for (j= 0; j < 2 ; j++)
16242   {
16243     rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16244     myquery(rc);
16245 
16246     rc= mysql_real_query(mysql, query, (ulong)(query_end - query));
16247     myquery(rc);
16248 
16249     result= mysql_use_result(mysql);
16250     DIE_UNLESS(result);
16251 
16252   field_count= mysql_field_count(mysql);
16253   for (i= 0; i < field_count; ++i)
16254   {
16255     field= mysql_fetch_field_direct(result, i);
16256     if (!opt_silent)
16257       if (!opt_silent)
16258         printf("%s -> %s ... ", expr[i * 2], field->name);
16259     fflush(stdout);
16260     DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
16261                field->table[0] == 0 && field->org_name[0] == 0);
16262     DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
16263     if (!opt_silent)
16264       if (!opt_silent)
16265         puts("OK");
16266   }
16267 
16268     mysql_free_result(result);
16269   }
16270   rc= mysql_query(mysql, "DROP TABLE t1");
16271   myquery(rc);
16272 
16273   DBUG_VOID_RETURN;
16274 }
16275 
16276 /*
16277   Bug#24179 "select b into $var" fails with --cursor_protocol"
16278   The failure is correct, check that the returned message is meaningful.
16279 */
16280 
test_bug24179()16281 static void test_bug24179()
16282 {
16283   int rc;
16284   MYSQL_STMT *stmt;
16285 
16286   DBUG_ENTER("test_bug24179");
16287   myheader("test_bug24179");
16288 
16289   stmt= open_cursor("select 1 into @a");
16290   rc= mysql_stmt_execute(stmt);
16291   DIE_UNLESS(rc);
16292   if (!opt_silent)
16293   {
16294     printf("Got error (as expected): %d %s\n",
16295            mysql_stmt_errno(stmt),
16296            mysql_stmt_error(stmt));
16297   }
16298   DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
16299   mysql_stmt_close(stmt);
16300 
16301   DBUG_VOID_RETURN;
16302 }
16303 
16304 
16305 /**
16306   Bug#32265 Server returns different metadata if prepared statement is used
16307 */
16308 
test_bug32265()16309 static void test_bug32265()
16310 {
16311   int rc;
16312   MYSQL_STMT *stmt;
16313   MYSQL_FIELD *field;
16314   MYSQL_RES *metadata;
16315 
16316   DBUG_ENTER("test_bug32265");
16317   myheader("test_bug32265");
16318 
16319   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16320   myquery(rc);
16321   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
16322   myquery(rc);
16323   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16324   myquery(rc);
16325   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
16326   myquery(rc);
16327 
16328   stmt= open_cursor("SELECT * FROM t1");
16329   rc= mysql_stmt_execute(stmt);
16330   check_execute(stmt, rc);
16331 
16332   metadata= mysql_stmt_result_metadata(stmt);
16333   field= mysql_fetch_field(metadata);
16334   DIE_UNLESS(field);
16335   DIE_UNLESS(strcmp(field->table, "t1") == 0);
16336   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16337   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16338   mysql_free_result(metadata);
16339   mysql_stmt_close(stmt);
16340 
16341   stmt= open_cursor("SELECT a '' FROM t1 ``");
16342   rc= mysql_stmt_execute(stmt);
16343   check_execute(stmt, rc);
16344 
16345   metadata= mysql_stmt_result_metadata(stmt);
16346   field= mysql_fetch_field(metadata);
16347   DIE_UNLESS(strcmp(field->table, "") == 0);
16348   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16349   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16350   mysql_free_result(metadata);
16351   mysql_stmt_close(stmt);
16352 
16353   stmt= open_cursor("SELECT a '' FROM t1 ``");
16354   rc= mysql_stmt_execute(stmt);
16355   check_execute(stmt, rc);
16356 
16357   metadata= mysql_stmt_result_metadata(stmt);
16358   field= mysql_fetch_field(metadata);
16359   DIE_UNLESS(strcmp(field->table, "") == 0);
16360   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16361   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16362   mysql_free_result(metadata);
16363   mysql_stmt_close(stmt);
16364 
16365   stmt= open_cursor("SELECT * FROM v1");
16366   rc= mysql_stmt_execute(stmt);
16367   check_execute(stmt, rc);
16368 
16369   metadata= mysql_stmt_result_metadata(stmt);
16370   field= mysql_fetch_field(metadata);
16371   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16372   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16373   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16374   mysql_free_result(metadata);
16375   mysql_stmt_close(stmt);
16376 
16377   stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
16378   rc= mysql_stmt_execute(stmt);
16379   check_execute(stmt, rc);
16380 
16381   metadata= mysql_stmt_result_metadata(stmt);
16382   field= mysql_fetch_field(metadata);
16383   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16384   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16385   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16386   mysql_free_result(metadata);
16387   mysql_stmt_close(stmt);
16388 
16389   rc= mysql_query(mysql, "DROP VIEW v1");
16390   myquery(rc);
16391   rc= mysql_query(mysql, "DROP TABLE t1");
16392   myquery(rc);
16393 
16394   DBUG_VOID_RETURN;
16395 }
16396 
16397 /*
16398   Bug#28075 "COM_DEBUG crashes mysqld"
16399 */
16400 
test_bug28075()16401 static void test_bug28075()
16402 {
16403   int rc;
16404 
16405   DBUG_ENTER("test_bug28075");
16406   myheader("test_bug28075");
16407 
16408   rc= mysql_dump_debug_info(mysql);
16409   DIE_UNLESS(rc == 0);
16410 
16411   rc= mysql_ping(mysql);
16412   DIE_UNLESS(rc == 0);
16413 
16414   DBUG_VOID_RETURN;
16415 }
16416 
16417 
16418 /*
16419   Bug#27876 (SF with cyrillic variable name fails during execution (regression))
16420 */
16421 
test_bug27876()16422 static void test_bug27876()
16423 {
16424   int rc;
16425   MYSQL_RES *result;
16426 
16427   uchar utf8_func[] =
16428   {
16429     0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
16430     0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
16431     0xd0, 0xb0,
16432     0x00
16433   };
16434 
16435   uchar utf8_param[] =
16436   {
16437     0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
16438     0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
16439     0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
16440     0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
16441     0x00
16442   };
16443 
16444   char query[500];
16445 
16446   DBUG_ENTER("test_bug27876");
16447   myheader("test_bug27876");
16448 
16449   rc= mysql_query(mysql, "set names utf8");
16450   myquery(rc);
16451 
16452   rc= mysql_query(mysql, "select version()");
16453   myquery(rc);
16454   result= mysql_store_result(mysql);
16455   mytest(result);
16456   mysql_free_result(result);
16457 
16458   sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
16459   rc= mysql_query(mysql, query);
16460   myquery(rc);
16461 
16462   sprintf(query,
16463           "CREATE FUNCTION %s( %s VARCHAR(25))"
16464           " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
16465           (char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
16466   rc= mysql_query(mysql, query);
16467   myquery(rc);
16468   sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
16469   rc= mysql_query(mysql, query);
16470   myquery(rc);
16471   result= mysql_store_result(mysql);
16472   mytest(result);
16473   mysql_free_result(result);
16474 
16475   sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
16476   rc= mysql_query(mysql, query);
16477   myquery(rc);
16478 
16479   rc= mysql_query(mysql, "set names default");
16480   myquery(rc);
16481 
16482   DBUG_VOID_RETURN;
16483 }
16484 
16485 
16486 /*
16487   Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
16488   flag is set.
16489 */
16490 
test_bug28505()16491 static void test_bug28505()
16492 {
16493   my_ulonglong res;
16494 
16495   myquery(mysql_query(mysql, "drop table if exists t1"));
16496   myquery(mysql_query(mysql, "create table t1(f1 int primary key)"));
16497   myquery(mysql_query(mysql, "insert into t1 values(1)"));
16498   myquery(mysql_query(mysql,
16499                   "insert into t1 values(1) on duplicate key update f1=1"));
16500   res= mysql_affected_rows(mysql);
16501   DIE_UNLESS(!res);
16502   myquery(mysql_query(mysql, "drop table t1"));
16503 }
16504 
16505 
16506 /*
16507   Bug#28934: server crash when receiving malformed com_execute packets
16508 */
16509 
test_bug28934()16510 static void test_bug28934()
16511 {
16512   my_bool error= 0;
16513   MYSQL_BIND bind[5];
16514   MYSQL_STMT *stmt;
16515   int cnt;
16516 
16517   myquery(mysql_query(mysql, "drop table if exists t1"));
16518   myquery(mysql_query(mysql, "create table t1(id int)"));
16519 
16520   myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)"));
16521   stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)");
16522   check_stmt(stmt);
16523 
16524   memset (&bind, 0, sizeof (bind));
16525   for (cnt= 0; cnt < 5; cnt++)
16526   {
16527     bind[cnt].buffer_type= MYSQL_TYPE_LONG;
16528     bind[cnt].buffer= (char*)&cnt;
16529     bind[cnt].buffer_length= 0;
16530   }
16531   myquery(mysql_stmt_bind_param(stmt, bind));
16532 
16533   stmt->param_count=2;
16534   error= mysql_stmt_execute(stmt);
16535   DIE_UNLESS(error != 0);
16536   myerror(NULL);
16537   mysql_stmt_close(stmt);
16538 
16539   myquery(mysql_query(mysql, "drop table t1"));
16540 }
16541 
16542 /*
16543   Test mysql_change_user() C API and COM_CHANGE_USER
16544 */
16545 
test_change_user()16546 static void test_change_user()
16547 {
16548   char buff[256];
16549   const char *user_pw= "mysqltest_pw";
16550   const char *user_no_pw= "mysqltest_no_pw";
16551   const char *pw= "password";
16552   const char *db= "mysqltest_user_test_database";
16553   int rc;
16554   MYSQL*       conn;
16555   MYSQL_RES* res;
16556   DBUG_ENTER("test_change_user");
16557   myheader("test_change_user");
16558 
16559   /* Prepare environment */
16560   sprintf(buff, "drop database if exists %s", db);
16561   rc= mysql_query(mysql, buff);
16562   myquery(rc);
16563 
16564   sprintf(buff, "create database %s", db);
16565   rc= mysql_query(mysql, buff);
16566   myquery(rc);
16567 
16568   rc= mysql_query(mysql, "SET SQL_MODE=''");
16569   myquery(rc);
16570 
16571   sprintf(buff,
16572           "grant select on %s.* to %s@'%%' identified by '%s'",
16573           db,
16574           user_pw,
16575           pw);
16576   rc= mysql_query(mysql, buff);
16577   myquery(rc);
16578 
16579   sprintf(buff,
16580           "grant select on %s.* to %s@'localhost' identified by '%s'",
16581           db,
16582           user_pw,
16583           pw);
16584   rc= mysql_query(mysql, buff);
16585   myquery(rc);
16586 
16587   sprintf(buff,
16588           "grant select on %s.* to %s@'%%'",
16589           db,
16590           user_no_pw);
16591   rc= mysql_query(mysql, buff);
16592   myquery(rc);
16593 
16594   sprintf(buff,
16595           "grant select on %s.* to %s@'localhost'",
16596           db,
16597           user_no_pw);
16598   rc= mysql_query(mysql, buff);
16599   myquery(rc);
16600 
16601   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16602 
16603   /* Try some combinations */
16604   rc= mysql_change_user(conn, NULL, NULL, NULL);
16605   DIE_UNLESS(rc);
16606   if (! opt_silent)
16607     printf("Got error (as expected): %s\n", mysql_error(conn));
16608 
16609 
16610   rc= mysql_change_user(conn, "", NULL, NULL);
16611   DIE_UNLESS(rc);
16612   if (! opt_silent)
16613     printf("Got error (as expected): %s\n", mysql_error(conn));
16614 
16615   rc= mysql_change_user(conn, "", "", NULL);
16616   DIE_UNLESS(rc);
16617   if (! opt_silent)
16618     printf("Got error (as expected): %s\n", mysql_error(conn));
16619 
16620   mysql_close(conn);
16621   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16622 
16623   rc= mysql_change_user(conn, "", "", "");
16624   DIE_UNLESS(rc);
16625   if (! opt_silent)
16626     printf("Got error (as expected): %s\n", mysql_error(conn));
16627 
16628   rc= mysql_change_user(conn, NULL, "", "");
16629   DIE_UNLESS(rc);
16630   if (! opt_silent)
16631     printf("Got error (as expected): %s\n", mysql_error(conn));
16632 
16633 
16634   rc= mysql_change_user(conn, NULL, NULL, "");
16635   DIE_UNLESS(rc);
16636   if (! opt_silent)
16637     printf("Got error (as expected): %s\n", mysql_error(conn));
16638 
16639   mysql_close(conn);
16640   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16641 
16642   rc= mysql_change_user(conn, "", NULL, "");
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, user_pw, NULL, "");
16648   DIE_UNLESS(rc);
16649   if (! opt_silent)
16650     printf("Got error (as expected): %s\n", mysql_error(conn));
16651 
16652   rc= mysql_change_user(conn, user_pw, "", "");
16653   DIE_UNLESS(rc);
16654   if (! opt_silent)
16655     printf("Got error (as expected): %s\n", mysql_error(conn));
16656 
16657   mysql_close(conn);
16658   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16659 
16660   rc= mysql_change_user(conn, user_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, user_pw, NULL, NULL);
16666   DIE_UNLESS(rc);
16667   if (! opt_silent)
16668     printf("Got error (as expected): %s\n", mysql_error(conn));
16669 
16670   rc= mysql_change_user(conn, user_pw, "", db);
16671   DIE_UNLESS(rc);
16672   if (! opt_silent)
16673     printf("Got error (as expected): %s\n", mysql_error(conn));
16674 
16675   mysql_close(conn);
16676   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16677 
16678   rc= mysql_change_user(conn, user_pw, NULL, db);
16679   DIE_UNLESS(rc);
16680   if (! opt_silent)
16681     printf("Got error (as expected): %s\n", mysql_error(conn));
16682 
16683   rc= mysql_change_user(conn, user_pw, pw, db);
16684   myquery(rc);
16685 
16686   rc= mysql_change_user(conn, user_pw, pw, NULL);
16687   myquery(rc);
16688 
16689   rc= mysql_change_user(conn, user_pw, pw, "");
16690   myquery(rc);
16691 
16692   /* MDEV-14581 : Check that there are no warnings after change user.*/
16693   rc = mysql_query(conn,"SIGNAL SQLSTATE '01000'");
16694   myquery(rc);
16695 
16696   rc = mysql_change_user(conn, user_pw, pw, "");
16697   myquery(rc);
16698 
16699   rc = mysql_query(conn, "SHOW WARNINGS");
16700   myquery(rc);
16701   res = mysql_store_result(conn);
16702   rc = my_process_result_set(res);
16703   DIE_UNLESS(rc == 0);
16704   mysql_free_result(res);
16705 
16706   rc= mysql_change_user(conn, user_no_pw, pw, db);
16707   DIE_UNLESS(rc);
16708   if (! opt_silent)
16709     printf("Got error (as expected): %s\n", mysql_error(conn));
16710 
16711   rc= mysql_change_user(conn, user_no_pw, pw, "");
16712   DIE_UNLESS(rc);
16713   if (! opt_silent)
16714     printf("Got error (as expected): %s\n", mysql_error(conn));
16715 
16716   mysql_close(conn);
16717   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16718 
16719   rc= mysql_change_user(conn, user_no_pw, pw, NULL);
16720   DIE_UNLESS(rc);
16721   if (! opt_silent)
16722     printf("Got error (as expected): %s\n", mysql_error(conn));
16723 
16724   rc= mysql_change_user(conn, user_no_pw, "", NULL);
16725   myquery(rc);
16726 
16727   rc= mysql_change_user(conn, user_no_pw, "", "");
16728   myquery(rc);
16729 
16730   rc= mysql_change_user(conn, user_no_pw, "", db);
16731   myquery(rc);
16732 
16733   rc= mysql_change_user(conn, user_no_pw, NULL, db);
16734   myquery(rc);
16735 
16736   rc= mysql_change_user(conn, "", pw, db);
16737   DIE_UNLESS(rc);
16738   if (! opt_silent)
16739     printf("Got error (as expected): %s\n", mysql_error(conn));
16740 
16741   rc= mysql_change_user(conn, "", pw, "");
16742   DIE_UNLESS(rc);
16743   if (! opt_silent)
16744     printf("Got error (as expected): %s\n", mysql_error(conn));
16745 
16746   mysql_close(conn);
16747   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16748 
16749   rc= mysql_change_user(conn, "", pw, NULL);
16750   DIE_UNLESS(rc);
16751   if (! opt_silent)
16752     printf("Got error (as expected): %s\n", mysql_error(conn));
16753 
16754   rc= mysql_change_user(conn, NULL, pw, NULL);
16755   DIE_UNLESS(rc);
16756   if (! opt_silent)
16757     printf("Got error (as expected): %s\n", mysql_error(conn));
16758 
16759   rc= mysql_change_user(conn, NULL, NULL, db);
16760   DIE_UNLESS(rc);
16761   if (! opt_silent)
16762     printf("Got error (as expected): %s\n", mysql_error(conn));
16763 
16764   mysql_close(conn);
16765   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16766 
16767   rc= mysql_change_user(conn, NULL, "", db);
16768   DIE_UNLESS(rc);
16769   if (! opt_silent)
16770     printf("Got error (as expected): %s\n", mysql_error(conn));
16771 
16772   rc= mysql_change_user(conn, "", "", db);
16773   DIE_UNLESS(rc);
16774   if (! opt_silent)
16775     printf("Got error (as expected): %s\n", mysql_error(conn));
16776 
16777   /* Cleanup the environment */
16778 
16779   mysql_change_user(conn, opt_user, opt_password, current_db);
16780 
16781   mysql_close(conn);
16782 
16783   sprintf(buff, "drop database %s", db);
16784   rc= mysql_query(mysql, buff);
16785   myquery(rc);
16786 
16787   sprintf(buff, "drop user %s@'%%'", user_pw);
16788   rc= mysql_query(mysql, buff);
16789   myquery(rc);
16790 
16791   sprintf(buff, "drop user %s@'%%'", user_no_pw);
16792   rc= mysql_query(mysql, buff);
16793   myquery(rc);
16794 
16795   sprintf(buff, "drop user %s@'localhost'", user_pw);
16796   rc= mysql_query(mysql, buff);
16797   myquery(rc);
16798 
16799   sprintf(buff, "drop user %s@'localhost'", user_no_pw);
16800   rc= mysql_query(mysql, buff);
16801   myquery(rc);
16802 
16803   DBUG_VOID_RETURN;
16804 }
16805 
16806 /*
16807   Bug#27592 (stack overrun when storing datetime value using prepared statements)
16808 */
16809 
test_bug27592()16810 static void test_bug27592()
16811 {
16812   const int NUM_ITERATIONS= 40;
16813   int i;
16814   int rc;
16815   MYSQL_STMT *stmt= NULL;
16816   MYSQL_BIND bind[1];
16817   MYSQL_TIME time_val;
16818 
16819   DBUG_ENTER("test_bug27592");
16820   myheader("test_bug27592");
16821 
16822   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16823   mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
16824 
16825   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
16826   DIE_UNLESS(stmt);
16827 
16828   memset(bind, 0, sizeof(bind));
16829 
16830   bind[0].buffer_type= MYSQL_TYPE_DATETIME;
16831   bind[0].buffer= (char *) &time_val;
16832   bind[0].length= NULL;
16833 
16834   for (i= 0; i < NUM_ITERATIONS; i++)
16835   {
16836     time_val.year= 2007;
16837     time_val.month= 6;
16838     time_val.day= 7;
16839     time_val.hour= 18;
16840     time_val.minute= 41;
16841     time_val.second= 3;
16842 
16843     time_val.second_part=0;
16844     time_val.neg=0;
16845 
16846     rc= mysql_stmt_bind_param(stmt, bind);
16847     check_execute(stmt, rc);
16848 
16849     rc= mysql_stmt_execute(stmt);
16850     check_execute(stmt, rc);
16851   }
16852 
16853   mysql_stmt_close(stmt);
16854 
16855   DBUG_VOID_RETURN;
16856 }
16857 
16858 /*
16859   Bug#29687 mysql_stmt_store_result memory leak in libmysqld
16860 */
16861 
test_bug29687()16862 static void test_bug29687()
16863 {
16864   const int NUM_ITERATIONS= 40;
16865   int i;
16866   int rc;
16867   MYSQL_STMT *stmt= NULL;
16868 
16869   DBUG_ENTER("test_bug29687");
16870   myheader("test_bug29687");
16871 
16872   stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2");
16873   DIE_UNLESS(stmt);
16874 
16875   for (i= 0; i < NUM_ITERATIONS; i++)
16876   {
16877     rc= mysql_stmt_execute(stmt);
16878     check_execute(stmt, rc);
16879     mysql_stmt_store_result(stmt);
16880     while (mysql_stmt_fetch(stmt)==0);
16881     mysql_stmt_free_result(stmt);
16882   }
16883 
16884   mysql_stmt_close(stmt);
16885   DBUG_VOID_RETURN;
16886 }
16887 
16888 
16889 /*
16890   Bug #29692  	Single row inserts can incorrectly report a huge number of
16891   row insertions
16892 */
16893 
test_bug29692()16894 static void test_bug29692()
16895 {
16896   MYSQL* conn;
16897 
16898   if (!(conn= mysql_client_init(NULL)))
16899   {
16900     myerror("test_bug29692 init failed");
16901     exit(1);
16902   }
16903 
16904   if (!(mysql_real_connect(conn, opt_host, opt_user,
16905                            opt_password, opt_db ? opt_db:"test", opt_port,
16906                            opt_unix_socket,  CLIENT_FOUND_ROWS)))
16907   {
16908     myerror("test_bug29692 connection failed");
16909     mysql_close(mysql);
16910     exit(1);
16911   }
16912   myquery(mysql_query(conn, "drop table if exists t1"));
16913   myquery(mysql_query(conn, "create table t1(f1 int)"));
16914   myquery(mysql_query(conn, "insert into t1 values(1)"));
16915   DIE_UNLESS(1 == mysql_affected_rows(conn));
16916   myquery(mysql_query(conn, "drop table t1"));
16917   mysql_close(conn);
16918 }
16919 
16920 /**
16921   Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
16922 */
16923 
test_bug29306()16924 static void test_bug29306()
16925 {
16926   MYSQL_FIELD *field;
16927   int rc;
16928   MYSQL_RES *res;
16929 
16930   DBUG_ENTER("test_bug29306");
16931   myheader("test_bug29306");
16932 
16933   rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
16934   myquery(rc);
16935   rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
16936   myquery(rc);
16937   rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
16938   myquery(rc);
16939   rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
16940   myquery(rc);
16941   rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
16942   myquery(rc);
16943 
16944   /* Checking the view */
16945   res= mysql_list_fields(mysql, "view17557", NULL);
16946   while ((field= mysql_fetch_field(res)))
16947   {
16948     if (! opt_silent)
16949     {
16950       printf("field name %s\n", field->name);
16951       printf("field table %s\n", field->table);
16952       printf("field decimals %d\n", field->decimals);
16953       if (field->decimals < 1)
16954         printf("Error! No decimals! \n");
16955       printf("\n\n");
16956     }
16957     DIE_UNLESS(field->decimals == 1);
16958   }
16959   mysql_free_result(res);
16960 
16961   rc= mysql_query(mysql, "DROP TABLE tab17557");
16962   myquery(rc);
16963   rc= mysql_query(mysql, "DROP VIEW view17557");
16964   myquery(rc);
16965 
16966   DBUG_VOID_RETURN;
16967 }
16968 /*
16969   Bug#30472: libmysql doesn't reset charset, insert_id after succ.
16970   mysql_change_user() call row insertions.
16971 */
16972 
bug30472_retrieve_charset_info(MYSQL * con,char * character_set_name,char * character_set_client,char * character_set_results,char * collation_connection)16973 static void bug30472_retrieve_charset_info(MYSQL *con,
16974                                            char *character_set_name,
16975                                            char *character_set_client,
16976                                            char *character_set_results,
16977                                            char *collation_connection)
16978 {
16979   MYSQL_RES *rs;
16980   MYSQL_ROW row;
16981 
16982   /* Get the cached client character set name. */
16983 
16984   strcpy(character_set_name, mysql_character_set_name(con));
16985 
16986   /* Retrieve server character set information. */
16987 
16988   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
16989   DIE_UNLESS(rs= mysql_store_result(con));
16990   DIE_UNLESS(row= mysql_fetch_row(rs));
16991   strcpy(character_set_client, row[1]);
16992   mysql_free_result(rs);
16993 
16994   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
16995   DIE_UNLESS(rs= mysql_store_result(con));
16996   DIE_UNLESS(row= mysql_fetch_row(rs));
16997   strcpy(character_set_results, row[1]);
16998   mysql_free_result(rs);
16999 
17000   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
17001   DIE_UNLESS(rs= mysql_store_result(con));
17002   DIE_UNLESS(row= mysql_fetch_row(rs));
17003   strcpy(collation_connection, row[1]);
17004   mysql_free_result(rs);
17005 }
17006 
test_bug30472()17007 static void test_bug30472()
17008 {
17009   MYSQL con;
17010 
17011   char character_set_name_1[MY_CS_NAME_SIZE];
17012   char character_set_client_1[MY_CS_NAME_SIZE];
17013   char character_set_results_1[MY_CS_NAME_SIZE];
17014   char collation_connnection_1[MY_CS_NAME_SIZE];
17015 
17016   char character_set_name_2[MY_CS_NAME_SIZE];
17017   char character_set_client_2[MY_CS_NAME_SIZE];
17018   char character_set_results_2[MY_CS_NAME_SIZE];
17019   char collation_connnection_2[MY_CS_NAME_SIZE];
17020 
17021   char character_set_name_3[MY_CS_NAME_SIZE];
17022   char character_set_client_3[MY_CS_NAME_SIZE];
17023   char character_set_results_3[MY_CS_NAME_SIZE];
17024   char collation_connnection_3[MY_CS_NAME_SIZE];
17025 
17026   char character_set_name_4[MY_CS_NAME_SIZE];
17027   char character_set_client_4[MY_CS_NAME_SIZE];
17028   char character_set_results_4[MY_CS_NAME_SIZE];
17029   char collation_connnection_4[MY_CS_NAME_SIZE];
17030 
17031   /* Create a new connection. */
17032 
17033   DIE_UNLESS(mysql_client_init(&con));
17034 
17035   DIE_UNLESS(mysql_real_connect(&con,
17036                                 opt_host,
17037                                 opt_user,
17038                                 opt_password,
17039                                 opt_db ? opt_db : "test",
17040                                 opt_port,
17041                                 opt_unix_socket,
17042                                 CLIENT_FOUND_ROWS));
17043 
17044   /* Retrieve character set information. */
17045 
17046   bug30472_retrieve_charset_info(&con,
17047                                  character_set_name_1,
17048                                  character_set_client_1,
17049                                  character_set_results_1,
17050                                  collation_connnection_1);
17051 
17052   /* Switch client character set. */
17053 
17054   DIE_IF(mysql_set_character_set(&con, "latin2"));
17055 
17056   /* Retrieve character set information. */
17057 
17058   bug30472_retrieve_charset_info(&con,
17059                                  character_set_name_2,
17060                                  character_set_client_2,
17061                                  character_set_results_2,
17062                                  collation_connnection_2);
17063 
17064   /*
17065     Check that
17066       1) character set has been switched and
17067       2) new character set is different from the original one.
17068   */
17069 
17070   DIE_UNLESS(strcmp(character_set_name_2, "latin2") == 0);
17071   DIE_UNLESS(strcmp(character_set_client_2, "latin2") == 0);
17072   DIE_UNLESS(strcmp(character_set_results_2, "latin2") == 0);
17073   DIE_UNLESS(strcmp(collation_connnection_2, "latin2_general_ci") == 0);
17074 
17075   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
17076   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
17077   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
17078   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
17079 
17080   /* Call mysql_change_user() with the same username, password, database. */
17081 
17082   DIE_IF(mysql_change_user(&con,
17083                            opt_user,
17084                            opt_password,
17085                            opt_db ? opt_db : "test"));
17086 
17087   /* Retrieve character set information. */
17088 
17089   bug30472_retrieve_charset_info(&con,
17090                                  character_set_name_3,
17091                                  character_set_client_3,
17092                                  character_set_results_3,
17093                                  collation_connnection_3);
17094 
17095   /* Check that character set information has been reset. */
17096 
17097   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
17098   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
17099   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
17100   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
17101 
17102   /* Change connection-default character set in the client. */
17103 
17104   mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8");
17105 
17106   /*
17107     Call mysql_change_user() in order to check that new connection will
17108     have UTF8 character set on the client and on the server.
17109   */
17110 
17111   DIE_IF(mysql_change_user(&con,
17112                            opt_user,
17113                            opt_password,
17114                            opt_db ? opt_db : "test"));
17115 
17116   /* Retrieve character set information. */
17117 
17118   bug30472_retrieve_charset_info(&con,
17119                                  character_set_name_4,
17120                                  character_set_client_4,
17121                                  character_set_results_4,
17122                                  collation_connnection_4);
17123 
17124   /* Check that we have UTF8 on the server and on the client. */
17125 
17126   DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
17127   DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
17128   DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
17129   DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
17130 
17131   /* That's it. Cleanup. */
17132 
17133   mysql_close(&con);
17134 }
17135 
bug20023_change_user(MYSQL * con)17136 static void bug20023_change_user(MYSQL *con)
17137 {
17138   DIE_IF(mysql_change_user(con,
17139                            opt_user,
17140                            opt_password,
17141                            opt_db ? opt_db : "test"));
17142 }
17143 
query_str_variable(MYSQL * con,const char * var_name,char * str,size_t len)17144 static my_bool query_str_variable(MYSQL *con,
17145                                   const char *var_name,
17146                                   char *str,
17147                                   size_t len)
17148 {
17149   MYSQL_RES *rs;
17150   MYSQL_ROW row;
17151 
17152   char query_buffer[MAX_TEST_QUERY_LENGTH];
17153 
17154   my_bool is_null;
17155 
17156   my_snprintf(query_buffer, sizeof (query_buffer),
17157               "SELECT %s", var_name);
17158 
17159   DIE_IF(mysql_query(con, query_buffer));
17160   DIE_UNLESS(rs= mysql_store_result(con));
17161   DIE_UNLESS(row= mysql_fetch_row(rs));
17162 
17163   is_null= row[0] == NULL;
17164 
17165   if (!is_null)
17166     my_snprintf(str, len, "%s", row[0]);
17167 
17168   mysql_free_result(rs);
17169 
17170   return is_null;
17171 }
17172 
query_int_variable(MYSQL * con,const char * var_name,int * var_value)17173 static my_bool query_int_variable(MYSQL *con,
17174                                   const char *var_name,
17175                                   int *var_value)
17176 {
17177   char str[32];
17178   my_bool is_null= query_str_variable(con, var_name, str, sizeof(str));
17179 
17180   if (!is_null)
17181     *var_value= atoi(str);
17182 
17183   return is_null;
17184 }
17185 
test_bug20023()17186 static void test_bug20023()
17187 {
17188   MYSQL con;
17189 
17190   int sql_big_selects_orig= 0;
17191   /*
17192     Type of max_join_size is ha_rows, which might be ulong or off_t
17193     depending on the platform or configure options. Preserve the string
17194     to avoid type overflow pitfalls.
17195   */
17196   char max_join_size_orig[32];
17197 
17198   int sql_big_selects_2= 0;
17199   int sql_big_selects_3= 0;
17200   int sql_big_selects_4= 0;
17201   int sql_big_selects_5= 0;
17202 
17203   char query_buffer[MAX_TEST_QUERY_LENGTH];
17204 
17205   /* Create a new connection. */
17206 
17207   DIE_UNLESS(mysql_client_init(&con));
17208 
17209   DIE_UNLESS(mysql_real_connect(&con,
17210                                 opt_host,
17211                                 opt_user,
17212                                 opt_password,
17213                                 opt_db ? opt_db : "test",
17214                                 opt_port,
17215                                 opt_unix_socket,
17216                                 CLIENT_FOUND_ROWS));
17217 
17218   /***********************************************************************
17219     Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
17220   ***********************************************************************/
17221 
17222   query_int_variable(&con,
17223                      "@@session.sql_big_selects",
17224                      &sql_big_selects_orig);
17225 
17226   query_str_variable(&con,
17227                      "@@global.max_join_size",
17228                      max_join_size_orig,
17229                      sizeof(max_join_size_orig));
17230 
17231   /***********************************************************************
17232     Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
17233   ***********************************************************************/
17234 
17235   /* Issue COM_CHANGE_USER. */
17236 
17237   bug20023_change_user(&con);
17238 
17239   /* Query SQL_BIG_SELECTS. */
17240 
17241   query_int_variable(&con,
17242                      "@@session.sql_big_selects",
17243                      &sql_big_selects_2);
17244 
17245   /* Check that SQL_BIG_SELECTS is reset properly. */
17246 
17247   DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2);
17248 
17249   /***********************************************************************
17250     Test that if MAX_JOIN_SIZE set to non-default value,
17251     SQL_BIG_SELECTS will be 0.
17252   ***********************************************************************/
17253 
17254   /* Set MAX_JOIN_SIZE to some non-default value. */
17255 
17256   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000"));
17257   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17258 
17259   /* Issue COM_CHANGE_USER. */
17260 
17261   bug20023_change_user(&con);
17262 
17263   /* Query SQL_BIG_SELECTS. */
17264 
17265   query_int_variable(&con,
17266                      "@@session.sql_big_selects",
17267                      &sql_big_selects_3);
17268 
17269   /* Check that SQL_BIG_SELECTS is 0. */
17270 
17271   DIE_UNLESS(sql_big_selects_3 == 0);
17272 
17273   /***********************************************************************
17274     Test that if MAX_JOIN_SIZE set to default value,
17275     SQL_BIG_SELECTS will be 1.
17276   ***********************************************************************/
17277 
17278   /* Set MAX_JOIN_SIZE to the default value (2^64-1). */
17279 
17280   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17281   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17282 
17283   /* Issue COM_CHANGE_USER. */
17284 
17285   bug20023_change_user(&con);
17286 
17287   /* Query SQL_BIG_SELECTS. */
17288 
17289   query_int_variable(&con,
17290                      "@@session.sql_big_selects",
17291                      &sql_big_selects_4);
17292 
17293   /* Check that SQL_BIG_SELECTS is 1. */
17294 
17295   DIE_UNLESS(sql_big_selects_4 == 1);
17296 
17297   /***********************************************************************
17298     Restore MAX_JOIN_SIZE.
17299     Check that SQL_BIG_SELECTS will be the original one.
17300   ***********************************************************************/
17301 
17302   /* Restore MAX_JOIN_SIZE. */
17303 
17304   my_snprintf(query_buffer,
17305            sizeof (query_buffer),
17306            "SET @@global.max_join_size = %s",
17307            max_join_size_orig);
17308 
17309   DIE_IF(mysql_query(&con, query_buffer));
17310 
17311   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17312   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17313 
17314   /* Issue COM_CHANGE_USER. */
17315 
17316   bug20023_change_user(&con);
17317 
17318   /* Query SQL_BIG_SELECTS. */
17319 
17320   query_int_variable(&con,
17321                      "@@session.sql_big_selects",
17322                      &sql_big_selects_5);
17323 
17324   /* Check that SQL_BIG_SELECTS is 1. */
17325 
17326   DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig);
17327 
17328   /***********************************************************************
17329     That's it. Cleanup.
17330   ***********************************************************************/
17331 
17332   mysql_close(&con);
17333 }
17334 
bug31418_impl()17335 static void bug31418_impl()
17336 {
17337   MYSQL con;
17338 
17339   my_bool is_null;
17340   int rc= 0;
17341 
17342   /* Create a new connection. */
17343 
17344   DIE_UNLESS(mysql_client_init(&con));
17345 
17346   DIE_UNLESS(mysql_real_connect(&con,
17347                                 opt_host,
17348                                 opt_user,
17349                                 opt_password,
17350                                 opt_db ? opt_db : "test",
17351                                 opt_port,
17352                                 opt_unix_socket,
17353                                 CLIENT_FOUND_ROWS));
17354 
17355   /***********************************************************************
17356     Check that lock is free:
17357       - IS_FREE_LOCK() should return 1;
17358       - IS_USED_LOCK() should return NULL;
17359   ***********************************************************************/
17360 
17361   is_null= query_int_variable(&con,
17362                               "IS_FREE_LOCK('bug31418')",
17363                               &rc);
17364   DIE_UNLESS(!is_null && rc);
17365 
17366   is_null= query_int_variable(&con,
17367                               "IS_USED_LOCK('bug31418')",
17368                               &rc);
17369   DIE_UNLESS(is_null);
17370 
17371   /***********************************************************************
17372     Acquire lock and check the lock status (the lock must be in use):
17373       - IS_FREE_LOCK() should return 0;
17374       - IS_USED_LOCK() should return non-zero thread id;
17375   ***********************************************************************/
17376 
17377   query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
17378   DIE_UNLESS(rc);
17379 
17380   is_null= query_int_variable(&con,
17381                               "IS_FREE_LOCK('bug31418')",
17382                               &rc);
17383   DIE_UNLESS(!is_null && !rc);
17384 
17385   is_null= query_int_variable(&con,
17386                               "IS_USED_LOCK('bug31418')",
17387                               &rc);
17388   DIE_UNLESS(!is_null && rc);
17389 
17390   /***********************************************************************
17391     Issue COM_CHANGE_USER command and check the lock status
17392     (the lock must be free):
17393       - IS_FREE_LOCK() should return 1;
17394       - IS_USED_LOCK() should return NULL;
17395   **********************************************************************/
17396 
17397   bug20023_change_user(&con);
17398 
17399   is_null= query_int_variable(&con,
17400                               "IS_FREE_LOCK('bug31418')",
17401                               &rc);
17402   DIE_UNLESS(!is_null && rc);
17403 
17404   is_null= query_int_variable(&con,
17405                               "IS_USED_LOCK('bug31418')",
17406                               &rc);
17407   DIE_UNLESS(is_null);
17408 
17409   /***********************************************************************
17410    That's it. Cleanup.
17411   ***********************************************************************/
17412 
17413   mysql_close(&con);
17414 }
17415 
test_bug31418()17416 static void test_bug31418()
17417 {
17418   /* Run test case for BUG#31418 for three different connections. */
17419 
17420   bug31418_impl();
17421 
17422   bug31418_impl();
17423 
17424   bug31418_impl();
17425 }
17426 
17427 
17428 
17429 /**
17430   Bug#31669 Buffer overflow in mysql_change_user()
17431 */
17432 
17433 #define LARGE_BUFFER_SIZE 2048
17434 #define OLD_USERNAME_CHAR_LENGTH 16
17435 
test_bug31669()17436 static void test_bug31669()
17437 {
17438   int rc;
17439   static char buff[LARGE_BUFFER_SIZE+1];
17440 #ifndef EMBEDDED_LIBRARY
17441   static char user[OLD_USERNAME_CHAR_LENGTH+1];
17442   static char db[NAME_CHAR_LEN+1];
17443   static char query[LARGE_BUFFER_SIZE*2];
17444 #endif
17445   MYSQL* conn;
17446 
17447   DBUG_ENTER("test_bug31669");
17448   myheader("test_bug31669");
17449 
17450   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17451 
17452   rc= mysql_change_user(conn, NULL, NULL, NULL);
17453   DIE_UNLESS(rc);
17454 
17455   rc= mysql_change_user(conn, "", "", "");
17456   DIE_UNLESS(rc);
17457 
17458   memset(buff, 'a', sizeof(buff) -  1);
17459   buff[sizeof(buff) -  1]= 0;
17460 
17461   mysql_close(conn);
17462   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17463 
17464   rc= mysql_change_user(conn, buff, buff, buff);
17465   DIE_UNLESS(rc);
17466 
17467   rc = mysql_change_user(conn, opt_user, opt_password, current_db);
17468   DIE_UNLESS(!rc);
17469 
17470 #ifndef EMBEDDED_LIBRARY
17471   memset(db, 'a', sizeof(db));
17472   db[NAME_CHAR_LEN]= 0;
17473   strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
17474   rc= mysql_query(conn, query);
17475   myquery(rc);
17476 
17477   memset(user, 'b', sizeof(user));
17478   user[OLD_USERNAME_CHAR_LENGTH]= 0;
17479   memset(buff, 'c', sizeof(buff));
17480   buff[LARGE_BUFFER_SIZE]= 0;
17481   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
17482                  "'", buff, "' WITH GRANT OPTION", NullS);
17483   rc= mysql_query(conn, query);
17484   myquery(rc);
17485 
17486   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY "
17487                  "'", buff, "' WITH GRANT OPTION", NullS);
17488   rc= mysql_query(conn, query);
17489   myquery(rc);
17490 
17491   rc= mysql_query(conn, "FLUSH PRIVILEGES");
17492   myquery(rc);
17493 
17494   rc= mysql_change_user(conn, user, buff, db);
17495   DIE_UNLESS(!rc);
17496 
17497   user[OLD_USERNAME_CHAR_LENGTH-1]= 'a';
17498   rc= mysql_change_user(conn, user, buff, db);
17499   DIE_UNLESS(rc);
17500 
17501   user[OLD_USERNAME_CHAR_LENGTH-1]= 'b';
17502   buff[LARGE_BUFFER_SIZE-1]= 'd';
17503   rc= mysql_change_user(conn, user, buff, db);
17504   DIE_UNLESS(rc);
17505 
17506   buff[LARGE_BUFFER_SIZE-1]= 'c';
17507   db[NAME_CHAR_LEN-1]= 'e';
17508   rc= mysql_change_user(conn, user, buff, db);
17509   DIE_UNLESS(rc);
17510 
17511   mysql_close(conn);
17512   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17513 
17514   db[NAME_CHAR_LEN-1]= 'a';
17515   rc= mysql_change_user(conn, user, buff, db);
17516   DIE_UNLESS(!rc);
17517 
17518   rc= mysql_change_user(conn, user + 1, buff + 1, db + 1);
17519   DIE_UNLESS(rc);
17520 
17521   rc = mysql_change_user(conn, opt_user, opt_password, current_db);
17522   DIE_UNLESS(!rc);
17523 
17524   strxmov(query, "DROP DATABASE ", db, NullS);
17525   rc= mysql_query(conn, query);
17526   myquery(rc);
17527 
17528   strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
17529   rc= mysql_query(conn, query);
17530   myquery(rc);
17531   DIE_UNLESS(mysql_affected_rows(conn) == 2);
17532 #endif
17533 
17534   mysql_close(conn);
17535 
17536   DBUG_VOID_RETURN;
17537 }
17538 
17539 
17540 /**
17541   Bug#28386 the general log is incomplete
17542 */
17543 
test_bug28386()17544 static void test_bug28386()
17545 {
17546   int rc;
17547   MYSQL_STMT *stmt;
17548   MYSQL_RES *result;
17549   MYSQL_ROW row;
17550   MYSQL_BIND bind;
17551   const char hello[]= "hello world!";
17552 
17553   DBUG_ENTER("test_bug28386");
17554   myheader("test_bug28386");
17555 
17556   rc= mysql_query(mysql, "select @@global.log_output");
17557   myquery(rc);
17558 
17559   result= mysql_store_result(mysql);
17560   DIE_UNLESS(result);
17561 
17562   row= mysql_fetch_row(result);
17563   if (! strstr(row[0], "TABLE"))
17564   {
17565     mysql_free_result(result);
17566     if (! opt_silent)
17567       printf("Skipping the test since logging to tables is not enabled\n");
17568     /* Log output is not to tables */
17569     DBUG_VOID_RETURN;
17570   }
17571   mysql_free_result(result);
17572 
17573   enable_query_logs(1);
17574 
17575   stmt= mysql_simple_prepare(mysql, "SELECT ?");
17576   check_stmt(stmt);
17577 
17578   memset(&bind, 0, sizeof(bind));
17579 
17580   bind.buffer_type= MYSQL_TYPE_STRING;
17581   bind.buffer= (void *) hello;
17582   bind.buffer_length= sizeof(hello);
17583 
17584   mysql_stmt_bind_param(stmt, &bind);
17585   mysql_stmt_send_long_data(stmt, 0, hello, sizeof(hello));
17586 
17587   rc= mysql_stmt_execute(stmt);
17588   check_execute(stmt, rc);
17589 
17590   rc= my_process_stmt_result(stmt);
17591   DIE_UNLESS(rc == 1);
17592 
17593   rc= mysql_stmt_reset(stmt);
17594   check_execute(stmt, rc);
17595 
17596   rc= mysql_stmt_close(stmt);
17597   DIE_UNLESS(!rc);
17598 
17599   rc= mysql_query(mysql, "select * from mysql.general_log where "
17600                          "command_type='Close stmt' or "
17601                          "command_type='Reset stmt' or "
17602                          "command_type='Long Data'");
17603   myquery(rc);
17604 
17605   result= mysql_store_result(mysql);
17606   mytest(result);
17607 
17608   DIE_UNLESS(mysql_num_rows(result) == 3);
17609 
17610   mysql_free_result(result);
17611 
17612   restore_query_logs();
17613 
17614   DBUG_VOID_RETURN;
17615 }
17616 
17617 
test_wl4166_1()17618 static void test_wl4166_1()
17619 {
17620   MYSQL_STMT *stmt;
17621   int        int_data;
17622   char       str_data[50];
17623   char       tiny_data;
17624   short      small_data;
17625   longlong   big_data;
17626   float      real_data;
17627   double     double_data;
17628   ulong      length[7];
17629   my_bool    is_null[7];
17630   MYSQL_BIND my_bind[7];
17631   int rc;
17632   int i;
17633 
17634   myheader("test_wl4166_1");
17635 
17636   rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
17637   myquery(rc);
17638 
17639   rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
17640                          "col2 varchar(15), col3 int, "
17641                          "col4 smallint, col5 bigint, "
17642                          "col6 float, col7 double, "
17643                          "colX varchar(10) default NULL)");
17644   myquery(rc);
17645 
17646   stmt= mysql_simple_prepare(mysql,
17647     "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
17648     "VALUES(?, ?, ?, ?, ?, ?, ?)");
17649   check_stmt(stmt);
17650 
17651   verify_param_count(stmt, 7);
17652 
17653   bzero(my_bind, sizeof(my_bind));
17654   /* tinyint */
17655   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
17656   my_bind[0].buffer= (void *)&tiny_data;
17657   /* string */
17658   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
17659   my_bind[1].buffer= (void *)str_data;
17660   my_bind[1].buffer_length= 1000;                  /* Max string length */
17661   /* integer */
17662   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
17663   my_bind[2].buffer= (void *)&int_data;
17664   /* short */
17665   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
17666   my_bind[3].buffer= (void *)&small_data;
17667   /* bigint */
17668   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
17669   my_bind[4].buffer= (void *)&big_data;
17670   /* float */
17671   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
17672   my_bind[5].buffer= (void *)&real_data;
17673   /* double */
17674   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
17675   my_bind[6].buffer= (void *)&double_data;
17676 
17677   for (i= 0; i < (int) array_elements(my_bind); i++)
17678   {
17679     my_bind[i].length= &length[i];
17680     my_bind[i].is_null= &is_null[i];
17681     is_null[i]= 0;
17682   }
17683 
17684   rc= mysql_stmt_bind_param(stmt, my_bind);
17685   check_execute(stmt, rc);
17686 
17687   int_data= 320;
17688   small_data= 1867;
17689   big_data= 1000;
17690   real_data= 2;
17691   double_data= 6578.001;
17692 
17693   /* now, execute the prepared statement to insert 10 records.. */
17694   for (tiny_data= 0; tiny_data < 10; tiny_data++)
17695   {
17696     length[1]= sprintf(str_data, "MySQL%d", int_data);
17697     rc= mysql_stmt_execute(stmt);
17698     check_execute(stmt, rc);
17699     int_data += 25;
17700     small_data += 10;
17701     big_data += 100;
17702     real_data += 1;
17703     double_data += 10.09;
17704   }
17705 
17706   /* force a re-prepare with some DDL */
17707 
17708   rc= mysql_query(mysql,
17709     "ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
17710   myquery(rc);
17711 
17712   /*
17713     execute the prepared statement again,
17714     without changing the types of parameters already bound.
17715   */
17716 
17717   for (tiny_data= 50; tiny_data < 60; tiny_data++)
17718   {
17719     length[1]= sprintf(str_data, "MySQL%d", int_data);
17720     rc= mysql_stmt_execute(stmt);
17721     check_execute(stmt, rc);
17722     int_data += 25;
17723     small_data += 10;
17724     big_data += 100;
17725     real_data += 1;
17726     double_data += 10.09;
17727   }
17728 
17729   mysql_stmt_close(stmt);
17730 
17731   rc= mysql_query(mysql, "DROP TABLE table_4166");
17732   myquery(rc);
17733 }
17734 
17735 
test_wl4166_2()17736 static void test_wl4166_2()
17737 {
17738   MYSQL_STMT *stmt;
17739   int        c_int;
17740   MYSQL_TIME d_date;
17741   MYSQL_BIND bind_out[2];
17742   int rc;
17743 
17744   myheader("test_wl4166_2");
17745 
17746   rc= mysql_query(mysql, "SET SQL_MODE=''");
17747   myquery(rc);
17748 
17749   rc= mysql_query(mysql, "drop table if exists t1");
17750   myquery(rc);
17751   rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
17752   myquery(rc);
17753   rc= mysql_query(mysql,
17754                   "insert into t1 (c_int, d_date) values (42, '1948-05-15')");
17755   myquery(rc);
17756 
17757   stmt= mysql_simple_prepare(mysql, "select * from t1");
17758   check_stmt(stmt);
17759 
17760   bzero(bind_out, sizeof(bind_out));
17761   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
17762   bind_out[0].buffer= (void*) &c_int;
17763 
17764   bind_out[1].buffer_type= MYSQL_TYPE_DATE;
17765   bind_out[1].buffer= (void*) &d_date;
17766 
17767   rc= mysql_stmt_bind_result(stmt, bind_out);
17768   check_execute(stmt, rc);
17769 
17770   /* int -> varchar transition */
17771 
17772   rc= mysql_query(mysql,
17773                   "alter table t1 change column c_int c_int varchar(11)");
17774   myquery(rc);
17775 
17776   rc= mysql_stmt_execute(stmt);
17777   check_execute(stmt, rc);
17778 
17779   rc= mysql_stmt_fetch(stmt);
17780   check_execute(stmt, rc);
17781 
17782   DIE_UNLESS(c_int == 42);
17783   DIE_UNLESS(d_date.year == 1948);
17784   DIE_UNLESS(d_date.month == 5);
17785   DIE_UNLESS(d_date.day == 15);
17786 
17787   rc= mysql_stmt_fetch(stmt);
17788   DIE_UNLESS(rc == MYSQL_NO_DATA);
17789 
17790   /* varchar to int retrieval with truncation */
17791 
17792   rc= mysql_query(mysql, "update t1 set c_int='abcde'");
17793   myquery(rc);
17794 
17795   rc= mysql_stmt_execute(stmt);
17796   check_execute(stmt, rc);
17797 
17798   rc= mysql_stmt_fetch(stmt);
17799   check_execute_r(stmt, rc);
17800 
17801   DIE_UNLESS(c_int == 0);
17802 
17803   rc= mysql_stmt_fetch(stmt);
17804   DIE_UNLESS(rc == MYSQL_NO_DATA);
17805 
17806   /* alter table and increase the number of columns */
17807   rc= mysql_query(mysql, "alter table t1 add column d_int int");
17808   myquery(rc);
17809 
17810   rc= mysql_stmt_execute(stmt);
17811   check_execute_r(stmt, rc);
17812 
17813   rc= mysql_stmt_reset(stmt);
17814   check_execute(stmt, rc);
17815 
17816   /* decrease the number of columns */
17817   rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
17818   myquery(rc);
17819 
17820   rc= mysql_stmt_execute(stmt);
17821   check_execute_r(stmt, rc);
17822 
17823   mysql_stmt_close(stmt);
17824   rc= mysql_query(mysql, "drop table t1");
17825   myquery(rc);
17826 }
17827 
17828 
17829 /**
17830   Test how warnings generated during assignment of parameters
17831   are (currently not) preserve in case of reprepare.
17832 */
17833 
test_wl4166_3()17834 static void test_wl4166_3()
17835 {
17836   int rc;
17837   MYSQL_STMT *stmt;
17838   MYSQL_BIND my_bind[1];
17839   MYSQL_TIME tm[1];
17840 
17841   myheader("test_wl4166_3");
17842 
17843   rc= mysql_query(mysql, "drop table if exists t1");
17844   myquery(rc);
17845 
17846   rc= mysql_query(mysql, "create table t1 (year datetime)");
17847   myquery(rc);
17848 
17849   stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)");
17850   check_stmt(stmt);
17851   verify_param_count(stmt, 1);
17852 
17853   bzero((char*) my_bind, sizeof(my_bind));
17854   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17855   my_bind[0].buffer= &tm[0];
17856 
17857   rc= mysql_stmt_bind_param(stmt, my_bind);
17858   check_execute(stmt, rc);
17859 
17860   tm[0].year= 10000;
17861   tm[0].month= 1; tm[0].day= 1;
17862   tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
17863   tm[0].second_part= 0; tm[0].neg= 0;
17864 
17865   /* Cause a statement reprepare */
17866   rc= mysql_query(mysql, "alter table t1 add column c int");
17867   myquery(rc);
17868 
17869   rc= mysql_stmt_execute(stmt);
17870   check_execute(stmt, rc);
17871   /*
17872     The warning about data truncation when assigning a parameter is lost.
17873     This is a bug.
17874   */
17875   my_process_warnings(mysql, 0);
17876 
17877   verify_col_data("t1", "year", "0000-00-00 00:00:00");
17878 
17879   mysql_stmt_close(stmt);
17880 
17881   rc= mysql_query(mysql, "drop table t1");
17882   myquery(rc);
17883 }
17884 
17885 
17886 /**
17887   Test that long data parameters, as well as parameters
17888   that were originally in a different character set, are
17889   preserved in case of reprepare.
17890 */
17891 
test_wl4166_4()17892 static void test_wl4166_4()
17893 {
17894   MYSQL_STMT *stmt;
17895   int rc;
17896   const char *stmt_text;
17897   MYSQL_BIND bind_array[2];
17898 
17899   /* Represented as numbers to keep UTF8 tools from clobbering them. */
17900   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
17901   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
17902   char buf1[16], buf2[16];
17903   ulong buf1_len, buf2_len;
17904 
17905   myheader("test_wl4166_4");
17906 
17907   rc= mysql_query(mysql, "drop table if exists t1");
17908   myquery(rc);
17909 
17910   /*
17911     Create table with binary columns, set session character set to cp1251,
17912     client character set to koi8, and make sure that there is conversion
17913     on insert and no conversion on select
17914   */
17915   rc= mysql_query(mysql,
17916                   "create table t1 (c1 varbinary(255), c2 varbinary(255))");
17917   myquery(rc);
17918   rc= mysql_query(mysql, "set character_set_client=koi8r, "
17919                          "character_set_connection=cp1251, "
17920                          "character_set_results=koi8r");
17921   myquery(rc);
17922 
17923   bzero((char*) bind_array, sizeof(bind_array));
17924 
17925   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
17926 
17927   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
17928   bind_array[1].buffer= (void *) koi8;
17929   bind_array[1].buffer_length= strlen(koi8);
17930 
17931   stmt= mysql_stmt_init(mysql);
17932   check_stmt(stmt);
17933 
17934   stmt_text= "insert into t1 (c1, c2) values (?, ?)";
17935 
17936   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17937   check_execute(stmt, rc);
17938 
17939   mysql_stmt_bind_param(stmt, bind_array);
17940 
17941   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
17942 
17943   /* Cause a reprepare at statement execute */
17944   rc= mysql_query(mysql, "alter table t1 add column d int");
17945   myquery(rc);
17946 
17947   rc= mysql_stmt_execute(stmt);
17948   check_execute(stmt, rc);
17949 
17950   stmt_text= "select c1, c2 from t1";
17951 
17952   /* c1 and c2 are binary so no conversion will be done on select */
17953   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17954   check_execute(stmt, rc);
17955 
17956   rc= mysql_stmt_execute(stmt);
17957   check_execute(stmt, rc);
17958 
17959   bind_array[0].buffer= buf1;
17960   bind_array[0].buffer_length= sizeof(buf1);
17961   bind_array[0].length= &buf1_len;
17962 
17963   bind_array[1].buffer= buf2;
17964   bind_array[1].buffer_length= sizeof(buf2);
17965   bind_array[1].length= &buf2_len;
17966 
17967   mysql_stmt_bind_result(stmt, bind_array);
17968 
17969   rc= mysql_stmt_fetch(stmt);
17970   check_execute(stmt, rc);
17971 
17972   DIE_UNLESS(buf1_len == strlen(cp1251));
17973   DIE_UNLESS(buf2_len == strlen(cp1251));
17974   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
17975   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
17976 
17977   rc= mysql_stmt_fetch(stmt);
17978   DIE_UNLESS(rc == MYSQL_NO_DATA);
17979 
17980   mysql_stmt_close(stmt);
17981 
17982   rc= mysql_query(mysql, "drop table t1");
17983   myquery(rc);
17984   rc= mysql_query(mysql, "set names default");
17985   myquery(rc);
17986 }
17987 
17988 /**
17989   Bug#36004 mysql_stmt_prepare resets the list of warnings
17990 */
17991 
test_bug36004()17992 static void test_bug36004()
17993 {
17994   int rc, warning_count= 0;
17995   MYSQL_STMT *stmt;
17996 
17997   DBUG_ENTER("test_bug36004");
17998   myheader("test_bug36004");
17999 
18000   rc= mysql_query(mysql, "drop table if exists inexistant");
18001   myquery(rc);
18002 
18003   DIE_UNLESS(mysql_warning_count(mysql) == 1);
18004   query_int_variable(mysql, "@@warning_count", &warning_count);
18005   DIE_UNLESS(warning_count);
18006 
18007   stmt= mysql_simple_prepare(mysql, "select 1");
18008   check_stmt(stmt);
18009 
18010   DIE_UNLESS(mysql_warning_count(mysql) == 0);
18011   query_int_variable(mysql, "@@warning_count", &warning_count);
18012   DIE_UNLESS(warning_count);
18013 
18014   rc= mysql_stmt_execute(stmt);
18015   check_execute(stmt, rc);
18016 
18017   DIE_UNLESS(mysql_warning_count(mysql) == 0);
18018   mysql_stmt_close(stmt);
18019 
18020   query_int_variable(mysql, "@@warning_count", &warning_count);
18021   DIE_UNLESS(warning_count);
18022 
18023   stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
18024   check_stmt(stmt);
18025 
18026   query_int_variable(mysql, "@@warning_count", &warning_count);
18027   DIE_UNLESS(warning_count == 0);
18028   mysql_stmt_close(stmt);
18029 
18030   DBUG_VOID_RETURN;
18031 }
18032 
18033 /**
18034   Test that COM_REFRESH issues a implicit commit.
18035 */
18036 
test_wl4284_1()18037 static void test_wl4284_1()
18038 {
18039   int rc;
18040   MYSQL_ROW row;
18041   MYSQL_RES *result;
18042 
18043   DBUG_ENTER("test_wl4284_1");
18044   myheader("test_wl4284_1");
18045 
18046   /* set AUTOCOMMIT to OFF */
18047   rc= mysql_autocommit(mysql, FALSE);
18048   myquery(rc);
18049 
18050   rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
18051   myquery(rc);
18052 
18053   rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
18054   myquery(rc);
18055 
18056   rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
18057   myquery(rc);
18058 
18059   rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
18060   myquery(rc);
18061 
18062   rc= mysql_rollback(mysql);
18063   myquery(rc);
18064 
18065   rc= mysql_query(mysql, "SELECT * FROM trans");
18066   myquery(rc);
18067 
18068   result= mysql_use_result(mysql);
18069   mytest(result);
18070 
18071   row= mysql_fetch_row(result);
18072   mytest(row);
18073 
18074   mysql_free_result(result);
18075 
18076   /* set AUTOCOMMIT to ON */
18077   rc= mysql_autocommit(mysql, TRUE);
18078   myquery(rc);
18079 
18080   rc= mysql_query(mysql, "DROP TABLE trans");
18081   myquery(rc);
18082 
18083   DBUG_VOID_RETURN;
18084 }
18085 
18086 
test_bug38486(void)18087 static void test_bug38486(void)
18088 {
18089   MYSQL_STMT *stmt;
18090   const char *stmt_text;
18091   unsigned long type= CURSOR_TYPE_READ_ONLY;
18092 
18093   DBUG_ENTER("test_bug38486");
18094   myheader("test_bug38486");
18095 
18096   stmt= mysql_stmt_init(mysql);
18097   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18098   stmt_text= "CREATE TABLE t1 (a INT)";
18099   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
18100   mysql_stmt_execute(stmt);
18101   mysql_stmt_close(stmt);
18102 
18103   stmt= mysql_stmt_init(mysql);
18104   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18105   stmt_text= "INSERT INTO t1 VALUES (1)";
18106   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
18107   mysql_stmt_execute(stmt);
18108   mysql_stmt_close(stmt);
18109 
18110   DBUG_VOID_RETURN;
18111 }
18112 
18113 
18114 /**
18115      Bug# 33831 mysql_real_connect() should fail if
18116      given an already connected MYSQL handle.
18117 */
18118 
test_bug33831(void)18119 static void test_bug33831(void)
18120 {
18121   MYSQL *l_mysql;
18122 
18123   DBUG_ENTER("test_bug33831");
18124 
18125   if (!(l_mysql= mysql_client_init(NULL)))
18126   {
18127     myerror("mysql_client_init() failed");
18128     DIE_UNLESS(0);
18129   }
18130   if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
18131                            opt_password, current_db, opt_port,
18132                            opt_unix_socket, 0)))
18133   {
18134     myerror("connection failed");
18135     DIE_UNLESS(0);
18136   }
18137 
18138   if (mysql_real_connect(l_mysql, opt_host, opt_user,
18139                          opt_password, current_db, opt_port,
18140                          opt_unix_socket, 0))
18141   {
18142     myerror("connection should have failed");
18143     DIE_UNLESS(0);
18144   }
18145 
18146   mysql_close(l_mysql);
18147 
18148   DBUG_VOID_RETURN;
18149 }
18150 
18151 
test_bug40365(void)18152 static void test_bug40365(void)
18153 {
18154   uint         rc, i;
18155   MYSQL_STMT   *stmt= 0;
18156   MYSQL_BIND   my_bind[2];
18157   my_bool      is_null[2]= {0};
18158   MYSQL_TIME   tm[2];
18159 
18160   DBUG_ENTER("test_bug40365");
18161 
18162   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18163   myquery(rc);
18164   rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \
18165                                           c2 DATE)");
18166   myquery(rc);
18167 
18168   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)");
18169   check_stmt(stmt);
18170   verify_param_count(stmt, 2);
18171 
18172   bzero((char*) my_bind, sizeof(my_bind));
18173   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
18174   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
18175   for (i= 0; i < (int) array_elements(my_bind); i++)
18176   {
18177     my_bind[i].buffer= (void *) &tm[i];
18178     my_bind[i].is_null= &is_null[i];
18179   }
18180 
18181   rc= mysql_stmt_bind_param(stmt, my_bind);
18182   check_execute(stmt, rc);
18183 
18184   for (i= 0; i < (int) array_elements(my_bind); i++)
18185   {
18186     tm[i].neg= 0;
18187     tm[i].second_part= 0;
18188     tm[i].year= 2009;
18189     tm[i].month= 2;
18190     tm[i].day= 29;
18191     tm[i].hour= 0;
18192     tm[i].minute= 0;
18193     tm[i].second= 0;
18194   }
18195   rc= mysql_stmt_execute(stmt);
18196   check_execute(stmt, rc);
18197 
18198   rc= mysql_commit(mysql);
18199   myquery(rc);
18200   mysql_stmt_close(stmt);
18201 
18202   stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1");
18203   check_stmt(stmt);
18204 
18205   rc= mysql_stmt_bind_result(stmt, my_bind);
18206   check_execute(stmt, rc);
18207 
18208   rc= mysql_stmt_execute(stmt);
18209   check_execute(stmt, rc);
18210 
18211   rc= mysql_stmt_store_result(stmt);
18212   check_execute(stmt, rc);
18213 
18214   rc= mysql_stmt_fetch(stmt);
18215   check_execute(stmt, rc);
18216 
18217   if (!opt_silent)
18218     fprintf(stdout, "\n");
18219 
18220   for (i= 0; i < array_elements(my_bind); i++)
18221   {
18222     if (!opt_silent)
18223       fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d ",
18224               i, tm[i].year, tm[i].month, tm[i].day);
18225     DIE_UNLESS(tm[i].year == 0);
18226     DIE_UNLESS(tm[i].month == 0);
18227     DIE_UNLESS(tm[i].day == 0);
18228   }
18229   mysql_stmt_close(stmt);
18230   rc= mysql_commit(mysql);
18231   myquery(rc);
18232 
18233   DBUG_VOID_RETURN;
18234 }
18235 
18236 
18237 /**
18238   Subtest for Bug#43560. Verifies that a loss of connection on the server side
18239   is handled well by the mysql_stmt_execute() call, i.e., no SIGSEGV due to
18240   a vio socket that is cleared upon closed connection.
18241 
18242   Assumes the presence of the close_conn_after_stmt_execute debug feature in
18243   the server. Verifies that it is connected to a debug server before proceeding
18244   with the test.
18245  */
test_bug43560(void)18246 static void test_bug43560(void)
18247 {
18248   MYSQL*       conn;
18249   uint         rc;
18250   MYSQL_STMT   *stmt= 0;
18251   MYSQL_BIND   bind;
18252   my_bool      is_null= 0;
18253   char         buffer[256];
18254   const uint   BUFSIZE= sizeof(buffer);
18255   const char*  values[] = {"eins", "zwei", "drei", "viele", NULL};
18256   const char   insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
18257   unsigned long length;
18258   const unsigned int drop_db= opt_drop_db;
18259 
18260   DBUG_ENTER("test_bug43560");
18261   myheader("test_bug43560");
18262 
18263   /* Make sure we only run against a debug server. */
18264   if (!strstr(mysql->server_version, "debug"))
18265   {
18266     fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
18267     DBUG_VOID_RETURN;
18268   }
18269   if (opt_unix_socket)
18270   {
18271     fprintf(stdout, "Skipping test_bug43560: connected via UNIX socket\n");
18272     DBUG_VOID_RETURN;
18273   }
18274   /*
18275     Set up a separate connection for this test to avoid messing up the
18276     general MYSQL object used in other subtests. Use TCP protocol to avoid
18277     problems with the buffer semantics of AF_UNIX, and turn off auto reconnect.
18278   */
18279   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
18280 
18281   rc= mysql_query(conn, "DROP TABLE IF EXISTS t1");
18282   myquery(rc);
18283   rc= mysql_query(conn,
18284     "CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))");
18285   myquery(rc);
18286 
18287   stmt= mysql_stmt_init(conn);
18288   check_stmt(stmt);
18289   rc= mysql_stmt_prepare(stmt, insert_str, strlen(insert_str));
18290   check_execute(stmt, rc);
18291 
18292   bind.buffer_type= MYSQL_TYPE_STRING;
18293   bind.buffer_length= BUFSIZE;
18294   bind.buffer= buffer;
18295   bind.is_null= &is_null;
18296   bind.length= &length;
18297   rc= mysql_stmt_bind_param(stmt, &bind);
18298   check_execute(stmt, rc);
18299 
18300   /* First execute; should succeed. */
18301   strncpy(buffer, values[0], BUFSIZE);
18302   length= strlen(buffer);
18303   rc= mysql_stmt_execute(stmt);
18304   check_execute(stmt, rc);
18305 
18306   /*
18307     Set up the server to close this session's server-side socket after
18308     next execution of prep statement.
18309   */
18310   rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'");
18311   myquery(rc);
18312 
18313   /* Second execute; should fail due to socket closed during execution. */
18314   strncpy(buffer, values[1], BUFSIZE);
18315   length= strlen(buffer);
18316   rc= mysql_stmt_execute(stmt);
18317   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18318 
18319   /*
18320     Third execute; should fail (connection already closed), or SIGSEGV in
18321     case of a Bug#43560 type regression in which case the whole test fails.
18322   */
18323   strncpy(buffer, values[2], BUFSIZE);
18324   length= strlen(buffer);
18325   rc= mysql_stmt_execute(stmt);
18326   DIE_UNLESS(rc && (mysql_stmt_errno(stmt) == CR_SERVER_LOST ||
18327                     mysql_stmt_errno(stmt) == CR_SERVER_GONE_ERROR));
18328 
18329   opt_drop_db= 0;
18330   client_disconnect(conn);
18331   rc= mysql_query(mysql, "DROP TABLE t1");
18332   myquery(rc);
18333   opt_drop_db= drop_db;
18334 
18335   DBUG_VOID_RETURN;
18336 }
18337 
18338 
18339 /**
18340   Bug#36326: nested transaction and select
18341 */
18342 
test_bug36326()18343 static void test_bug36326()
18344 {
18345   int rc;
18346 
18347   DBUG_ENTER("test_bug36326");
18348   myheader("test_bug36326");
18349 
18350   if (! is_query_cache_available())
18351   {
18352     fprintf(stdout, "Skipping test_bug36326: Query cache not available.\n");
18353     DBUG_VOID_RETURN;
18354   }
18355 
18356   rc= mysql_autocommit(mysql, TRUE);
18357   myquery(rc);
18358   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18359   myquery(rc);
18360   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
18361   myquery(rc);
18362   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
18363   myquery(rc);
18364   rc= mysql_query(mysql,
18365                   "set @save_query_cache_type="
18366                   "@@global.query_cache_type,"
18367                   "@save_query_cache_size="
18368                   "@@global.query_cache_size");
18369   myquery(rc);
18370   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
18371   myquery(rc);
18372   rc= mysql_query(mysql, "SET LOCAL query_cache_type = 1");
18373   myquery(rc);
18374   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576");
18375   myquery(rc);
18376   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18377   DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
18378   rc= mysql_query(mysql, "BEGIN");
18379   myquery(rc);
18380   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
18381   rc= mysql_query(mysql, "SELECT * FROM t1");
18382   myquery(rc);
18383   rc= my_process_result(mysql);
18384   DIE_UNLESS(rc == 1);
18385   rc= mysql_rollback(mysql);
18386   myquery(rc);
18387   rc= mysql_query(mysql, "ROLLBACK");
18388   myquery(rc);
18389   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18390   rc= mysql_query(mysql, "SELECT * FROM t1");
18391   myquery(rc);
18392   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18393   rc= my_process_result(mysql);
18394   DIE_UNLESS(rc == 1);
18395   rc= mysql_query(mysql, "DROP TABLE t1");
18396   myquery(rc);
18397   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = @save_query_cache_size");
18398   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = @save_query_cache_type");
18399   myquery(rc);
18400 
18401   DBUG_VOID_RETURN;
18402 }
18403 
18404 /**
18405   Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
18406              string value.
18407 */
18408 
test_bug41078(void)18409 static void test_bug41078(void)
18410 {
18411   uint         rc;
18412   MYSQL_STMT   *stmt= 0;
18413   MYSQL_BIND   param, result;
18414   ulong        cursor_type= CURSOR_TYPE_READ_ONLY;
18415   ulong        len;
18416   char         str[64];
18417   const char   param_str[]= "abcdefghijklmn";
18418   my_bool      is_null, error;
18419 
18420   DBUG_ENTER("test_bug41078");
18421 
18422   rc= mysql_query(mysql, "SET NAMES UTF8");
18423   myquery(rc);
18424 
18425   stmt= mysql_simple_prepare(mysql, "SELECT ?");
18426   check_stmt(stmt);
18427   verify_param_count(stmt, 1);
18428 
18429   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type);
18430   check_execute(stmt, rc);
18431 
18432   bzero(&param, sizeof(param));
18433   param.buffer_type= MYSQL_TYPE_STRING;
18434   param.buffer= (void *) param_str;
18435   len= sizeof(param_str) - 1;
18436   param.length= &len;
18437 
18438   rc= mysql_stmt_bind_param(stmt, &param);
18439   check_execute(stmt, rc);
18440 
18441   rc= mysql_stmt_execute(stmt);
18442   check_execute(stmt, rc);
18443 
18444   bzero(&result, sizeof(result));
18445   result.buffer_type= MYSQL_TYPE_STRING;
18446   result.buffer= str;
18447   result.buffer_length= sizeof(str);
18448   result.is_null= &is_null;
18449   result.length= &len;
18450   result.error=  &error;
18451 
18452   rc= mysql_stmt_bind_result(stmt, &result);
18453   check_execute(stmt, rc);
18454 
18455   rc= mysql_stmt_store_result(stmt);
18456   check_execute(stmt, rc);
18457 
18458   rc= mysql_stmt_fetch(stmt);
18459   check_execute(stmt, rc);
18460 
18461   DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str));
18462 
18463   mysql_stmt_close(stmt);
18464 
18465   DBUG_VOID_RETURN;
18466 }
18467 
18468 /**
18469   Bug#45010: invalid memory reads during parsing some strange statements
18470 */
test_bug45010()18471 static void test_bug45010()
18472 {
18473   int rc;
18474   const char query1[]= "select a.\x80",
18475              query2[]= "describe `table\xef";
18476 
18477   DBUG_ENTER("test_bug45010");
18478   myheader("test_bug45010");
18479 
18480   rc= mysql_query(mysql, "set names utf8");
18481   myquery(rc);
18482 
18483   /* \x80 (-128) could be used as a index of ident_map. */
18484   rc= mysql_real_query(mysql, query1, sizeof(query1) - 1);
18485   DIE_UNLESS(rc);
18486 
18487   /* \xef (-17) could be used to skip 3 bytes past the buffer end. */
18488   rc= mysql_real_query(mysql, query2, sizeof(query2) - 1);
18489   DIE_UNLESS(rc);
18490 
18491   rc= mysql_query(mysql, "set names default");
18492   myquery(rc);
18493 
18494   DBUG_VOID_RETURN;
18495 }
18496 
18497 /**
18498   Bug#44495: Prepared Statement:
18499              CALL p(<x>) - `thd->protocol == &thd->protocol_text' failed
18500 */
18501 
test_bug44495()18502 static void test_bug44495()
18503 {
18504   int rc;
18505   MYSQL con;
18506   MYSQL_STMT *stmt;
18507 
18508   DBUG_ENTER("test_bug44495");
18509   myheader("test_44495");
18510 
18511   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18512   myquery(rc);
18513 
18514   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN arg VARCHAR(25))"
18515                          "  BEGIN SET @stmt = CONCAT('SELECT \"', arg, '\"');"
18516                          "  PREPARE ps1 FROM @stmt;"
18517                          "  EXECUTE ps1;"
18518                          "  DROP PREPARE ps1;"
18519                          "END;");
18520   myquery(rc);
18521 
18522   DIE_UNLESS(mysql_client_init(&con));
18523 
18524   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18525                                 current_db, opt_port, opt_unix_socket,
18526                                 CLIENT_MULTI_RESULTS));
18527 
18528   stmt= mysql_simple_prepare(&con, "CALL p1('abc')");
18529   check_stmt(stmt);
18530 
18531   rc= mysql_stmt_execute(stmt);
18532   check_execute(stmt, rc);
18533 
18534   rc= my_process_stmt_result(stmt);
18535   DIE_UNLESS(rc == 1);
18536 
18537   mysql_stmt_close(stmt);
18538 
18539   mysql_close(&con);
18540 
18541   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18542   myquery(rc);
18543 
18544   DBUG_VOID_RETURN;
18545 }
18546 
test_bug53371()18547 static void test_bug53371()
18548 {
18549   int rc;
18550   MYSQL_RES *result;
18551 
18552   myheader("test_bug53371");
18553 
18554   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18555   myquery(rc);
18556   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
18557   myquery(rc);
18558   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18559 
18560   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18561   myquery(rc);
18562   rc= mysql_query(mysql, "CREATE DATABASE bug53371");
18563   myquery(rc);
18564   rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
18565   myquery(rc);
18566 
18567   rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
18568   myquery(rc);
18569 
18570   rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
18571   DIE_UNLESS(rc);
18572   DIE_UNLESS(mysql_errno(mysql) == 1142);
18573 
18574   result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
18575   DIE_IF(result);
18576 
18577   result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
18578   DIE_IF(result);
18579 
18580   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
18581   myquery(rc);
18582   rc= mysql_query(mysql, "DROP TABLE t1");
18583   myquery(rc);
18584   rc= mysql_query(mysql, "DROP DATABASE bug53371");
18585   myquery(rc);
18586   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18587   myquery(rc);
18588 }
18589 
18590 
18591 
18592 /**
18593   Bug#42373: libmysql can mess a connection at connect
18594 */
test_bug42373()18595 static void test_bug42373()
18596 {
18597   int rc;
18598   MYSQL con;
18599   MYSQL_STMT *stmt;
18600 
18601   DBUG_ENTER("test_bug42373");
18602   myheader("test_42373");
18603 
18604   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18605   myquery(rc);
18606 
18607   rc= mysql_query(mysql, "CREATE PROCEDURE p1()"
18608                          "  BEGIN"
18609                          "  SELECT 1;"
18610                          "  INSERT INTO t1 VALUES (2);"
18611                          "END;");
18612   myquery(rc);
18613 
18614   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18615   myquery(rc);
18616 
18617   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18618   myquery(rc);
18619 
18620   /* Try with a stored procedure. */
18621   DIE_UNLESS(mysql_client_init(&con));
18622 
18623   mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()");
18624 
18625   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18626                                 current_db, opt_port, opt_unix_socket,
18627                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18628 
18629   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18630   check_stmt(stmt);
18631 
18632   rc= mysql_stmt_execute(stmt);
18633   check_execute(stmt, rc);
18634 
18635   rc= my_process_stmt_result(stmt);
18636   DIE_UNLESS(rc == 1);
18637 
18638   mysql_stmt_close(stmt);
18639   mysql_close(&con);
18640 
18641   /* Now try with a multi-statement. */
18642   DIE_UNLESS(mysql_client_init(&con));
18643 
18644   mysql_options(&con, MYSQL_INIT_COMMAND,
18645                 "SELECT 3; INSERT INTO t1 VALUES (4)");
18646 
18647   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18648                                 current_db, opt_port, opt_unix_socket,
18649                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18650 
18651   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18652   check_stmt(stmt);
18653 
18654   rc= mysql_stmt_execute(stmt);
18655   check_execute(stmt, rc);
18656 
18657   rc= my_process_stmt_result(stmt);
18658   DIE_UNLESS(rc == 2);
18659 
18660   mysql_stmt_close(stmt);
18661   mysql_close(&con);
18662 
18663   rc= mysql_query(mysql, "DROP TABLE t1");
18664   myquery(rc);
18665 
18666   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18667   myquery(rc);
18668 
18669   DBUG_VOID_RETURN;
18670 }
18671 
18672 
18673 /**
18674   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18675 */
18676 
test_bug54041_impl()18677 static void test_bug54041_impl()
18678 {
18679   int rc;
18680   MYSQL_STMT *stmt;
18681   MYSQL_BIND bind;
18682 
18683   DBUG_ENTER("test_bug54041");
18684   myheader("test_bug54041");
18685 
18686   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18687   myquery(rc);
18688 
18689   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18690   myquery(rc);
18691 
18692   stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?");
18693   check_stmt(stmt);
18694   verify_param_count(stmt, 1);
18695 
18696   memset(&bind, 0, sizeof(bind));
18697 
18698   /* Any type that does not support long data handling. */
18699   bind.buffer_type= MYSQL_TYPE_LONG;
18700 
18701   rc= mysql_stmt_bind_param(stmt, &bind);
18702   check_execute(stmt, rc);
18703 
18704   /*
18705     Trick the client API into sending a long data packet for
18706     the parameter. Long data is only supported for string and
18707     binary types.
18708   */
18709   stmt->params[0].buffer_type= MYSQL_TYPE_STRING;
18710 
18711   rc= mysql_stmt_send_long_data(stmt, 0, "data", 5);
18712   check_execute(stmt, rc);
18713 
18714   /* Undo API violation. */
18715   stmt->params[0].buffer_type= MYSQL_TYPE_LONG;
18716 
18717   rc= mysql_stmt_execute(stmt);
18718   /* Incorrect arguments. */
18719   check_execute_r(stmt, rc);
18720 
18721   mysql_stmt_close(stmt);
18722 
18723   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18724   myquery(rc);
18725 
18726   DBUG_VOID_RETURN;
18727 }
18728 
18729 
18730 /**
18731   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18732 */
18733 
test_bug54041()18734 static void test_bug54041()
18735 {
18736   enable_query_logs(0);
18737   test_bug54041_impl();
18738   disable_query_logs();
18739   test_bug54041_impl();
18740   restore_query_logs();
18741 }
18742 
18743 
18744 /**
18745   Bug#47485: mysql_store_result returns a result set for a prepared statement
18746 */
test_bug47485()18747 static void test_bug47485()
18748 {
18749   MYSQL_STMT   *stmt;
18750   MYSQL_RES    *res;
18751   MYSQL_BIND    bind[2];
18752   int           rc;
18753   const char*   sql_select = "SELECT 1, 'a'";
18754   int           int_data;
18755   char          str_data[16];
18756   my_bool       is_null[2];
18757   my_bool       error[2];
18758   unsigned long length[2];
18759 
18760   DBUG_ENTER("test_bug47485");
18761   myheader("test_bug47485");
18762 
18763   stmt= mysql_stmt_init(mysql);
18764   check_stmt(stmt);
18765   rc= mysql_stmt_prepare(stmt, sql_select, strlen(sql_select));
18766   check_execute(stmt, rc);
18767 
18768   rc= mysql_stmt_execute(stmt);
18769   check_execute(stmt, rc);
18770 
18771   res = mysql_store_result(mysql);
18772   DIE_UNLESS(res == NULL);
18773 
18774   mysql_stmt_reset(stmt);
18775 
18776   rc= mysql_stmt_execute(stmt);
18777   check_execute(stmt, rc);
18778 
18779   res = mysql_use_result(mysql);
18780   DIE_UNLESS(res == NULL);
18781 
18782   mysql_stmt_reset(stmt);
18783 
18784   memset(bind, 0, sizeof(bind));
18785   bind[0].buffer_type= MYSQL_TYPE_LONG;
18786   bind[0].buffer= (char *)&int_data;
18787   bind[0].is_null= &is_null[0];
18788   bind[0].length= &length[0];
18789   bind[0].error= &error[0];
18790 
18791   bind[1].buffer_type= MYSQL_TYPE_STRING;
18792   bind[1].buffer= (char *)str_data;
18793   bind[1].buffer_length= sizeof(str_data);
18794   bind[1].is_null= &is_null[1];
18795   bind[1].length= &length[1];
18796   bind[1].error= &error[1];
18797 
18798   rc= mysql_stmt_bind_result(stmt, bind);
18799   check_execute(stmt, rc);
18800 
18801   rc= mysql_stmt_execute(stmt);
18802   check_execute(stmt, rc);
18803 
18804   rc= mysql_stmt_store_result(stmt);
18805   check_execute(stmt, rc);
18806 
18807   while (!(rc= mysql_stmt_fetch(stmt)))
18808     ;
18809 
18810   DIE_UNLESS(rc == MYSQL_NO_DATA);
18811 
18812   mysql_stmt_reset(stmt);
18813 
18814   memset(bind, 0, sizeof(bind));
18815   bind[0].buffer_type= MYSQL_TYPE_LONG;
18816   bind[0].buffer= (char *)&int_data;
18817   bind[0].is_null= &is_null[0];
18818   bind[0].length= &length[0];
18819   bind[0].error= &error[0];
18820 
18821   bind[1].buffer_type= MYSQL_TYPE_STRING;
18822   bind[1].buffer= (char *)str_data;
18823   bind[1].buffer_length= sizeof(str_data);
18824   bind[1].is_null= &is_null[1];
18825   bind[1].length= &length[1];
18826   bind[1].error= &error[1];
18827 
18828   rc= mysql_stmt_bind_result(stmt, bind);
18829   check_execute(stmt, rc);
18830 
18831   rc= mysql_stmt_execute(stmt);
18832   check_execute(stmt, rc);
18833 
18834   while (!(rc= mysql_stmt_fetch(stmt)))
18835     ;
18836 
18837   DIE_UNLESS(rc == MYSQL_NO_DATA);
18838 
18839   mysql_stmt_close(stmt);
18840 
18841   DBUG_VOID_RETURN;
18842 }
18843 
18844 
18845 /*
18846   Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server
18847 */
test_bug58036()18848 static void test_bug58036()
18849 {
18850   MYSQL *conn;
18851   DBUG_ENTER("test_bug58036");
18852   myheader("test_bug58036");
18853 
18854   /* Part1: try to connect with ucs2 client character set */
18855   conn= mysql_client_init(NULL);
18856   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18857 
18858   if (mysql_real_connect(conn, opt_host, opt_user,
18859                          opt_password,  opt_db ? opt_db : "test",
18860                          opt_port, opt_unix_socket, 0))
18861   {
18862     if (!opt_silent)
18863       printf("mysql_real_connect() succeeded (failure expected)\n");
18864     mysql_close(conn);
18865     DIE("");
18866   }
18867 
18868   if (!opt_silent)
18869     printf("Got mysql_real_connect() error (expected): %s (%d)\n",
18870            mysql_error(conn), mysql_errno(conn));
18871   DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR ||
18872              mysql_errno(conn)== CR_CANT_READ_CHARSET);
18873   mysql_close(conn);
18874 
18875 
18876   /*
18877     Part2:
18878     - connect with latin1
18879     - then change client character set to ucs2
18880     - then try mysql_change_user()
18881   */
18882   conn= mysql_client_init(NULL);
18883   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1");
18884   if (!mysql_real_connect(conn, opt_host, opt_user,
18885                          opt_password, opt_db ? opt_db : "test",
18886                          opt_port, opt_unix_socket, 0))
18887   {
18888     if (!opt_silent)
18889       printf("mysql_real_connect() failed: %s (%d)\n",
18890              mysql_error(conn), mysql_errno(conn));
18891     mysql_close(conn);
18892     DIE("");
18893   }
18894 
18895   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18896   if (!mysql_change_user(conn, opt_user, opt_password, NULL))
18897   {
18898     if (!opt_silent)
18899       printf("mysql_change_user() succeeded, error expected!");
18900     mysql_close(conn);
18901     DIE("");
18902   }
18903 
18904   if (!opt_silent)
18905     printf("Got mysql_change_user() error (expected): %s (%d)\n",
18906            mysql_error(conn), mysql_errno(conn));
18907   mysql_close(conn);
18908   DBUG_VOID_RETURN;
18909 }
18910 
18911 
18912 /*
18913   Bug#49972: Crash in prepared statements.
18914 
18915   The following case lead to a server crash:
18916     - Use binary protocol;
18917     - Prepare a statement with OUT-parameter;
18918     - Execute the statement;
18919     - Cause re-prepare of the statement (change dependencies);
18920     - Execute the statement again -- crash here.
18921 */
18922 
test_bug49972()18923 static void test_bug49972()
18924 {
18925   int rc;
18926   MYSQL_STMT *stmt;
18927 
18928   MYSQL_BIND in_param_bind;
18929   MYSQL_BIND out_param_bind;
18930   int int_data;
18931   my_bool is_null;
18932 
18933   DBUG_ENTER("test_bug49972");
18934   myheader("test_bug49972");
18935 
18936   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
18937   myquery(rc);
18938 
18939   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18940   myquery(rc);
18941 
18942   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18943   myquery(rc);
18944 
18945   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a");
18946   myquery(rc);
18947 
18948   stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)");
18949   check_stmt(stmt);
18950 
18951   bzero((char *) &in_param_bind, sizeof (in_param_bind));
18952 
18953   in_param_bind.buffer_type= MYSQL_TYPE_LONG;
18954   in_param_bind.buffer= (char *) &int_data;
18955   int_data= 0;
18956   in_param_bind.length= 0;
18957   in_param_bind.is_null= 0;
18958 
18959   rc= mysql_stmt_bind_param(stmt, &in_param_bind);
18960 
18961   rc= mysql_stmt_execute(stmt);
18962   check_execute(stmt, rc);
18963 
18964   {
18965     bzero(&out_param_bind, sizeof (out_param_bind));
18966 
18967     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18968     out_param_bind.is_null= &is_null;
18969     out_param_bind.buffer= &int_data;
18970     out_param_bind.buffer_length= sizeof (int_data);
18971 
18972     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18973     check_execute(stmt, rc);
18974 
18975     rc= mysql_stmt_fetch(stmt);
18976     rc= mysql_stmt_fetch(stmt);
18977     DBUG_ASSERT(rc == MYSQL_NO_DATA);
18978 
18979     mysql_stmt_next_result(stmt);
18980     mysql_stmt_fetch(stmt);
18981   }
18982 
18983   rc= mysql_query(mysql, "DROP FUNCTION f1");
18984   myquery(rc);
18985 
18986   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18987   myquery(rc);
18988 
18989   rc= mysql_stmt_execute(stmt);
18990   check_execute(stmt, rc);
18991 
18992   {
18993     bzero(&out_param_bind, sizeof (out_param_bind));
18994 
18995     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18996     out_param_bind.is_null= &is_null;
18997     out_param_bind.buffer= &int_data;
18998     out_param_bind.buffer_length= sizeof (int_data);
18999 
19000     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
19001     check_execute(stmt, rc);
19002 
19003     rc= mysql_stmt_fetch(stmt);
19004     rc= mysql_stmt_fetch(stmt);
19005     DBUG_ASSERT(rc == MYSQL_NO_DATA);
19006 
19007     mysql_stmt_next_result(stmt);
19008     mysql_stmt_fetch(stmt);
19009   }
19010 
19011   mysql_stmt_close(stmt);
19012 
19013   rc= mysql_query(mysql, "DROP PROCEDURE p1");
19014   myquery(rc);
19015 
19016   rc= mysql_query(mysql, "DROP FUNCTION f1");
19017   myquery(rc);
19018 
19019   DBUG_VOID_RETURN;
19020 }
19021 
19022 
19023 /*
19024   Bug #56976:   Severe Denial Of Service in prepared statements
19025 */
test_bug56976()19026 static void test_bug56976()
19027 {
19028   MYSQL_STMT   *stmt;
19029   MYSQL_BIND    bind[1];
19030   int           rc;
19031   const char*   query = "SELECT LENGTH(?)";
19032   char *long_buffer;
19033   unsigned long i, packet_len = 256 * 1024L;
19034   unsigned long dos_len    = 35000000;
19035 
19036   DBUG_ENTER("test_bug56976");
19037   myheader("test_bug56976");
19038 
19039   stmt= mysql_stmt_init(mysql);
19040   check_stmt(stmt);
19041 
19042   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19043   check_execute(stmt, rc);
19044 
19045   memset(bind, 0, sizeof(bind));
19046   bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;
19047 
19048   rc= mysql_stmt_bind_param(stmt, bind);
19049   check_execute(stmt, rc);
19050 
19051   long_buffer= (char*) my_malloc(PSI_NOT_INSTRUMENTED, packet_len, MYF(0));
19052   DIE_UNLESS(long_buffer);
19053 
19054   memset(long_buffer, 'a', packet_len);
19055 
19056   for (i= 0; i < dos_len / packet_len; i++)
19057   {
19058     rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len);
19059     check_execute(stmt, rc);
19060   }
19061 
19062   my_free(long_buffer);
19063   rc= mysql_stmt_execute(stmt);
19064 
19065   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);
19066 
19067   mysql_stmt_close(stmt);
19068 
19069   DBUG_VOID_RETURN;
19070 }
19071 
19072 /*
19073   Test that CLIENT_PROGRESS works.
19074 */
19075 
19076 uint progress_stage, progress_max_stage, progress_count;
19077 
report_progress(const MYSQL * mysql,uint stage,uint max_stage,double progress,const char * proc_info,uint proc_info_length)19078 static void report_progress(const MYSQL *mysql __attribute__((unused)),
19079                             uint stage, uint max_stage,
19080                             double progress __attribute__((unused)),
19081                             const char *proc_info __attribute__((unused)),
19082                             uint proc_info_length __attribute__((unused)))
19083 {
19084   progress_stage= stage;
19085   progress_max_stage= max_stage;
19086   progress_count++;
19087 }
19088 
19089 
test_progress_reporting()19090 static void test_progress_reporting()
19091 {
19092   int rc, i;
19093   MYSQL*       conn;
19094 
19095   /* Progress reporting doesn't work yet with embedded server */
19096   if (embedded_server_arg_count)
19097     return;
19098 
19099   myheader("test_progress_reporting");
19100 
19101 
19102   conn= client_connect(CLIENT_PROGRESS_OBSOLETE, MYSQL_PROTOCOL_TCP, 0);
19103   DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS_OBSOLETE);
19104 
19105   mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);
19106   rc= mysql_query(conn, "set @save=@@global.progress_report_time");
19107   myquery(rc);
19108   rc= mysql_query(conn, "set @@global.progress_report_time=1");
19109   myquery(rc);
19110 
19111   rc= mysql_query(conn, "drop table if exists t1,t2");
19112   myquery(rc);
19113   rc= mysql_query(conn, "create table t1 (f2 varchar(255)) engine=aria");
19114   myquery(rc);
19115   rc= mysql_query(conn, "create table t2 like t1");
19116   myquery(rc);
19117   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))");
19118   myquery(rc);
19119   for (i= 0 ; i < 5 ; i++)
19120   {
19121     rc= mysql_query(conn, "insert into t2 (f2) select f2 from t1");
19122     myquery(rc);
19123     rc= mysql_query(conn, "insert into t1 (f2) select f2 from t2");
19124     myquery(rc);
19125   }
19126 
19127   progress_stage= progress_max_stage= progress_count= 0;
19128   rc= mysql_query(conn, "alter table t1 add f1 int primary key auto_increment, order by f2");
19129   myquery(rc);
19130   if (!opt_silent)
19131     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19132            progress_count, progress_stage, progress_max_stage);
19133   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 3);
19134 
19135   progress_stage= progress_max_stage= progress_count= 0;
19136   rc= mysql_query(conn, "create index f2 on t1 (f2)");
19137   myquery(rc);
19138   if (!opt_silent)
19139     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19140            progress_count, progress_stage, progress_max_stage);
19141   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 2);
19142 
19143   progress_stage= progress_max_stage= progress_count= 0;
19144   rc= mysql_query(conn, "drop index f2 on t1");
19145   myquery(rc);
19146   if (!opt_silent)
19147     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19148            progress_count, progress_stage, progress_max_stage);
19149   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 2);
19150 
19151   rc= mysql_query(conn, "set @@global.progress_report_time=@save");
19152   myquery(rc);
19153   mysql_close(conn);
19154 }
19155 
19156 /**
19157   MDEV-3885 - connection suicide via mysql_kill() causes assertion in server
19158 */
19159 
test_mdev3885()19160 static void test_mdev3885()
19161 {
19162   int rc;
19163   MYSQL *conn;
19164 
19165   myheader("test_mdev3885");
19166   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
19167   rc= mysql_kill(conn, mysql_thread_id(conn));
19168   DIE_UNLESS(rc);
19169   mysql_close(conn);
19170 }
19171 
19172 
19173 /**
19174   Bug#57058 SERVER_QUERY_WAS_SLOW not wired up.
19175 */
19176 
test_bug57058()19177 static void test_bug57058()
19178 {
19179   MYSQL_RES *res;
19180   int rc;
19181 
19182   DBUG_ENTER("test_bug57058");
19183   myheader("test_bug57058");
19184 
19185   rc= mysql_query(mysql, "set @@session.long_query_time=0.1");
19186   myquery(rc);
19187 
19188   DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW));
19189 
19190   rc= mysql_query(mysql, "select sleep(1)");
19191   myquery(rc);
19192 
19193   /*
19194     Important: the flag is sent in the last EOF packet of
19195     the query, the one which ends the result. Read the
19196     result to see the "slow" status.
19197   */
19198   res= mysql_store_result(mysql);
19199 
19200   DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW);
19201 
19202   mysql_free_result(res);
19203 
19204   rc= mysql_query(mysql, "set @@session.long_query_time=default");
19205   myquery(rc);
19206 
19207   DBUG_VOID_RETURN;
19208 }
19209 
19210 
19211 /**
19212   Bug#11766854: 60075: MYSQL_LOAD_CLIENT_PLUGIN DOESN'T CLEAR ERROR
19213 */
19214 
test_bug11766854()19215 static void test_bug11766854()
19216 {
19217   struct st_mysql_client_plugin *plugin;
19218 
19219   DBUG_ENTER("test_bug11766854");
19220   myheader("test_bug11766854");
19221 
19222   plugin= mysql_load_plugin(mysql, "foo", -1, 0);
19223   DIE_UNLESS(plugin == 0);
19224 
19225   plugin= mysql_load_plugin(mysql, "qa_auth_client", -1, 0);
19226   DIE_UNLESS(plugin != 0);
19227   DIE_IF(mysql_errno(mysql));
19228 
19229   DBUG_VOID_RETURN;
19230 }
19231 
19232 /**
19233   Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR
19234                        CHAR/VARCHAR/TEXT COLUMNS IN VIEWS
19235 */
test_bug12337762()19236 static void test_bug12337762()
19237 {
19238   int rc,i=0;
19239   MYSQL_RES *result;
19240   MYSQL_FIELD *field;
19241   unsigned int tab_charsetnr[3]= {0};
19242 
19243   DBUG_ENTER("test_bug12337762");
19244   myheader("test_bug12337762");
19245 
19246   /*
19247     Creating table with specific charset.
19248   */
19249   rc= mysql_query(mysql, "drop table if exists charset_tab");
19250   rc= mysql_query(mysql, "create table charset_tab("\
19251                          "txt1 varchar(32) character set Latin1,"\
19252                          "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
19253                          "txt3 varchar(32) character set utf8 collate utf8_bin"\
19254 						 ")");
19255 
19256   DIE_UNLESS(rc == 0);
19257   DIE_IF(mysql_errno(mysql));
19258 
19259   /*
19260     Creating view from table created earlier.
19261   */
19262   rc= mysql_query(mysql, "drop view if exists charset_view");
19263   rc= mysql_query(mysql, "create view charset_view as "\
19264                          "select * from charset_tab;");
19265   DIE_UNLESS(rc == 0);
19266   DIE_IF(mysql_errno(mysql));
19267 
19268   /*
19269     Checking field information for table.
19270   */
19271   result= mysql_list_fields(mysql, "charset_tab", NULL);
19272   DIE_IF(mysql_errno(mysql));
19273   i=0;
19274   while((field= mysql_fetch_field(result)))
19275   {
19276     printf("field name %s\n", field->name);
19277     printf("field table %s\n", field->table);
19278     printf("field type %d\n", field->type);
19279     printf("field charset %d\n", field->charsetnr);
19280     tab_charsetnr[i++]= field->charsetnr;
19281     printf("\n");
19282   }
19283   mysql_free_result(result);
19284 
19285   /*
19286     Checking field information for view.
19287   */
19288   result= mysql_list_fields(mysql, "charset_view", NULL);
19289   DIE_IF(mysql_errno(mysql));
19290   i=0;
19291   while((field= mysql_fetch_field(result)))
19292   {
19293     printf("field name %s\n", field->name);
19294     printf("field table %s\n", field->table);
19295     printf("field type %d\n", field->type);
19296     printf("field charset %d\n", field->charsetnr);
19297     printf("\n");
19298     /*
19299       charset value for field must be same for both, view and table.
19300     */
19301     DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
19302   }
19303   mysql_free_result(result);
19304 
19305   DBUG_VOID_RETURN;
19306 }
19307 
19308 /*
19309    MDEV-4603: mysql_stmt_reset doesn't clear
19310               all result sets (from stored procedures).
19311    This test requires also fix for MDEV-4604
19312 */
test_mdev4603()19313 static void test_mdev4603()
19314 {
19315   MYSQL *my;
19316   MYSQL_STMT *stmt;
19317   int i, rc;
19318   int a[] = {10,20,30};
19319   MYSQL_BIND bind[3];
19320 
19321   myheader("test_mdev4603");
19322   my= mysql_client_init(NULL);
19323 
19324   if (!mysql_real_connect(my, opt_host, opt_user,
19325                                opt_password, current_db, opt_port,
19326                                opt_unix_socket, CLIENT_MULTI_RESULTS))
19327     DIE("mysql_real_connect failed");
19328 
19329   /* 1st test:
19330      use a procedure with out param
19331   */
19332   rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1");
19333   myquery(rc);
19334 
19335   rc= mysql_query(mysql, "CREATE PROCEDURE p1(OUT p_out VARCHAR(19), IN p_in INT, INOUT p_inout INT)"
19336                          "BEGIN "
19337                           "  SET p_in = 300, p_out := 'This is OUT param', p_inout = 200; "
19338                           "  SELECT p_inout, p_in, substring(p_out, 9);"
19339                          "END");
19340   myquery(rc);
19341 
19342   stmt= mysql_stmt_init(mysql);
19343   DIE_UNLESS(stmt != NULL);
19344 
19345   rc= mysql_stmt_prepare(stmt, "CALL P1(?,?,?)", 14);
19346   DIE_UNLESS(rc == 0);
19347 
19348   DIE_UNLESS(mysql_stmt_param_count(stmt) == 3);
19349 
19350   memset(bind, 0, sizeof(MYSQL_BIND) * 3);
19351   for (i=0; i < 3; i++)
19352   {
19353     bind[i].buffer= &a[i];
19354     bind[i].buffer_type= MYSQL_TYPE_LONG;
19355   }
19356   bind[0].buffer_type= MYSQL_TYPE_NULL;
19357   rc= mysql_stmt_bind_param(stmt, bind);
19358   DIE_UNLESS(rc == 0);
19359 
19360   rc= mysql_stmt_execute(stmt);
19361   DIE_UNLESS(rc == 0);
19362 
19363   rc= mysql_stmt_fetch(stmt);
19364   DIE_UNLESS(rc == 0);
19365 
19366   rc= mysql_stmt_reset(stmt);
19367   DIE_UNLESS(rc == 0);
19368 
19369   /*connection shouldn't be blocked now */
19370 
19371   rc= mysql_query(mysql, "DROP PROCEDURE p1");
19372   myquery(rc);
19373 
19374   /* 2nd test:
19375      reset all result sets */
19376   rc= mysql_query(my, "CREATE PROCEDURE p1() "
19377                       "BEGIN"
19378                       "  SELECT 1,2,3 FROM DUAL;"
19379                       "  SELECT 'foo' FROM DUAL;"
19380                       "END");
19381   myquery(rc);
19382 
19383   rc= mysql_stmt_prepare(stmt, "CALL P1()", 9);
19384   DIE_UNLESS(rc == 0);
19385 
19386   rc= mysql_stmt_execute(stmt);
19387   DIE_UNLESS(rc == 0);
19388 
19389   rc= mysql_stmt_reset(stmt);
19390   DIE_UNLESS(rc == 0);
19391 
19392   /* 3rd test:
19393      mysql_stmt_close should also flush all pending
19394      result sets
19395   */
19396 
19397   rc= mysql_stmt_prepare(stmt, "CALL P1()", 9);
19398   DIE_UNLESS(rc == 0);
19399 
19400   rc= mysql_stmt_execute(stmt);
19401   DIE_UNLESS(rc == 0);
19402 
19403   rc= mysql_stmt_close(stmt);
19404   DIE_UNLESS(rc == 0);
19405 
19406   rc= mysql_query(my, "DROP PROCEDURE p1");
19407   myquery(rc);
19408 
19409   mysql_close(my);
19410 }
19411 
19412 /*
19413   BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
19414 */
19415 
test_bug11754979()19416 static void test_bug11754979()
19417 {
19418   MYSQL* conn;
19419   DBUG_ENTER("test_bug11754979");
19420 
19421   myheader("test_bug11754979");
19422   DIE_UNLESS((conn= mysql_client_init(NULL)));
19423   DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
19424              opt_password, opt_db ? opt_db:"test", opt_port,
19425              opt_unix_socket,  CLIENT_FOUND_ROWS));
19426   myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
19427   myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
19428   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
19429   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
19430                             "ON DUPLICATE KEY UPDATE id = 4"));
19431   DIE_UNLESS(mysql_affected_rows(conn) == 2);
19432   myquery(mysql_query(conn, "DROP TABLE t1"));
19433   mysql_close(conn);
19434 
19435   DBUG_VOID_RETURN;
19436 }
19437 
test_ps_sp_out_params()19438 static void test_ps_sp_out_params()
19439 {
19440   MYSQL *my;
19441   MYSQL_STMT *stmt;
19442   MYSQL_BIND bind[1];
19443   char buffer[20];
19444   int status, rc;
19445 
19446   myheader("test_ps_sp_out_params");
19447   my= mysql_client_init(NULL);
19448 
19449   if (!mysql_real_connect(my, opt_host, opt_user,
19450                                opt_password, current_db, opt_port,
19451                                opt_unix_socket, CLIENT_MULTI_RESULTS))
19452     DIE("mysql_real_connect failed");
19453 
19454   rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1");
19455   myquery(rc);
19456 
19457   rc= mysql_query(my,
19458     "CREATE PROCEDURE p1(OUT out_param VARCHAR(19)) "
19459     "BEGIN"
19460     " SELECT 'foo' FROM DUAL;"
19461     " SET out_param='foo';"
19462     " SELECT 'foo' FROM DUAL;"
19463     "END");
19464   myquery(rc);
19465 
19466   stmt= mysql_stmt_init(my);
19467 
19468   rc= mysql_stmt_prepare(stmt, "CALL P1(?)", 10);
19469   DIE_UNLESS(rc==0);
19470 
19471   DIE_UNLESS(mysql_stmt_param_count(stmt) == 1);
19472 
19473   memset(bind, 0, sizeof(MYSQL_BIND));
19474   memset(buffer, 0, sizeof buffer);
19475   bind[0].buffer= buffer;
19476   bind[0].buffer_length= sizeof(buffer);
19477   bind[0].buffer_type= MYSQL_TYPE_STRING;
19478 
19479   mysql_stmt_bind_param(stmt, bind);
19480 
19481   rc= mysql_stmt_execute(stmt);
19482   check_execute(stmt, rc);
19483 
19484   do {
19485     if (mysql_stmt_field_count(stmt))
19486     {
19487       /* since server sends a status packet at the end,
19488          there must follow at least one additional packet */
19489       DIE_UNLESS(mysql_more_results(stmt->mysql));
19490 
19491       mysql_stmt_bind_result(stmt, bind);
19492 
19493       rc= mysql_stmt_fetch(stmt);
19494       DIE_UNLESS(rc== 0);
19495 
19496       DIE_UNLESS(strcmp(buffer, "foo") == 0);
19497     }
19498     status= mysql_stmt_next_result(stmt);
19499   } while (status == 0);
19500 
19501   rc= mysql_stmt_reset(stmt);
19502   DIE_UNLESS(rc== 0);
19503 
19504   mysql_stmt_close(stmt);
19505   mysql_close(my);
19506 
19507   printf("end\n");
19508 }
19509 
19510 /*
19511   Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
19512 */
test_bug13001491()19513 static void test_bug13001491()
19514 {
19515   int rc;
19516   char query[MAX_TEST_QUERY_LENGTH];
19517   MYSQL *c;
19518 
19519   myheader("test_bug13001491");
19520 
19521   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19522            "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
19523            opt_host ? opt_host : "'localhost'");
19524 
19525   rc= mysql_query(mysql, query);
19526   myquery(rc);
19527 
19528   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19529            "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
19530            opt_host ? opt_host : "'localhost'");
19531 
19532   rc= mysql_query(mysql, query);
19533   myquery(rc);
19534 
19535   c= mysql_client_init(NULL);
19536 
19537   DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
19538                                 current_db, opt_port, opt_unix_socket,
19539                                 CLIENT_MULTI_STATEMENTS |
19540                                 CLIENT_MULTI_RESULTS));
19541 
19542   rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
19543   myquery(rc);
19544 
19545   rc= mysql_query(c,
19546     "CREATE PROCEDURE p1() "
19547     "BEGIN "
19548     " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
19549     " SELECT COUNT(*) "
19550     " FROM INFORMATION_SCHEMA.PROCESSLIST "
19551     " GROUP BY user "
19552     " ORDER BY NULL "
19553     " INTO @a; "
19554     "END");
19555   myquery(rc);
19556 
19557   rc= mysql_query(c, "CALL p1()");
19558   myquery(rc);
19559 
19560   mysql_free_result(mysql_store_result(c));
19561 
19562   /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
19563   rc= mysql_refresh(c, REFRESH_GRANT |
19564                        REFRESH_TABLES | REFRESH_HOSTS |
19565                        REFRESH_STATUS | REFRESH_THREADS);
19566   myquery(rc);
19567 
19568   /*
19569     Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
19570     fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
19571     location.
19572   */
19573   mysql_refresh(c, REFRESH_LOG);
19574 
19575   rc= mysql_query(c, "DROP PROCEDURE p1");
19576   myquery(rc);
19577 
19578   mysql_close(c);
19579   c= NULL;
19580 
19581   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19582            "DROP USER mysqltest_u1@%s",
19583            opt_host ? opt_host : "'localhost'");
19584 
19585   rc= mysql_query(mysql, query);
19586   myquery(rc);
19587 }
19588 
test_mdev4326()19589 static void test_mdev4326()
19590 {
19591   MYSQL_STMT   *stmt;
19592   MYSQL_BIND    bind;
19593   char query[]= "SELECT * FROM mysql.user LIMIT ?";
19594   char str_data[]= "1";
19595   unsigned long length= 0;
19596   int int_data= 1;
19597   int rc, count;
19598   my_bool is_null= 0;
19599   my_bool error= 0;
19600   myheader("test_mdev4326");
19601 
19602   rc= mysql_change_user(mysql, opt_user, opt_password, "mysql");
19603   myquery(rc);
19604 
19605   rc= mysql_query(mysql, "SET GLOBAL general_log = 1");
19606   myquery(rc);
19607 
19608   stmt= mysql_stmt_init(mysql);
19609   check_stmt(stmt);
19610 
19611   /* Numeric parameter test */
19612 
19613   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19614   check_execute(stmt, rc);
19615   check_stmt(stmt);
19616   verify_param_count(stmt, 1);
19617 
19618   memset((char *)&bind, 0, sizeof(bind));
19619   bind.buffer_type= MYSQL_TYPE_LONG;
19620   bind.buffer= (char *)&int_data;
19621   bind.is_null= &is_null;
19622   bind.length= &length;
19623   bind.error= &error;
19624 
19625   rc= mysql_stmt_bind_param(stmt, &bind);
19626   check_execute(stmt, rc);
19627   rc= mysql_stmt_execute(stmt);
19628   check_execute(stmt, rc);
19629   count= 0;
19630   while (!(rc= mysql_stmt_fetch(stmt)))
19631     count++;
19632   DIE_UNLESS(count == 1);
19633   rc= mysql_stmt_execute(stmt);
19634   check_execute(stmt, rc);
19635   count= 0;
19636   while (!(rc= mysql_stmt_fetch(stmt)))
19637     count++;
19638   DIE_UNLESS(count == 1);
19639   int_data= 0;
19640   rc= mysql_stmt_execute(stmt);
19641   check_execute(stmt, rc);
19642   count= 0;
19643   while (!(rc= mysql_stmt_fetch(stmt)))
19644     count++;
19645   DIE_UNLESS(count == 0);
19646   rc= mysql_stmt_close(stmt);
19647   check_execute(stmt, rc);
19648 
19649   /* String parameter test */
19650 
19651   stmt= mysql_stmt_init(mysql);
19652   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19653   check_execute(stmt, rc);
19654   check_stmt(stmt);
19655   verify_param_count(stmt, 1);
19656 
19657   memset((char *)&bind, 0, sizeof(bind));
19658   bind.buffer_type= MYSQL_TYPE_STRING;
19659   bind.buffer= (char *)str_data;
19660   length= bind.buffer_length= sizeof(str_data);
19661   bind.is_null= &is_null;
19662   bind.length= &length;
19663   bind.error= &error;
19664 
19665   rc= mysql_stmt_bind_param(stmt, &bind);
19666   check_execute(stmt, rc);
19667   rc= mysql_stmt_execute(stmt);
19668   check_execute(stmt, rc);
19669   count= 0;
19670   while (!(rc= mysql_stmt_fetch(stmt)))
19671     count++;
19672   DIE_UNLESS(count == 1);
19673   rc= mysql_stmt_execute(stmt);
19674   check_execute(stmt, rc);
19675   count= 0;
19676   while (!(rc= mysql_stmt_fetch(stmt)))
19677     count++;
19678   DIE_UNLESS(count == 1);
19679   str_data[0]= '0';
19680   rc= mysql_stmt_execute(stmt);
19681   check_execute(stmt, rc);
19682   count= 0;
19683   while (!(rc= mysql_stmt_fetch(stmt)))
19684     count++;
19685   DIE_UNLESS(count == 0);
19686   rc= mysql_stmt_close(stmt);
19687   check_execute(stmt, rc);
19688 
19689   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
19690   myquery(rc);
19691 }
19692 
19693 /* Test uses MYSQL_PROTOCOL_SOCKET, not on Windows */
19694 
19695 #ifndef _WIN32
19696 /**
19697    BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST()
19698 */
test_bug17512527()19699 static void test_bug17512527()
19700 {
19701   MYSQL *conn;
19702   MYSQL_STMT *stmt1, *stmt2;
19703   unsigned long thread_id;
19704   char query[MAX_TEST_QUERY_LENGTH];
19705   int rc;
19706 
19707   conn= client_connect(0, MYSQL_PROTOCOL_SOCKET, 1);
19708 
19709   stmt1 = mysql_stmt_init(conn);
19710   check_stmt(stmt1);
19711   rc= mysql_stmt_prepare(stmt1, STRING_WITH_LEN("SELECT 1"));
19712   check_execute(stmt1, rc);
19713 
19714   stmt2 = mysql_stmt_init(conn);
19715   check_stmt(stmt2);
19716 
19717   thread_id= mysql_thread_id(conn);
19718   sprintf(query, "KILL %lu", thread_id);
19719   if (thread_query(query))
19720     exit(1);
19721 
19722   rc= mysql_stmt_prepare(stmt2, STRING_WITH_LEN("SELECT 2"));
19723   check_execute(stmt2, rc);
19724 
19725   rc= mysql_stmt_execute(stmt1);
19726   check_execute_r(stmt1, rc);
19727 
19728   rc= mysql_stmt_execute(stmt2);
19729   check_execute(stmt2, rc);
19730 
19731   mysql_close(conn);
19732 
19733   mysql_stmt_close(stmt2);
19734   mysql_stmt_close(stmt1);
19735 }
19736 #endif
19737 
19738 
19739 /*
19740   Check compressed protocol
19741 */
19742 
test_compressed_protocol()19743 static void test_compressed_protocol()
19744 {
19745   MYSQL *mysql_local;
19746   char query[4096], *end;
19747   int i;
19748   myheader("test_compressed_protocol");
19749 
19750   if (!(mysql_local= mysql_client_init(NULL)))
19751   {
19752     fprintf(stderr, "\n mysql_client_init() failed");
19753     exit(1);
19754   }
19755 
19756   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
19757                            opt_password, current_db, opt_port,
19758                            opt_unix_socket, CLIENT_COMPRESS)))
19759   {
19760     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
19761     exit(1);
19762   }
19763   mysql_options(mysql_local,MYSQL_OPT_COMPRESS,NullS);
19764 
19765   end= strmov(strfill(strmov(query, "select length(\""),1000,'a'),"\")");
19766 
19767   for (i=0 ; i < 2 ; i++)
19768   {
19769     MYSQL_RES *res;
19770 
19771     int rc= mysql_real_query(mysql, query, (int) (end-query));
19772     myquery(rc);
19773     res= mysql_store_result(mysql);
19774     DBUG_ASSERT(res != 0);
19775     mysql_free_result(res);
19776   }
19777 
19778   mysql_close(mysql_local);
19779 }
19780 
19781 /*
19782   Check big packets
19783 */
19784 
test_big_packet()19785 static void test_big_packet()
19786 {
19787   MYSQL *mysql_local;
19788   char *query, *end;
19789   /* We run the tests with a server with max packet size of 3200000 */
19790   size_t big_packet= 31000000L;
19791   int i;
19792   MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
19793   long org_max_allowed_packet= *mysql_params->p_max_allowed_packet;
19794   long opt_net_buffer_length= *mysql_params->p_net_buffer_length;
19795 
19796   myheader("test_big_packet");
19797 
19798   query= (char*) my_malloc(PSI_NOT_INSTRUMENTED, big_packet+1024, MYF(MY_WME));
19799   DIE_UNLESS(query);
19800 
19801   if (!(mysql_local= mysql_client_init(NULL)))
19802   {
19803     fprintf(stderr, "\n mysql_client_init() failed");
19804     exit(1);
19805   }
19806 
19807   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
19808                            opt_password, current_db, opt_port,
19809                            opt_unix_socket, 0)))
19810   {
19811     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
19812     mysql_close(mysql_local);
19813     exit(1);
19814   }
19815 
19816   *mysql_params->p_max_allowed_packet= big_packet+1000;
19817   *mysql_params->p_net_buffer_length=  8L*256L*256L;
19818 
19819   end= strmov(strfill(strmov(query, "select length(\""), big_packet,'a'),"\")");
19820 
19821   for (i=0 ; i < 2 ; i++)
19822   {
19823     MYSQL_RES *res;
19824     int rc= mysql_real_query(mysql, query, (int) (end-query));
19825     myquery(rc);
19826     res= mysql_store_result(mysql);
19827     DBUG_ASSERT(res != 0);
19828     mysql_free_result(res);
19829   }
19830 
19831   mysql_close(mysql_local);
19832   my_free(query);
19833 
19834   *mysql_params->p_max_allowed_packet= org_max_allowed_packet;
19835   *mysql_params->p_net_buffer_length = opt_net_buffer_length;
19836 }
19837 
19838 
test_prepare_analyze()19839 static void test_prepare_analyze()
19840 {
19841   MYSQL_STMT *stmt;
19842   const char *query= "ANALYZE SELECT 1";
19843   int rc;
19844   myheader("test_prepare_analyze");
19845 
19846   stmt= mysql_stmt_init(mysql);
19847   check_stmt(stmt);
19848   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19849   check_execute(stmt, rc);
19850 
19851   rc= mysql_stmt_execute(stmt);
19852   check_execute(stmt, rc);
19853 
19854   rc= mysql_stmt_store_result(stmt);
19855   check_execute(stmt, rc);
19856 
19857   while (!(rc= mysql_stmt_fetch(stmt)))
19858     ;
19859 
19860   DIE_UNLESS(rc == MYSQL_NO_DATA);
19861 
19862   rc= mysql_stmt_close(stmt);
19863   check_execute(stmt, rc);
19864 }
19865 
test_mdev12579()19866 static void test_mdev12579()
19867 {
19868   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
19869   MYSQL_BIND bind[2];
19870   int rc;
19871   long l=3;
19872   const char *data = "123456";
19873 
19874   rc= mysql_query(mysql, "CREATE TABLE mdev12579 (k integer,t LONGTEXT,b LONGBLOB,x integer)");
19875   myquery(rc);
19876 
19877   rc= mysql_stmt_prepare(stmt, "INSERT INTO mdev12579 VALUES (1,?,NULL,?)", -1);
19878   myquery(rc);
19879 
19880   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19881   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19882   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19883 
19884   memset(bind, 0, sizeof(MYSQL_BIND) * 2);
19885   bind[0].buffer_type= MYSQL_TYPE_VAR_STRING;
19886   bind[1].buffer_type= MYSQL_TYPE_LONG;
19887   bind[1].buffer= &l;
19888   mysql_stmt_bind_param(stmt, bind);
19889 
19890   rc= mysql_stmt_execute(stmt);
19891   check_execute(stmt, rc);
19892 
19893   mysql_stmt_close(stmt);
19894 
19895   rc= mysql_query(mysql, "DROP TABLE mdev12579");
19896   myquery(rc);
19897 }
19898 
19899 /* Test test_mdev14013 sql_mode=EMPTY_STRING_IS_NULL */
19900 
test_mdev14013()19901 static void test_mdev14013()
19902 {
19903   MYSQL *lmysql;
19904   MYSQL_STMT *stmt1;
19905   MYSQL_BIND  my_bind[2];
19906   MYSQL_RES   *result;
19907   char       str_data[20];
19908   unsigned int  count;
19909   int   rc;
19910   char query[MAX_TEST_QUERY_LENGTH];
19911 
19912   myheader("test_mdev14013");
19913 
19914   if (!opt_silent)
19915     fprintf(stdout, "\n Establishing a test connection ...");
19916   if (!(lmysql= mysql_client_init(NULL)))
19917   {
19918     myerror("mysql_client_init() failed");
19919     exit(1);
19920   }
19921   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
19922                            opt_password, current_db, opt_port,
19923                            opt_unix_socket, 0)))
19924   {
19925     myerror("connection failed");
19926     exit(1);
19927   }
19928   mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
19929   if (!opt_silent)
19930     fprintf(stdout, "OK");
19931 
19932   /* set AUTOCOMMIT to ON*/
19933   mysql_autocommit(lmysql, TRUE);
19934 
19935   strmov(query, "SET SQL_MODE= \"EMPTY_STRING_IS_NULL\"");
19936   if (!opt_silent)
19937     fprintf(stdout, "\n With %s", query);
19938   rc= mysql_query(mysql, query);
19939   myquery(rc);
19940 
19941   rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_mdev14013");
19942   myquery(rc);
19943 
19944   rc= mysql_query(lmysql, "CREATE TABLE test_mdev14013(id int, val varchar(10))");
19945   myquery(rc);
19946 
19947   strmov(query, "INSERT INTO test_mdev14013(id,val) VALUES(?,?)");
19948   stmt1= mysql_simple_prepare(mysql, query);
19949   check_stmt(stmt1);
19950 
19951   verify_param_count(stmt1, 2);
19952 
19953   /*
19954     We need to bzero bind structure because mysql_stmt_bind_param checks all
19955     its members.
19956   */
19957   bzero((char*) my_bind, sizeof(my_bind));
19958 
19959   my_bind[0].buffer= (void *)&count;
19960   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
19961   count= 100;
19962 
19963   strcpy(str_data,"");
19964   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
19965   my_bind[1].buffer= (char *) str_data;
19966   my_bind[1].buffer_length= strlen(str_data);
19967 
19968   rc= mysql_stmt_bind_param(stmt1, my_bind);
19969 
19970   rc= mysql_stmt_execute(stmt1);
19971   check_execute(stmt1, rc);
19972 
19973   verify_st_affected_rows(stmt1, 1);
19974 
19975   rc= mysql_stmt_close(stmt1);
19976 
19977   strmov(query, "SET SQL_MODE= default");
19978   if (!opt_silent)
19979     fprintf(stdout, "\n With %s\n", query);
19980   rc= mysql_query(mysql, query);
19981   myquery(rc);
19982 
19983   strmov(query, "INSERT INTO test_mdev14013(id,val) VALUES(?,?)");
19984   stmt1= mysql_simple_prepare(mysql, query);
19985   check_stmt(stmt1);
19986 
19987   count= 200;
19988   rc= mysql_stmt_bind_param(stmt1, my_bind);
19989 
19990   rc= mysql_stmt_execute(stmt1);
19991   check_execute(stmt1, rc);
19992 
19993   verify_st_affected_rows(stmt1, 1);
19994 
19995   rc= mysql_stmt_close(stmt1);
19996   if (!opt_silent)
19997     fprintf(stdout, "\n test_mdev14013(x) returned: %d", rc);
19998   DIE_UNLESS( rc == 0);
19999 
20000   rc= mysql_query(mysql, "SELECT id, val FROM test_mdev14013 order by id");
20001   myquery(rc);
20002 
20003   result= mysql_store_result(mysql);
20004   mytest(result);
20005 
20006   rc= my_process_result_set(result);
20007   DIE_UNLESS(rc == 2);
20008   mysql_free_result(result);
20009 
20010   rc= mysql_query(mysql, "SELECT id, val FROM test_mdev14013 where val is null");
20011   myquery(rc);
20012 
20013   result= mysql_store_result(mysql);
20014   mytest(result);
20015 
20016   rc= my_process_result_set(result);
20017   DIE_UNLESS(rc == 1);
20018   mysql_free_result(result);
20019 
20020   myquery(mysql_query(mysql, "drop table test_mdev14013"));
20021   mysql_close(lmysql);
20022 }
20023 
test_mdev14013_1()20024 static void test_mdev14013_1()
20025 {
20026   MYSQL *lmysql;
20027   MYSQL_STMT *stmt1;
20028   MYSQL_BIND  my_bind[3];
20029   char       str_data[3][255];
20030   int  rc;
20031   char query[MAX_TEST_QUERY_LENGTH];
20032 
20033   myheader("test_mdev14013_1");
20034 
20035   if (!opt_silent)
20036     fprintf(stdout, "\n Establishing a test connection ...");
20037   if (!(lmysql= mysql_client_init(NULL)))
20038   {
20039     myerror("mysql_client_init() failed");
20040     exit(1);
20041   }
20042   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
20043                            opt_password, current_db, opt_port,
20044                            opt_unix_socket, 0)))
20045   {
20046     myerror("connection failed");
20047     exit(1);
20048   }
20049   mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
20050   if (!opt_silent)
20051     fprintf(stdout, "OK");
20052 
20053   /* set AUTOCOMMIT to ON*/
20054   mysql_autocommit(lmysql, TRUE);
20055 
20056   strmov(query, "SET SQL_MODE= \"EMPTY_STRING_IS_NULL\"");
20057   if (!opt_silent)
20058     fprintf(stdout, "\n With %s", query);
20059   rc= mysql_query(mysql, query);
20060   myquery(rc);
20061 
20062   rc= mysql_query(mysql,
20063     "CREATE OR REPLACE PROCEDURE test_mdev14013_p1("
20064     "   IN i1 VARCHAR(255) , "
20065     "   INOUT io1 VARCHAR(255), "
20066     "   OUT o2 VARBINARY(255)) "
20067     "BEGIN "
20068     "   SET o2 = concat(concat(coalesce(i1,'i1 is null'),' - '),coalesce(i1,'io1 is null')); "
20069     "END");
20070   myquery(rc);
20071 
20072   strmov(query, "CALL test_mdev14013_p1(?, ?, ?)");
20073   stmt1= mysql_simple_prepare(mysql, query);
20074   check_stmt(stmt1);
20075 
20076   /* Init PS-parameters. */
20077 
20078   bzero((char *) my_bind, sizeof (my_bind));
20079 
20080   strcpy(str_data[0],"");
20081   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
20082   my_bind[0].buffer= (char *) str_data[0];
20083   my_bind[0].buffer_length= strlen(str_data[0]);
20084 
20085   strcpy(str_data[1],"");
20086   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
20087   my_bind[1].buffer= (char *) str_data[1];
20088   my_bind[1].buffer_length= strlen(str_data[1]);
20089 
20090   strcpy(str_data[2],"");
20091   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
20092   my_bind[2].buffer= (char *) str_data[2];
20093   my_bind[2].buffer_length= strlen(str_data[2]);
20094 
20095   /* Bind parameters. */
20096 
20097   rc= mysql_stmt_bind_param(stmt1, my_bind);
20098   check_execute(stmt1, rc);
20099   /* Execute */
20100 
20101   rc= mysql_stmt_execute(stmt1);
20102   check_execute(stmt1, rc);
20103 
20104   my_bind[0].buffer_length= sizeof(str_data[0]);
20105   my_bind[1].buffer_length= sizeof(str_data[1]);
20106 
20107   mysql_stmt_bind_result(stmt1, my_bind);
20108   rc= mysql_stmt_fetch(stmt1);
20109 
20110   if (!opt_silent)
20111     fprintf(stdout,"\nstr_data[1]=%s\n",str_data[1]);
20112 
20113   DIE_UNLESS(strcmp(str_data[1], "i1 is null - io1 is null") == 0);
20114 
20115   rc= mysql_stmt_close(stmt1);
20116   DIE_UNLESS( rc == 0);
20117 
20118   myquery(mysql_query(mysql, "drop procedure test_mdev14013_p1"));
20119   mysql_close(lmysql);
20120 }
20121 
20122 
test_mdev14454_internal(const char * init,unsigned int csid,const char * value)20123 static void test_mdev14454_internal(const char *init,
20124                                     unsigned int csid,
20125                                     const char *value)
20126 {
20127   MYSQL_STMT *stmt;
20128   MYSQL_BIND bind;
20129   const char *stmtstr= "CALL P1(?)";
20130   char res[20];
20131   int rc;
20132 
20133   if ((rc= mysql_query_or_error(mysql, init)) ||
20134       (rc= mysql_query_or_error(mysql, "DROP PROCEDURE IF EXISTS p1")) ||
20135       (rc= mysql_query_or_error(mysql,
20136                                "CREATE PROCEDURE p1"
20137                                "("
20138                                "  OUT param1 TEXT CHARACTER SET utf8"
20139                                ")"
20140                                "BEGIN "
20141                                "  SET param1 = _latin1'test\xFF'; "
20142                                "END")))
20143     DIE("Initiation failed");
20144 
20145   stmt= mysql_stmt_init(mysql);
20146   rc= mysql_stmt_prepare(stmt, stmtstr, strlen(stmtstr));
20147   DIE_UNLESS(rc == 0);
20148   DIE_UNLESS(mysql_stmt_param_count(stmt) == 1);
20149 
20150   memset(&bind, 0, sizeof bind);
20151   bind.buffer_type= MYSQL_TYPE_NULL;
20152   rc= mysql_stmt_bind_param(stmt, &bind);
20153   DIE_UNLESS(rc == 0);
20154 
20155   rc= mysql_stmt_execute(stmt);
20156   DIE_UNLESS(rc == 0);
20157 
20158   memset(res, 0, sizeof(res));
20159   bind.buffer_type= MYSQL_TYPE_STRING;
20160   bind.buffer_length= sizeof(res);
20161   bind.buffer= res;
20162 
20163   do {
20164     if (mysql->server_status & SERVER_PS_OUT_PARAMS)
20165     {
20166       MYSQL_FIELD *field;
20167       printf("\nOUT param result set:\n");
20168       DIE_UNLESS(mysql_stmt_field_count(stmt) == 1);
20169       field= &stmt->fields[0];
20170       printf("Field: %s\n", field->name);
20171       printf("Type: %d\n", field->type);
20172       printf("Collation: %d\n", field->charsetnr);
20173       printf("Length: %lu\n", field->length);
20174       DIE_UNLESS(stmt->fields[0].charsetnr == csid);
20175 
20176       rc= mysql_stmt_bind_result(stmt, &bind);
20177       DIE_UNLESS(rc == 0);
20178       rc= mysql_stmt_fetch(stmt);
20179       DIE_UNLESS(rc == 0);
20180       printf("Value: %s\n", res);
20181       DIE_UNLESS(strcmp(res, value) == 0);
20182     }
20183     else if (mysql_stmt_field_count(stmt))
20184     {
20185       printf("sp result set\n");
20186     }
20187   } while (mysql_stmt_next_result(stmt) == 0);
20188 
20189   mysql_stmt_close(stmt);
20190   DIE_UNLESS(mysql_query_or_error(mysql, "DROP PROCEDURE p1") == 0);
20191 }
20192 
20193 
test_mdev14454()20194 static void test_mdev14454()
20195 {
20196   myheader("test_mdev14454");
20197   test_mdev14454_internal("SET NAMES latin1", 8, "test\xFF");
20198   test_mdev14454_internal("SET NAMES utf8", 33, "test\xC3\xBF");
20199 }
20200 
20201 
20202 typedef struct {
20203   char sig[12];
20204   char ver_cmd;
20205   char fam;
20206   short len;
20207   union {
20208     struct {  /* for TCP/UDP over IPv4, len = 12 */
20209       int src_addr;
20210       int dst_addr;
20211       short src_port;
20212       short dst_port;
20213     } ip4;
20214     struct {  /* for TCP/UDP over IPv6, len = 36 */
20215       char  src_addr[16];
20216       char  dst_addr[16];
20217       short src_port;
20218       short dst_port;
20219     } ip6;
20220     struct {  /* for AF_UNIX sockets, len = 216 */
20221       char src_addr[108];
20222       char dst_addr[108];
20223     } unx;
20224   } addr;
20225 } v2_proxy_header;
20226 
20227 #ifndef EMBEDDED_LIBRARY
test_proxy_header_tcp(const char * ipaddr,int port)20228 static void test_proxy_header_tcp(const char *ipaddr, int port)
20229 {
20230 
20231   int rc;
20232   MYSQL_RES *result;
20233   int family = (strchr(ipaddr,':') == NULL)?AF_INET:AF_INET6;
20234   char query[256];
20235   char text_header[256];
20236   char addr_bin[16];
20237   v2_proxy_header v2_header;
20238   void *header_data[2];
20239   size_t header_lengths[2];
20240   int i;
20241 
20242   // normalize IPv4-mapped IPv6 addresses, e.g ::ffff:127.0.0.2 to 127.0.0.2
20243   const char *normalized_addr= strncmp(ipaddr, "::ffff:", 7)?ipaddr : ipaddr + 7;
20244 
20245   memset(&v2_header, 0, sizeof(v2_header));
20246   sprintf(text_header,"PROXY %s %s %s %d 3306\r\n",family == AF_INET?"TCP4":"TCP6", ipaddr, ipaddr, port);
20247 
20248   inet_pton(family,ipaddr,addr_bin);
20249 
20250   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20251   v2_header.ver_cmd = (0x2 << 4) | 0x1; /* Version (0x2) , Command = PROXY (0x1) */
20252   if(family == AF_INET)
20253   {
20254     v2_header.fam= 0x11;
20255     v2_header.len= htons(12);
20256     v2_header.addr.ip4.src_port= htons(port);
20257     v2_header.addr.ip4.dst_port= htons(3306);
20258     memcpy(&v2_header.addr.ip4.src_addr,addr_bin, sizeof (v2_header.addr.ip4.src_addr));
20259     memcpy(&v2_header.addr.ip4.dst_addr,addr_bin, sizeof (v2_header.addr.ip4.dst_addr));
20260   }
20261   else
20262   {
20263     v2_header.fam= 0x21;
20264     v2_header.len= htons(36);
20265     v2_header.addr.ip6.src_port= htons(port);
20266     v2_header.addr.ip6.dst_port= htons(3306);
20267     memcpy(v2_header.addr.ip6.src_addr,addr_bin, sizeof (v2_header.addr.ip6.src_addr));
20268     memcpy(v2_header.addr.ip6.dst_addr,addr_bin, sizeof (v2_header.addr.ip6.dst_addr));
20269   }
20270 
20271   sprintf(query,"CREATE USER 'u'@'%s' IDENTIFIED BY 'password'",normalized_addr);
20272   rc= mysql_query(mysql, query);
20273   myquery(rc);
20274 
20275   header_data[0]= text_header;
20276   header_data[1]= &v2_header;
20277 
20278   header_lengths[0]= strlen(text_header);
20279   header_lengths[1]= family == AF_INET ? 28 : 52;
20280 
20281   for (i = 0; i < 2; i++)
20282   {
20283     MYSQL *m;
20284     size_t addrlen;
20285     MYSQL_ROW row;
20286     m = mysql_client_init(NULL);
20287     DIE_UNLESS(m);
20288     mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header_data[i], header_lengths[i]);
20289     if (!mysql_real_connect(m, opt_host, "u", "password", NULL, opt_port, opt_unix_socket, 0))
20290     {
20291        DIE_UNLESS(0);
20292     }
20293     rc= mysql_query(m, "select host from information_schema.processlist WHERE ID = connection_id()");
20294     myquery(rc);
20295     /* get the result */
20296     result= mysql_store_result(m);
20297     mytest(result);
20298     row = mysql_fetch_row(result);
20299     addrlen = strlen(normalized_addr);
20300     printf("%.*s %.*s\n", (int)addrlen, row[0], (int)addrlen, normalized_addr);
20301     DIE_UNLESS(strncmp(row[0], normalized_addr, addrlen) == 0);
20302     DIE_UNLESS(atoi(row[0] + addrlen+1) == port);
20303     mysql_free_result(result);
20304     mysql_close(m);
20305   }
20306   sprintf(query,"DROP USER 'u'@'%s'",normalized_addr);
20307   rc = mysql_query(mysql, query);
20308   myquery(rc);
20309 }
20310 
20311 
20312 /* Test proxy protocol with AF_UNIX (localhost) */
test_proxy_header_localhost()20313 static void test_proxy_header_localhost()
20314 {
20315   v2_proxy_header v2_header;
20316   void *header_data = &v2_header;
20317   size_t header_length= 216 + 16;
20318   MYSQL *m;
20319   MYSQL_RES *result;
20320   MYSQL_ROW row;
20321   int rc;
20322 
20323   memset(&v2_header, 0, sizeof(v2_header));
20324   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20325   v2_header.ver_cmd = (0x2 << 4) | 0x1; /* Version (0x2) , Command = PROXY (0x1) */
20326   v2_header.fam= 0x31;
20327   v2_header.len= htons(216);
20328   strcpy(v2_header.addr.unx.src_addr,"/tmp/mysql.sock");
20329   strcpy(v2_header.addr.unx.dst_addr,"/tmp/mysql.sock");
20330   rc = mysql_query(mysql, "CREATE USER 'u'@'localhost' IDENTIFIED BY 'password'");
20331   myquery(rc);
20332   m = mysql_client_init(NULL);
20333   DIE_UNLESS(m != NULL);
20334   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header_data, header_length);
20335   DIE_UNLESS(mysql_real_connect(m, opt_host, "u", "password", NULL, opt_port, opt_unix_socket, 0) == m);
20336   DIE_UNLESS(mysql_query(m, "select host from information_schema.processlist WHERE ID = connection_id()") == 0);
20337   /* get the result */
20338   result= mysql_store_result(m);
20339   mytest(result);
20340   row = mysql_fetch_row(result);
20341   DIE_UNLESS(strcmp(row[0], "localhost") == 0);
20342   mysql_free_result(result);
20343   mysql_close(m);
20344   rc = mysql_query(mysql,  "DROP USER 'u'@'localhost'");
20345   myquery(rc);
20346 }
20347 
20348 /* Proxy header ignoring */
test_proxy_header_ignore()20349 static void test_proxy_header_ignore()
20350 {
20351   int rc;
20352   MYSQL *m = mysql_client_init(NULL);
20353   v2_proxy_header v2_header;
20354   DIE_UNLESS(m != NULL);
20355   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, "PROXY UNKNOWN\r\n",15);
20356   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == m);
20357   mysql_close(m);
20358 
20359   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20360   v2_header.ver_cmd = (0x2 << 4) | 0x0; /* Version (0x2) , Command = LOCAL (0x0) */
20361   v2_header.fam= 0x0; /* AF_UNSPEC*/
20362   v2_header.len= htons(0);
20363   m = mysql_client_init(NULL);
20364   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header,16);
20365   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == m);
20366   mysql_close(m);
20367 
20368   /* test for connection denied with empty proxy_protocol_networks */
20369   rc = mysql_query(mysql, "select @@proxy_protocol_networks into @sv_proxy_protocol_networks");
20370   myquery(rc);
20371   mysql_query(mysql, "set global proxy_protocol_networks=default");
20372   myquery(rc);
20373   m = mysql_client_init(NULL);
20374   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header,16);
20375   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == 0);
20376   mysql_close(m);
20377   mysql_query(mysql, "set global proxy_protocol_networks= @sv_proxy_protocol_networks");
20378   myquery(rc);
20379 }
20380 
20381 
test_proxy_header()20382 static void test_proxy_header()
20383 {
20384   test_proxy_header_tcp("192.0.2.1",3333);
20385   test_proxy_header_tcp("2001:db8:85a3::8a2e:370:7334",2222);
20386   test_proxy_header_tcp("::ffff:192.0.2.1",2222);
20387   test_proxy_header_localhost();
20388   test_proxy_header_ignore();
20389 }
20390 
20391 
test_bulk_autoinc()20392 static void test_bulk_autoinc()
20393 {
20394   int rc;
20395   MYSQL_STMT *stmt;
20396   MYSQL_BIND bind[1];
20397   MYSQL_ROW  row;
20398   char       indicator[]= {0, STMT_INDICATOR_NULL, 0/*STMT_INDICATOR_IGNORE*/};
20399   my_bool   error[1];
20400   int        i, id[]= {2, 3, 777}, count= sizeof(id)/sizeof(id[0]);
20401   MYSQL_RES *result;
20402 
20403   rc= mysql_query(mysql, "DROP TABLE IF EXISTS ai_field_value");
20404   myquery(rc);
20405   rc= mysql_query(mysql, "CREATE TABLE ai_field_value (id int not null primary key auto_increment)");
20406   myquery(rc);
20407   stmt= mysql_stmt_init(mysql);
20408   rc= mysql_stmt_prepare(stmt, "INSERT INTO ai_field_value(id) values(?)", -1);
20409   check_execute(stmt, rc);
20410 
20411   memset(bind, 0, sizeof(bind));
20412   bind[0].buffer_type = MYSQL_TYPE_LONG;
20413   bind[0].buffer = (void *)id;
20414   bind[0].buffer_length = 0;
20415   bind[0].is_null = NULL;
20416   bind[0].length = NULL;
20417   bind[0].error = error;
20418   bind[0].u.indicator= indicator;
20419 
20420   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20421   rc= mysql_stmt_bind_param(stmt, bind);
20422   check_execute(stmt, rc);
20423 
20424   rc= mysql_stmt_execute(stmt);
20425   check_execute(stmt, rc);
20426 
20427   mysql_stmt_close(stmt);
20428 
20429   rc= mysql_query(mysql, "SELECT id FROM ai_field_value");
20430   myquery(rc);
20431 
20432   result= mysql_store_result(mysql);
20433   mytest(result);
20434 
20435   i= 0;
20436   while ((row= mysql_fetch_row(result)))
20437   {
20438     DIE_IF(atoi(row[0]) != id[i++]);
20439   }
20440   mysql_free_result(result);
20441   rc= mysql_query(mysql, "DROP TABLE ai_field_value");
20442   myquery(rc);
20443 }
20444 
test_bulk_delete()20445 static void test_bulk_delete()
20446 {
20447   int rc;
20448   MYSQL_STMT *stmt;
20449   MYSQL_BIND bind[1];
20450   MYSQL_ROW  row;
20451   char       indicator[]= {0, 0, 0};
20452   my_bool   error[1];
20453   int        i, id[]= {1, 2, 4}, count= sizeof(id)/sizeof(id[0]);
20454   MYSQL_RES *result;
20455 
20456   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20457   myquery(rc);
20458   rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key)");
20459   myquery(rc);
20460   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1),(2),(3),(4)");
20461   myquery(rc);
20462   verify_affected_rows(4);
20463 
20464   stmt= mysql_stmt_init(mysql);
20465   rc= mysql_stmt_prepare(stmt, "DELETE FROM t1 where id=?", -1);
20466   check_execute(stmt, rc);
20467 
20468   memset(bind, 0, sizeof(bind));
20469   bind[0].buffer_type = MYSQL_TYPE_LONG;
20470   bind[0].buffer = (void *)id;
20471   bind[0].buffer_length = 0;
20472   bind[0].is_null = NULL;
20473   bind[0].length = NULL;
20474   bind[0].error = error;
20475   bind[0].u.indicator= indicator;
20476 
20477   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20478   rc= mysql_stmt_bind_param(stmt, bind);
20479   check_execute(stmt, rc);
20480 
20481   rc= mysql_stmt_execute(stmt);
20482   check_execute(stmt, rc);
20483   verify_affected_rows(3);
20484 
20485   mysql_stmt_close(stmt);
20486 
20487   rc= mysql_query(mysql, "SELECT id FROM t1");
20488   myquery(rc);
20489 
20490   result= mysql_store_result(mysql);
20491   mytest(result);
20492 
20493   i= 0;
20494   while ((row= mysql_fetch_row(result)))
20495   {
20496     i++;
20497     DIE_IF(atoi(row[0]) != 3);
20498   }
20499   DIE_IF(i != 1);
20500   mysql_free_result(result);
20501 
20502   rc= mysql_query(mysql, "DROP TABLE t1");
20503   myquery(rc);
20504 }
20505 
test_bulk_replace()20506 static void test_bulk_replace()
20507 {
20508   int rc;
20509   MYSQL_STMT *stmt;
20510   MYSQL_BIND bind[2];
20511   MYSQL_ROW  row;
20512   int        i,
20513              id[]= {1, 2, 3, 4},
20514              val[]= {1, 1, 1, 1},
20515              count= sizeof(id)/sizeof(id[0]);
20516   MYSQL_RES *result;
20517 
20518   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20519   myquery(rc);
20520   rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key, active int)");
20521   myquery(rc);
20522   rc= mysql_query(mysql, "insert into t1 values (1, 0), (2, 0), (3, 0)");
20523   myquery(rc);
20524   verify_affected_rows(3);
20525 
20526   stmt= mysql_stmt_init(mysql);
20527   rc= mysql_stmt_prepare(stmt, "replace into t1 (id, active) values (?, ?)", -1);
20528   check_execute(stmt, rc);
20529 
20530   memset(bind, 0, sizeof(bind));
20531   bind[0].buffer_type = MYSQL_TYPE_LONG;
20532   bind[0].buffer = (void *)id;
20533   bind[0].buffer_length = 0;
20534   bind[1].buffer_type = MYSQL_TYPE_LONG;
20535   bind[1].buffer = (void *)val;
20536   bind[1].buffer_length = 0;
20537 
20538   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20539   rc= mysql_stmt_bind_param(stmt, bind);
20540   check_execute(stmt, rc);
20541 
20542   rc= mysql_stmt_execute(stmt);
20543   check_execute(stmt, rc);
20544 
20545   mysql_stmt_close(stmt);
20546 
20547   rc= mysql_query(mysql, "SELECT active FROM t1");
20548   myquery(rc);
20549 
20550   result= mysql_store_result(mysql);
20551   mytest(result);
20552 
20553   i= 0;
20554   while ((row= mysql_fetch_row(result)))
20555   {
20556     i++;
20557     DIE_IF(atoi(row[0]) != 1);
20558   }
20559   DIE_IF(i != 4);
20560   mysql_free_result(result);
20561 
20562   rc= mysql_query(mysql, "DROP TABLE t1");
20563   myquery(rc);
20564 }
20565 
20566 
test_bulk_insert_returning()20567 static void test_bulk_insert_returning()
20568 {
20569   int rc;
20570   MYSQL_STMT *stmt;
20571   MYSQL_BIND bind[2], res_bind[2];
20572   MYSQL_ROW  row;
20573   MYSQL_RES *result;
20574   int        i,
20575              id[]= {1, 2, 3, 4},
20576              val[]= {1, 1, 1, 1},
20577              count= sizeof(id)/sizeof(id[0]);
20578   unsigned long length[2];
20579   my_bool       is_null[2];
20580   my_bool       error[2];
20581   int32         res[2];
20582 
20583   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20584   myquery(rc);
20585   rc= mysql_query(mysql,
20586                   "CREATE TABLE t1 (id int not null primary key, active int)");
20587   myquery(rc);
20588 
20589   stmt= mysql_stmt_init(mysql);
20590   rc= mysql_stmt_prepare(stmt,
20591                          "insert into t1  values (?, ?) returning id, active",
20592                          -1);
20593   check_execute(stmt, rc);
20594 
20595   memset(bind, 0, sizeof(bind));
20596   bind[0].buffer_type = MYSQL_TYPE_LONG;
20597   bind[0].buffer = (void *)id;
20598   bind[0].buffer_length = 0;
20599   bind[1].buffer_type = MYSQL_TYPE_LONG;
20600   bind[1].buffer = (void *)val;
20601   bind[1].buffer_length = 0;
20602 
20603   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20604   rc= mysql_stmt_bind_param(stmt, bind);
20605   check_execute(stmt, rc);
20606 
20607   rc= mysql_stmt_execute(stmt);
20608   myquery(rc);
20609 
20610   memset(res_bind, 0, sizeof(res_bind));
20611   for (i= 0; i < 2; i++)
20612   {
20613     res_bind[i].buffer_type= MYSQL_TYPE_LONG;
20614     res_bind[i].buffer= (char *)&res[i];
20615     res_bind[i].is_null= &is_null[i];
20616     res_bind[i].length= &length[i];
20617     res_bind[i].error= &error[i];
20618   }
20619   rc= mysql_stmt_bind_result(stmt, res_bind);
20620   myquery(rc);
20621   rc= mysql_stmt_store_result(stmt);
20622   myquery(rc);
20623 
20624   i= 0;
20625   while (!mysql_stmt_fetch(stmt))
20626   {
20627     i++;
20628     DIE_IF(is_null[0] || is_null[1]);
20629     DIE_IF(res[0] != i);
20630     DIE_IF(res[1] != 1);
20631   }
20632   DIE_IF(i != 4);
20633 
20634   mysql_stmt_close(stmt);
20635 
20636   rc= mysql_query(mysql, "SELECT id,active FROM t1");
20637   myquery(rc);
20638 
20639   result= mysql_store_result(mysql);
20640   mytest(result);
20641 
20642   i= 0;
20643   while ((row= mysql_fetch_row(result)))
20644   {
20645     i++;
20646     DIE_IF(atoi(row[0]) != i);
20647     DIE_IF(atoi(row[1]) != 1);
20648   }
20649   DIE_IF(i != 4);
20650   mysql_free_result(result);
20651 
20652 
20653   rc= mysql_query(mysql, "DROP TABLE t1");
20654   myquery(rc);
20655 }
20656 
test_bulk_delete_returning()20657 static void test_bulk_delete_returning()
20658 {
20659   int rc;
20660   MYSQL_STMT *stmt;
20661   MYSQL_BIND bind[2], res_bind[2];
20662   MYSQL_ROW  row;
20663   MYSQL_RES *result;
20664   int        i,
20665              id[]= {1, 2, 3, 4},
20666              count= sizeof(id)/sizeof(id[0]);
20667   unsigned long length[1];
20668   my_bool       is_null[1];
20669   my_bool       error[1];
20670   int32         res[1];
20671 
20672   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20673   myquery(rc);
20674   rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key)");
20675   myquery(rc);
20676   rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
20677   myquery(rc);
20678   verify_affected_rows(4);
20679 
20680   stmt= mysql_stmt_init(mysql);
20681   rc= mysql_stmt_prepare(stmt, "DELETE FROM t1 WHERE id=? RETURNING id", -1);
20682   check_execute(stmt, rc);
20683 
20684   memset(bind, 0, sizeof(bind));
20685   bind[0].buffer_type = MYSQL_TYPE_LONG;
20686   bind[0].buffer = (void *)id;
20687   bind[0].buffer_length = 0;
20688 
20689   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20690   rc= mysql_stmt_bind_param(stmt, bind);
20691   check_execute(stmt, rc);
20692 
20693   rc= mysql_stmt_execute(stmt);
20694   myquery(rc);
20695 
20696   memset(res_bind, 0, sizeof(res_bind));
20697   res_bind[0].buffer_type= MYSQL_TYPE_LONG;
20698   res_bind[0].buffer= (char *)&res[0];
20699   res_bind[0].is_null= &is_null[0];
20700   res_bind[0].length= &length[0];
20701   res_bind[0].error= &error[0];
20702   rc= mysql_stmt_bind_result(stmt, res_bind);
20703   myquery(rc);
20704   rc= mysql_stmt_store_result(stmt);
20705   myquery(rc);
20706 
20707   i= 0;
20708   while (!mysql_stmt_fetch(stmt))
20709   {
20710     i++;
20711     DIE_IF(is_null[0]);
20712     DIE_IF(res[0] != i);
20713   }
20714   DIE_IF(i != 4);
20715 
20716   mysql_stmt_close(stmt);
20717 
20718   rc= mysql_query(mysql, "SELECT id FROM t1");
20719   myquery(rc);
20720 
20721   result= mysql_store_result(mysql);
20722   mytest(result);
20723 
20724   i= 0;
20725   while ((row= mysql_fetch_row(result)))
20726   {
20727     i++;
20728     printf("\nResult (SHOULD NOT BE HERE!!!) %d %s \n", i, row[0]);
20729   }
20730   DIE_IF(i != 0 );
20731   mysql_free_result(result);
20732 
20733 
20734   rc= mysql_query(mysql, "DROP TABLE t1");
20735   myquery(rc);
20736 }
20737 #endif
20738 
20739 
test_ps_params_in_ctes()20740 static void test_ps_params_in_ctes()
20741 {
20742   int rc;
20743   const char *query;
20744   MYSQL_BIND ps_params[1];
20745   int int_data[1];
20746   MYSQL_STMT *stmt;
20747 
20748   rc= mysql_query(mysql, "create table t1(a int, b int, key(a))");
20749   myquery(rc);
20750 
20751   rc= mysql_query(mysql, "insert into t1 (a) values "
20752                          "(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)");
20753   myquery(rc);
20754 
20755   query=
20756     "explain "
20757     "with T as "
20758     "( "
20759     "  select * from t1 where t1.a=? limit 2 "
20760     ") "
20761     "select * from T as TA, T as TB;";
20762 
20763   stmt= mysql_stmt_init(mysql);
20764   check_stmt(stmt);
20765 
20766   rc= mysql_stmt_prepare(stmt, query, (uint) strlen(query));
20767   check_execute(stmt, rc);
20768 
20769   int_data[0]=2;
20770 
20771   memset(ps_params, 0, sizeof ps_params);
20772   ps_params[0].buffer_type= MYSQL_TYPE_LONG;
20773   ps_params[0].buffer= (char *) &int_data[0];
20774   ps_params[0].length= 0;
20775   ps_params[0].is_null= 0;
20776 
20777   rc= mysql_stmt_bind_param(stmt, ps_params);
20778   check_execute(stmt, rc);
20779 
20780   rc= mysql_stmt_execute(stmt);
20781   check_execute(stmt, rc);
20782 
20783   rc= mysql_stmt_store_result(stmt);
20784   check_execute(stmt, rc);
20785 
20786   mysql_stmt_close(stmt);
20787 
20788   rc= mysql_query(mysql, "drop table t1");
20789   myquery(rc);
20790 }
20791 
display_result_metadata(MYSQL_FIELD * field,uint num_fields)20792 void display_result_metadata(MYSQL_FIELD *field,
20793                              uint num_fields)
20794 {
20795   MYSQL_FIELD* field_end;
20796 
20797   mct_log("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
20798           "Column_alias\tType\tLength\tMax length\tIs_null\t"
20799           "Flags\tDecimals\tCharsetnr\n");
20800   for (field_end= field+num_fields; field < field_end; field++)
20801   {
20802     mct_log("%s\t", field->catalog);
20803     mct_log("%s\t", field->db);
20804     mct_log("%s\t", field->org_table);
20805     mct_log("%s\t", field->table);
20806     mct_log("%s\t", field->org_name);
20807     mct_log("%s\t", field->name);
20808     mct_log("%u\t", field->type);
20809     mct_log("%lu\t", field->length);
20810     mct_log("%lu\t", field->max_length);
20811     mct_log("%s\t", (IS_NOT_NULL(field->flags) ?  "N" : "Y"));
20812     mct_log("%u\t", field->flags);
20813     mct_log("%u\t", field->decimals);
20814     mct_log("%u\n", field->charsetnr);
20815   }
20816 }
20817 
test_mdev_26145()20818 static void test_mdev_26145()
20819 {
20820   MYSQL_STMT *stmt;
20821   MYSQL_RES *result;
20822   MYSQL_FIELD *fields;
20823   int        rc, num_fields;
20824 
20825   myheader("test_mdev_26145");
20826 
20827   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20828   myquery(rc);
20829 
20830   rc= mysql_query(mysql, "CREATE TABLE t1(a INT)");
20831   myquery(rc);
20832 
20833   stmt= mysql_simple_prepare(
20834     mysql, "(SELECT MAX(a) FROM t1) UNION (SELECT MAX(a) FROM t1)");
20835   check_stmt(stmt);
20836 
20837   rc= mysql_stmt_execute(stmt);
20838   check_execute(stmt, rc);
20839 
20840   result= mysql_stmt_result_metadata(stmt);
20841   DIE_UNLESS(result);
20842 
20843   num_fields= mysql_stmt_field_count(stmt);
20844   fields= mysql_fetch_fields(result);
20845 
20846   mct_start_logging("test_mdev26145");
20847   display_result_metadata(fields, num_fields);
20848   mct_close_log();
20849 
20850   mysql_free_result(result);
20851   mysql_stmt_close(stmt);
20852 
20853   rc= mysql_query(mysql, "DROP TABLE t1");
20854 
20855   myquery(rc);
20856 }
20857 
test_mdev24827()20858 static void test_mdev24827()
20859 {
20860   int rc;
20861   MYSQL_STMT *stmt;
20862   unsigned long cursor = CURSOR_TYPE_READ_ONLY;
20863   const char* query=
20864     "SELECT t2.c1 AS c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 "
20865     "WHERE EXISTS (SELECT 1 FROM t1 WHERE c2 = -1) ORDER BY c1";
20866 
20867   myheader("test_mdev24827");
20868 
20869   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20870   myquery(rc);
20871 
20872   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
20873   myquery(rc);
20874 
20875   rc= mysql_query(mysql, "CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT)");
20876   myquery(rc);
20877 
20878   rc= mysql_query(mysql, "CREATE TABLE t2 (c1 INT PRIMARY KEY, c2 INT, "
20879                   "KEY idx_c2(c2))");
20880   myquery(rc);
20881 
20882   rc= mysql_query(mysql, "INSERT INTO t1 (c1, c2) "
20883                   "SELECT seq, seq FROM seq_1_to_10000");
20884   myquery(rc);
20885 
20886   rc= mysql_query(mysql, "INSERT INTO t2 (c1, c2) "
20887                   "SELECT seq, seq FROM seq_1_to_20000");
20888   myquery(rc);
20889 
20890   stmt= mysql_stmt_init(mysql);
20891   check_stmt(stmt);
20892 
20893   rc= mysql_stmt_prepare(stmt, query, strlen(query));
20894   check_execute(stmt, rc);
20895 
20896   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor);
20897   check_execute(stmt, rc);
20898 
20899   rc= mysql_stmt_execute(stmt);
20900   check_execute(stmt, rc);
20901   mysql_stmt_close(stmt);
20902 
20903   rc= mysql_query(mysql, "DROP TABLE t1");
20904   myquery(rc);
20905 
20906   rc= mysql_query(mysql, "DROP TABLE t2");
20907   myquery(rc);
20908 }
20909 
test_mdev_20516()20910 static void test_mdev_20516()
20911 {
20912   MYSQL_STMT *stmt;
20913   int        rc;
20914   unsigned long cursor= CURSOR_TYPE_READ_ONLY;
20915   const char* query=
20916     "CREATE VIEW v1 AS SELECT * FROM t1";
20917 
20918   myheader("test_mdev_20516");
20919 
20920   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20921   myquery(rc);
20922 
20923   rc= mysql_query(mysql, "CREATE TABLE t1(a INT)");
20924   myquery(rc);
20925 
20926   stmt= mysql_stmt_init(mysql);
20927   check_stmt(stmt);
20928 
20929   rc= mysql_stmt_prepare(stmt, query, strlen(query));
20930   check_execute(stmt, rc);
20931 
20932   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor);
20933   check_execute(stmt, rc);
20934 
20935   rc= mysql_stmt_execute(stmt);
20936   check_execute(stmt, rc);
20937   mysql_stmt_close(stmt);
20938 
20939   rc= mysql_query(mysql, "DROP TABLE t1");
20940   myquery(rc);
20941 }
20942 
print_metadata(MYSQL_RES * rs_metadata,int num_fields)20943 static void print_metadata(MYSQL_RES *rs_metadata, int num_fields)
20944 {
20945   int i;
20946   MYSQL_FIELD *fields= mysql_fetch_fields(rs_metadata);
20947 
20948   for (i = 0; i < num_fields; ++i)
20949   {
20950     mct_log("  - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
20951         "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
20952         "type: %d; decimals: %d\n",
20953         (int) i,
20954         (const char *) fields[i].name,
20955         (const char *) fields[i].org_name,
20956         (const char *) fields[i].table,
20957         (const char *) fields[i].org_table,
20958         (const char *) fields[i].db,
20959         (const char *) fields[i].catalog,
20960         (int) fields[i].length,
20961         (int) fields[i].max_length,
20962         (int) fields[i].type,
20963         (int) fields[i].decimals);
20964 
20965   }
20966 }
20967 
test_explain_meta()20968 static void test_explain_meta()
20969 {
20970   MYSQL_STMT *stmt;
20971   int num_fields;
20972   char query[MAX_TEST_QUERY_LENGTH];
20973   MYSQL_RES *rs_metadata;
20974   int rc;
20975 
20976   myheader("test_explain_meta");
20977   mct_start_logging("test_explain_meta");
20978 
20979   strmov(query, "SELECT 1");
20980   stmt= mysql_simple_prepare(mysql, query);
20981   check_stmt(stmt);
20982 
20983   rs_metadata= mysql_stmt_result_metadata(stmt);
20984 
20985   num_fields= mysql_stmt_field_count(stmt);
20986   mct_log("SELECT number of fields: %d\n", (int) num_fields);
20987   if (num_fields != 1)
20988   {
20989     mct_close_log();
20990     DIE("num_fields != 1");
20991   }
20992   mysql_free_result(rs_metadata);
20993   mysql_stmt_close(stmt);
20994 
20995   strmov(query, "EXPLAIN SELECT 1");
20996   stmt= mysql_simple_prepare(mysql, query);
20997   check_stmt(stmt);
20998 
20999   rs_metadata= mysql_stmt_result_metadata(stmt);
21000 
21001   num_fields= mysql_stmt_field_count(stmt);
21002   mct_log("EXPALIN number of fields: %d\n", (int) num_fields);
21003   if (num_fields != 10)
21004   {
21005     mct_close_log();
21006     DIE("num_fields != 10");
21007   }
21008   print_metadata(rs_metadata, num_fields);
21009   mysql_free_result(rs_metadata);
21010   mysql_stmt_close(stmt);
21011 
21012   strmov(query, "EXPLAIN format=json SELECT 1");
21013   stmt= mysql_simple_prepare(mysql, query);
21014   check_stmt(stmt);
21015 
21016   rs_metadata= mysql_stmt_result_metadata(stmt);
21017 
21018   num_fields= mysql_stmt_field_count(stmt);
21019   mct_log("EXPALIN JSON number of fields: %d\n", (int) num_fields);
21020   if (num_fields != 1)
21021   {
21022     mct_close_log();
21023     DIE("num_fields != 1");
21024   }
21025   print_metadata(rs_metadata, num_fields);
21026   mysql_free_result(rs_metadata);
21027   mysql_stmt_close(stmt);
21028 
21029 
21030   strmov(query, "ANALYZE SELECT 1");
21031   stmt= mysql_simple_prepare(mysql, query);
21032   check_stmt(stmt);
21033 
21034   rs_metadata= mysql_stmt_result_metadata(stmt);
21035 
21036   num_fields= mysql_stmt_field_count(stmt);
21037   mct_log("ANALYZE number of fields: %d\n", (int) num_fields);
21038   if (num_fields != 13)
21039   {
21040     mct_close_log();
21041     DIE("num_fields != 13");
21042   }
21043   print_metadata(rs_metadata, num_fields);
21044   mysql_free_result(rs_metadata);
21045   mysql_stmt_close(stmt);
21046 
21047   strmov(query, "ANALYZE format=json SELECT 1");
21048   stmt= mysql_simple_prepare(mysql, query);
21049   check_stmt(stmt);
21050 
21051   rs_metadata= mysql_stmt_result_metadata(stmt);
21052 
21053   num_fields= mysql_stmt_field_count(stmt);
21054   mct_log("ANALYZE JSON number of fields: %d\n", (int) num_fields);
21055   if (num_fields != 1)
21056   {
21057     mct_close_log();
21058     DIE("num_fields != 1");
21059   }
21060   print_metadata(rs_metadata, num_fields);
21061   mysql_free_result(rs_metadata);
21062   mysql_stmt_close(stmt);
21063 
21064   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
21065   myquery(rc);
21066 
21067   strmov(query, "EXPLAIN INSERT INTO t1 values (1)");
21068   stmt= mysql_simple_prepare(mysql, query);
21069   check_stmt(stmt);
21070 
21071   rs_metadata= mysql_stmt_result_metadata(stmt);
21072 
21073   num_fields= mysql_stmt_field_count(stmt);
21074   mct_log("EXPALIN INSERT number of fields: %d\n", (int) num_fields);
21075   if (num_fields != 10)
21076   {
21077     mct_close_log();
21078     DIE("num_fields != 10");
21079   }
21080   print_metadata(rs_metadata, num_fields);
21081   mysql_free_result(rs_metadata);
21082   mysql_stmt_close(stmt);
21083 
21084   strmov(query, "EXPLAIN format=json INSERT INTO t1 values(1)");
21085   stmt= mysql_simple_prepare(mysql, query);
21086   check_stmt(stmt);
21087 
21088   rs_metadata= mysql_stmt_result_metadata(stmt);
21089 
21090   num_fields= mysql_stmt_field_count(stmt);
21091   mct_log("EXPALIN JSON INSERT number of fields: %d\n", (int) num_fields);
21092   if (num_fields != 1)
21093   {
21094     mct_close_log();
21095     DIE("num_fields != 1");
21096   }
21097   print_metadata(rs_metadata, num_fields);
21098   mysql_free_result(rs_metadata);
21099   mysql_stmt_close(stmt);
21100 
21101 
21102   strmov(query, "ANALYZE INSERT INTO t1 values(1)");
21103   stmt= mysql_simple_prepare(mysql, query);
21104   check_stmt(stmt);
21105 
21106   rs_metadata= mysql_stmt_result_metadata(stmt);
21107 
21108   num_fields= mysql_stmt_field_count(stmt);
21109   mct_log("ANALYZE INSERT number of fields: %d\n", (int) num_fields);
21110   if (num_fields != 13)
21111   {
21112     mct_close_log();
21113     DIE("num_fields != 13");
21114   }
21115   print_metadata(rs_metadata, num_fields);
21116   mysql_free_result(rs_metadata);
21117   mysql_stmt_close(stmt);
21118 
21119   strmov(query, "ANALYZE format=json INSERT INTO t1 values(1)");
21120   stmt= mysql_simple_prepare(mysql, query);
21121   check_stmt(stmt);
21122 
21123   rs_metadata= mysql_stmt_result_metadata(stmt);
21124 
21125   num_fields= mysql_stmt_field_count(stmt);
21126   mct_log("ANALYZE JSON INSERT number of fields: %d\n", (int) num_fields);
21127   if (num_fields != 1)
21128   {
21129     mct_close_log();
21130     DIE("num_fields != 1");
21131   }
21132   print_metadata(rs_metadata, num_fields);
21133   mysql_free_result(rs_metadata);
21134   mysql_stmt_close(stmt);
21135 
21136 
21137   strmov(query, "EXPLAIN UPDATE t1 set a=2");
21138   stmt= mysql_simple_prepare(mysql, query);
21139   check_stmt(stmt);
21140 
21141   rs_metadata= mysql_stmt_result_metadata(stmt);
21142 
21143   num_fields= mysql_stmt_field_count(stmt);
21144   mct_log("EXPALIN UPDATE number of fields: %d\n", (int) num_fields);
21145   if (num_fields != 10)
21146   {
21147     mct_close_log();
21148     DIE("num_fields != 10");
21149   }
21150   print_metadata(rs_metadata, num_fields);
21151   mysql_free_result(rs_metadata);
21152   mysql_stmt_close(stmt);
21153 
21154   strmov(query, "EXPLAIN format=json  UPDATE t1 set a=2");
21155   stmt= mysql_simple_prepare(mysql, query);
21156   check_stmt(stmt);
21157 
21158   rs_metadata= mysql_stmt_result_metadata(stmt);
21159 
21160   num_fields= mysql_stmt_field_count(stmt);
21161   mct_log("EXPALIN JSON UPDATE number of fields: %d\n", (int) num_fields);
21162   if (num_fields != 1)
21163   {
21164     mct_close_log();
21165     DIE("num_fields != 1");
21166   }
21167   print_metadata(rs_metadata, num_fields);
21168   mysql_free_result(rs_metadata);
21169   mysql_stmt_close(stmt);
21170 
21171 
21172   strmov(query, "ANALYZE UPDATE t1 set a=2");
21173   stmt= mysql_simple_prepare(mysql, query);
21174   check_stmt(stmt);
21175 
21176   rs_metadata= mysql_stmt_result_metadata(stmt);
21177 
21178   num_fields= mysql_stmt_field_count(stmt);
21179   mct_log("ANALYZE UPDATE number of fields: %d\n", (int) num_fields);
21180   if (num_fields != 13)
21181   {
21182     mct_close_log();
21183     DIE("num_fields != 13");
21184   }
21185   print_metadata(rs_metadata, num_fields);
21186   mysql_free_result(rs_metadata);
21187   mysql_stmt_close(stmt);
21188 
21189   strmov(query, "ANALYZE format=json UPDATE t1 set a=2");
21190   stmt= mysql_simple_prepare(mysql, query);
21191   check_stmt(stmt);
21192 
21193   rs_metadata= mysql_stmt_result_metadata(stmt);
21194 
21195   num_fields= mysql_stmt_field_count(stmt);
21196   mct_log("ANALYZE JSON UPDATE number of fields: %d\n", (int) num_fields);
21197   if (num_fields != 1)
21198   {
21199     mct_close_log();
21200     DIE("num_fields != 1");
21201   }
21202   print_metadata(rs_metadata, num_fields);
21203   mysql_free_result(rs_metadata);
21204   mysql_stmt_close(stmt);
21205 
21206 
21207   strmov(query, "EXPLAIN DELETE FROM t1");
21208   stmt= mysql_simple_prepare(mysql, query);
21209   check_stmt(stmt);
21210 
21211   rs_metadata= mysql_stmt_result_metadata(stmt);
21212 
21213   num_fields= mysql_stmt_field_count(stmt);
21214   mct_log("EXPALIN DELETE number of fields: %d\n", (int) num_fields);
21215   if (num_fields != 10)
21216   {
21217     mct_close_log();
21218     DIE("num_fields != 10");
21219   }
21220   print_metadata(rs_metadata, num_fields);
21221   mysql_free_result(rs_metadata);
21222   mysql_stmt_close(stmt);
21223 
21224   strmov(query, "EXPLAIN format=json DELETE FROM t1");
21225   stmt= mysql_simple_prepare(mysql, query);
21226   check_stmt(stmt);
21227 
21228   rs_metadata= mysql_stmt_result_metadata(stmt);
21229 
21230   num_fields= mysql_stmt_field_count(stmt);
21231   mct_log("EXPALIN JSON DELETE number of fields: %d\n", (int) num_fields);
21232   if (num_fields != 1)
21233   {
21234     mct_close_log();
21235     DIE("num_fields != 1");
21236   }
21237   print_metadata(rs_metadata, num_fields);
21238   mysql_free_result(rs_metadata);
21239   mysql_stmt_close(stmt);
21240 
21241 
21242   strmov(query, "ANALYZE DELETE FROM t1");
21243   stmt= mysql_simple_prepare(mysql, query);
21244   check_stmt(stmt);
21245 
21246   rs_metadata= mysql_stmt_result_metadata(stmt);
21247 
21248   num_fields= mysql_stmt_field_count(stmt);
21249   mct_log("ANALYZE DELETE number of fields: %d\n", (int) num_fields);
21250   if (num_fields != 13)
21251   {
21252     mct_close_log();
21253     DIE("num_fields != 13");
21254   }
21255   print_metadata(rs_metadata, num_fields);
21256   mysql_free_result(rs_metadata);
21257   mysql_stmt_close(stmt);
21258 
21259   strmov(query, "ANALYZE format=json DELETE FROM t1");
21260   stmt= mysql_simple_prepare(mysql, query);
21261   check_stmt(stmt);
21262 
21263   rs_metadata= mysql_stmt_result_metadata(stmt);
21264 
21265   num_fields= mysql_stmt_field_count(stmt);
21266   mct_log("ANALYZE JSON DELETE number of fields: %d\n", (int) num_fields);
21267   if (num_fields != 1)
21268   {
21269     mct_close_log();
21270     DIE("num_fields != 1");
21271   }
21272   print_metadata(rs_metadata, num_fields);
21273   mysql_free_result(rs_metadata);
21274   mysql_stmt_close(stmt);
21275 
21276   rc= mysql_query(mysql, "DROP TABLE t1");
21277   myquery(rc);
21278   mct_close_log();
21279 }
21280 
21281 
21282 #ifndef EMBEDDED_LIBRARY
21283 #define MDEV19838_MAX_PARAM_COUNT 32
21284 #define MDEV19838_FIELDS_COUNT 17
test_mdev19838()21285 static void test_mdev19838()
21286 {
21287   int rc;
21288   MYSQL_BIND bind[MDEV19838_MAX_PARAM_COUNT];
21289   unsigned int i, paramCount = 1;
21290   char charvalue[] = "012345678901234567890123456789012345";
21291   MYSQL_STMT *stmt;
21292 
21293   myheader("test_mdev19838");
21294 
21295   rc = mysql_query(mysql, "CREATE TABLE mdev19838("
21296           "f1  char(36),"
21297           "f2  char(36),"
21298           "f3  char(36),"
21299           "f4  char(36),"
21300           "f5  char(36),"
21301           "f6  char(36),"
21302           "f7  char(36),"
21303           "f8  char(36),"
21304           "f9  char(36),"
21305           "f10 char(36),"
21306           "f11 char(36),"
21307           "f12 char(36),"
21308           "f13 char(36),"
21309           "f14 char(36),"
21310           "f15 char(36),"
21311           "f16 char(36),"
21312           "f17 char(36)"
21313     ")");
21314   myquery(rc);
21315 
21316   stmt = mysql_stmt_init(mysql);
21317   check_stmt(stmt);
21318 
21319   memset(bind, 0, sizeof(bind));
21320 
21321   for (i = 0; i < MDEV19838_MAX_PARAM_COUNT; ++i)
21322   {
21323     bind[i].buffer = charvalue;
21324     bind[i].buffer_type = MYSQL_TYPE_STRING;
21325     bind[i].buffer_length = strlen(charvalue) + 1;
21326     bind[i].length = &bind[i].length_value;
21327     bind[i].length_value = bind[i].buffer_length - 1;
21328   }
21329 
21330   for (paramCount = 1; paramCount < MDEV19838_FIELDS_COUNT; ++paramCount)
21331   {
21332     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21333 
21334     rc = mysql_stmt_bind_param(stmt, bind);
21335     check_execute(stmt, rc);
21336 
21337     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21338       "(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
21339       " VALUES "
21340       "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21341 
21342     /* Expecting an error */
21343     DIE_UNLESS(rc != 0);
21344 
21345     mysql_stmt_close(stmt);
21346     stmt = mysql_stmt_init(mysql);
21347     check_stmt(stmt);
21348   }
21349 
21350   paramCount = 0;
21351   mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21352   rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838(f1)"
21353     " VALUES (?)", -1);
21354   /* Expecting an error */
21355   DIE_UNLESS(rc != 0);
21356   mysql_stmt_close(stmt);
21357 
21358   stmt = mysql_stmt_init(mysql);
21359   check_stmt(stmt);
21360   /* Correct number of parameters */
21361   paramCount = MDEV19838_FIELDS_COUNT;
21362   mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21363   mysql_stmt_bind_param(stmt, bind);
21364 
21365   rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21366     "(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
21367     " VALUES "
21368     "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21369   check_execute(stmt, rc);
21370 
21371   /* MYSQL_TYPE_TINY = 1. This parameter byte can be read as "parameters send" flag byte.
21372      Checking that wrong packet is still detected */
21373   bind[0].buffer_type = MYSQL_TYPE_TINY;
21374   bind[0].length_value = 1;
21375   bind[0].buffer_length = 1;
21376 
21377   for (paramCount = 8; paramCount > 0; --paramCount)
21378   {
21379     mysql_stmt_close(stmt);
21380     stmt = mysql_stmt_init(mysql);
21381     check_stmt(stmt);
21382 
21383     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21384 
21385     rc = mysql_stmt_bind_param(stmt, bind);
21386     check_execute(stmt, rc);
21387 
21388     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21389       "(f1, f2, f3, f4, f5, f6, f7, f8, f9)"
21390       " VALUES "
21391       "(?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21392 
21393     /* Expecting an error */
21394     DIE_UNLESS(rc != 0);
21395   }
21396 
21397   /* Test of query w/out parameters, with parameter sent and not sent */
21398   for (paramCount = MDEV19838_MAX_PARAM_COUNT; paramCount != (unsigned int)-1; --paramCount)
21399   {
21400     mysql_stmt_close(stmt);
21401     stmt = mysql_stmt_init(mysql);
21402     check_stmt(stmt);
21403 
21404     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21405 
21406     if (paramCount > 0)
21407     {
21408       rc = mysql_stmt_bind_param(stmt, bind);
21409       check_execute(stmt, rc);
21410     }
21411 
21412     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21413       "(f1)"
21414       " VALUES "
21415       "(0x1111111111111111)", -1);
21416 
21417     /*
21418       We allow junk at the end of the packet in case of
21419       no parameters. So it will succeed.
21420     */
21421     DIE_UNLESS(rc == 0);
21422   }
21423 
21424   mysql_stmt_close(stmt);
21425 
21426   rc = mysql_query(mysql, "drop table mdev19838");
21427   myquery(rc);
21428 }
21429 #endif // EMBEDDED_LIBRARY
21430 
21431 
21432 /*
21433   MDEV-20261 NULL passed to String::eq, SEGV, server crash, regression in 10.4
21434 */
test_mdev20261()21435 static void test_mdev20261()
21436 {
21437   int rc;
21438   MYSQL_STMT *stmt;
21439   MYSQL_BIND param[1];
21440   const char *query= "SELECT * FROM t1 WHERE f = ? OR f = 'foo'";
21441   char val[]= "";
21442   my_bool is_null= TRUE;
21443 
21444   myheader("test_mdev20261");
21445 
21446   rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (f varchar(64)) ENGINE=MyISAM");
21447   myquery(rc);
21448 
21449   stmt= mysql_stmt_init(mysql);
21450   check_stmt(stmt);
21451   rc= mysql_stmt_prepare(stmt, query, strlen(query));
21452   check_execute(stmt, rc);
21453 
21454   verify_param_count(stmt, 1);
21455 
21456   bzero((char*) param, sizeof(param));
21457 
21458   param[0].buffer= &val;
21459   param[0].buffer_type= MYSQL_TYPE_STRING;
21460   param[0].is_null= &is_null;
21461 
21462   rc= mysql_stmt_bind_param(stmt, param);
21463   check_execute(stmt, rc);
21464 
21465   rc= mysql_stmt_execute(stmt);
21466   check_execute(stmt, rc);
21467 
21468   rc= mysql_stmt_store_result(stmt);
21469   check_execute(stmt, rc);
21470 
21471   mysql_stmt_close(stmt);
21472 
21473   rc= mysql_query(mysql, "DROP TABLE t1");
21474   myquery(rc);
21475 }
21476 
21477 
21478 static struct my_tests_st my_tests[]= {
21479   { "test_mdev_20516", test_mdev_20516 },
21480   { "test_mdev24827", test_mdev24827 },
21481   { "test_mdev_26145", test_mdev_26145 },
21482   { "disable_query_logs", disable_query_logs },
21483   { "test_view_sp_list_fields", test_view_sp_list_fields },
21484   { "client_query", client_query },
21485   { "test_prepare_insert_update", test_prepare_insert_update},
21486 #ifdef EMBEDDED_LIBRARY
21487   { "test_embedded_start_stop", test_embedded_start_stop },
21488 #endif
21489 #ifdef NOT_YET_WORKING
21490   { "test_drop_temp", test_drop_temp },
21491 #endif
21492   { "test_fetch_seek", test_fetch_seek },
21493   { "test_fetch_nobuffs", test_fetch_nobuffs },
21494   { "test_open_direct", test_open_direct },
21495   { "test_fetch_null", test_fetch_null },
21496   { "test_ps_null_param", test_ps_null_param },
21497   { "test_fetch_date", test_fetch_date },
21498   { "test_fetch_str", test_fetch_str },
21499   { "test_fetch_long", test_fetch_long },
21500   { "test_fetch_short", test_fetch_short },
21501   { "test_fetch_tiny", test_fetch_tiny },
21502   { "test_fetch_bigint", test_fetch_bigint },
21503   { "test_fetch_float", test_fetch_float },
21504   { "test_fetch_double", test_fetch_double },
21505   { "test_bind_result_ext", test_bind_result_ext },
21506   { "test_bind_result_ext1", test_bind_result_ext1 },
21507   { "test_select_direct", test_select_direct },
21508   { "test_select_prepare", test_select_prepare },
21509   { "test_select", test_select },
21510   { "test_select_version", test_select_version },
21511   { "test_ps_conj_select", test_ps_conj_select },
21512   { "test_select_show_table", test_select_show_table },
21513   { "test_func_fields", test_func_fields },
21514   { "test_long_data", test_long_data },
21515   { "test_insert", test_insert },
21516   { "test_set_variable", test_set_variable },
21517   { "test_select_show", test_select_show },
21518   { "test_prepare_noparam", test_prepare_noparam },
21519   { "test_bind_result", test_bind_result },
21520   { "test_prepare_simple", test_prepare_simple },
21521   { "test_prepare", test_prepare },
21522   { "test_null", test_null },
21523   { "test_debug_example", test_debug_example },
21524   { "test_update", test_update },
21525   { "test_simple_update", test_simple_update },
21526   { "test_simple_delete", test_simple_delete },
21527   { "test_double_compare", test_double_compare },
21528   { "client_store_result", client_store_result },
21529   { "client_use_result", client_use_result },
21530   { "test_tran_bdb", test_tran_bdb },
21531   { "test_tran_innodb", test_tran_innodb },
21532   { "test_prepare_ext", test_prepare_ext },
21533   { "test_prepare_syntax", test_prepare_syntax },
21534   { "test_field_names", test_field_names },
21535   { "test_field_flags", test_field_flags },
21536   { "test_long_data_str", test_long_data_str },
21537   { "test_long_data_str1", test_long_data_str1 },
21538   { "test_long_data_bin", test_long_data_bin },
21539   { "test_warnings", test_warnings },
21540   { "test_errors", test_errors },
21541   { "test_prepare_resultset", test_prepare_resultset },
21542   { "test_stmt_close", test_stmt_close },
21543   { "test_prepare_field_result", test_prepare_field_result },
21544   { "test_multi_stmt", test_multi_stmt },
21545   { "test_multi_statements", test_multi_statements },
21546   { "test_prepare_multi_statements", test_prepare_multi_statements },
21547   { "test_store_result", test_store_result },
21548   { "test_store_result1", test_store_result1 },
21549   { "test_store_result2", test_store_result2 },
21550   { "test_subselect", test_subselect },
21551   { "test_date", test_date },
21552   { "test_date_date", test_date_date },
21553   { "test_date_time", test_date_time },
21554   { "test_date_ts", test_date_ts },
21555   { "test_date_dt", test_date_dt },
21556   { "test_prepare_alter", test_prepare_alter },
21557   { "test_manual_sample", test_manual_sample },
21558   { "test_pure_coverage", test_pure_coverage },
21559   { "test_buffers", test_buffers },
21560   { "test_ushort_bug", test_ushort_bug },
21561   { "test_sshort_bug", test_sshort_bug },
21562   { "test_stiny_bug", test_stiny_bug },
21563   { "test_field_misc", test_field_misc },
21564   { "test_set_option", test_set_option },
21565 #ifndef EMBEDDED_LIBRARY
21566   { "test_prepare_grant", test_prepare_grant },
21567 
21568 #endif
21569   { "test_frm_bug", test_frm_bug },
21570   { "test_explain_bug", test_explain_bug },
21571   { "test_decimal_bug", test_decimal_bug },
21572   { "test_nstmts", test_nstmts },
21573   { "test_logs;", test_logs },
21574   { "test_cuted_rows", test_cuted_rows },
21575   { "test_fetch_offset", test_fetch_offset },
21576   { "test_fetch_column", test_fetch_column },
21577   { "test_mem_overun", test_mem_overun },
21578   { "test_list_fields", test_list_fields },
21579   { "test_list_information_schema_fields", test_list_information_schema_fields },
21580   { "test_list_fields_blob", test_list_fields_blob },
21581   { "test_list_fields_default", test_list_fields_default },
21582   { "test_free_result", test_free_result },
21583   { "test_free_store_result", test_free_store_result },
21584   { "test_sqlmode", test_sqlmode },
21585   { "test_ts", test_ts },
21586   { "test_bug1115", test_bug1115 },
21587   { "test_bug1180", test_bug1180 },
21588   { "test_bug1500", test_bug1500 },
21589   { "test_bug1644", test_bug1644 },
21590   { "test_bug1946", test_bug1946 },
21591   { "test_bug2248", test_bug2248 },
21592   { "test_parse_error_and_bad_length", test_parse_error_and_bad_length },
21593   { "test_bug2247", test_bug2247 },
21594   { "test_subqueries", test_subqueries },
21595   { "test_bad_union", test_bad_union },
21596   { "test_distinct", test_distinct },
21597   { "test_subqueries_ref", test_subqueries_ref },
21598   { "test_union", test_union },
21599   { "test_bug3117", test_bug3117 },
21600   { "test_join", test_join },
21601   { "test_selecttmp", test_selecttmp },
21602   { "test_create_drop", test_create_drop },
21603   { "test_rename", test_rename },
21604   { "test_do_set", test_do_set },
21605   { "test_multi", test_multi },
21606   { "test_insert_select", test_insert_select },
21607   { "test_bind_nagative", test_bind_nagative },
21608   { "test_derived", test_derived },
21609   { "test_xjoin", test_xjoin },
21610   { "test_bug3035", test_bug3035 },
21611   { "test_union2", test_union2 },
21612   { "test_bug1664", test_bug1664 },
21613   { "test_union_param", test_union_param },
21614   { "test_order_param", test_order_param },
21615   { "test_ps_i18n", test_ps_i18n },
21616   { "test_bug3796", test_bug3796 },
21617   { "test_bug4026", test_bug4026 },
21618   { "test_bug4079", test_bug4079 },
21619   { "test_bug4236", test_bug4236 },
21620   { "test_bug4030", test_bug4030 },
21621   { "test_bug5126", test_bug5126 },
21622   { "test_bug4231", test_bug4231 },
21623   { "test_bug5399", test_bug5399 },
21624   { "test_bug5194", test_bug5194 },
21625   { "test_bug5315", test_bug5315 },
21626   { "test_bug6049", test_bug6049 },
21627   { "test_bug6058", test_bug6058 },
21628   { "test_bug6059", test_bug6059 },
21629   { "test_bug6046", test_bug6046 },
21630   { "test_bug6081", test_bug6081 },
21631   { "test_bug6096", test_bug6096 },
21632   { "test_datetime_ranges", test_datetime_ranges },
21633   { "test_datetime_ranges_mdev15289", test_datetime_ranges_mdev15289 },
21634   { "test_bug4172", test_bug4172 },
21635   { "test_conversion", test_conversion },
21636   { "test_rewind", test_rewind },
21637   { "test_bug6761", test_bug6761 },
21638   { "test_view", test_view },
21639   { "test_view_where", test_view_where },
21640   { "test_view_2where", test_view_2where },
21641   { "test_view_star", test_view_star },
21642   { "test_view_insert", test_view_insert },
21643   { "test_left_join_view", test_left_join_view },
21644   { "test_view_insert_fields", test_view_insert_fields },
21645   { "test_basic_cursors", test_basic_cursors },
21646   { "test_cursors_with_union", test_cursors_with_union },
21647   { "test_cursors_with_procedure", test_cursors_with_procedure },
21648   { "test_truncation", test_truncation },
21649   { "test_truncation_option", test_truncation_option },
21650   { "test_client_character_set", test_client_character_set },
21651   { "test_bug8330", test_bug8330 },
21652   { "test_bug7990", test_bug7990 },
21653   { "test_bug8378", test_bug8378 },
21654   { "test_bug8722", test_bug8722 },
21655   { "test_bug8880", test_bug8880 },
21656   { "test_open_cursor_prepared_statement_query_cache",
21657     test_open_cursor_prepared_statement_query_cache },
21658   { "test_bug9159", test_bug9159 },
21659   { "test_bug9520", test_bug9520 },
21660   { "test_bug9478", test_bug9478 },
21661   { "test_bug9643", test_bug9643 },
21662   { "test_bug10729", test_bug10729 },
21663   { "test_bug11111", test_bug11111 },
21664   { "test_bug9992", test_bug9992 },
21665   { "test_bug10736", test_bug10736 },
21666   { "test_bug10794", test_bug10794 },
21667   { "test_bug11172", test_bug11172 },
21668   { "test_bug11656", test_bug11656 },
21669   { "test_bug10214", test_bug10214 },
21670   { "test_bug9735", test_bug9735 },
21671   { "test_bug11183", test_bug11183 },
21672   { "test_bug11037", test_bug11037 },
21673   { "test_bug10760", test_bug10760 },
21674   { "test_bug12001", test_bug12001 },
21675   { "test_bug11718", test_bug11718 },
21676   { "test_bug12925", test_bug12925 },
21677   { "test_bug11909", test_bug11909 },
21678   { "test_bug11901", test_bug11901 },
21679   { "test_bug11904", test_bug11904 },
21680   { "test_bug12243", test_bug12243 },
21681   { "test_bug14210", test_bug14210 },
21682   { "test_bug13488", test_bug13488 },
21683   { "test_bug13524", test_bug13524 },
21684   { "test_bug14845", test_bug14845 },
21685   { "test_opt_reconnect", test_opt_reconnect },
21686   { "test_bug15510", test_bug15510},
21687 #ifndef EMBEDDED_LIBRARY
21688   { "test_bug12744", test_bug12744 },
21689 #endif
21690   { "test_bug16143", test_bug16143 },
21691   { "test_bug16144", test_bug16144 },
21692   { "test_bug15613", test_bug15613 },
21693   { "test_bug20152", test_bug20152 },
21694   { "test_bug14169", test_bug14169 },
21695   { "test_bug17667", test_bug17667 },
21696   { "test_bug15752", test_bug15752 },
21697   { "test_mysql_insert_id", test_mysql_insert_id },
21698   { "test_bug19671", test_bug19671 },
21699   { "test_bug21206", test_bug21206 },
21700   { "test_bug21726", test_bug21726 },
21701   { "test_bug15518", test_bug15518 },
21702   { "test_bug23383", test_bug23383 },
21703   { "test_bug32265", test_bug32265 },
21704   { "test_bug21635", test_bug21635 },
21705   { "test_status",   test_status   },
21706   { "test_bug24179", test_bug24179 },
21707   { "test_ps_query_cache", test_ps_query_cache },
21708   { "test_bug28075", test_bug28075 },
21709   { "test_bug27876", test_bug27876 },
21710   { "test_bug28505", test_bug28505 },
21711   { "test_bug28934", test_bug28934 },
21712   { "test_bug27592", test_bug27592 },
21713   { "test_bug29687", test_bug29687 },
21714   { "test_bug29692", test_bug29692 },
21715   { "test_bug29306", test_bug29306 },
21716   { "test_change_user", test_change_user },
21717   { "test_bug30472", test_bug30472 },
21718   { "test_bug20023", test_bug20023 },
21719   { "test_bug45010", test_bug45010 },
21720   { "test_bug53371", test_bug53371 },
21721   { "test_bug31418", test_bug31418 },
21722   { "test_bug31669", test_bug31669 },
21723   { "test_bug28386", test_bug28386 },
21724   { "test_wl4166_1", test_wl4166_1 },
21725   { "test_wl4166_2", test_wl4166_2 },
21726   { "test_wl4166_3", test_wl4166_3 },
21727   { "test_wl4166_4", test_wl4166_4 },
21728   { "test_bug36004", test_bug36004 },
21729   { "test_wl4284_1", test_wl4284_1 },
21730   { "test_wl4435",   test_wl4435 },
21731   { "test_wl4435_2", test_wl4435_2 },
21732   { "test_wl4435_3", test_wl4435_3 },
21733   { "test_bug38486", test_bug38486 },
21734   { "test_bug33831", test_bug33831 },
21735   { "test_bug40365", test_bug40365 },
21736   { "test_bug43560", test_bug43560 },
21737   { "test_bug36326", test_bug36326 },
21738   { "test_bug41078", test_bug41078 },
21739   { "test_bug44495", test_bug44495 },
21740   { "test_bug49972", test_bug49972 },
21741   { "test_bug42373", test_bug42373 },
21742   { "test_bug54041", test_bug54041 },
21743   { "test_bug47485", test_bug47485 },
21744   { "test_bug58036", test_bug58036 },
21745   { "test_bug57058", test_bug57058 },
21746   { "test_bug56976", test_bug56976 },
21747   { "test_mdev3885", test_mdev3885 },
21748   { "test_mdev4603", test_mdev4603 },
21749   { "test_bug11766854", test_bug11766854 },
21750   { "test_bug12337762", test_bug12337762 },
21751   { "test_progress_reporting", test_progress_reporting },
21752   { "test_bug11754979", test_bug11754979 },
21753   { "test_bug13001491", test_bug13001491 },
21754   { "test_mdev4326", test_mdev4326 },
21755   { "test_ps_sp_out_params", test_ps_sp_out_params },
21756 #ifndef _WIN32
21757   { "test_bug17512527", test_bug17512527},
21758 #endif
21759   { "test_compressed_protocol", test_compressed_protocol },
21760   { "test_big_packet", test_big_packet },
21761   { "test_prepare_analyze", test_prepare_analyze },
21762   { "test_mdev12579", test_mdev12579 },
21763   { "test_mdev14013", test_mdev14013 },
21764   { "test_mdev14013_1", test_mdev14013_1 },
21765   { "test_mdev14454", test_mdev14454 },
21766 #ifndef EMBEDDED_LIBRARY
21767   { "test_proxy_header", test_proxy_header},
21768   { "test_bulk_autoinc", test_bulk_autoinc},
21769   { "test_bulk_delete", test_bulk_delete },
21770   { "test_bulk_replace", test_bulk_replace },
21771   { "test_bulk_insert_returning", test_bulk_insert_returning },
21772   { "test_bulk_delete_returning", test_bulk_delete_returning },
21773 #endif
21774   { "test_ps_params_in_ctes", test_ps_params_in_ctes },
21775   { "test_explain_meta", test_explain_meta },
21776 #ifndef EMBEDDED_LIBRARY
21777   { "test_mdev19838", test_mdev19838 },
21778 #endif
21779   { "test_mdev18408", test_mdev18408 },
21780   { "test_mdev20261", test_mdev20261 },
21781   { 0, 0 }
21782 };
21783 
21784 
get_my_tests()21785 static struct my_tests_st *get_my_tests() { return my_tests; }
21786