1 /* Copyright (c) 2002, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22 
23 /*
24   XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
25   DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
26 */
27 
28 
29 /*
30   The fw.c file includes all the mysql_client_test framework; this file
31   contains only the actual tests, plus the list of test functions to call.
32 */
33 
34 #include "mysql_client_fw.c"
35 
36 /* Query processing */
37 
client_query()38 static void client_query()
39 {
40   int rc;
41 
42   myheader("client_query");
43 
44   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
45   myquery(rc);
46 
47   rc= mysql_query(mysql, "CREATE TABLE t1("
48                          "id int primary key auto_increment, "
49                          "name varchar(20))");
50   myquery(rc);
51 
52   rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))");
53   myquery_r(rc);
54 
55   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')");
56   myquery(rc);
57 
58   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')");
59   myquery(rc);
60 
61   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')");
62   myquery(rc);
63 
64   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
65   myquery(rc);
66 
67   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
68   myquery(rc);
69 
70   rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' "
71                           "WHERE name= 'deleted'");
72   myquery(rc);
73 
74   rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'");
75   myquery_r(rc);
76 
77   myquery(mysql_query(mysql, "drop table t1"));
78 }
79 
80 
81 /* Store result processing */
82 
client_store_result()83 static void client_store_result()
84 {
85   MYSQL_RES *result;
86   int       rc;
87 
88   myheader("client_store_result");
89 
90   rc= mysql_query(mysql, "SELECT * FROM t1");
91   myquery(rc);
92 
93   /* get the result */
94   result= mysql_store_result(mysql);
95   mytest(result);
96 
97   (void) my_process_result_set(result);
98   mysql_free_result(result);
99 }
100 
101 
102 /* Fetch the results */
103 
client_use_result()104 static void client_use_result()
105 {
106   MYSQL_RES *result;
107   int       rc;
108   myheader("client_use_result");
109 
110   rc= mysql_query(mysql, "SELECT * FROM t1");
111   myquery(rc);
112 
113   /* get the result */
114   result= mysql_use_result(mysql);
115   mytest(result);
116 
117   (void) my_process_result_set(result);
118   mysql_free_result(result);
119 }
120 
121 
122 /* Query processing */
123 
test_debug_example()124 static void test_debug_example()
125 {
126   int rc;
127   MYSQL_RES *result;
128 
129   myheader("test_debug_example");
130 
131   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_debug_example");
132   myquery(rc);
133 
134   rc= mysql_query(mysql, "CREATE TABLE test_debug_example("
135                          "id INT PRIMARY KEY AUTO_INCREMENT, "
136                          "name VARCHAR(20), xxx INT)");
137   myquery(rc);
138 
139   rc= mysql_query(mysql, "INSERT INTO test_debug_example (name) "
140                          "VALUES ('mysql')");
141   myquery(rc);
142 
143   rc= mysql_query(mysql, "UPDATE test_debug_example SET name='updated' "
144                          "WHERE name='deleted'");
145   myquery(rc);
146 
147   rc= mysql_query(mysql, "SELECT * FROM test_debug_example where name='mysql'");
148   myquery(rc);
149 
150   result= mysql_use_result(mysql);
151   mytest(result);
152 
153   (void) my_process_result_set(result);
154   mysql_free_result(result);
155 
156   rc= mysql_query(mysql, "DROP TABLE test_debug_example");
157   myquery(rc);
158 }
159 
160 
161 /* Test autocommit feature for BDB tables */
162 
test_tran_bdb()163 static void test_tran_bdb()
164 {
165   MYSQL_RES *result;
166   MYSQL_ROW row;
167   int       rc;
168 
169   myheader("test_tran_bdb");
170 
171   /* set AUTOCOMMIT to OFF */
172   rc= mysql_autocommit(mysql, FALSE);
173   myquery(rc);
174 
175   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction");
176   myquery(rc);
177 
178 
179   /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
180   rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction( "
181                          "col1 int , col2 varchar(30)) ENGINE= BDB");
182   myquery(rc);
183 
184   /* insert a row and commit the transaction */
185   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')");
186   myquery(rc);
187 
188   rc= mysql_commit(mysql);
189   myquery(rc);
190 
191   /* now insert the second row, and roll back the transaction */
192   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
193   myquery(rc);
194 
195   rc= mysql_rollback(mysql);
196   myquery(rc);
197 
198   /* delete first row, and roll it back */
199   rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
200   myquery(rc);
201 
202   rc= mysql_rollback(mysql);
203   myquery(rc);
204 
205   /* test the results now, only one row should exist */
206   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
207   myquery(rc);
208 
209   /* get the result */
210   result= mysql_store_result(mysql);
211   mytest(result);
212 
213   (void) my_process_result_set(result);
214   mysql_free_result(result);
215 
216   /* test the results now, only one row should exist */
217   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
218   myquery(rc);
219 
220   /* get the result */
221   result= mysql_use_result(mysql);
222   mytest(result);
223 
224   row= mysql_fetch_row(result);
225   mytest(row);
226 
227   row= mysql_fetch_row(result);
228   mytest_r(row);
229 
230   mysql_free_result(result);
231   mysql_autocommit(mysql, TRUE);
232 }
233 
234 
235 /* Test autocommit feature for InnoDB tables */
236 
test_tran_innodb()237 static void test_tran_innodb()
238 {
239   MYSQL_RES *result;
240   MYSQL_ROW row;
241   int       rc;
242 
243   myheader("test_tran_innodb");
244 
245   /* set AUTOCOMMIT to OFF */
246   rc= mysql_autocommit(mysql, FALSE);
247   myquery(rc);
248 
249   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction");
250   myquery(rc);
251 
252   /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
253   rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction(col1 int, "
254                          "col2 varchar(30)) ENGINE= InnoDB");
255   myquery(rc);
256 
257   /* insert a row and commit the transaction */
258   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')");
259   myquery(rc);
260 
261   rc= mysql_commit(mysql);
262   myquery(rc);
263 
264   /* now insert the second row, and roll back the transaction */
265   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
266   myquery(rc);
267 
268   rc= mysql_rollback(mysql);
269   myquery(rc);
270 
271   /* delete first row, and roll it back */
272   rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
273   myquery(rc);
274 
275   rc= mysql_rollback(mysql);
276   myquery(rc);
277 
278   /* test the results now, only one row should exist */
279   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
280   myquery(rc);
281 
282   /* get the result */
283   result= mysql_store_result(mysql);
284   mytest(result);
285 
286   (void) my_process_result_set(result);
287   mysql_free_result(result);
288 
289   /* test the results now, only one row should exist */
290   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
291   myquery(rc);
292 
293   /* get the result */
294   result= mysql_use_result(mysql);
295   mytest(result);
296 
297   row= mysql_fetch_row(result);
298   mytest(row);
299 
300   row= mysql_fetch_row(result);
301   mytest_r(row);
302 
303   mysql_free_result(result);
304   mysql_autocommit(mysql, TRUE);
305 }
306 
307 
308 /* Test for BUG#7242 */
309 
test_prepare_insert_update()310 static void test_prepare_insert_update()
311 {
312   MYSQL_STMT *stmt;
313   int        rc;
314   int        i;
315   const char *testcase[]= {
316     "CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B))",
317     "INSERT t1 VALUES (1,2,10), (3,4,20)",
318     "INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100",
319     "SELECT * FROM t1",
320     "INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0",
321     "SELECT * FROM t1",
322     "INSERT t1 VALUES (2,1,11), (7,4,40) ON DUPLICATE KEY UPDATE c=c+VALUES(a)",
323     NULL};
324   const char **cur_query;
325 
326   myheader("test_prepare_insert_update");
327 
328   for (cur_query= testcase; *cur_query; cur_query++)
329   {
330     char query[MAX_TEST_QUERY_LENGTH];
331     printf("\nRunning query: %s", *cur_query);
332     my_stpcpy(query, *cur_query);
333     stmt= mysql_simple_prepare(mysql, query);
334     check_stmt(stmt);
335 
336     verify_param_count(stmt, 0);
337     rc= mysql_stmt_execute(stmt);
338 
339     check_execute(stmt, rc);
340     /* try the last query several times */
341     if (!cur_query[1])
342     {
343       for (i=0; i < 3;i++)
344       {
345         printf("\nExecuting last statement again");
346         rc= mysql_stmt_execute(stmt);
347         check_execute(stmt, rc);
348         rc= mysql_stmt_execute(stmt);
349         check_execute(stmt, rc);
350       }
351     }
352     mysql_stmt_close(stmt);
353   }
354 
355   rc= mysql_commit(mysql);
356   myquery(rc);
357 }
358 
359 /* Test simple prepares of all DML statements */
360 
test_prepare_simple()361 static void test_prepare_simple()
362 {
363   MYSQL_STMT *stmt;
364   int        rc;
365   char query[MAX_TEST_QUERY_LENGTH];
366 
367   myheader("test_prepare_simple");
368 
369   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_simple");
370   myquery(rc);
371 
372   rc= mysql_query(mysql, "CREATE TABLE test_prepare_simple("
373                          "id int, name varchar(50))");
374   myquery(rc);
375 
376   /* insert */
377   my_stpcpy(query, "INSERT INTO test_prepare_simple VALUES(?, ?)");
378   stmt= mysql_simple_prepare(mysql, query);
379   check_stmt(stmt);
380 
381   verify_param_count(stmt, 2);
382   mysql_stmt_close(stmt);
383 
384   /* update */
385   my_stpcpy(query, "UPDATE test_prepare_simple SET id=? "
386                 "WHERE id=? AND CONVERT(name USING utf8)= ?");
387   stmt= mysql_simple_prepare(mysql, query);
388   check_stmt(stmt);
389 
390   verify_param_count(stmt, 3);
391   mysql_stmt_close(stmt);
392 
393   /* delete */
394   my_stpcpy(query, "DELETE FROM test_prepare_simple WHERE id=10");
395   stmt= mysql_simple_prepare(mysql, query);
396   check_stmt(stmt);
397 
398   verify_param_count(stmt, 0);
399 
400   rc= mysql_stmt_execute(stmt);
401   check_execute(stmt, rc);
402   mysql_stmt_close(stmt);
403 
404   /* delete */
405   my_stpcpy(query, "DELETE FROM test_prepare_simple WHERE id=?");
406   stmt= mysql_simple_prepare(mysql, query);
407   check_stmt(stmt);
408 
409   verify_param_count(stmt, 1);
410 
411   mysql_stmt_close(stmt);
412 
413   /* select */
414   my_stpcpy(query, "SELECT * FROM test_prepare_simple WHERE id=? "
415                 "AND CONVERT(name USING utf8)= ?");
416   stmt= mysql_simple_prepare(mysql, query);
417   check_stmt(stmt);
418 
419   verify_param_count(stmt, 2);
420 
421   mysql_stmt_close(stmt);
422 
423   /* now fetch the results ..*/
424   rc= mysql_commit(mysql);
425   myquery(rc);
426 }
427 
428 /************************************************************************/
429 
430 #define FILE_PATH_SIZE 4096
431 
432 char mct_log_file_path[FILE_PATH_SIZE];
433 FILE *mct_log_file= NULL;
434 
mct_start_logging(const char * test_case_name)435 void mct_start_logging(const char *test_case_name)
436 {
437   const char *tmp_dir= getenv("MYSQL_TMP_DIR");
438 
439   if (!tmp_dir)
440   {
441     printf("Warning: MYSQL_TMP_DIR is not set. Logging is disabled.\n");
442     return;
443   }
444 
445   if (mct_log_file)
446   {
447     printf("Warning: can not start logging for test case '%s' "
448            "because log is already open\n",
449            (const char *) test_case_name);
450     return;
451   }
452 
453   /*
454     Path is: <tmp_dir>/<test_case_name>.out.log
455     10 is length of '/' + '.out.log' + \0
456   */
457 
458   if (strlen(tmp_dir) + strlen(test_case_name) + 10 > FILE_PATH_SIZE)
459   {
460     printf("Warning: MYSQL_TMP_DIR is too long. Logging is disabled.\n");
461     return;
462   }
463 
464   my_snprintf(mct_log_file_path, FILE_PATH_SIZE,
465               "%s/%s.out.log",
466               (const char *) tmp_dir,
467               (const char *) test_case_name);
468 
469   mct_log_file= my_fopen(mct_log_file_path, O_WRONLY | O_BINARY, MYF(MY_WME));
470 
471   if (!mct_log_file)
472   {
473     printf("Warning: can not open log file (%s): %s. Logging is disabled.\n",
474         (const char *) mct_log_file_path,
475         (const char *) strerror(errno));
476     return;
477   }
478 }
479 
mct_log(const char * format,...)480 void mct_log(const char *format, ...)
481 {
482   va_list args;
483   va_start(args, format);
484   vprintf(format, args);
485   va_end(args);
486 
487   if (mct_log_file)
488   {
489     va_list args;
490     va_start(args, format);
491     vfprintf(mct_log_file, format, args);
492     va_end(args);
493   }
494 }
495 
mct_close_log()496 void mct_close_log()
497 {
498   if (!mct_log_file)
499     return;
500 
501   my_fclose(mct_log_file, MYF(0));
502   mct_log_file= NULL;
503 }
504 
505 #define WL4435_NUM_PARAMS 10
506 #define WL4435_STRING_SIZE 30
507 
test_wl4435()508 static void test_wl4435()
509 {
510   MYSQL_STMT *stmt;
511   int        rc;
512   char query[MAX_TEST_QUERY_LENGTH];
513 
514   char       str_data[20][WL4435_STRING_SIZE];
515   double     dbl_data[20];
516   char       dec_data[20][WL4435_STRING_SIZE];
517   int        int_data[20];
518   ulong      str_length= WL4435_STRING_SIZE;
519   my_bool    is_null;
520   MYSQL_BIND ps_params[WL4435_NUM_PARAMS];
521 
522   int exec_counter;
523 
524   memset(str_data, 0, sizeof(str_data));
525   memset(dbl_data, 0, sizeof(dbl_data));
526   memset(dec_data, 0, sizeof(dec_data));
527   memset(int_data, 0, sizeof(int_data));
528 
529   myheader("test_wl4435");
530   mct_start_logging("test_wl4435");
531 
532   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
533   myquery(rc);
534 
535   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p2");
536   myquery(rc);
537 
538   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
539   myquery(rc);
540 
541   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
542   myquery(rc);
543 
544   rc= mysql_query(mysql, "CREATE TABLE t1(a1 INT, a2 CHAR(32), "
545                        "  a3 DOUBLE(4, 2), a4 DECIMAL(3, 1))");
546   myquery(rc);
547 
548   rc= mysql_query(mysql, "CREATE TABLE t2(b0 INT, b1 INT, b2 CHAR(32), "
549                        "  b3 DOUBLE(4, 2), b4 DECIMAL(3, 1))");
550   myquery(rc);
551 
552   rc= mysql_query(mysql, "INSERT INTO t1 VALUES"
553     "(1, '11', 12.34, 56.7), "
554     "(2, '12', 56.78, 90.1), "
555     "(3, '13', 23.45, 67.8)");
556   myquery(rc);
557 
558   rc= mysql_query(mysql, "INSERT INTO t2 VALUES"
559     "(100, 10, '110', 70.70, 10.1), "
560     "(200, 20, '120', 80.80, 20.2), "
561     "(300, 30, '130', 90.90, 30.3)");
562   myquery(rc);
563 
564   rc= mysql_query(mysql,
565     "CREATE PROCEDURE p1("
566     "   IN v0 INT, "
567     "   OUT v_str_1 CHAR(32), "
568     "   OUT v_dbl_1 DOUBLE(4, 2), "
569     "   OUT v_dec_1 DECIMAL(6, 3), "
570     "   OUT v_int_1 INT, "
571     "   IN v1 INT, "
572     "   INOUT v_str_2 CHAR(64), "
573     "   INOUT v_dbl_2 DOUBLE(5, 3), "
574     "   INOUT v_dec_2 DECIMAL(7, 4), "
575     "   INOUT v_int_2 INT)"
576     "BEGIN "
577     "   SET v0 = -1; "
578     "   SET v1 = -1; "
579     "   SET v_str_1 = 'test_1'; "
580     "   SET v_dbl_1 = 12.34; "
581     "   SET v_dec_1 = 567.891; "
582     "   SET v_int_1 = 2345; "
583     "   SET v_str_2 = 'test_2'; "
584     "   SET v_dbl_2 = 67.891; "
585     "   SET v_dec_2 = 234.6789; "
586     "   SET v_int_2 = 6789; "
587     "   SELECT * FROM t1; "
588     "   SELECT * FROM t2; "
589     "END");
590   myquery(rc);
591 
592   rc= mysql_query(mysql,
593     "CREATE PROCEDURE p2("
594     "   IN i1 VARCHAR(255) CHARACTER SET koi8r, "
595     "   OUT o1 VARCHAR(255) CHARACTER SET cp1251, "
596     "   OUT o2 VARBINARY(255)) "
597     "BEGIN "
598     "   SET o1 = i1; "
599     "   SET o2 = i1; "
600     "END");
601   myquery(rc);
602 
603   my_stpcpy(query, "CALL p1(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
604   stmt= mysql_simple_prepare(mysql, query);
605   check_stmt(stmt);
606 
607   /* Init PS-parameters. */
608 
609   memset(ps_params, 0, sizeof (ps_params));
610 
611   /* - v0 -- INT */
612 
613   ps_params[0].buffer_type= MYSQL_TYPE_LONG;
614   ps_params[0].buffer= (char *) &int_data[0];
615   ps_params[0].length= 0;
616   ps_params[0].is_null= 0;
617 
618   /* - v_str_1 -- CHAR(32) */
619 
620   ps_params[1].buffer_type= MYSQL_TYPE_STRING;
621   ps_params[1].buffer= (char *) str_data[0];
622   ps_params[1].buffer_length= WL4435_STRING_SIZE;
623   ps_params[1].length= &str_length;
624   ps_params[1].is_null= 0;
625 
626   /* - v_dbl_1 -- DOUBLE */
627 
628   ps_params[2].buffer_type= MYSQL_TYPE_DOUBLE;
629   ps_params[2].buffer= (char *) &dbl_data[0];
630   ps_params[2].length= 0;
631   ps_params[2].is_null= 0;
632 
633   /* - v_dec_1 -- DECIMAL */
634 
635   ps_params[3].buffer_type= MYSQL_TYPE_NEWDECIMAL;
636   ps_params[3].buffer= (char *) dec_data[0];
637   ps_params[3].buffer_length= WL4435_STRING_SIZE;
638   ps_params[3].length= 0;
639   ps_params[3].is_null= 0;
640 
641   /* - v_int_1 -- INT */
642 
643   ps_params[4].buffer_type= MYSQL_TYPE_LONG;
644   ps_params[4].buffer= (char *) &int_data[0];
645   ps_params[4].length= 0;
646   ps_params[4].is_null= 0;
647 
648   /* - v1 -- INT */
649 
650   ps_params[5].buffer_type= MYSQL_TYPE_LONG;
651   ps_params[5].buffer= (char *) &int_data[0];
652   ps_params[5].length= 0;
653   ps_params[5].is_null= 0;
654 
655   /* - v_str_2 -- CHAR(32) */
656 
657   ps_params[6].buffer_type= MYSQL_TYPE_STRING;
658   ps_params[6].buffer= (char *) str_data[0];
659   ps_params[6].buffer_length= WL4435_STRING_SIZE;
660   ps_params[6].length= &str_length;
661   ps_params[6].is_null= 0;
662 
663   /* - v_dbl_2 -- DOUBLE */
664 
665   ps_params[7].buffer_type= MYSQL_TYPE_DOUBLE;
666   ps_params[7].buffer= (char *) &dbl_data[0];
667   ps_params[7].length= 0;
668   ps_params[7].is_null= 0;
669 
670   /* - v_dec_2 -- DECIMAL */
671 
672   ps_params[8].buffer_type= MYSQL_TYPE_DECIMAL;
673   ps_params[8].buffer= (char *) dec_data[0];
674   ps_params[8].buffer_length= WL4435_STRING_SIZE;
675   ps_params[8].length= 0;
676   ps_params[8].is_null= 0;
677 
678   /* - v_int_2 -- INT */
679 
680   ps_params[9].buffer_type= MYSQL_TYPE_LONG;
681   ps_params[9].buffer= (char *) &int_data[0];
682   ps_params[9].length= 0;
683   ps_params[9].is_null= 0;
684 
685   /* Bind parameters. */
686 
687   rc= mysql_stmt_bind_param(stmt, ps_params);
688 
689   /* Execute! */
690 
691   for (exec_counter= 0; exec_counter < 3; ++exec_counter)
692   {
693     int i;
694     int num_fields;
695     MYSQL_BIND *rs_bind;
696 
697     mct_log("\nexec_counter: %d\n", (int) exec_counter);
698 
699     rc= mysql_stmt_execute(stmt);
700     check_execute(stmt, rc);
701 
702     while (1)
703     {
704       MYSQL_FIELD *fields;
705 
706       MYSQL_RES *rs_metadata= mysql_stmt_result_metadata(stmt);
707 
708       num_fields= mysql_stmt_field_count(stmt);
709       fields= mysql_fetch_fields(rs_metadata);
710 
711       rs_bind= (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
712       memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);
713 
714       mct_log("num_fields: %d\n", (int) num_fields);
715 
716       for (i = 0; i < num_fields; ++i)
717       {
718         mct_log("  - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
719                 "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
720                 "type: %d; decimals: %d\n",
721                 (int) i,
722                 (const char *) fields[i].name,
723                 (const char *) fields[i].org_name,
724                 (const char *) fields[i].table,
725                 (const char *) fields[i].org_table,
726                 (const char *) fields[i].db,
727                 (const char *) fields[i].catalog,
728                 (int) fields[i].length,
729                 (int) fields[i].max_length,
730                 (int) fields[i].type,
731                 (int) fields[i].decimals);
732 
733         rs_bind[i].buffer_type= fields[i].type;
734         rs_bind[i].is_null= &is_null;
735 
736         switch (fields[i].type)
737         {
738           case MYSQL_TYPE_LONG:
739             rs_bind[i].buffer= (char *) &(int_data[i]);
740             rs_bind[i].buffer_length= (ulong)sizeof (int_data);
741             break;
742 
743           case MYSQL_TYPE_STRING:
744             rs_bind[i].buffer= (char *) str_data[i];
745             rs_bind[i].buffer_length= WL4435_STRING_SIZE;
746             rs_bind[i].length= &str_length;
747             break;
748 
749           case MYSQL_TYPE_DOUBLE:
750             rs_bind[i].buffer= (char *) &dbl_data[i];
751             rs_bind[i].buffer_length= (ulong)sizeof (dbl_data);
752             break;
753 
754           case MYSQL_TYPE_NEWDECIMAL:
755             rs_bind[i].buffer= (char *) dec_data[i];
756             rs_bind[i].buffer_length= WL4435_STRING_SIZE;
757             rs_bind[i].length= &str_length;
758             break;
759 
760           default:
761             fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
762             exit(1);
763         }
764       }
765 
766       rc= mysql_stmt_bind_result(stmt, rs_bind);
767       check_execute(stmt, rc);
768 
769       mct_log("Data:\n");
770 
771       while (1)
772       {
773         int rc= mysql_stmt_fetch(stmt);
774 
775         if (rc == 1 || rc == MYSQL_NO_DATA)
776           break;
777 
778         mct_log(" ");
779 
780         for (i = 0; i < num_fields; ++i)
781         {
782           switch (rs_bind[i].buffer_type)
783           {
784             case MYSQL_TYPE_LONG:
785               mct_log(" int: %ld;",
786                       (long) *((int *) rs_bind[i].buffer));
787               break;
788 
789             case MYSQL_TYPE_STRING:
790               mct_log(" str: '%s';",
791                       (char *) rs_bind[i].buffer);
792               break;
793 
794             case MYSQL_TYPE_DOUBLE:
795               mct_log(" dbl: %lf;",
796                       (double) *((double *) rs_bind[i].buffer));
797               break;
798 
799             case MYSQL_TYPE_NEWDECIMAL:
800               mct_log(" dec: '%s';",
801                       (char *) rs_bind[i].buffer);
802               break;
803 
804             default:
805               printf("  unexpected type (%d)\n",
806                 rs_bind[i].buffer_type);
807           }
808         }
809         mct_log("\n");
810       }
811 
812       mct_log("EOF\n");
813 
814       rc= mysql_stmt_next_result(stmt);
815       mct_log("mysql_stmt_next_result(): %d; field_count: %d\n",
816               (int) rc, (int) mysql->field_count);
817 
818       free(rs_bind);
819       mysql_free_result(rs_metadata);
820 
821       if (rc > 0)
822       {
823         printf("Error: %s (errno: %d)\n",
824                mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
825         DIE(rc > 0);
826       }
827 
828       if (rc)
829         break;
830 
831       if (!mysql->field_count)
832       {
833         /* This is the last OK-packet. No more resultsets. */
834         break;
835       }
836     }
837 
838   }
839 
840   mysql_stmt_close(stmt);
841 
842   mct_close_log();
843 
844   rc= mysql_commit(mysql);
845   myquery(rc);
846 
847   /* i18n part of test case. */
848 
849   {
850     const char *str_koi8r= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
851     const char *str_cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
852     char o1_buffer[255];
853     ulong o1_length;
854     char o2_buffer[255];
855     ulong o2_length;
856 
857     MYSQL_BIND rs_bind[2];
858 
859     my_stpcpy(query, "CALL p2(?, ?, ?)");
860     stmt= mysql_simple_prepare(mysql, query);
861     check_stmt(stmt);
862 
863     /* Init PS-parameters. */
864 
865     memset(ps_params, 0, sizeof (ps_params));
866 
867     ps_params[0].buffer_type= MYSQL_TYPE_STRING;
868     ps_params[0].buffer= (char *) str_koi8r;
869     ps_params[0].buffer_length= (ulong)strlen(str_koi8r);
870 
871     ps_params[1].buffer_type= MYSQL_TYPE_STRING;
872     ps_params[1].buffer= o1_buffer;
873     ps_params[1].buffer_length= 0;
874 
875     ps_params[2].buffer_type= MYSQL_TYPE_STRING;
876     ps_params[2].buffer= o2_buffer;
877     ps_params[2].buffer_length= 0;
878 
879     /* Bind parameters. */
880 
881     rc= mysql_stmt_bind_param(stmt, ps_params);
882     check_execute(stmt, rc);
883 
884     /* Prevent converting to character_set_results. */
885 
886     rc= mysql_query(mysql, "SET NAMES binary");
887     myquery(rc);
888 
889     /* Execute statement. */
890 
891     rc= mysql_stmt_execute(stmt);
892     check_execute(stmt, rc);
893 
894     /* Bind result. */
895 
896     memset(rs_bind, 0, sizeof (rs_bind));
897 
898     rs_bind[0].buffer_type= MYSQL_TYPE_STRING;
899     rs_bind[0].buffer= o1_buffer;
900     rs_bind[0].buffer_length= (ulong)sizeof (o1_buffer);
901     rs_bind[0].length= &o1_length;
902 
903     rs_bind[1].buffer_type= MYSQL_TYPE_BLOB;
904     rs_bind[1].buffer= o2_buffer;
905     rs_bind[1].buffer_length= (ulong)sizeof (o2_buffer);
906     rs_bind[1].length= &o2_length;
907 
908     rc= mysql_stmt_bind_result(stmt, rs_bind);
909     check_execute(stmt, rc);
910 
911     /* Fetch result. */
912 
913     rc= mysql_stmt_fetch(stmt);
914     check_execute(stmt, rc);
915 
916     /* Check result. */
917 
918     DIE_UNLESS(o1_length == strlen(str_cp1251));
919     DIE_UNLESS(o2_length == strlen(str_koi8r));
920     DIE_UNLESS(!memcmp(o1_buffer, str_cp1251, o1_length));
921     DIE_UNLESS(!memcmp(o2_buffer, str_koi8r, o2_length));
922 
923     rc= mysql_stmt_fetch(stmt);
924     DIE_UNLESS(rc == MYSQL_NO_DATA);
925 
926     rc= mysql_stmt_next_result(stmt);
927     DIE_UNLESS(rc == 0 && mysql->field_count == 0);
928 
929     mysql_stmt_close(stmt);
930 
931     rc= mysql_commit(mysql);
932     myquery(rc);
933   }
934 }
935 
test_wl4435_2()936 static void test_wl4435_2()
937 {
938   MYSQL_STMT *stmt;
939   int  i;
940   int  rc;
941   char query[MAX_TEST_QUERY_LENGTH];
942 
943   myheader("test_wl4435_2");
944   mct_start_logging("test_wl4435_2");
945 
946   /*
947     Do a few iterations so that we catch any problem with incorrect
948     handling/flushing prepared statement results.
949   */
950 
951   for (i= 0; i < 10; ++i)
952   {
953     /*
954       Prepare a procedure. That can be moved out of the loop, but it was
955       left in the loop for the sake of having as many statements as
956       possible.
957     */
958 
959     rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
960     myquery(rc);
961 
962     rc= mysql_query(mysql,
963       "CREATE PROCEDURE p1()"
964       "BEGIN "
965       "  SELECT 1; "
966       "  SELECT 2, 3 UNION SELECT 4, 5; "
967       "  SELECT 6, 7, 8; "
968       "END");
969     myquery(rc);
970 
971     /* Invoke a procedure, that returns several result sets. */
972 
973     my_stpcpy(query, "CALL p1()");
974     stmt= mysql_simple_prepare(mysql, query);
975     check_stmt(stmt);
976 
977     /* Execute! */
978 
979     rc= mysql_stmt_execute(stmt);
980     check_execute(stmt, rc);
981 
982     /* Flush all the results. */
983 
984     mysql_stmt_close(stmt);
985 
986     /* Clean up. */
987     rc= mysql_commit(mysql);
988     myquery(rc);
989 
990     rc= mysql_query(mysql, "DROP PROCEDURE p1");
991     myquery(rc);
992   }
993   mct_close_log();
994 }
995 
996 
997 #define WL4435_TEST(sql_type, sql_value, \
998                     c_api_in_type, c_api_out_type, \
999                     c_type, c_type_ext, \
1000                     printf_args, assert_condition) \
1001 \
1002   do { \
1003   int rc; \
1004   MYSQL_STMT *ps; \
1005   MYSQL_BIND psp; \
1006   MYSQL_RES *rs_metadata; \
1007   MYSQL_FIELD *fields; \
1008   c_type pspv c_type_ext; \
1009   my_bool psp_null= FALSE; \
1010   \
1011   memset(&pspv, 0, sizeof (pspv));                \
1012   \
1013   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); \
1014   myquery(rc); \
1015   \
1016   rc= mysql_query(mysql, \
1017     "CREATE PROCEDURE p1(OUT v " sql_type ") SET v = " sql_value ";"); \
1018   myquery(rc); \
1019   \
1020   ps = mysql_simple_prepare(mysql, "CALL p1(?)"); \
1021   check_stmt(ps); \
1022   memset(&psp, 0, sizeof (psp));              \
1023   psp.buffer_type= c_api_in_type; \
1024   psp.is_null= &psp_null; \
1025   psp.buffer= (char *) &pspv; \
1026   psp.buffer_length= (ulong)sizeof (psp);       \
1027   \
1028   rc= mysql_stmt_bind_param(ps, &psp); \
1029   check_execute(ps, rc); \
1030   \
1031   rc= mysql_stmt_execute(ps); \
1032   check_execute(ps, rc); \
1033   \
1034   if (!(mysql->server_capabilities & CLIENT_DEPRECATE_EOF)) \
1035   DIE_UNLESS(mysql->server_status & SERVER_PS_OUT_PARAMS); \
1036   DIE_UNLESS(mysql_stmt_field_count(ps) == 1); \
1037   \
1038   rs_metadata= mysql_stmt_result_metadata(ps); \
1039   fields= mysql_fetch_fields(rs_metadata); \
1040   \
1041   rc= mysql_stmt_bind_result(ps, &psp); \
1042   check_execute(ps, rc); \
1043   \
1044   rc= mysql_stmt_fetch(ps); \
1045   DIE_UNLESS(rc == 0); \
1046   \
1047   DIE_UNLESS(fields[0].type == c_api_out_type); \
1048   printf printf_args; \
1049   printf("; in type: %d; out type: %d\n", \
1050          (int) c_api_in_type, (int) c_api_out_type); \
1051   \
1052   rc= mysql_stmt_fetch(ps); \
1053   DIE_UNLESS(rc == MYSQL_NO_DATA); \
1054   \
1055   rc= mysql_stmt_next_result(ps); \
1056   DIE_UNLESS(rc == 0); \
1057   \
1058   mysql_free_result(rs_metadata); \
1059   mysql_stmt_free_result(ps); \
1060   mysql_stmt_close(ps); \
1061   \
1062   DIE_UNLESS(assert_condition); \
1063   \
1064   } while (0)
1065 
test_wl4435_3()1066 static void test_wl4435_3()
1067 {
1068   char tmp[255];
1069 
1070   puts("");
1071 
1072   /*
1073     The following types are not supported:
1074      - ENUM
1075      - SET
1076 
1077     The following types are supported but can not be used for
1078     OUT-parameters:
1079      - MEDIUMINT;
1080      - BIT(..);
1081 
1082     The problem is that those types are not supported for IN-parameters,
1083     and OUT-parameters should be bound as IN-parameters before execution
1084 
1085     The following types should not be used:
1086      - MYSQL_TYPE_YEAR (use MYSQL_TYPE_SHORT instead);
1087      - MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB
1088        (use MYSQL_TYPE_BLOB instead);
1089   */
1090 
1091   WL4435_TEST("TINYINT", "127",
1092               MYSQL_TYPE_TINY, MYSQL_TYPE_TINY,
1093               char, ,
1094               ("  - TINYINT / char / MYSQL_TYPE_TINY:\t\t\t %d", (int) pspv),
1095               pspv == 127);
1096 
1097   WL4435_TEST("SMALLINT", "32767",
1098               MYSQL_TYPE_SHORT, MYSQL_TYPE_SHORT,
1099               short, ,
1100               ("  - SMALLINT / short / MYSQL_TYPE_SHORT:\t\t %d", (int) pspv),
1101               pspv == 32767);
1102 
1103   WL4435_TEST("INT", "2147483647",
1104               MYSQL_TYPE_LONG, MYSQL_TYPE_LONG,
1105               int, ,
1106               ("  - INT / int / MYSQL_TYPE_LONG:\t\t\t %d", pspv),
1107               pspv == 2147483647l);
1108 
1109   WL4435_TEST("BIGINT", "9223372036854775807",
1110               MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG,
1111               long long, ,
1112               ("  - BIGINT / long long / MYSQL_TYPE_LONGLONG:\t\t %lld", pspv),
1113               pspv == 9223372036854775807ll);
1114 
1115   WL4435_TEST("TIMESTAMP", "'2007-11-18 15:01:02'",
1116               MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP,
1117               MYSQL_TIME, ,
1118               ("  - TIMESTAMP / MYSQL_TIME / MYSQL_TYPE_TIMESTAMP:\t "
1119                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1120                (int) pspv.year, (int) pspv.month, (int) pspv.day,
1121                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1122               pspv.year == 2007 && pspv.month == 11 && pspv.day == 18 &&
1123               pspv.hour == 15 && pspv.minute == 1 && pspv.second == 2);
1124 
1125   WL4435_TEST("DATETIME", "'1234-11-12 12:34:59'",
1126               MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME,
1127               MYSQL_TIME, ,
1128               ("  - DATETIME / MYSQL_TIME / MYSQL_TYPE_DATETIME:\t "
1129                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1130                (int) pspv.year, (int) pspv.month, (int) pspv.day,
1131                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1132               pspv.year == 1234 && pspv.month == 11 && pspv.day == 12 &&
1133               pspv.hour == 12 && pspv.minute == 34 && pspv.second == 59);
1134 
1135   WL4435_TEST("TIME", "'123:45:01'",
1136               MYSQL_TYPE_TIME, MYSQL_TYPE_TIME,
1137               MYSQL_TIME, ,
1138               ("  - TIME / MYSQL_TIME / MYSQL_TYPE_TIME:\t\t "
1139                "%.3d:%.2d:%.2d",
1140                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1141               pspv.hour == 123 && pspv.minute == 45 && pspv.second == 1);
1142 
1143   WL4435_TEST("DATE", "'1234-11-12'",
1144               MYSQL_TYPE_DATE, MYSQL_TYPE_DATE,
1145               MYSQL_TIME, ,
1146               ("  - DATE / MYSQL_TIME / MYSQL_TYPE_DATE:\t\t "
1147                "%.4d-%.2d-%.2d",
1148                (int) pspv.year, (int) pspv.month, (int) pspv.day),
1149               pspv.year == 1234 && pspv.month == 11 && pspv.day == 12);
1150 
1151   WL4435_TEST("YEAR", "'2010'",
1152               MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR,
1153               short, ,
1154               ("  - YEAR / short / MYSQL_TYPE_SHORT:\t\t\t %.4d", (int) pspv),
1155               pspv == 2010);
1156 
1157   WL4435_TEST("FLOAT(7, 4)", "123.4567",
1158               MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT,
1159               float, ,
1160               ("  - FLOAT / float / MYSQL_TYPE_FLOAT:\t\t\t %g", (double) pspv),
1161               pspv - 123.4567 < 0.0001);
1162 
1163   WL4435_TEST("DOUBLE(8, 5)", "123.45678",
1164               MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE,
1165               double, ,
1166               ("  - DOUBLE / double / MYSQL_TYPE_DOUBLE:\t\t %g", (double) pspv),
1167               pspv - 123.45678 < 0.00001);
1168 
1169   WL4435_TEST("DECIMAL(9, 6)", "123.456789",
1170               MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL,
1171               char, [255],
1172               ("  - DECIMAL / char[] / MYSQL_TYPE_NEWDECIMAL:\t\t '%s'", (char *) pspv),
1173               !strcmp(pspv, "123.456789"));
1174 
1175   WL4435_TEST("CHAR(32)", "REPEAT('C', 16)",
1176               MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1177               char, [255],
1178               ("  - CHAR(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1179               !strcmp(pspv, "CCCCCCCCCCCCCCCC"));
1180 
1181   WL4435_TEST("VARCHAR(32)", "REPEAT('V', 16)",
1182               MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1183               char, [255],
1184               ("  - VARCHAR(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1185               !strcmp(pspv, "VVVVVVVVVVVVVVVV"));
1186 
1187   WL4435_TEST("TINYTEXT", "REPEAT('t', 16)",
1188               MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1189               char, [255],
1190               ("  - TINYTEXT / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1191               !strcmp(pspv, "tttttttttttttttt"));
1192 
1193   WL4435_TEST("TEXT", "REPEAT('t', 16)",
1194               MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1195               char, [255],
1196               ("  - TEXT / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1197               !strcmp(pspv, "tttttttttttttttt"));
1198 
1199   WL4435_TEST("MEDIUMTEXT", "REPEAT('t', 16)",
1200               MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1201               char, [255],
1202               ("  - MEDIUMTEXT / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1203               !strcmp(pspv, "tttttttttttttttt"));
1204 
1205   WL4435_TEST("LONGTEXT", "REPEAT('t', 16)",
1206               MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1207               char, [255],
1208               ("  - LONGTEXT / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1209               !strcmp(pspv, "tttttttttttttttt"));
1210 
1211   WL4435_TEST("BINARY(32)", "REPEAT('\1', 16)",
1212               MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1213               char, [255],
1214               ("  - BINARY(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1215               memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1216 
1217   WL4435_TEST("VARBINARY(32)", "REPEAT('\1', 16)",
1218               MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1219               char, [255],
1220               ("  - VARBINARY(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1221               memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1222 
1223   WL4435_TEST("TINYBLOB", "REPEAT('\2', 16)",
1224               MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1225               char, [255],
1226               ("  - TINYBLOB / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1227               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1228 
1229   WL4435_TEST("BLOB", "REPEAT('\2', 16)",
1230               MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1231               char, [255],
1232               ("  - BLOB / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1233               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1234 
1235   WL4435_TEST("MEDIUMBLOB", "REPEAT('\2', 16)",
1236               MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1237               char, [255],
1238               ("  - MEDIUMBLOB / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1239               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1240 
1241   WL4435_TEST("LONGBLOB", "REPEAT('\2', 16)",
1242               MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1243               char, [255],
1244               ("  - LONGBLOB / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1245               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1246 }
1247 
1248 
1249 /* Test simple prepare field results */
1250 
test_prepare_field_result()1251 static void test_prepare_field_result()
1252 {
1253   MYSQL_STMT *stmt;
1254   MYSQL_RES  *result;
1255   int        rc;
1256   char query[MAX_TEST_QUERY_LENGTH];
1257 
1258   myheader("test_prepare_field_result");
1259 
1260   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_field_result");
1261   myquery(rc);
1262 
1263   rc= mysql_query(mysql, "CREATE TABLE test_prepare_field_result(int_c int, "
1264                          "var_c varchar(50), ts_c timestamp, "
1265                          "char_c char(4), date_c date, extra tinyint)");
1266   myquery(rc);
1267 
1268   /* insert */
1269   my_stpcpy(query, "SELECT int_c, var_c, date_c as date, ts_c, char_c FROM "
1270                 " test_prepare_field_result as t1 WHERE int_c=?");
1271   stmt= mysql_simple_prepare(mysql, query);
1272   check_stmt(stmt);
1273 
1274   verify_param_count(stmt, 1);
1275 
1276   result= mysql_stmt_result_metadata(stmt);
1277   mytest(result);
1278 
1279   my_print_result_metadata(result);
1280 
1281   if (!opt_silent)
1282     fprintf(stdout, "\n\n field attributes:\n");
1283   verify_prepare_field(result, 0, "int_c", "int_c", MYSQL_TYPE_LONG,
1284                        "t1", "test_prepare_field_result", current_db, 11, 0);
1285   verify_prepare_field(result, 1, "var_c", "var_c", MYSQL_TYPE_VAR_STRING,
1286                        "t1", "test_prepare_field_result", current_db, 50, 0);
1287   verify_prepare_field(result, 2, "date", "date_c", MYSQL_TYPE_DATE,
1288                        "t1", "test_prepare_field_result", current_db, 10, 0);
1289   verify_prepare_field(result, 3, "ts_c", "ts_c", MYSQL_TYPE_TIMESTAMP,
1290                        "t1", "test_prepare_field_result", current_db, 19, 0);
1291   verify_prepare_field(result, 4, "char_c", "char_c",
1292                        (mysql_get_server_version(mysql) <= 50000 ?
1293                         MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING),
1294                        "t1", "test_prepare_field_result", current_db, 4, 0);
1295 
1296   verify_field_count(result, 5);
1297   mysql_free_result(result);
1298   mysql_stmt_close(stmt);
1299 }
1300 
1301 
1302 /* Test simple prepare field results */
1303 
test_prepare_syntax()1304 static void test_prepare_syntax()
1305 {
1306   MYSQL_STMT *stmt;
1307   int        rc;
1308   char query[MAX_TEST_QUERY_LENGTH];
1309 
1310   myheader("test_prepare_syntax");
1311 
1312   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_syntax");
1313   myquery(rc);
1314 
1315   rc= mysql_query(mysql, "CREATE TABLE test_prepare_syntax("
1316                          "id int, name varchar(50), extra int)");
1317   myquery(rc);
1318 
1319   my_stpcpy(query, "INSERT INTO test_prepare_syntax VALUES(?");
1320   stmt= mysql_simple_prepare(mysql, query);
1321   check_stmt_r(stmt);
1322 
1323   my_stpcpy(query, "SELECT id, name FROM test_prepare_syntax WHERE id=? AND WHERE");
1324   stmt= mysql_simple_prepare(mysql, query);
1325   check_stmt_r(stmt);
1326 
1327   /* now fetch the results ..*/
1328   rc= mysql_commit(mysql);
1329   myquery(rc);
1330 }
1331 
1332 
1333 /* Test a simple prepare */
1334 
test_prepare()1335 static void test_prepare()
1336 {
1337   MYSQL_STMT *stmt;
1338   int        rc, i;
1339   int        int_data, o_int_data;
1340   char       str_data[50], data[50];
1341   char       tiny_data, o_tiny_data;
1342   short      small_data, o_small_data;
1343   longlong   big_data, o_big_data;
1344   float      real_data, o_real_data;
1345   double     double_data, o_double_data;
1346   ulong      length[7], len;
1347   my_bool    is_null[7];
1348   char	     llbuf[22];
1349   MYSQL_BIND my_bind[7];
1350   char query[MAX_TEST_QUERY_LENGTH];
1351 
1352   myheader("test_prepare");
1353 
1354   rc= mysql_autocommit(mysql, TRUE);
1355   myquery(rc);
1356 
1357   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
1358   myquery(rc);
1359 
1360   rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 tinyint, "
1361                          "col2 varchar(15), col3 int, "
1362                          "col4 smallint, col5 bigint, "
1363                          "col6 float, col7 double )");
1364   myquery(rc);
1365 
1366   /* insert by prepare */
1367   strxmov(query, "INSERT INTO my_prepare VALUES(?, ?, ?, ?, ?, ?, ?)", NullS);
1368   stmt= mysql_simple_prepare(mysql, query);
1369   check_stmt(stmt);
1370 
1371   verify_param_count(stmt, 7);
1372 
1373   memset(my_bind, 0, sizeof(my_bind));
1374 
1375   /* tinyint */
1376   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1377   my_bind[0].buffer= (void *)&tiny_data;
1378   /* string */
1379   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1380   my_bind[1].buffer= (void *)str_data;
1381   my_bind[1].buffer_length= 1000;                  /* Max string length */
1382   /* integer */
1383   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
1384   my_bind[2].buffer= (void *)&int_data;
1385   /* short */
1386   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
1387   my_bind[3].buffer= (void *)&small_data;
1388   /* bigint */
1389   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
1390   my_bind[4].buffer= (void *)&big_data;
1391   /* float */
1392   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
1393   my_bind[5].buffer= (void *)&real_data;
1394   /* double */
1395   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
1396   my_bind[6].buffer= (void *)&double_data;
1397 
1398   for (i= 0; i < (int) array_elements(my_bind); i++)
1399   {
1400     my_bind[i].length= &length[i];
1401     my_bind[i].is_null= &is_null[i];
1402     is_null[i]= 0;
1403   }
1404 
1405   rc= mysql_stmt_bind_param(stmt, my_bind);
1406   check_execute(stmt, rc);
1407 
1408   int_data= 320;
1409   small_data= 1867;
1410   big_data= 1000;
1411   real_data= 2;
1412   double_data= 6578.001;
1413 
1414   /* now, execute the prepared statement to insert 10 records.. */
1415   for (tiny_data= 0; tiny_data < 100; tiny_data++)
1416   {
1417     length[1]= sprintf(str_data, "MySQL%d", int_data);
1418     rc= mysql_stmt_execute(stmt);
1419     check_execute(stmt, rc);
1420     int_data += 25;
1421     small_data += 10;
1422     big_data += 100;
1423     real_data += 1;
1424     double_data += 10.09;
1425   }
1426 
1427   mysql_stmt_close(stmt);
1428 
1429   /* now fetch the results ..*/
1430   rc= mysql_commit(mysql);
1431   myquery(rc);
1432 
1433   /* test the results now, only one row should exist */
1434   rc= my_stmt_result("SELECT * FROM my_prepare");
1435   DIE_UNLESS(tiny_data == (char) rc);
1436 
1437   stmt= mysql_simple_prepare(mysql, "SELECT * FROM my_prepare");
1438   check_stmt(stmt);
1439 
1440   rc= mysql_stmt_bind_result(stmt, my_bind);
1441   check_execute(stmt, rc);
1442 
1443   /* get the result */
1444   rc= mysql_stmt_execute(stmt);
1445   check_execute(stmt, rc);
1446 
1447   o_int_data= 320;
1448   o_small_data= 1867;
1449   o_big_data= 1000;
1450   o_real_data= 2;
1451   o_double_data= 6578.001;
1452 
1453   /* now, execute the prepared statement to insert 10 records.. */
1454   for (o_tiny_data= 0; o_tiny_data < 100; o_tiny_data++)
1455   {
1456     len= sprintf(data, "MySQL%d", o_int_data);
1457 
1458     rc= mysql_stmt_fetch(stmt);
1459     check_execute(stmt, rc);
1460 
1461     if (!opt_silent)
1462     {
1463       fprintf(stdout, "\n");
1464       fprintf(stdout, "\n\t tiny   : %d (%lu)", tiny_data, length[0]);
1465       fprintf(stdout, "\n\t short  : %d (%lu)", small_data, length[3]);
1466       fprintf(stdout, "\n\t int    : %d (%lu)", int_data, length[2]);
1467       fprintf(stdout, "\n\t big    : %s (%lu)", llstr(big_data, llbuf),
1468               length[4]);
1469 
1470       fprintf(stdout, "\n\t float  : %f (%lu)", real_data, length[5]);
1471       fprintf(stdout, "\n\t double : %f (%lu)", double_data, length[6]);
1472 
1473       fprintf(stdout, "\n\t str    : %s (%lu)", str_data, length[1]);
1474     }
1475 
1476     DIE_UNLESS(tiny_data == o_tiny_data);
1477     DIE_UNLESS(is_null[0] == 0);
1478     DIE_UNLESS(length[0] == 1);
1479 
1480     DIE_UNLESS(int_data == o_int_data);
1481     DIE_UNLESS(length[2] == 4);
1482 
1483     DIE_UNLESS(small_data == o_small_data);
1484     DIE_UNLESS(length[3] == 2);
1485 
1486     DIE_UNLESS(big_data == o_big_data);
1487     DIE_UNLESS(length[4] == 8);
1488 
1489     DIE_UNLESS(real_data == o_real_data);
1490     DIE_UNLESS(length[5] == 4);
1491 
1492     DIE_UNLESS(cmp_double(&double_data, &o_double_data));
1493     DIE_UNLESS(length[6] == 8);
1494 
1495     DIE_UNLESS(strcmp(data, str_data) == 0);
1496     DIE_UNLESS(length[1] == len);
1497 
1498     o_int_data += 25;
1499     o_small_data += 10;
1500     o_big_data += 100;
1501     o_real_data += 1;
1502     o_double_data += 10.09;
1503   }
1504 
1505   rc= mysql_stmt_fetch(stmt);
1506   DIE_UNLESS(rc == MYSQL_NO_DATA);
1507 
1508   mysql_stmt_close(stmt);
1509 
1510 }
1511 
1512 
1513 /* Test double comparision */
1514 
test_double_compare()1515 static void test_double_compare()
1516 {
1517   MYSQL_STMT *stmt;
1518   int        rc;
1519   char       real_data[10], tiny_data;
1520   double     double_data;
1521   MYSQL_RES  *result;
1522   MYSQL_BIND my_bind[3];
1523   ulong      length[3];
1524   char query[MAX_TEST_QUERY_LENGTH];
1525 
1526   myheader("test_double_compare");
1527 
1528   rc= mysql_autocommit(mysql, TRUE);
1529   myquery(rc);
1530 
1531   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_double_compare");
1532   myquery(rc);
1533 
1534   rc= mysql_query(mysql, "CREATE TABLE test_double_compare(col1 tinyint, "
1535                          " col2 float, col3 double )");
1536   myquery(rc);
1537 
1538   rc= mysql_query(mysql, "INSERT INTO test_double_compare "
1539                          "VALUES (1, 10.2, 34.5)");
1540   myquery(rc);
1541 
1542   my_stpcpy(query, "UPDATE test_double_compare SET col1=100 "
1543                 "WHERE col1 = ? AND col2 = ? AND COL3 = ?");
1544   stmt= mysql_simple_prepare(mysql, query);
1545   check_stmt(stmt);
1546 
1547   verify_param_count(stmt, 3);
1548 
1549   /* Always memset bind array because there can be internal members */
1550   memset(my_bind, 0, sizeof(my_bind));
1551   memset(real_data, 0, sizeof(real_data));
1552 
1553   /* tinyint */
1554   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1555   my_bind[0].buffer= (void *)&tiny_data;
1556 
1557   /* string->float */
1558   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1559   my_bind[1].buffer= (void *)&real_data;
1560   my_bind[1].buffer_length= (ulong)sizeof(real_data);
1561   my_bind[1].length= &length[1];
1562   length[1]= 10;
1563 
1564   /* double */
1565   my_bind[2].buffer_type= MYSQL_TYPE_DOUBLE;
1566   my_bind[2].buffer= (void *)&double_data;
1567 
1568   tiny_data= 1;
1569   my_stpcpy(real_data, "10.2");
1570   double_data= 34.5;
1571   rc= mysql_stmt_bind_param(stmt, my_bind);
1572   check_execute(stmt, rc);
1573 
1574   rc= mysql_stmt_execute(stmt);
1575   check_execute(stmt, rc);
1576 
1577   verify_affected_rows(0);
1578 
1579   mysql_stmt_close(stmt);
1580 
1581   /* now fetch the results ..*/
1582   rc= mysql_commit(mysql);
1583   myquery(rc);
1584 
1585   /* test the results now, only one row should exist */
1586   rc= mysql_query(mysql, "SELECT * FROM test_double_compare");
1587   myquery(rc);
1588 
1589   /* get the result */
1590   result= mysql_store_result(mysql);
1591   mytest(result);
1592 
1593   rc= my_process_result_set(result);
1594   DIE_UNLESS((int)tiny_data == rc);
1595   mysql_free_result(result);
1596 }
1597 
1598 
1599 /* Test simple null */
1600 
test_null()1601 static void test_null()
1602 {
1603   MYSQL_STMT *stmt;
1604   int        rc;
1605   uint       nData;
1606   MYSQL_BIND my_bind[2];
1607   my_bool    is_null[2];
1608   char query[MAX_TEST_QUERY_LENGTH];
1609 
1610   myheader("test_null");
1611 
1612   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_null");
1613   myquery(rc);
1614 
1615   rc= mysql_query(mysql, "CREATE TABLE test_null(col1 int, col2 varchar(50))");
1616   myquery(rc);
1617 
1618   /* insert by prepare, wrong column name */
1619   my_stpcpy(query, "INSERT INTO test_null(col3, col2) VALUES(?, ?)");
1620   stmt= mysql_simple_prepare(mysql, query);
1621   check_stmt_r(stmt);
1622 
1623   my_stpcpy(query, "INSERT INTO test_null(col1, col2) VALUES(?, ?)");
1624   stmt= mysql_simple_prepare(mysql, query);
1625   check_stmt(stmt);
1626 
1627   verify_param_count(stmt, 2);
1628 
1629   /* Always memset all members of bind parameter */
1630   memset(my_bind, 0, sizeof(my_bind));
1631 
1632   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1633   my_bind[0].is_null= &is_null[0];
1634   is_null[0]= 1;
1635   my_bind[1]= my_bind[0];
1636 
1637   rc= mysql_stmt_bind_param(stmt, my_bind);
1638   check_execute(stmt, rc);
1639 
1640   /* now, execute the prepared statement to insert 10 records.. */
1641   for (nData= 0; nData<10; nData++)
1642   {
1643     rc= mysql_stmt_execute(stmt);
1644     check_execute(stmt, rc);
1645   }
1646 
1647   /* Re-bind with MYSQL_TYPE_NULL */
1648   my_bind[0].buffer_type= MYSQL_TYPE_NULL;
1649   is_null[0]= 0; /* reset */
1650   my_bind[1]= my_bind[0];
1651 
1652   rc= mysql_stmt_bind_param(stmt, my_bind);
1653   check_execute(stmt, rc);
1654 
1655   for (nData= 0; nData<10; nData++)
1656   {
1657     rc= mysql_stmt_execute(stmt);
1658     check_execute(stmt, rc);
1659   }
1660 
1661   mysql_stmt_close(stmt);
1662 
1663   /* now fetch the results ..*/
1664   rc= mysql_commit(mysql);
1665   myquery(rc);
1666 
1667   nData*= 2;
1668   rc= my_stmt_result("SELECT * FROM test_null");;
1669   DIE_UNLESS((int) nData == rc);
1670 
1671   /* Fetch results */
1672   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1673   my_bind[0].buffer= (void *)&nData; /* this buffer won't be altered */
1674   my_bind[0].length= 0;
1675   my_bind[1]= my_bind[0];
1676   my_bind[0].is_null= &is_null[0];
1677   my_bind[1].is_null= &is_null[1];
1678 
1679   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_null");
1680   check_stmt(stmt);
1681 
1682   rc= mysql_stmt_execute(stmt);
1683   check_execute(stmt, rc);
1684 
1685   rc= mysql_stmt_bind_result(stmt, my_bind);
1686   check_execute(stmt, rc);
1687 
1688   rc= 0;
1689   is_null[0]= is_null[1]= 0;
1690   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1691   {
1692     DIE_UNLESS(is_null[0]);
1693     DIE_UNLESS(is_null[1]);
1694     rc++;
1695     is_null[0]= is_null[1]= 0;
1696   }
1697   DIE_UNLESS(rc == (int) nData);
1698   mysql_stmt_close(stmt);
1699 }
1700 
1701 
1702 /* Test for NULL as PS parameter (BUG#3367, BUG#3371) */
1703 
test_ps_null_param()1704 static void test_ps_null_param()
1705 {
1706   MYSQL_STMT *stmt;
1707   int        rc;
1708 
1709   MYSQL_BIND in_bind;
1710   my_bool    in_is_null;
1711   long int   in_long;
1712 
1713   MYSQL_BIND out_bind;
1714   ulong      out_length;
1715   my_bool    out_is_null;
1716   char       out_str_data[20];
1717 
1718   const char *queries[]= {"select ?", "select ?+1",
1719                     "select col1 from test_ps_nulls where col1 <=> ?",
1720                     NULL
1721                     };
1722   const char **cur_query= queries;
1723 
1724   myheader("test_null_ps_param_in_result");
1725 
1726   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ps_nulls");
1727   myquery(rc);
1728 
1729   rc= mysql_query(mysql, "CREATE TABLE test_ps_nulls(col1 int)");
1730   myquery(rc);
1731 
1732   rc= mysql_query(mysql, "INSERT INTO test_ps_nulls values (1), (null)");
1733   myquery(rc);
1734 
1735   /* Always memset all members of bind parameter */
1736   memset(&in_bind, 0, sizeof(in_bind));
1737   memset(&out_bind, 0, sizeof(out_bind));
1738 
1739   in_bind.buffer_type= MYSQL_TYPE_LONG;
1740   in_bind.is_null= &in_is_null;
1741   in_bind.length= 0;
1742   in_bind.buffer= (void *)&in_long;
1743   in_is_null= 1;
1744   in_long= 1;
1745 
1746   out_bind.buffer_type= MYSQL_TYPE_STRING;
1747   out_bind.is_null= &out_is_null;
1748   out_bind.length= &out_length;
1749   out_bind.buffer= out_str_data;
1750   out_bind.buffer_length= array_elements(out_str_data);
1751 
1752   /* Execute several queries, all returning NULL in result. */
1753   for(cur_query= queries; *cur_query; cur_query++)
1754   {
1755     char query[MAX_TEST_QUERY_LENGTH];
1756     my_stpcpy(query, *cur_query);
1757     stmt= mysql_simple_prepare(mysql, query);
1758     check_stmt(stmt);
1759     verify_param_count(stmt, 1);
1760 
1761     rc= mysql_stmt_bind_param(stmt, &in_bind);
1762     check_execute(stmt, rc);
1763     rc= mysql_stmt_bind_result(stmt, &out_bind);
1764     check_execute(stmt, rc);
1765     rc= mysql_stmt_execute(stmt);
1766     check_execute(stmt, rc);
1767     rc= mysql_stmt_fetch(stmt);
1768     DIE_UNLESS(rc != MYSQL_NO_DATA);
1769     DIE_UNLESS(out_is_null);
1770     rc= mysql_stmt_fetch(stmt);
1771     DIE_UNLESS(rc == MYSQL_NO_DATA);
1772     mysql_stmt_close(stmt);
1773   }
1774 }
1775 
1776 
1777 /* Test fetch null */
1778 
test_fetch_null()1779 static void test_fetch_null()
1780 {
1781   MYSQL_STMT *stmt;
1782   int        rc;
1783   int        i, nData;
1784   MYSQL_BIND my_bind[11];
1785   ulong      length[11];
1786   my_bool    is_null[11];
1787   char query[MAX_TEST_QUERY_LENGTH];
1788 
1789   myheader("test_fetch_null");
1790 
1791   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null");
1792   myquery(rc);
1793 
1794   rc= mysql_query(mysql, "CREATE TABLE test_fetch_null("
1795                          " col1 tinyint, col2 smallint, "
1796                          " col3 int, col4 bigint, "
1797                          " col5 float, col6 double, "
1798                          " col7 date, col8 time, "
1799                          " col9 varbinary(10), "
1800                          " col10 varchar(50), "
1801                          " col11 char(20))");
1802   myquery(rc);
1803 
1804   rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) "
1805                          "VALUES (1000), (88), (389789)");
1806   myquery(rc);
1807 
1808   rc= mysql_commit(mysql);
1809   myquery(rc);
1810 
1811   /* fetch */
1812   memset(my_bind, 0, sizeof(my_bind));
1813   for (i= 0; i < (int) array_elements(my_bind); i++)
1814   {
1815     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
1816     my_bind[i].is_null= &is_null[i];
1817     my_bind[i].length= &length[i];
1818   }
1819   my_bind[i-1].buffer= (void *)&nData;              /* Last column is not null */
1820 
1821   my_stpcpy((char *)query , "SELECT * FROM test_fetch_null");
1822 
1823   rc= my_stmt_result(query);
1824   DIE_UNLESS(rc == 3);
1825 
1826   stmt= mysql_simple_prepare(mysql, query);
1827   check_stmt(stmt);
1828 
1829   rc= mysql_stmt_bind_result(stmt, my_bind);
1830   check_execute(stmt, rc);
1831 
1832   rc= mysql_stmt_execute(stmt);
1833   check_execute(stmt, rc);
1834 
1835   rc= 0;
1836   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1837   {
1838     rc++;
1839     for (i= 0; i < 10; i++)
1840     {
1841       if (!opt_silent)
1842         fprintf(stdout, "\n data[%d] : %s", i,
1843                 is_null[i] ? "NULL" : "NOT NULL");
1844       DIE_UNLESS(is_null[i]);
1845     }
1846     if (!opt_silent)
1847       fprintf(stdout, "\n data[%d]: %d", i, nData);
1848     DIE_UNLESS(nData == 1000 || nData == 88 || nData == 389789);
1849     DIE_UNLESS(is_null[i] == 0);
1850     DIE_UNLESS(length[i] == 4);
1851   }
1852   DIE_UNLESS(rc == 3);
1853   mysql_stmt_close(stmt);
1854 }
1855 
1856 
1857 /* Test simple select */
1858 
test_select_version()1859 static void test_select_version()
1860 {
1861   MYSQL_STMT *stmt;
1862   int        rc;
1863 
1864   myheader("test_select_version");
1865 
1866   stmt= mysql_simple_prepare(mysql, "SELECT @@version");
1867   check_stmt(stmt);
1868 
1869   verify_param_count(stmt, 0);
1870 
1871   rc= mysql_stmt_execute(stmt);
1872   check_execute(stmt, rc);
1873 
1874   my_process_stmt_result(stmt);
1875   mysql_stmt_close(stmt);
1876 }
1877 
1878 
1879 /* Test simple show */
1880 
test_select_show_table()1881 static void test_select_show_table()
1882 {
1883   MYSQL_STMT *stmt;
1884   int        rc, i;
1885 
1886   myheader("test_select_show_table");
1887 
1888   stmt= mysql_simple_prepare(mysql, "SHOW TABLES FROM mysql");
1889   check_stmt(stmt);
1890 
1891   verify_param_count(stmt, 0);
1892 
1893   for (i= 1; i < 3; i++)
1894   {
1895     rc= mysql_stmt_execute(stmt);
1896     check_execute(stmt, rc);
1897   }
1898 
1899   my_process_stmt_result(stmt);
1900   mysql_stmt_close(stmt);
1901 }
1902 
1903 
1904 /* Test simple select to debug */
1905 
test_select_direct()1906 static void test_select_direct()
1907 {
1908   int        rc;
1909   MYSQL_RES  *result;
1910 
1911   myheader("test_select_direct");
1912 
1913   rc= mysql_autocommit(mysql, TRUE);
1914   myquery(rc);
1915 
1916   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
1917   myquery(rc);
1918 
1919   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
1920                                                  " id2 float, "
1921                                                  " id3 double, "
1922                                                  " name varchar(50))");
1923   myquery(rc);
1924 
1925   /* insert a row and commit the transaction */
1926   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')");
1927   myquery(rc);
1928 
1929   rc= mysql_commit(mysql);
1930   myquery(rc);
1931 
1932   rc= mysql_query(mysql, "SELECT * FROM test_select");
1933   myquery(rc);
1934 
1935   /* get the result */
1936   result= mysql_store_result(mysql);
1937   mytest(result);
1938 
1939   (void) my_process_result_set(result);
1940   mysql_free_result(result);
1941 }
1942 
1943 
1944 /* Test simple select with prepare */
1945 
test_select_prepare()1946 static void test_select_prepare()
1947 {
1948   int        rc;
1949   MYSQL_STMT *stmt;
1950 
1951   myheader("test_select_prepare");
1952 
1953   rc= mysql_autocommit(mysql, TRUE);
1954   myquery(rc);
1955 
1956   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
1957   myquery(rc);
1958 
1959   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
1960   myquery(rc);
1961 
1962   /* insert a row and commit the transaction */
1963   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
1964   myquery(rc);
1965 
1966   rc= mysql_commit(mysql);
1967   myquery(rc);
1968 
1969   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
1970   check_stmt(stmt);
1971 
1972   rc= mysql_stmt_execute(stmt);
1973   check_execute(stmt, rc);
1974 
1975   rc= my_process_stmt_result(stmt);
1976   DIE_UNLESS(rc == 1);
1977   mysql_stmt_close(stmt);
1978 
1979   rc= mysql_query(mysql, "DROP TABLE test_select");
1980   myquery(rc);
1981 
1982   rc= mysql_query(mysql, "CREATE TABLE test_select(id tinyint, id1 int, "
1983                                                 "  id2 float, id3 float, "
1984                                                 "  name varchar(50))");
1985   myquery(rc);
1986 
1987   /* insert a row and commit the transaction */
1988   rc= mysql_query(mysql, "INSERT INTO test_select(id, id1, id2, name) VALUES(10, 5, 2.3, 'venu')");
1989   myquery(rc);
1990 
1991   rc= mysql_commit(mysql);
1992   myquery(rc);
1993 
1994   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
1995   check_stmt(stmt);
1996 
1997   rc= mysql_stmt_execute(stmt);
1998   check_execute(stmt, rc);
1999 
2000   rc= my_process_stmt_result(stmt);
2001   DIE_UNLESS(rc == 1);
2002   mysql_stmt_close(stmt);
2003 }
2004 
2005 
2006 /* Test simple select */
2007 
test_select()2008 static void test_select()
2009 {
2010   MYSQL_STMT *stmt;
2011   int        rc;
2012   char       szData[25];
2013   int        nData= 1;
2014   MYSQL_BIND my_bind[2];
2015   ulong      length[2];
2016   char query[MAX_TEST_QUERY_LENGTH];
2017 
2018   myheader("test_select");
2019 
2020   rc= mysql_autocommit(mysql, TRUE);
2021   myquery(rc);
2022 
2023   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2024   myquery(rc);
2025 
2026   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
2027   myquery(rc);
2028 
2029   /* insert a row and commit the transaction */
2030   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
2031   myquery(rc);
2032 
2033   /* now insert the second row, and roll back the transaction */
2034   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(20, 'mysql')");
2035   myquery(rc);
2036 
2037   rc= mysql_commit(mysql);
2038   myquery(rc);
2039 
2040   my_stpcpy(query, "SELECT * FROM test_select WHERE id= ? "
2041                 "AND CONVERT(name USING utf8) =?");
2042   stmt= mysql_simple_prepare(mysql, query);
2043   check_stmt(stmt);
2044 
2045   verify_param_count(stmt, 2);
2046 
2047   /* Always memset all members of bind parameter */
2048   memset(my_bind, 0, sizeof(my_bind));
2049 
2050   /* string data */
2051   nData= 10;
2052   my_stpcpy(szData, (char *)"venu");
2053   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2054   my_bind[1].buffer= (void *)szData;
2055   my_bind[1].buffer_length= 4;
2056   my_bind[1].length= &length[1];
2057   length[1]= 4;
2058 
2059   my_bind[0].buffer= (void *)&nData;
2060   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2061 
2062   rc= mysql_stmt_bind_param(stmt, my_bind);
2063   check_execute(stmt, rc);
2064 
2065   rc= mysql_stmt_execute(stmt);
2066   check_execute(stmt, rc);
2067 
2068   rc= my_process_stmt_result(stmt);
2069   DIE_UNLESS(rc == 1);
2070 
2071   mysql_stmt_close(stmt);
2072 }
2073 
2074 
2075 /*
2076   Test for BUG#3420 ("select id1, value1 from t where id= ? or value= ?"
2077   returns all rows in the table)
2078 */
2079 
test_ps_conj_select()2080 static void test_ps_conj_select()
2081 {
2082   MYSQL_STMT *stmt;
2083   int        rc;
2084   MYSQL_BIND my_bind[2];
2085   int32      int_data;
2086   char       str_data[32];
2087   ulong      str_length;
2088   char query[MAX_TEST_QUERY_LENGTH];
2089   myheader("test_ps_conj_select");
2090 
2091   rc= mysql_query(mysql, "drop table if exists t1");
2092   myquery(rc);
2093 
2094   rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2095                          "value2 varchar(100), value1 varchar(100))");
2096   myquery(rc);
2097 
2098   rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2099                           "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2100   myquery(rc);
2101 
2102   my_stpcpy(query, "select id1, value1 from t1 where id1= ? or "
2103                 "CONVERT(value1 USING utf8)= ?");
2104   stmt= mysql_simple_prepare(mysql, query);
2105   check_stmt(stmt);
2106 
2107   verify_param_count(stmt, 2);
2108 
2109   /* Always memset all members of bind parameter */
2110   memset(my_bind, 0, sizeof(my_bind));
2111 
2112   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2113   my_bind[0].buffer= (void *)&int_data;
2114 
2115   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2116   my_bind[1].buffer= (void *)str_data;
2117   my_bind[1].buffer_length= array_elements(str_data);
2118   my_bind[1].length= &str_length;
2119 
2120   rc= mysql_stmt_bind_param(stmt, my_bind);
2121   check_execute(stmt, rc);
2122 
2123   int_data= 1;
2124   my_stpcpy(str_data, "hh");
2125   str_length= (ulong)strlen(str_data);
2126 
2127   rc= mysql_stmt_execute(stmt);
2128   check_execute(stmt, rc);
2129 
2130   rc= my_process_stmt_result(stmt);
2131   DIE_UNLESS(rc == 3);
2132 
2133   mysql_stmt_close(stmt);
2134 }
2135 
2136 
2137 /* reads Qcache_hits from server and returns its value */
query_cache_hits(MYSQL * conn)2138 static uint query_cache_hits(MYSQL *conn)
2139 {
2140   MYSQL_RES *res;
2141   MYSQL_ROW row;
2142   int rc;
2143   uint result;
2144 
2145   rc= mysql_query(conn, "show status like 'qcache_hits'");
2146   myquery(rc);
2147   res= mysql_use_result(conn);
2148   DIE_UNLESS(res);
2149 
2150   row= mysql_fetch_row(res);
2151   DIE_UNLESS(row);
2152 
2153   result= atoi(row[1]);
2154   mysql_free_result(res);
2155   return result;
2156 }
2157 
2158 
2159 /*
2160   utility for the next test; expects 3 rows in the result from a SELECT,
2161   compares each row/field with an expected value.
2162  */
2163 #define test_ps_query_cache_result(i1,s1,l1,i2,s2,l2,i3,s3,l3)    \
2164   r_metadata= mysql_stmt_result_metadata(stmt);                   \
2165   DIE_UNLESS(r_metadata != NULL);                                 \
2166   rc= mysql_stmt_fetch(stmt);                                     \
2167   check_execute(stmt, rc);                                        \
2168   if (!opt_silent)                                                \
2169     fprintf(stdout, "\n row 1: %d, %s(%lu)", r_int_data,          \
2170             r_str_data, r_str_length);                            \
2171   DIE_UNLESS((r_int_data == i1) && (r_str_length == l1) &&        \
2172              (strcmp(r_str_data, s1) == 0));                      \
2173   rc= mysql_stmt_fetch(stmt);                                     \
2174   check_execute(stmt, rc);                                        \
2175   if (!opt_silent)                                                \
2176     fprintf(stdout, "\n row 2: %d, %s(%lu)", r_int_data,          \
2177             r_str_data, r_str_length);                            \
2178   DIE_UNLESS((r_int_data == i2) && (r_str_length == l2) &&        \
2179              (strcmp(r_str_data, s2) == 0));                      \
2180   rc= mysql_stmt_fetch(stmt);                                     \
2181   check_execute(stmt, rc);                                        \
2182   if (!opt_silent)                                                \
2183     fprintf(stdout, "\n row 3: %d, %s(%lu)", r_int_data,          \
2184             r_str_data, r_str_length);                            \
2185   DIE_UNLESS((r_int_data == i3) && (r_str_length == l3) &&        \
2186              (strcmp(r_str_data, s3) == 0));                      \
2187   rc= mysql_stmt_fetch(stmt);                                     \
2188   DIE_UNLESS(rc == MYSQL_NO_DATA);                                \
2189   mysql_free_result(r_metadata);
2190 
2191 
2192 /*
2193   Test that prepared statements make use of the query cache just as normal
2194   statements (BUG#735).
2195 */
test_ps_query_cache()2196 static void test_ps_query_cache()
2197 {
2198   MYSQL      *lmysql= mysql;
2199   MYSQL_STMT *stmt;
2200   int        rc;
2201   MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */
2202   int32      p_int_data, r_int_data;
2203   char       p_str_data[32], r_str_data[32];
2204   ulong      p_str_length, r_str_length;
2205   MYSQL_RES  *r_metadata;
2206   char       query[MAX_TEST_QUERY_LENGTH];
2207   uint       hits1, hits2;
2208   enum enum_test_ps_query_cache
2209   {
2210     /*
2211       We iterate the same prepare/executes block, but have iterations where
2212       we vary the query cache conditions.
2213     */
2214     /* the query cache is enabled for the duration of prep&execs: */
2215     TEST_QCACHE_ON= 0,
2216     /*
2217       same but using a new connection (to see if qcache serves results from
2218       the previous connection as it should):
2219     */
2220     TEST_QCACHE_ON_WITH_OTHER_CONN,
2221     /*
2222       First border case: disables the query cache before prepare and
2223       re-enables it before execution (to test if we have no bug then):
2224     */
2225     TEST_QCACHE_OFF_ON,
2226     /*
2227       Second border case: enables the query cache before prepare and
2228       disables it before execution:
2229     */
2230     TEST_QCACHE_ON_OFF
2231   };
2232   enum enum_test_ps_query_cache iteration;
2233 
2234   myheader("test_ps_query_cache");
2235 
2236   rc= mysql_query(mysql, "SET SQL_MODE=''");
2237   myquery(rc);
2238 
2239   /* prepare the table */
2240 
2241   rc= mysql_query(mysql, "drop table if exists t1");
2242   myquery(rc);
2243 
2244   rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2245                          "value2 varchar(100), value1 varchar(100))");
2246   myquery(rc);
2247 
2248   rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2249                           "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2250   myquery(rc);
2251 
2252   for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++)
2253   {
2254 
2255     switch (iteration) {
2256     case TEST_QCACHE_ON:
2257     case TEST_QCACHE_ON_OFF:
2258       rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2259       myquery(rc);
2260       break;
2261     case TEST_QCACHE_OFF_ON:
2262       rc= mysql_query(lmysql, "set global query_cache_size=0");
2263       myquery(rc);
2264       break;
2265     case TEST_QCACHE_ON_WITH_OTHER_CONN:
2266       if (!opt_silent)
2267         fprintf(stdout, "\n Establishing a test connection ...");
2268       if (!(lmysql= mysql_client_init(NULL)))
2269       {
2270         printf("mysql_client_init() failed");
2271         DIE_UNLESS(0);
2272       }
2273       if (!(mysql_real_connect(lmysql, opt_host, opt_user,
2274                                opt_password, current_db, opt_port,
2275                                opt_unix_socket, 0)))
2276       {
2277         printf("connection failed");
2278         mysql_close(lmysql);
2279         DIE_UNLESS(0);
2280       }
2281       rc= mysql_query(lmysql, "SET SQL_MODE=''");
2282       myquery(rc);
2283 
2284       if (!opt_silent)
2285         fprintf(stdout, "OK");
2286     }
2287 
2288     my_stpcpy(query, "select id1, value1 from t1 where id1= ? or "
2289            "CONVERT(value1 USING utf8)= ?");
2290     stmt= mysql_simple_prepare(lmysql, query);
2291     check_stmt(stmt);
2292 
2293     verify_param_count(stmt, 2);
2294 
2295     switch (iteration) {
2296     case TEST_QCACHE_OFF_ON:
2297       rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2298       myquery(rc);
2299       break;
2300     case TEST_QCACHE_ON_OFF:
2301       rc= mysql_query(lmysql, "set global query_cache_size=0");
2302       myquery(rc);
2303     default:
2304       break;
2305     }
2306 
2307     memset(p_bind, 0, sizeof(p_bind));
2308     p_bind[0].buffer_type= MYSQL_TYPE_LONG;
2309     p_bind[0].buffer= (void *)&p_int_data;
2310     p_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2311     p_bind[1].buffer= (void *)p_str_data;
2312     p_bind[1].buffer_length= array_elements(p_str_data);
2313     p_bind[1].length= &p_str_length;
2314 
2315     rc= mysql_stmt_bind_param(stmt, p_bind);
2316     check_execute(stmt, rc);
2317 
2318     p_int_data= 1;
2319     my_stpcpy(p_str_data, "hh");
2320     p_str_length= (ulong)strlen(p_str_data);
2321 
2322     memset(r_bind, 0, sizeof(r_bind));
2323     r_bind[0].buffer_type= MYSQL_TYPE_LONG;
2324     r_bind[0].buffer= (void *)&r_int_data;
2325     r_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2326     r_bind[1].buffer= (void *)r_str_data;
2327     r_bind[1].buffer_length= array_elements(r_str_data);
2328     r_bind[1].length= &r_str_length;
2329 
2330     rc= mysql_stmt_bind_result(stmt, r_bind);
2331     check_execute(stmt, rc);
2332 
2333     rc= mysql_stmt_execute(stmt);
2334     check_execute(stmt, rc);
2335 
2336     test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2337 
2338     /* now retry with the same parameter values and see qcache hits */
2339     hits1= query_cache_hits(lmysql);
2340     rc= mysql_stmt_execute(stmt);
2341     check_execute(stmt, rc);
2342     test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2343     hits2= query_cache_hits(lmysql);
2344     switch(iteration) {
2345     case TEST_QCACHE_ON_WITH_OTHER_CONN:
2346     case TEST_QCACHE_ON:                 /* should have hit */
2347       DIE_UNLESS(hits2-hits1 == 1);
2348       break;
2349     case TEST_QCACHE_OFF_ON:
2350     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2351       DIE_UNLESS(hits2-hits1 == 0);
2352       break;
2353     }
2354 
2355     /* now modify parameter values and see qcache hits */
2356     my_stpcpy(p_str_data, "ii");
2357     p_str_length= (ulong)strlen(p_str_data);
2358     rc= mysql_stmt_execute(stmt);
2359     check_execute(stmt, rc);
2360     test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2361     hits1= query_cache_hits(lmysql);
2362 
2363     switch(iteration) {
2364     case TEST_QCACHE_ON:
2365     case TEST_QCACHE_OFF_ON:
2366     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2367       DIE_UNLESS(hits2-hits1 == 0);
2368       break;
2369     case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2370       DIE_UNLESS(hits1-hits2 == 1);
2371       break;
2372     }
2373 
2374     rc= mysql_stmt_execute(stmt);
2375     check_execute(stmt, rc);
2376 
2377     test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2378     hits2= query_cache_hits(lmysql);
2379 
2380     mysql_stmt_close(stmt);
2381 
2382     switch(iteration) {
2383     case TEST_QCACHE_ON:                 /* should have hit */
2384       DIE_UNLESS(hits2-hits1 == 1);
2385       break;
2386     case TEST_QCACHE_OFF_ON:
2387     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2388       DIE_UNLESS(hits2-hits1 == 0);
2389       break;
2390     case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2391       DIE_UNLESS(hits2-hits1 == 1);
2392       break;
2393     }
2394 
2395   } /* for(iteration=...) */
2396 
2397   if (lmysql != mysql)
2398     mysql_close(lmysql);
2399 
2400   rc= mysql_query(mysql, "set global query_cache_size=DEFAULT");
2401   myquery(rc);
2402 }
2403 
2404 
2405 /* Test BUG#1115 (incorrect string parameter value allocation) */
2406 
test_bug1115()2407 static void test_bug1115()
2408 {
2409   MYSQL_STMT *stmt;
2410   int rc;
2411   MYSQL_BIND my_bind[1];
2412   ulong length[1];
2413   char szData[11];
2414   char query[MAX_TEST_QUERY_LENGTH];
2415 
2416   myheader("test_bug1115");
2417 
2418   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2419   myquery(rc);
2420 
2421   rc= mysql_query(mysql, "CREATE TABLE test_select(\
2422 session_id  char(9) NOT NULL, \
2423     a       int(8) unsigned NOT NULL, \
2424     b        int(5) NOT NULL, \
2425     c      int(5) NOT NULL, \
2426     d  datetime NOT NULL)");
2427   myquery(rc);
2428   rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2429                          "(\"abc\", 1, 2, 3, 2003-08-30), "
2430                          "(\"abd\", 1, 2, 3, 2003-08-30), "
2431                          "(\"abf\", 1, 2, 3, 2003-08-30), "
2432                          "(\"abg\", 1, 2, 3, 2003-08-30), "
2433                          "(\"abh\", 1, 2, 3, 2003-08-30), "
2434                          "(\"abj\", 1, 2, 3, 2003-08-30), "
2435                          "(\"abk\", 1, 2, 3, 2003-08-30), "
2436                          "(\"abl\", 1, 2, 3, 2003-08-30), "
2437                          "(\"abq\", 1, 2, 3, 2003-08-30) ");
2438   myquery(rc);
2439   rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2440                          "(\"abw\", 1, 2, 3, 2003-08-30), "
2441                          "(\"abe\", 1, 2, 3, 2003-08-30), "
2442                          "(\"abr\", 1, 2, 3, 2003-08-30), "
2443                          "(\"abt\", 1, 2, 3, 2003-08-30), "
2444                          "(\"aby\", 1, 2, 3, 2003-08-30), "
2445                          "(\"abu\", 1, 2, 3, 2003-08-30), "
2446                          "(\"abi\", 1, 2, 3, 2003-08-30), "
2447                          "(\"abo\", 1, 2, 3, 2003-08-30), "
2448                          "(\"abp\", 1, 2, 3, 2003-08-30), "
2449                          "(\"abz\", 1, 2, 3, 2003-08-30), "
2450                          "(\"abx\", 1, 2, 3, 2003-08-30)");
2451   myquery(rc);
2452 
2453   my_stpcpy(query, "SELECT * FROM test_select WHERE "
2454                 "CONVERT(session_id USING utf8)= ?");
2455   stmt= mysql_simple_prepare(mysql, query);
2456   check_stmt(stmt);
2457 
2458   verify_param_count(stmt, 1);
2459 
2460   /* Always memset all members of bind parameter */
2461   memset(my_bind, 0, sizeof(my_bind));
2462 
2463   my_stpcpy(szData, (char *)"abc");
2464   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2465   my_bind[0].buffer= (void *)szData;
2466   my_bind[0].buffer_length= 10;
2467   my_bind[0].length= &length[0];
2468   length[0]= 3;
2469 
2470   rc= mysql_stmt_bind_param(stmt, my_bind);
2471   check_execute(stmt, rc);
2472 
2473   rc= mysql_stmt_execute(stmt);
2474   check_execute(stmt, rc);
2475 
2476   rc= my_process_stmt_result(stmt);
2477   DIE_UNLESS(rc == 1);
2478 
2479   my_stpcpy(szData, (char *)"venu");
2480   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2481   my_bind[0].buffer= (void *)szData;
2482   my_bind[0].buffer_length= 10;
2483   my_bind[0].length= &length[0];
2484   length[0]= 4;
2485   my_bind[0].is_null= 0;
2486 
2487   rc= mysql_stmt_bind_param(stmt, my_bind);
2488   check_execute(stmt, rc);
2489 
2490   rc= mysql_stmt_execute(stmt);
2491   check_execute(stmt, rc);
2492 
2493   rc= my_process_stmt_result(stmt);
2494   DIE_UNLESS(rc == 0);
2495 
2496   my_stpcpy(szData, (char *)"abc");
2497   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2498   my_bind[0].buffer= (void *)szData;
2499   my_bind[0].buffer_length= 10;
2500   my_bind[0].length= &length[0];
2501   length[0]= 3;
2502   my_bind[0].is_null= 0;
2503 
2504   rc= mysql_stmt_bind_param(stmt, my_bind);
2505   check_execute(stmt, rc);
2506 
2507   rc= mysql_stmt_execute(stmt);
2508   check_execute(stmt, rc);
2509 
2510   rc= my_process_stmt_result(stmt);
2511   DIE_UNLESS(rc == 1);
2512 
2513   mysql_stmt_close(stmt);
2514 }
2515 
2516 
2517 /* Test BUG#1180 (optimized away part of WHERE clause) */
2518 
test_bug1180()2519 static void test_bug1180()
2520 {
2521   MYSQL_STMT *stmt;
2522   int rc;
2523   MYSQL_BIND my_bind[1];
2524   ulong length[1];
2525   char szData[11];
2526   char query[MAX_TEST_QUERY_LENGTH];
2527 
2528   myheader("test_select_bug");
2529 
2530   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2531   myquery(rc);
2532 
2533   rc= mysql_query(mysql, "CREATE TABLE test_select(session_id  char(9) NOT NULL)");
2534   myquery(rc);
2535   rc= mysql_query(mysql, "INSERT INTO test_select VALUES (\"abc\")");
2536   myquery(rc);
2537 
2538   my_stpcpy(query, "SELECT * FROM test_select WHERE ?= \"1111\" and "
2539                 "session_id= \"abc\"");
2540   stmt= mysql_simple_prepare(mysql, query);
2541   check_stmt(stmt);
2542 
2543   verify_param_count(stmt, 1);
2544 
2545   /* Always memset all members of bind parameter */
2546   memset(my_bind, 0, sizeof(my_bind));
2547 
2548   my_stpcpy(szData, (char *)"abc");
2549   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2550   my_bind[0].buffer= (void *)szData;
2551   my_bind[0].buffer_length= 10;
2552   my_bind[0].length= &length[0];
2553   length[0]= 3;
2554   my_bind[0].is_null= 0;
2555 
2556   rc= mysql_stmt_bind_param(stmt, my_bind);
2557   check_execute(stmt, rc);
2558 
2559   rc= mysql_stmt_execute(stmt);
2560   check_execute(stmt, rc);
2561 
2562   rc= my_process_stmt_result(stmt);
2563   DIE_UNLESS(rc == 0);
2564 
2565   my_stpcpy(szData, (char *)"1111");
2566   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2567   my_bind[0].buffer= (void *)szData;
2568   my_bind[0].buffer_length= 10;
2569   my_bind[0].length= &length[0];
2570   length[0]= 4;
2571   my_bind[0].is_null= 0;
2572 
2573   rc= mysql_stmt_bind_param(stmt, my_bind);
2574   check_execute(stmt, rc);
2575 
2576   rc= mysql_stmt_execute(stmt);
2577   check_execute(stmt, rc);
2578 
2579   rc= my_process_stmt_result(stmt);
2580   DIE_UNLESS(rc == 1);
2581 
2582   my_stpcpy(szData, (char *)"abc");
2583   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2584   my_bind[0].buffer= (void *)szData;
2585   my_bind[0].buffer_length= 10;
2586   my_bind[0].length= &length[0];
2587   length[0]= 3;
2588   my_bind[0].is_null= 0;
2589 
2590   rc= mysql_stmt_bind_param(stmt, my_bind);
2591   check_execute(stmt, rc);
2592 
2593   rc= mysql_stmt_execute(stmt);
2594   check_execute(stmt, rc);
2595 
2596   rc= my_process_stmt_result(stmt);
2597   DIE_UNLESS(rc == 0);
2598 
2599   mysql_stmt_close(stmt);
2600 }
2601 
2602 
2603 /*
2604   Test BUG#1644 (Insertion of more than 3 NULL columns with parameter
2605   binding fails)
2606 */
2607 
test_bug1644()2608 static void test_bug1644()
2609 {
2610   MYSQL_STMT *stmt;
2611   MYSQL_RES *result;
2612   MYSQL_ROW row;
2613   MYSQL_BIND my_bind[4];
2614   int num;
2615   my_bool isnull;
2616   int rc, i;
2617   char query[MAX_TEST_QUERY_LENGTH];
2618 
2619   myheader("test_bug1644");
2620 
2621   rc= mysql_query(mysql, "DROP TABLE IF EXISTS foo_dfr");
2622   myquery(rc);
2623 
2624   rc= mysql_query(mysql,
2625            "CREATE TABLE foo_dfr(col1 int, col2 int, col3 int, col4 int);");
2626   myquery(rc);
2627 
2628   my_stpcpy(query, "INSERT INTO foo_dfr VALUES (?, ?, ?, ? )");
2629   stmt= mysql_simple_prepare(mysql, query);
2630   check_stmt(stmt);
2631 
2632   verify_param_count(stmt, 4);
2633 
2634   /* Always memset all members of bind parameter */
2635   memset(my_bind, 0, sizeof(my_bind));
2636 
2637   num= 22;
2638   isnull= 0;
2639   for (i= 0 ; i < 4 ; i++)
2640   {
2641     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
2642     my_bind[i].buffer= (void *)&num;
2643     my_bind[i].is_null= &isnull;
2644   }
2645 
2646   rc= mysql_stmt_bind_param(stmt, my_bind);
2647   check_execute(stmt, rc);
2648 
2649   rc= mysql_stmt_execute(stmt);
2650   check_execute(stmt, rc);
2651 
2652   isnull= 1;
2653   for (i= 0 ; i < 4 ; i++)
2654     my_bind[i].is_null= &isnull;
2655 
2656   rc= mysql_stmt_bind_param(stmt, my_bind);
2657   check_execute(stmt, rc);
2658 
2659   rc= mysql_stmt_execute(stmt);
2660   check_execute(stmt, rc);
2661 
2662   isnull= 0;
2663   num= 88;
2664   for (i= 0 ; i < 4 ; i++)
2665     my_bind[i].is_null= &isnull;
2666 
2667   rc= mysql_stmt_bind_param(stmt, my_bind);
2668   check_execute(stmt, rc);
2669 
2670   rc= mysql_stmt_execute(stmt);
2671   check_execute(stmt, rc);
2672 
2673   mysql_stmt_close(stmt);
2674 
2675   rc= mysql_query(mysql, "SELECT * FROM foo_dfr");
2676   myquery(rc);
2677 
2678   result= mysql_store_result(mysql);
2679   mytest(result);
2680 
2681   rc= my_process_result_set(result);
2682   DIE_UNLESS(rc == 3);
2683 
2684   mysql_data_seek(result, 0);
2685 
2686   row= mysql_fetch_row(result);
2687   mytest(row);
2688   for (i= 0 ; i < 4 ; i++)
2689   {
2690     DIE_UNLESS(strcmp(row[i], "22") == 0);
2691   }
2692   row= mysql_fetch_row(result);
2693   mytest(row);
2694   for (i= 0 ; i < 4 ; i++)
2695   {
2696     DIE_UNLESS(row[i] == 0);
2697   }
2698   row= mysql_fetch_row(result);
2699   mytest(row);
2700   for (i= 0 ; i < 4 ; i++)
2701   {
2702     DIE_UNLESS(strcmp(row[i], "88") == 0);
2703   }
2704   row= mysql_fetch_row(result);
2705   mytest_r(row);
2706 
2707   mysql_free_result(result);
2708 }
2709 
2710 
2711 /* Test simple select show */
2712 
test_select_show()2713 static void test_select_show()
2714 {
2715   MYSQL_STMT *stmt;
2716   int        rc;
2717   char query[MAX_TEST_QUERY_LENGTH];
2718 
2719   myheader("test_select_show");
2720 
2721   mysql_autocommit(mysql, TRUE);
2722 
2723   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_show");
2724   myquery(rc);
2725 
2726   rc= mysql_query(mysql, "CREATE TABLE test_show(id int(4) NOT NULL primary "
2727                          " key, name char(2))");
2728   myquery(rc);
2729 
2730   stmt= mysql_simple_prepare(mysql, "show columns from test_show");
2731   check_stmt(stmt);
2732 
2733   verify_param_count(stmt, 0);
2734 
2735   rc= mysql_stmt_execute(stmt);
2736   check_execute(stmt, rc);
2737 
2738   my_process_stmt_result(stmt);
2739   mysql_stmt_close(stmt);
2740 
2741   stmt= mysql_simple_prepare(mysql, "show tables from mysql like ?");
2742   check_stmt_r(stmt);
2743 
2744   strxmov(query, "show tables from ", current_db, " like \'test_show\'", NullS);
2745   stmt= mysql_simple_prepare(mysql, query);
2746   check_stmt(stmt);
2747 
2748   rc= mysql_stmt_execute(stmt);
2749   check_execute(stmt, rc);
2750 
2751   my_process_stmt_result(stmt);
2752   mysql_stmt_close(stmt);
2753 
2754   stmt= mysql_simple_prepare(mysql, "describe test_show");
2755   check_stmt(stmt);
2756 
2757   rc= mysql_stmt_execute(stmt);
2758   check_execute(stmt, rc);
2759 
2760   my_process_stmt_result(stmt);
2761   mysql_stmt_close(stmt);
2762 
2763   stmt= mysql_simple_prepare(mysql, "show keys from test_show");
2764   check_stmt(stmt);
2765 
2766   rc= mysql_stmt_execute(stmt);
2767   check_execute(stmt, rc);
2768 
2769   rc= my_process_stmt_result(stmt);
2770   DIE_UNLESS(rc == 1);
2771   mysql_stmt_close(stmt);
2772 }
2773 
2774 
2775 /* Test simple update */
2776 
test_simple_update()2777 static void test_simple_update()
2778 {
2779   MYSQL_STMT *stmt;
2780   int        rc;
2781   char       szData[25];
2782   int        nData= 1;
2783   MYSQL_RES  *result;
2784   MYSQL_BIND my_bind[2];
2785   ulong      length[2];
2786   char query[MAX_TEST_QUERY_LENGTH];
2787 
2788   myheader("test_simple_update");
2789 
2790   rc= mysql_autocommit(mysql, TRUE);
2791   myquery(rc);
2792 
2793   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
2794   myquery(rc);
2795 
2796   rc= mysql_query(mysql, "CREATE TABLE test_update(col1 int, "
2797                          " col2 varchar(50), col3 int )");
2798   myquery(rc);
2799 
2800   rc= mysql_query(mysql, "INSERT INTO test_update VALUES(1, 'MySQL', 100)");
2801   myquery(rc);
2802 
2803   verify_affected_rows(1);
2804 
2805   rc= mysql_commit(mysql);
2806   myquery(rc);
2807 
2808   /* insert by prepare */
2809   my_stpcpy(query, "UPDATE test_update SET col2= ? WHERE col1= ?");
2810   stmt= mysql_simple_prepare(mysql, query);
2811   check_stmt(stmt);
2812 
2813   verify_param_count(stmt, 2);
2814 
2815   /* Always memset all members of bind parameter */
2816   memset(my_bind, 0, sizeof(my_bind));
2817 
2818   nData= 1;
2819   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2820   my_bind[0].buffer= szData;                /* string data */
2821   my_bind[0].buffer_length= (ulong)sizeof(szData);
2822   my_bind[0].length= &length[0];
2823   length[0]= sprintf(szData, "updated-data");
2824 
2825   my_bind[1].buffer= (void *) &nData;
2826   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
2827 
2828   rc= mysql_stmt_bind_param(stmt, my_bind);
2829   check_execute(stmt, rc);
2830 
2831   rc= mysql_stmt_execute(stmt);
2832   check_execute(stmt, rc);
2833   verify_affected_rows(1);
2834 
2835   mysql_stmt_close(stmt);
2836 
2837   /* now fetch the results ..*/
2838   rc= mysql_commit(mysql);
2839   myquery(rc);
2840 
2841   /* test the results now, only one row should exist */
2842   rc= mysql_query(mysql, "SELECT * FROM test_update");
2843   myquery(rc);
2844 
2845   /* get the result */
2846   result= mysql_store_result(mysql);
2847   mytest(result);
2848 
2849   rc= my_process_result_set(result);
2850   DIE_UNLESS(rc == 1);
2851   mysql_free_result(result);
2852 }
2853 
2854 
2855 /* Test simple long data handling */
2856 
test_long_data()2857 static void test_long_data()
2858 {
2859   MYSQL_STMT *stmt;
2860   int        rc, int_data;
2861   char       *data= NullS;
2862   MYSQL_RES  *result;
2863   MYSQL_BIND my_bind[3];
2864   char query[MAX_TEST_QUERY_LENGTH];
2865 
2866   myheader("test_long_data");
2867 
2868   rc= mysql_autocommit(mysql, TRUE);
2869   myquery(rc);
2870 
2871   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
2872   myquery(rc);
2873 
2874   rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, "
2875                          "      col2 long varchar, col3 long varbinary)");
2876   myquery(rc);
2877 
2878   my_stpcpy(query, "INSERT INTO test_long_data(col1, col2) VALUES(?)");
2879   stmt= mysql_simple_prepare(mysql, query);
2880   check_stmt_r(stmt);
2881 
2882   my_stpcpy(query, "INSERT INTO test_long_data(col1, col2, col3) VALUES(?, ?, ?)");
2883   stmt= mysql_simple_prepare(mysql, query);
2884   check_stmt(stmt);
2885 
2886   verify_param_count(stmt, 3);
2887 
2888   /* Always memset all members of bind parameter */
2889   memset(my_bind, 0, sizeof(my_bind));
2890 
2891   my_bind[0].buffer= (void *)&int_data;
2892   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2893 
2894   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2895 
2896   my_bind[2]= my_bind[1];
2897   rc= mysql_stmt_bind_param(stmt, my_bind);
2898   check_execute(stmt, rc);
2899 
2900   int_data= 999;
2901   data= (char *)"Michael";
2902 
2903   /* supply data in pieces */
2904   rc= mysql_stmt_send_long_data(stmt, 1, data, (ulong)strlen(data));
2905   data= (char *)" 'Monty' Widenius";
2906   rc= mysql_stmt_send_long_data(stmt, 1, data, (ulong)strlen(data));
2907   check_execute(stmt, rc);
2908   rc= mysql_stmt_send_long_data(stmt, 2, "Venu (venu@mysql.com)", 4);
2909   check_execute(stmt, rc);
2910 
2911   /* execute */
2912   rc= mysql_stmt_execute(stmt);
2913   if (!opt_silent)
2914     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
2915   check_execute(stmt, rc);
2916 
2917   rc= mysql_commit(mysql);
2918   myquery(rc);
2919 
2920   /* now fetch the results ..*/
2921   rc= mysql_query(mysql, "SELECT * FROM test_long_data");
2922   myquery(rc);
2923 
2924   /* get the result */
2925   result= mysql_store_result(mysql);
2926   mytest(result);
2927 
2928   rc= my_process_result_set(result);
2929   DIE_UNLESS(rc == 1);
2930   mysql_free_result(result);
2931 
2932   verify_col_data("test_long_data", "col1", "999");
2933   verify_col_data("test_long_data", "col2", "Michael 'Monty' Widenius");
2934   verify_col_data("test_long_data", "col3", "Venu");
2935   mysql_stmt_close(stmt);
2936 }
2937 
2938 
2939 /* Test long data (string) handling */
2940 
test_long_data_str()2941 static void test_long_data_str()
2942 {
2943   MYSQL_STMT *stmt;
2944   int        rc, i;
2945   char       data[255];
2946   long       length;
2947   ulong      length1;
2948   MYSQL_RES  *result;
2949   MYSQL_BIND my_bind[2];
2950   my_bool    is_null[2];
2951   char query[MAX_TEST_QUERY_LENGTH];
2952 
2953   myheader("test_long_data_str");
2954 
2955   rc= mysql_autocommit(mysql, TRUE);
2956   myquery(rc);
2957 
2958   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
2959   myquery(rc);
2960 
2961   rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(id int, longstr long varchar)");
2962   myquery(rc);
2963 
2964   my_stpcpy(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
2965   stmt= mysql_simple_prepare(mysql, query);
2966   check_stmt(stmt);
2967 
2968   verify_param_count(stmt, 2);
2969 
2970   /* Always memset all members of bind parameter */
2971   memset(my_bind, 0, sizeof(my_bind));
2972 
2973   my_bind[0].buffer= (void *)&length;
2974   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2975   my_bind[0].is_null= &is_null[0];
2976   is_null[0]= 0;
2977   length= 0;
2978 
2979   my_bind[1].buffer= data;                          /* string data */
2980   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2981   my_bind[1].length= &length1;
2982   my_bind[1].is_null= &is_null[1];
2983   is_null[1]= 0;
2984   rc= mysql_stmt_bind_param(stmt, my_bind);
2985   check_execute(stmt, rc);
2986 
2987   length= 40;
2988   my_stpcpy(data, "MySQL AB");
2989 
2990   /* supply data in pieces */
2991   for(i= 0; i < 4; i++)
2992   {
2993     rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 5);
2994     check_execute(stmt, rc);
2995   }
2996   /* execute */
2997   rc= mysql_stmt_execute(stmt);
2998   if (!opt_silent)
2999     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3000   check_execute(stmt, rc);
3001 
3002   mysql_stmt_close(stmt);
3003 
3004   rc= mysql_commit(mysql);
3005   myquery(rc);
3006 
3007   /* now fetch the results ..*/
3008   rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr FROM test_long_data_str");
3009   myquery(rc);
3010 
3011   /* get the result */
3012   result= mysql_store_result(mysql);
3013   mytest(result);
3014 
3015   rc= my_process_result_set(result);
3016   DIE_UNLESS(rc == 1);
3017   mysql_free_result(result);
3018 
3019   sprintf(data, "%d", i*5);
3020   verify_col_data("test_long_data_str", "LENGTH(longstr)", data);
3021   data[0]= '\0';
3022   while (i--)
3023    strxmov(data, data, "MySQL", NullS);
3024   verify_col_data("test_long_data_str", "longstr", data);
3025 
3026   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3027   myquery(rc);
3028 }
3029 
3030 
3031 /* Test long data (string) handling */
3032 
test_long_data_str1()3033 static void test_long_data_str1()
3034 {
3035   MYSQL_STMT *stmt;
3036   int        rc, i;
3037   char       data[255];
3038   long       length;
3039   ulong      max_blob_length, blob_length, length1;
3040   my_bool    true_value;
3041   MYSQL_RES  *result;
3042   MYSQL_BIND my_bind[2];
3043   MYSQL_FIELD *field;
3044   char query[MAX_TEST_QUERY_LENGTH];
3045 
3046   myheader("test_long_data_str1");
3047 
3048   rc= mysql_autocommit(mysql, TRUE);
3049   myquery(rc);
3050 
3051   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
3052   myquery(rc);
3053 
3054   rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(longstr long varchar, blb long varbinary)");
3055   myquery(rc);
3056 
3057   my_stpcpy(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
3058   stmt= mysql_simple_prepare(mysql, query);
3059   check_stmt(stmt);
3060 
3061   verify_param_count(stmt, 2);
3062 
3063   /* Always memset all members of bind parameter */
3064   memset(my_bind, 0, sizeof(my_bind));
3065 
3066   my_bind[0].buffer= data;            /* string data */
3067   my_bind[0].buffer_length= (ulong)sizeof(data);
3068   my_bind[0].length= &length1;
3069   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3070   length1= 0;
3071 
3072   my_bind[1]= my_bind[0];
3073   my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3074 
3075   rc= mysql_stmt_bind_param(stmt, my_bind);
3076   check_execute(stmt, rc);
3077   length= sprintf(data, "MySQL AB");
3078 
3079   /* supply data in pieces */
3080   for (i= 0; i < 3; i++)
3081   {
3082     rc= mysql_stmt_send_long_data(stmt, 0, data, length);
3083     check_execute(stmt, rc);
3084 
3085     rc= mysql_stmt_send_long_data(stmt, 1, data, 2);
3086     check_execute(stmt, rc);
3087   }
3088 
3089   /* execute */
3090   rc= mysql_stmt_execute(stmt);
3091   if (!opt_silent)
3092     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3093   check_execute(stmt, rc);
3094 
3095   mysql_stmt_close(stmt);
3096 
3097   rc= mysql_commit(mysql);
3098   myquery(rc);
3099 
3100   /* now fetch the results ..*/
3101   rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr, LENGTH(blb), blb FROM test_long_data_str");
3102   myquery(rc);
3103 
3104   /* get the result */
3105   result= mysql_store_result(mysql);
3106 
3107   mysql_field_seek(result, 1);
3108   field= mysql_fetch_field(result);
3109   max_blob_length= field->max_length;
3110 
3111   mytest(result);
3112 
3113   rc= my_process_result_set(result);
3114   DIE_UNLESS(rc == 1);
3115   mysql_free_result(result);
3116 
3117   sprintf(data, "%ld", (long)i*length);
3118   verify_col_data("test_long_data_str", "length(longstr)", data);
3119 
3120   sprintf(data, "%d", i*2);
3121   verify_col_data("test_long_data_str", "length(blb)", data);
3122 
3123   /* Test length of field->max_length */
3124   stmt= mysql_simple_prepare(mysql, "SELECT * from test_long_data_str");
3125   check_stmt(stmt);
3126   verify_param_count(stmt, 0);
3127 
3128   rc= mysql_stmt_execute(stmt);
3129   check_execute(stmt, rc);
3130 
3131   rc= mysql_stmt_store_result(stmt);
3132   check_execute(stmt, rc);
3133 
3134   result= mysql_stmt_result_metadata(stmt);
3135   field= mysql_fetch_fields(result);
3136 
3137   /* First test what happens if STMT_ATTR_UPDATE_MAX_LENGTH is not used */
3138   DIE_UNLESS(field->max_length == 0);
3139   mysql_free_result(result);
3140 
3141   /* Enable updating of field->max_length */
3142   true_value= 1;
3143   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &true_value);
3144   rc= mysql_stmt_execute(stmt);
3145   check_execute(stmt, rc);
3146 
3147   rc= mysql_stmt_store_result(stmt);
3148   check_execute(stmt, rc);
3149 
3150   result= mysql_stmt_result_metadata(stmt);
3151   field= mysql_fetch_fields(result);
3152 
3153   DIE_UNLESS(field->max_length == max_blob_length);
3154 
3155   /* Fetch results into a data buffer that is smaller than data */
3156   memset(my_bind, 0, sizeof(*my_bind));
3157   my_bind[0].buffer_type= MYSQL_TYPE_BLOB;
3158   my_bind[0].buffer= (void *) &data; /* this buffer won't be altered */
3159   my_bind[0].buffer_length= 16;
3160   my_bind[0].length= &blob_length;
3161   my_bind[0].error= &my_bind[0].error_value;
3162   rc= mysql_stmt_bind_result(stmt, my_bind);
3163   data[16]= 0;
3164 
3165   rc= mysql_stmt_fetch(stmt);
3166   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
3167   DIE_UNLESS(my_bind[0].error_value);
3168   DIE_UNLESS(strlen(data) == 16);
3169   DIE_UNLESS(blob_length == max_blob_length);
3170 
3171   /* Fetch all data */
3172   memset((my_bind+1), 0, sizeof(*my_bind));
3173   my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3174   my_bind[1].buffer= (void *) &data; /* this buffer won't be altered */
3175   my_bind[1].buffer_length= (ulong)sizeof(data);
3176   my_bind[1].length= &blob_length;
3177   memset(data, 0, sizeof(data));
3178   mysql_stmt_fetch_column(stmt, my_bind+1, 0, 0);
3179   DIE_UNLESS(strlen(data) == max_blob_length);
3180 
3181   mysql_free_result(result);
3182   mysql_stmt_close(stmt);
3183 
3184   /* Drop created table */
3185   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3186   myquery(rc);
3187 }
3188 
3189 
3190 /* Test long data (binary) handling */
3191 
test_long_data_bin()3192 static void test_long_data_bin()
3193 {
3194   MYSQL_STMT *stmt;
3195   int        rc;
3196   char       data[255];
3197   long       length;
3198   MYSQL_RES  *result;
3199   MYSQL_BIND my_bind[2];
3200   char query[MAX_TEST_QUERY_LENGTH];
3201 
3202 
3203   myheader("test_long_data_bin");
3204 
3205   rc= mysql_autocommit(mysql, TRUE);
3206   myquery(rc);
3207 
3208   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_bin");
3209   myquery(rc);
3210 
3211   rc= mysql_query(mysql, "CREATE TABLE test_long_data_bin(id int, longbin long varbinary)");
3212   myquery(rc);
3213 
3214   my_stpcpy(query, "INSERT INTO test_long_data_bin VALUES(?, ?)");
3215   stmt= mysql_simple_prepare(mysql, query);
3216   check_stmt(stmt);
3217 
3218   verify_param_count(stmt, 2);
3219 
3220   /* Always memset all members of bind parameter */
3221   memset(my_bind, 0, sizeof(my_bind));
3222 
3223   my_bind[0].buffer= (void *)&length;
3224   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3225   length= 0;
3226 
3227   my_bind[1].buffer= data;           /* string data */
3228   my_bind[1].buffer_type= MYSQL_TYPE_LONG_BLOB;
3229   rc= mysql_stmt_bind_param(stmt, my_bind);
3230   check_execute(stmt, rc);
3231 
3232   length= 10;
3233   my_stpcpy(data, "MySQL AB");
3234 
3235   /* supply data in pieces */
3236   {
3237     int i;
3238     for (i= 0; i < 100; i++)
3239     {
3240       rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 4);
3241       check_execute(stmt, rc);
3242     }
3243   }
3244   /* execute */
3245   rc= mysql_stmt_execute(stmt);
3246   if (!opt_silent)
3247     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3248   check_execute(stmt, rc);
3249 
3250   mysql_stmt_close(stmt);
3251 
3252   rc= mysql_commit(mysql);
3253   myquery(rc);
3254 
3255   /* now fetch the results ..*/
3256   rc= mysql_query(mysql, "SELECT LENGTH(longbin), longbin FROM test_long_data_bin");
3257   myquery(rc);
3258 
3259   /* get the result */
3260   result= mysql_store_result(mysql);
3261   mytest(result);
3262 
3263   rc= my_process_result_set(result);
3264   DIE_UNLESS(rc == 1);
3265   mysql_free_result(result);
3266 }
3267 
3268 
3269 /* Test simple delete */
3270 
test_simple_delete()3271 static void test_simple_delete()
3272 {
3273   MYSQL_STMT *stmt;
3274   int        rc;
3275   char       szData[30]= {0};
3276   int        nData= 1;
3277   MYSQL_RES  *result;
3278   MYSQL_BIND my_bind[2];
3279   ulong      length[2];
3280   char query[MAX_TEST_QUERY_LENGTH];
3281 
3282   myheader("test_simple_delete");
3283 
3284   rc= mysql_autocommit(mysql, TRUE);
3285   myquery(rc);
3286 
3287   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_simple_delete");
3288   myquery(rc);
3289 
3290   rc= mysql_query(mysql, "CREATE TABLE test_simple_delete(col1 int, \
3291                                 col2 varchar(50), col3 int )");
3292   myquery(rc);
3293 
3294   rc= mysql_query(mysql, "INSERT INTO test_simple_delete VALUES(1, 'MySQL', 100)");
3295   myquery(rc);
3296 
3297   verify_affected_rows(1);
3298 
3299   rc= mysql_commit(mysql);
3300   myquery(rc);
3301 
3302   /* insert by prepare */
3303   my_stpcpy(query, "DELETE FROM test_simple_delete WHERE col1= ? AND "
3304                 "CONVERT(col2 USING utf8)= ? AND col3= 100");
3305   stmt= mysql_simple_prepare(mysql, query);
3306   check_stmt(stmt);
3307 
3308   verify_param_count(stmt, 2);
3309 
3310   /* Always memset all members of bind parameter */
3311   memset(my_bind, 0, sizeof(my_bind));
3312 
3313   nData= 1;
3314   my_stpcpy(szData, "MySQL");
3315   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3316   my_bind[1].buffer= szData;               /* string data */
3317   my_bind[1].buffer_length= (ulong)sizeof(szData);
3318   my_bind[1].length= &length[1];
3319   length[1]= 5;
3320 
3321   my_bind[0].buffer= (void *)&nData;
3322   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3323 
3324   rc= mysql_stmt_bind_param(stmt, my_bind);
3325   check_execute(stmt, rc);
3326 
3327   rc= mysql_stmt_execute(stmt);
3328   check_execute(stmt, rc);
3329 
3330   verify_affected_rows(1);
3331 
3332   mysql_stmt_close(stmt);
3333 
3334   /* now fetch the results ..*/
3335   rc= mysql_commit(mysql);
3336   myquery(rc);
3337 
3338   /* test the results now, only one row should exist */
3339   rc= mysql_query(mysql, "SELECT * FROM test_simple_delete");
3340   myquery(rc);
3341 
3342   /* get the result */
3343   result= mysql_store_result(mysql);
3344   mytest(result);
3345 
3346   rc= my_process_result_set(result);
3347   DIE_UNLESS(rc == 0);
3348   mysql_free_result(result);
3349 }
3350 
3351 
3352 /* Test simple update */
3353 
test_update()3354 static void test_update()
3355 {
3356   MYSQL_STMT *stmt;
3357   int        rc;
3358   char       szData[25];
3359   int        nData= 1;
3360   MYSQL_RES  *result;
3361   MYSQL_BIND my_bind[2];
3362   ulong      length[2];
3363   char query[MAX_TEST_QUERY_LENGTH];
3364 
3365   myheader("test_update");
3366 
3367   rc= mysql_autocommit(mysql, TRUE);
3368   myquery(rc);
3369 
3370   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
3371   myquery(rc);
3372 
3373   rc= mysql_query(mysql, "CREATE TABLE test_update("
3374                                "col1 int primary key auto_increment, "
3375                                "col2 varchar(50), col3 int )");
3376   myquery(rc);
3377 
3378   my_stpcpy(query, "INSERT INTO test_update(col2, col3) VALUES(?, ?)");
3379   stmt= mysql_simple_prepare(mysql, query);
3380   check_stmt(stmt);
3381 
3382   verify_param_count(stmt, 2);
3383 
3384   /* Always memset all members of bind parameter */
3385   memset(my_bind, 0, sizeof(my_bind));
3386 
3387   /* string data */
3388   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3389   my_bind[0].buffer= szData;
3390   my_bind[0].buffer_length= (ulong)sizeof(szData);
3391   my_bind[0].length= &length[0];
3392   length[0]= sprintf(szData, "inserted-data");
3393 
3394   my_bind[1].buffer= (void *)&nData;
3395   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3396 
3397   rc= mysql_stmt_bind_param(stmt, my_bind);
3398   check_execute(stmt, rc);
3399 
3400   nData= 100;
3401   rc= mysql_stmt_execute(stmt);
3402   check_execute(stmt, rc);
3403 
3404   verify_affected_rows(1);
3405   mysql_stmt_close(stmt);
3406 
3407   my_stpcpy(query, "UPDATE test_update SET col2= ? WHERE col3= ?");
3408   stmt= mysql_simple_prepare(mysql, query);
3409   check_stmt(stmt);
3410 
3411   verify_param_count(stmt, 2);
3412   nData= 100;
3413 
3414   /* Always memset all members of bind parameter */
3415   memset(my_bind, 0, sizeof(my_bind));
3416 
3417   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3418   my_bind[0].buffer= szData;
3419   my_bind[0].buffer_length= (ulong)sizeof(szData);
3420   my_bind[0].length= &length[0];
3421   length[0]= sprintf(szData, "updated-data");
3422 
3423   my_bind[1].buffer= (void *)&nData;
3424   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3425 
3426   rc= mysql_stmt_bind_param(stmt, my_bind);
3427   check_execute(stmt, rc);
3428 
3429   rc= mysql_stmt_execute(stmt);
3430   check_execute(stmt, rc);
3431   verify_affected_rows(1);
3432 
3433   mysql_stmt_close(stmt);
3434 
3435   /* now fetch the results ..*/
3436   rc= mysql_commit(mysql);
3437   myquery(rc);
3438 
3439   /* test the results now, only one row should exist */
3440   rc= mysql_query(mysql, "SELECT * FROM test_update");
3441   myquery(rc);
3442 
3443   /* get the result */
3444   result= mysql_store_result(mysql);
3445   mytest(result);
3446 
3447   rc= my_process_result_set(result);
3448   DIE_UNLESS(rc == 1);
3449   mysql_free_result(result);
3450 }
3451 
3452 
3453 /* Test prepare without parameters */
3454 
test_prepare_noparam()3455 static void test_prepare_noparam()
3456 {
3457   MYSQL_STMT *stmt;
3458   int        rc;
3459   MYSQL_RES  *result;
3460   char query[MAX_TEST_QUERY_LENGTH];
3461 
3462   myheader("test_prepare_noparam");
3463 
3464   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
3465   myquery(rc);
3466 
3467 
3468   rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 int, col2 varchar(50))");
3469   myquery(rc);
3470 
3471   /* insert by prepare */
3472   my_stpcpy(query, "INSERT INTO my_prepare VALUES(10, 'venu')");
3473   stmt= mysql_simple_prepare(mysql, query);
3474   check_stmt(stmt);
3475 
3476   verify_param_count(stmt, 0);
3477 
3478   rc= mysql_stmt_execute(stmt);
3479   check_execute(stmt, rc);
3480 
3481   mysql_stmt_close(stmt);
3482 
3483   /* now fetch the results ..*/
3484   rc= mysql_commit(mysql);
3485   myquery(rc);
3486 
3487   /* test the results now, only one row should exist */
3488   rc= mysql_query(mysql, "SELECT * FROM my_prepare");
3489   myquery(rc);
3490 
3491   /* get the result */
3492   result= mysql_store_result(mysql);
3493   mytest(result);
3494 
3495   rc= my_process_result_set(result);
3496   DIE_UNLESS(rc == 1);
3497   mysql_free_result(result);
3498 }
3499 
3500 
3501 /* Test simple bind result */
3502 
test_bind_result()3503 static void test_bind_result()
3504 {
3505   MYSQL_STMT *stmt;
3506   int        rc;
3507   int        nData;
3508   ulong      length1;
3509   char       szData[100];
3510   MYSQL_BIND my_bind[2];
3511   my_bool    is_null[2];
3512 
3513   myheader("test_bind_result");
3514 
3515   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3516   myquery(rc);
3517 
3518   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(col1 int , col2 varchar(50))");
3519   myquery(rc);
3520 
3521   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(10, 'venu')");
3522   myquery(rc);
3523 
3524   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(20, 'MySQL')");
3525   myquery(rc);
3526 
3527   rc= mysql_query(mysql, "INSERT INTO test_bind_result(col2) VALUES('monty')");
3528   myquery(rc);
3529 
3530   rc= mysql_commit(mysql);
3531   myquery(rc);
3532 
3533   /* fetch */
3534 
3535   memset(my_bind, 0, sizeof(my_bind));
3536   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3537   my_bind[0].buffer= (void *) &nData;      /* integer data */
3538   my_bind[0].is_null= &is_null[0];
3539 
3540   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3541   my_bind[1].buffer= szData;                /* string data */
3542   my_bind[1].buffer_length= (ulong)sizeof(szData);
3543   my_bind[1].length= &length1;
3544   my_bind[1].is_null= &is_null[1];
3545 
3546   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
3547   check_stmt(stmt);
3548 
3549   rc= mysql_stmt_bind_result(stmt, my_bind);
3550   check_execute(stmt, rc);
3551 
3552   rc= mysql_stmt_execute(stmt);
3553   check_execute(stmt, rc);
3554 
3555   rc= mysql_stmt_fetch(stmt);
3556   check_execute(stmt, rc);
3557 
3558   if (!opt_silent)
3559     fprintf(stdout, "\n row 1: %d, %s(%lu)", nData, szData, length1);
3560   DIE_UNLESS(nData == 10);
3561   DIE_UNLESS(strcmp(szData, "venu") == 0);
3562   DIE_UNLESS(length1 == 4);
3563 
3564   rc= mysql_stmt_fetch(stmt);
3565   check_execute(stmt, rc);
3566 
3567   if (!opt_silent)
3568     fprintf(stdout, "\n row 2: %d, %s(%lu)", nData, szData, length1);
3569   DIE_UNLESS(nData == 20);
3570   DIE_UNLESS(strcmp(szData, "MySQL") == 0);
3571   DIE_UNLESS(length1 == 5);
3572 
3573   rc= mysql_stmt_fetch(stmt);
3574   check_execute(stmt, rc);
3575 
3576   if (!opt_silent && is_null[0])
3577     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
3578   DIE_UNLESS(is_null[0]);
3579   DIE_UNLESS(strcmp(szData, "monty") == 0);
3580   DIE_UNLESS(length1 == 5);
3581 
3582   rc= mysql_stmt_fetch(stmt);
3583   DIE_UNLESS(rc == MYSQL_NO_DATA);
3584 
3585   mysql_stmt_close(stmt);
3586 }
3587 
3588 
3589 /* Test ext bind result */
3590 
test_bind_result_ext()3591 static void test_bind_result_ext()
3592 {
3593   MYSQL_STMT *stmt;
3594   int        rc, i;
3595   uchar      t_data;
3596   short      s_data;
3597   int        i_data;
3598   longlong   b_data;
3599   float      f_data;
3600   double     d_data;
3601   char       szData[20], bData[20];
3602   ulong      szLength, bLength;
3603   MYSQL_BIND my_bind[8];
3604   ulong      length[8];
3605   my_bool    is_null[8];
3606   char	     llbuf[22];
3607   myheader("test_bind_result_ext");
3608 
3609   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3610   myquery(rc);
3611 
3612   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, "
3613                                                       " c2 smallint, "
3614                                                       " c3 int, c4 bigint, "
3615                                                       " c5 float, c6 double, "
3616                                                       " c7 varbinary(10), "
3617                                                       " c8 varchar(50))");
3618   myquery(rc);
3619 
3620   rc= mysql_query(mysql, "INSERT INTO test_bind_result "
3621                          "VALUES (19, 2999, 3999, 4999999, "
3622                          " 2345.6, 5678.89563, 'venu', 'mysql')");
3623   myquery(rc);
3624 
3625   rc= mysql_commit(mysql);
3626   myquery(rc);
3627 
3628   memset(my_bind, 0, sizeof(my_bind));
3629   for (i= 0; i < (int) array_elements(my_bind); i++)
3630   {
3631     my_bind[i].length=  &length[i];
3632     my_bind[i].is_null= &is_null[i];
3633   }
3634 
3635   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
3636   my_bind[0].buffer= (void *)&t_data;
3637 
3638   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
3639   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
3640 
3641   my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
3642   my_bind[1].buffer= (void *)&s_data;
3643 
3644   my_bind[2].buffer= (void *)&i_data;
3645   my_bind[3].buffer= (void *)&b_data;
3646 
3647   my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
3648   my_bind[4].buffer= (void *)&f_data;
3649 
3650   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
3651   my_bind[5].buffer= (void *)&d_data;
3652 
3653   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
3654   my_bind[6].buffer= (void *)szData;
3655   my_bind[6].buffer_length= (ulong)sizeof(szData);
3656   my_bind[6].length= &szLength;
3657 
3658   my_bind[7].buffer_type= MYSQL_TYPE_TINY_BLOB;
3659   my_bind[7].buffer= (void *)&bData;
3660   my_bind[7].length= &bLength;
3661   my_bind[7].buffer_length= (ulong)sizeof(bData);
3662 
3663   stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3664   check_stmt(stmt);
3665 
3666   rc= mysql_stmt_bind_result(stmt, my_bind);
3667   check_execute(stmt, rc);
3668 
3669   rc= mysql_stmt_execute(stmt);
3670   check_execute(stmt, rc);
3671 
3672   rc= mysql_stmt_fetch(stmt);
3673   check_execute(stmt, rc);
3674 
3675   if (!opt_silent)
3676   {
3677     fprintf(stdout, "\n data (tiny)   : %d", t_data);
3678     fprintf(stdout, "\n data (short)  : %d", s_data);
3679     fprintf(stdout, "\n data (int)    : %d", i_data);
3680     fprintf(stdout, "\n data (big)    : %s", llstr(b_data, llbuf));
3681 
3682     fprintf(stdout, "\n data (float)  : %f", f_data);
3683     fprintf(stdout, "\n data (double) : %f", d_data);
3684 
3685     fprintf(stdout, "\n data (str)    : %s(%lu)", szData, szLength);
3686 
3687     bData[bLength]= '\0';                         /* bData is binary */
3688     fprintf(stdout, "\n data (bin)    : %s(%lu)", bData, bLength);
3689   }
3690 
3691   DIE_UNLESS(t_data == 19);
3692   DIE_UNLESS(s_data == 2999);
3693   DIE_UNLESS(i_data == 3999);
3694   DIE_UNLESS(b_data == 4999999);
3695   /*DIE_UNLESS(f_data == 2345.60);*/
3696   /*DIE_UNLESS(d_data == 5678.89563);*/
3697   DIE_UNLESS(strcmp(szData, "venu") == 0);
3698   DIE_UNLESS(strncmp(bData, "mysql", 5) == 0);
3699   DIE_UNLESS(szLength == 4);
3700   DIE_UNLESS(bLength == 5);
3701 
3702   rc= mysql_stmt_fetch(stmt);
3703   DIE_UNLESS(rc == MYSQL_NO_DATA);
3704 
3705   mysql_stmt_close(stmt);
3706 }
3707 
3708 
3709 /* Test ext bind result */
3710 
test_bind_result_ext1()3711 static void test_bind_result_ext1()
3712 {
3713   MYSQL_STMT *stmt;
3714   uint       i;
3715   int        rc;
3716   char       t_data[20];
3717   float      s_data;
3718   short      i_data;
3719   uchar      b_data;
3720   int        f_data;
3721   long       bData= 0;
3722   char       d_data[20];
3723   double     szData;
3724   MYSQL_BIND my_bind[8];
3725   ulong      length[8];
3726   my_bool    is_null[8];
3727   myheader("test_bind_result_ext1");
3728 
3729   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3730   myquery(rc);
3731 
3732   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, \
3733                                                         c3 int, c4 bigint, \
3734                                                         c5 float, c6 double, \
3735                                                         c7 varbinary(10), \
3736                                                         c8 varchar(10))");
3737   myquery(rc);
3738 
3739   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(120, 2999, 3999, 54, \
3740                                                               2.6, 58.89, \
3741                                                               '206', '6.7')");
3742   myquery(rc);
3743 
3744   rc= mysql_commit(mysql);
3745   myquery(rc);
3746 
3747   memset(my_bind, 0, sizeof(my_bind));
3748   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3749   my_bind[0].buffer= (void *) t_data;
3750   my_bind[0].buffer_length= (ulong)sizeof(t_data);
3751   my_bind[0].error= &my_bind[0].error_value;
3752 
3753   my_bind[1].buffer_type= MYSQL_TYPE_FLOAT;
3754   my_bind[1].buffer= (void *)&s_data;
3755   my_bind[1].buffer_length= 0;
3756   my_bind[1].error= &my_bind[1].error_value;
3757 
3758   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
3759   my_bind[2].buffer= (void *)&i_data;
3760   my_bind[2].buffer_length= 0;
3761   my_bind[2].error= &my_bind[2].error_value;
3762 
3763   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
3764   my_bind[3].buffer= (void *)&b_data;
3765   my_bind[3].buffer_length= 0;
3766   my_bind[3].error= &my_bind[3].error_value;
3767 
3768   my_bind[4].buffer_type= MYSQL_TYPE_LONG;
3769   my_bind[4].buffer= (void *)&f_data;
3770   my_bind[4].buffer_length= 0;
3771   my_bind[4].error= &my_bind[4].error_value;
3772 
3773   my_bind[5].buffer_type= MYSQL_TYPE_STRING;
3774   my_bind[5].buffer= (void *)d_data;
3775   my_bind[5].buffer_length= (ulong)sizeof(d_data);
3776   my_bind[5].error= &my_bind[5].error_value;
3777 
3778   my_bind[6].buffer_type= MYSQL_TYPE_LONG;
3779   my_bind[6].buffer= (void *)&bData;
3780   my_bind[6].buffer_length= 0;
3781   my_bind[6].error= &my_bind[6].error_value;
3782 
3783   my_bind[7].buffer_type= MYSQL_TYPE_DOUBLE;
3784   my_bind[7].buffer= (void *)&szData;
3785   my_bind[7].buffer_length= 0;
3786   my_bind[7].error= &my_bind[7].error_value;
3787 
3788   for (i= 0; i < array_elements(my_bind); i++)
3789   {
3790     my_bind[i].is_null= &is_null[i];
3791     my_bind[i].length= &length[i];
3792   }
3793 
3794   stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3795   check_stmt(stmt);
3796 
3797   rc= mysql_stmt_bind_result(stmt, my_bind);
3798   check_execute(stmt, rc);
3799 
3800   rc= mysql_stmt_execute(stmt);
3801   check_execute(stmt, rc);
3802 
3803   rc= mysql_stmt_fetch(stmt);
3804   printf("rc=%d\n", rc);
3805   DIE_UNLESS(rc == 0);
3806 
3807   if (!opt_silent)
3808   {
3809     fprintf(stdout, "\n data (tiny)   : %s(%lu)", t_data, length[0]);
3810     fprintf(stdout, "\n data (short)  : %f(%lu)", s_data, length[1]);
3811     fprintf(stdout, "\n data (int)    : %d(%lu)", i_data, length[2]);
3812     fprintf(stdout, "\n data (big)    : %d(%lu)", b_data, length[3]);
3813 
3814     fprintf(stdout, "\n data (float)  : %d(%lu)", f_data, length[4]);
3815     fprintf(stdout, "\n data (double) : %s(%lu)", d_data, length[5]);
3816 
3817     fprintf(stdout, "\n data (bin)    : %ld(%lu)", bData, length[6]);
3818     fprintf(stdout, "\n data (str)    : %g(%lu)", szData, length[7]);
3819   }
3820 
3821   DIE_UNLESS(strcmp(t_data, "120") == 0);
3822   DIE_UNLESS(i_data == 3999);
3823   DIE_UNLESS(f_data == 2);
3824   DIE_UNLESS(strcmp(d_data, "58.89") == 0);
3825   DIE_UNLESS(b_data == 54);
3826 
3827   DIE_UNLESS(length[0] == 3);
3828   DIE_UNLESS(length[1] == 4);
3829   DIE_UNLESS(length[2] == 2);
3830   DIE_UNLESS(length[3] == 1);
3831   DIE_UNLESS(length[4] == 4);
3832   DIE_UNLESS(length[5] == 5);
3833   DIE_UNLESS(length[6] == 4);
3834   DIE_UNLESS(length[7] == 8);
3835 
3836   rc= mysql_stmt_fetch(stmt);
3837   DIE_UNLESS(rc == MYSQL_NO_DATA);
3838 
3839   mysql_stmt_close(stmt);
3840 }
3841 
3842 
3843 /* Generalized fetch conversion routine for all basic types */
3844 
bind_fetch(int row_count)3845 static void bind_fetch(int row_count)
3846 {
3847   MYSQL_STMT   *stmt;
3848   int          rc, i, count= row_count;
3849   int32        data[10];
3850   int8         i8_data;
3851   int16        i16_data;
3852   int32        i32_data;
3853   longlong     i64_data;
3854   float        f_data;
3855   double       d_data;
3856   char         s_data[10];
3857   ulong        length[10];
3858   MYSQL_BIND   my_bind[7];
3859   my_bool      is_null[7];
3860 
3861   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_bind_fetch VALUES "
3862                                     "(?, ?, ?, ?, ?, ?, ?)");
3863   check_stmt(stmt);
3864 
3865   verify_param_count(stmt, 7);
3866 
3867   /* Always memset all members of bind parameter */
3868   memset(my_bind, 0, sizeof(my_bind));
3869 
3870   for (i= 0; i < (int) array_elements(my_bind); i++)
3871   {
3872     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
3873     my_bind[i].buffer= (void *) &data[i];
3874   }
3875   rc= mysql_stmt_bind_param(stmt, my_bind);
3876   check_execute(stmt, rc);
3877 
3878   while (count--)
3879   {
3880     rc= 10+count;
3881     for (i= 0; i < (int) array_elements(my_bind); i++)
3882     {
3883       data[i]= rc+i;
3884       rc+= 12;
3885     }
3886     rc= mysql_stmt_execute(stmt);
3887     check_execute(stmt, rc);
3888   }
3889 
3890   rc= mysql_commit(mysql);
3891   myquery(rc);
3892 
3893   mysql_stmt_close(stmt);
3894 
3895   rc= my_stmt_result("SELECT * FROM test_bind_fetch");
3896   DIE_UNLESS(row_count == rc);
3897 
3898   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_fetch");
3899   check_stmt(stmt);
3900 
3901   for (i= 0; i < (int) array_elements(my_bind); i++)
3902   {
3903     my_bind[i].buffer= (void *) &data[i];
3904     my_bind[i].length= &length[i];
3905     my_bind[i].is_null= &is_null[i];
3906   }
3907 
3908   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
3909   my_bind[0].buffer= (void *)&i8_data;
3910 
3911   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
3912   my_bind[1].buffer= (void *)&i16_data;
3913 
3914   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
3915   my_bind[2].buffer= (void *)&i32_data;
3916 
3917   my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
3918   my_bind[3].buffer= (void *)&i64_data;
3919 
3920   my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
3921   my_bind[4].buffer= (void *)&f_data;
3922 
3923   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
3924   my_bind[5].buffer= (void *)&d_data;
3925 
3926   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
3927   my_bind[6].buffer= (void *)&s_data;
3928   my_bind[6].buffer_length= (ulong)sizeof(s_data);
3929 
3930   rc= mysql_stmt_bind_result(stmt, my_bind);
3931   check_execute(stmt, rc);
3932 
3933   rc= mysql_stmt_execute(stmt);
3934   check_execute(stmt, rc);
3935 
3936   rc= mysql_stmt_store_result(stmt);
3937   check_execute(stmt, rc);
3938 
3939   while (row_count--)
3940   {
3941     rc= mysql_stmt_fetch(stmt);
3942     check_execute(stmt, rc);
3943 
3944     if (!opt_silent)
3945     {
3946       fprintf(stdout, "\n");
3947       fprintf(stdout, "\n tiny     : %ld(%lu)", (ulong) i8_data, length[0]);
3948       fprintf(stdout, "\n short    : %ld(%lu)", (ulong) i16_data, length[1]);
3949       fprintf(stdout, "\n int      : %ld(%lu)", (ulong) i32_data, length[2]);
3950       fprintf(stdout, "\n longlong : %ld(%lu)", (ulong) i64_data, length[3]);
3951       fprintf(stdout, "\n float    : %f(%lu)",  f_data,  length[4]);
3952       fprintf(stdout, "\n double   : %g(%lu)",  d_data,  length[5]);
3953       fprintf(stdout, "\n char     : %s(%lu)",  s_data,  length[6]);
3954     }
3955     rc= 10+row_count;
3956 
3957     /* TINY */
3958     DIE_UNLESS((int) i8_data == rc);
3959     DIE_UNLESS(length[0] == 1);
3960     rc+= 13;
3961 
3962     /* SHORT */
3963     DIE_UNLESS((int) i16_data == rc);
3964     DIE_UNLESS(length[1] == 2);
3965     rc+= 13;
3966 
3967     /* LONG */
3968     DIE_UNLESS((int) i32_data == rc);
3969     DIE_UNLESS(length[2] == 4);
3970     rc+= 13;
3971 
3972     /* LONGLONG */
3973     DIE_UNLESS((int) i64_data == rc);
3974     DIE_UNLESS(length[3] == 8);
3975     rc+= 13;
3976 
3977     /* FLOAT */
3978     DIE_UNLESS((int)f_data == rc);
3979     DIE_UNLESS(length[4] == 4);
3980     rc+= 13;
3981 
3982     /* DOUBLE */
3983     DIE_UNLESS((int)d_data == rc);
3984     DIE_UNLESS(length[5] == 8);
3985     rc+= 13;
3986 
3987     /* CHAR */
3988     {
3989       char buff[20];
3990       long len= sprintf(buff, "%d", rc);
3991       DIE_UNLESS(strcmp(s_data, buff) == 0);
3992       DIE_UNLESS(length[6] == (ulong) len);
3993     }
3994   }
3995   rc= mysql_stmt_fetch(stmt);
3996   DIE_UNLESS(rc == MYSQL_NO_DATA);
3997 
3998   mysql_stmt_close(stmt);
3999 }
4000 
4001 
4002 /* Test fetching of date, time and ts */
4003 
test_fetch_date()4004 static void test_fetch_date()
4005 {
4006   MYSQL_STMT *stmt;
4007   uint       i;
4008   int        rc, year;
4009   char       date[25], my_time[25], ts[25], ts_4[25], ts_6[20], dt[20];
4010   ulong      d_length, t_length, ts_length, ts4_length, ts6_length,
4011              dt_length, y_length;
4012   MYSQL_BIND my_bind[8];
4013   my_bool    is_null[8];
4014   ulong      length[8];
4015 
4016   myheader("test_fetch_date");
4017 
4018   /* Will not work if sql_mode is STRICT (implicit if TRADITIONAL) */
4019   rc= mysql_query(mysql, "SET SQL_MODE=''");
4020   myquery(rc);
4021 
4022   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
4023   myquery(rc);
4024 
4025   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \
4026                                                         c3 timestamp, \
4027                                                         c4 year, \
4028                                                         c5 datetime, \
4029                                                         c6 timestamp, \
4030                                                         c7 timestamp)");
4031   myquery(rc);
4032 
4033   rc= mysql_query(mysql, "SET SQL_MODE=''");
4034   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \
4035                                                               '12:49:00', \
4036                                                               '2002-01-02 17:46:59', \
4037                                                               2010, \
4038                                                               '2010-07-10', \
4039                                                               '2020', '1999-12-29')");
4040   myquery(rc);
4041 
4042   rc= mysql_commit(mysql);
4043   myquery(rc);
4044 
4045   memset(my_bind, 0, sizeof(my_bind));
4046   for (i= 0; i < array_elements(my_bind); i++)
4047   {
4048     my_bind[i].is_null= &is_null[i];
4049     my_bind[i].length= &length[i];
4050   }
4051 
4052   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
4053   my_bind[1]= my_bind[2]= my_bind[0];
4054 
4055   my_bind[0].buffer= (void *)&date;
4056   my_bind[0].buffer_length= (ulong)sizeof(date);
4057   my_bind[0].length= &d_length;
4058 
4059   my_bind[1].buffer= (void *)&my_time;
4060   my_bind[1].buffer_length= (ulong)sizeof(my_time);
4061   my_bind[1].length= &t_length;
4062 
4063   my_bind[2].buffer= (void *)&ts;
4064   my_bind[2].buffer_length= (ulong)sizeof(ts);
4065   my_bind[2].length= &ts_length;
4066 
4067   my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4068   my_bind[3].buffer= (void *)&year;
4069   my_bind[3].length= &y_length;
4070 
4071   my_bind[4].buffer_type= MYSQL_TYPE_STRING;
4072   my_bind[4].buffer= (void *)&dt;
4073   my_bind[4].buffer_length= (ulong)sizeof(dt);
4074   my_bind[4].length= &dt_length;
4075 
4076   my_bind[5].buffer_type= MYSQL_TYPE_STRING;
4077   my_bind[5].buffer= (void *)&ts_4;
4078   my_bind[5].buffer_length= (ulong)sizeof(ts_4);
4079   my_bind[5].length= &ts4_length;
4080 
4081   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
4082   my_bind[6].buffer= (void *)&ts_6;
4083   my_bind[6].buffer_length= (ulong)sizeof(ts_6);
4084   my_bind[6].length= &ts6_length;
4085 
4086   rc= my_stmt_result("SELECT * FROM test_bind_result");
4087   DIE_UNLESS(rc == 1);
4088 
4089   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
4090   check_stmt(stmt);
4091 
4092   rc= mysql_stmt_bind_result(stmt, my_bind);
4093   check_execute(stmt, rc);
4094 
4095   rc= mysql_stmt_execute(stmt);
4096   check_execute(stmt, rc);
4097 
4098   ts_4[0]= '\0';
4099   rc= mysql_stmt_fetch(stmt);
4100   check_execute(stmt, rc);
4101 
4102   if (!opt_silent)
4103   {
4104     fprintf(stdout, "\n date   : %s(%lu)", date, d_length);
4105     fprintf(stdout, "\n time   : %s(%lu)", my_time, t_length);
4106     fprintf(stdout, "\n ts     : %s(%lu)", ts, ts_length);
4107     fprintf(stdout, "\n year   : %d(%lu)", year, y_length);
4108     fprintf(stdout, "\n dt     : %s(%lu)", dt,  dt_length);
4109     fprintf(stdout, "\n ts(4)  : %s(%lu)", ts_4, ts4_length);
4110     fprintf(stdout, "\n ts(6)  : %s(%lu)", ts_6, ts6_length);
4111   }
4112 
4113   DIE_UNLESS(strcmp(date, "2002-01-02") == 0);
4114   DIE_UNLESS(d_length == 10);
4115 
4116   DIE_UNLESS(strcmp(my_time, "12:49:00") == 0);
4117   DIE_UNLESS(t_length == 8);
4118 
4119   DIE_UNLESS(strcmp(ts, "2002-01-02 17:46:59") == 0);
4120   DIE_UNLESS(ts_length == 19);
4121 
4122   DIE_UNLESS(year == 2010);
4123   DIE_UNLESS(y_length == 4);
4124 
4125   DIE_UNLESS(strcmp(dt, "2010-07-10 00:00:00") == 0);
4126   DIE_UNLESS(dt_length == 19);
4127 
4128   DIE_UNLESS(strcmp(ts_4, "0000-00-00 00:00:00") == 0);
4129   DIE_UNLESS(ts4_length == strlen("0000-00-00 00:00:00"));
4130 
4131   DIE_UNLESS(strcmp(ts_6, "1999-12-29 00:00:00") == 0);
4132   DIE_UNLESS(ts6_length == 19);
4133 
4134   rc= mysql_stmt_fetch(stmt);
4135   DIE_UNLESS(rc == MYSQL_NO_DATA);
4136 
4137   mysql_stmt_close(stmt);
4138 }
4139 
4140 
4141 /* Test fetching of str to all types */
4142 
test_fetch_str()4143 static void test_fetch_str()
4144 {
4145   int rc;
4146 
4147   myheader("test_fetch_str");
4148 
4149   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4150   myquery(rc);
4151 
4152   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 char(10), \
4153                                                      c2 char(10), \
4154                                                      c3 char(20), \
4155                                                      c4 char(20), \
4156                                                      c5 char(30), \
4157                                                      c6 char(40), \
4158                                                      c7 char(20))");
4159   myquery(rc);
4160 
4161   bind_fetch(3);
4162 }
4163 
4164 
4165 /* Test fetching of long to all types */
4166 
test_fetch_long()4167 static void test_fetch_long()
4168 {
4169   int rc;
4170 
4171   myheader("test_fetch_long");
4172 
4173   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4174   myquery(rc);
4175 
4176   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 int unsigned, \
4177                                                      c2 int unsigned, \
4178                                                      c3 int, \
4179                                                      c4 int, \
4180                                                      c5 int, \
4181                                                      c6 int unsigned, \
4182                                                      c7 int)");
4183   myquery(rc);
4184 
4185   bind_fetch(4);
4186 }
4187 
4188 
4189 /* Test fetching of short to all types */
4190 
test_fetch_short()4191 static void test_fetch_short()
4192 {
4193   int rc;
4194 
4195   myheader("test_fetch_short");
4196 
4197   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4198   myquery(rc);
4199 
4200   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, \
4201                                                      c2 smallint, \
4202                                                      c3 smallint unsigned, \
4203                                                      c4 smallint, \
4204                                                      c5 smallint, \
4205                                                      c6 smallint, \
4206                                                      c7 smallint unsigned)");
4207   myquery(rc);
4208 
4209   bind_fetch(5);
4210 }
4211 
4212 
4213 /* Test fetching of tiny to all types */
4214 
test_fetch_tiny()4215 static void test_fetch_tiny()
4216 {
4217   int rc;
4218 
4219   myheader("test_fetch_tiny");
4220 
4221   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4222   myquery(rc);
4223 
4224   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 tinyint unsigned, \
4225                                                      c2 tinyint, \
4226                                                      c3 tinyint unsigned, \
4227                                                      c4 tinyint, \
4228                                                      c5 tinyint, \
4229                                                      c6 tinyint, \
4230                                                      c7 tinyint unsigned)");
4231   myquery(rc);
4232 
4233   bind_fetch(3);
4234 
4235 }
4236 
4237 
4238 /* Test fetching of longlong to all types */
4239 
test_fetch_bigint()4240 static void test_fetch_bigint()
4241 {
4242   int rc;
4243 
4244   myheader("test_fetch_bigint");
4245 
4246   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4247   myquery(rc);
4248 
4249   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 bigint, \
4250                                                      c2 bigint, \
4251                                                      c3 bigint unsigned, \
4252                                                      c4 bigint unsigned, \
4253                                                      c5 bigint unsigned, \
4254                                                      c6 bigint unsigned, \
4255                                                      c7 bigint unsigned)");
4256   myquery(rc);
4257 
4258   bind_fetch(2);
4259 
4260 }
4261 
4262 
4263 /* Test fetching of float to all types */
4264 
test_fetch_float()4265 static void test_fetch_float()
4266 {
4267   int rc;
4268 
4269   myheader("test_fetch_float");
4270 
4271   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4272   myquery(rc);
4273 
4274   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 float(3), \
4275                                                      c2 float, \
4276                                                      c3 float unsigned, \
4277                                                      c4 float, \
4278                                                      c5 float, \
4279                                                      c6 float, \
4280                                                      c7 float(10) unsigned)");
4281   myquery(rc);
4282 
4283   bind_fetch(2);
4284 
4285 }
4286 
4287 
4288 /* Test fetching of double to all types */
4289 
test_fetch_double()4290 static void test_fetch_double()
4291 {
4292   int rc;
4293 
4294   myheader("test_fetch_double");
4295 
4296   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4297   myquery(rc);
4298 
4299   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 double(5, 2), "
4300                          "c2 double unsigned, c3 double unsigned, "
4301                          "c4 double unsigned, c5 double unsigned, "
4302                          "c6 double unsigned, c7 double unsigned)");
4303   myquery(rc);
4304 
4305   bind_fetch(3);
4306 
4307 }
4308 
4309 
4310 /* Test simple prepare with all possible types */
4311 
test_prepare_ext()4312 static void test_prepare_ext()
4313 {
4314   MYSQL_STMT *stmt;
4315   int        rc;
4316   char       *sql;
4317   int        nData= 1;
4318   char       tData= 1;
4319   short      sData= 10;
4320   longlong   bData= 20;
4321   MYSQL_BIND my_bind[6];
4322   char query[MAX_TEST_QUERY_LENGTH];
4323   myheader("test_prepare_ext");
4324 
4325   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext");
4326   myquery(rc);
4327 
4328   sql= (char *)"CREATE TABLE test_prepare_ext"
4329                "("
4330                " c1  tinyint,"
4331                " c2  smallint,"
4332                " c3  mediumint,"
4333                " c4  int,"
4334                " c5  integer,"
4335                " c6  bigint,"
4336                " c7  float,"
4337                " c8  double,"
4338                " c9  double precision,"
4339                " c10 real,"
4340                " c11 decimal(7, 4),"
4341                " c12 numeric(8, 4),"
4342                " c13 date,"
4343                " c14 datetime,"
4344                " c15 timestamp,"
4345                " c16 time,"
4346                " c17 year,"
4347                " c18 bit,"
4348                " c19 bool,"
4349                " c20 char,"
4350                " c21 char(10),"
4351                " c22 varchar(30),"
4352                " c23 tinyblob,"
4353                " c24 tinytext,"
4354                " c25 blob,"
4355                " c26 text,"
4356                " c27 mediumblob,"
4357                " c28 mediumtext,"
4358                " c29 longblob,"
4359                " c30 longtext,"
4360                " c31 enum('one', 'two', 'three'),"
4361                " c32 set('monday', 'tuesday', 'wednesday'))";
4362 
4363   rc= mysql_query(mysql, sql);
4364   myquery(rc);
4365 
4366   /* insert by prepare - all integers */
4367   my_stpcpy(query, (char *)"INSERT INTO test_prepare_ext(c1, c2, c3, c4, c5, c6) VALUES(?, ?, ?, ?, ?, ?)");
4368   stmt= mysql_simple_prepare(mysql, query);
4369   check_stmt(stmt);
4370 
4371   verify_param_count(stmt, 6);
4372 
4373   /* Always memset all members of bind parameter */
4374   memset(my_bind, 0, sizeof(my_bind));
4375 
4376   /*tinyint*/
4377   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4378   my_bind[0].buffer= (void *)&tData;
4379 
4380   /*smallint*/
4381   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
4382   my_bind[1].buffer= (void *)&sData;
4383 
4384   /*mediumint*/
4385   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
4386   my_bind[2].buffer= (void *)&nData;
4387 
4388   /*int*/
4389   my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4390   my_bind[3].buffer= (void *)&nData;
4391 
4392   /*integer*/
4393   my_bind[4].buffer_type= MYSQL_TYPE_LONG;
4394   my_bind[4].buffer= (void *)&nData;
4395 
4396   /*bigint*/
4397   my_bind[5].buffer_type= MYSQL_TYPE_LONGLONG;
4398   my_bind[5].buffer= (void *)&bData;
4399 
4400   rc= mysql_stmt_bind_param(stmt, my_bind);
4401   check_execute(stmt, rc);
4402 
4403   /*
4404   *  integer to integer
4405   */
4406   for (nData= 0; nData<10; nData++, tData++, sData++, bData++)
4407   {
4408     rc= mysql_stmt_execute(stmt);
4409     check_execute(stmt, rc);
4410   }
4411   mysql_stmt_close(stmt);
4412 
4413   /* now fetch the results ..*/
4414 
4415   stmt= mysql_simple_prepare(mysql, "SELECT c1, c2, c3, c4, c5, c6 "
4416                                     "FROM test_prepare_ext");
4417   check_stmt(stmt);
4418 
4419   /* get the result */
4420   rc= mysql_stmt_execute(stmt);
4421   check_execute(stmt, rc);
4422 
4423   rc= my_process_stmt_result(stmt);
4424   DIE_UNLESS(nData == rc);
4425 
4426   mysql_stmt_close(stmt);
4427 }
4428 
4429 
4430 /* Test real and alias names */
4431 
test_field_names()4432 static void test_field_names()
4433 {
4434   int        rc;
4435   MYSQL_RES  *result;
4436 
4437   myheader("test_field_names");
4438 
4439   if (!opt_silent)
4440     fprintf(stdout, "\n %d, %d, %d", MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_ENUM);
4441   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names1");
4442   myquery(rc);
4443 
4444   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names2");
4445   myquery(rc);
4446 
4447   rc= mysql_query(mysql, "CREATE TABLE test_field_names1(id int, name varchar(50))");
4448   myquery(rc);
4449 
4450   rc= mysql_query(mysql, "CREATE TABLE test_field_names2(id int, name varchar(50))");
4451   myquery(rc);
4452 
4453   /* with table name included with TRUE column name */
4454   rc= mysql_query(mysql, "SELECT id as 'id-alias' FROM test_field_names1");
4455   myquery(rc);
4456 
4457   result= mysql_use_result(mysql);
4458   mytest(result);
4459 
4460   rc= my_process_result_set(result);
4461   DIE_UNLESS(rc == 0);
4462   mysql_free_result(result);
4463 
4464   /* with table name included with TRUE column name */
4465   rc= mysql_query(mysql, "SELECT t1.id as 'id-alias', test_field_names2.name FROM test_field_names1 t1, test_field_names2");
4466   myquery(rc);
4467 
4468   result= mysql_use_result(mysql);
4469   mytest(result);
4470 
4471   rc= my_process_result_set(result);
4472   DIE_UNLESS(rc == 0);
4473   mysql_free_result(result);
4474 }
4475 
4476 
4477 /* Test warnings */
4478 
test_warnings()4479 static void test_warnings()
4480 {
4481   int        rc;
4482   MYSQL_RES  *result;
4483 
4484   myheader("test_warnings");
4485 
4486   mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4487 
4488   rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4489   myquery(rc);
4490 
4491   if (!opt_silent)
4492     fprintf(stdout, "\n total warnings: %d", mysql_warning_count(mysql));
4493   rc= mysql_query(mysql, "SHOW WARNINGS");
4494   myquery(rc);
4495 
4496   result= mysql_store_result(mysql);
4497   mytest(result);
4498 
4499   rc= my_process_result_set(result);
4500   DIE_UNLESS(rc == 1);
4501   mysql_free_result(result);
4502 }
4503 
4504 
4505 /* Test errors */
4506 
test_errors()4507 static void test_errors()
4508 {
4509   int        rc;
4510   MYSQL_RES  *result;
4511 
4512   myheader("test_errors");
4513 
4514   mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4515 
4516   rc= mysql_query(mysql, "DROP TABLE test_non_exists");
4517   myquery_r(rc);
4518 
4519   rc= mysql_query(mysql, "SHOW ERRORS");
4520   myquery(rc);
4521 
4522   result= mysql_store_result(mysql);
4523   mytest(result);
4524 
4525   (void) my_process_result_set(result);
4526   mysql_free_result(result);
4527 }
4528 
4529 
4530 /* Test simple prepare-insert */
4531 
test_insert()4532 static void test_insert()
4533 {
4534   MYSQL_STMT *stmt;
4535   int        rc;
4536   char       str_data[50];
4537   char       tiny_data;
4538   MYSQL_RES  *result;
4539   MYSQL_BIND my_bind[2];
4540   ulong      length;
4541 
4542   myheader("test_insert");
4543 
4544   rc= mysql_autocommit(mysql, TRUE);
4545   myquery(rc);
4546 
4547   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_insert");
4548   myquery(rc);
4549 
4550   rc= mysql_query(mysql, "CREATE TABLE test_prep_insert(col1 tinyint, \
4551                                 col2 varchar(50))");
4552   myquery(rc);
4553 
4554   /* insert by prepare */
4555   stmt= mysql_simple_prepare(mysql,
4556                              "INSERT INTO test_prep_insert VALUES(?, ?)");
4557   check_stmt(stmt);
4558 
4559   verify_param_count(stmt, 2);
4560 
4561   /*
4562     We need to memset bind structure because mysql_stmt_bind_param checks all
4563     its members.
4564   */
4565   memset(my_bind, 0, sizeof(my_bind));
4566 
4567   /* tinyint */
4568   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4569   my_bind[0].buffer= (void *)&tiny_data;
4570 
4571   /* string */
4572   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
4573   my_bind[1].buffer= str_data;
4574   my_bind[1].buffer_length= (ulong)sizeof(str_data);
4575   my_bind[1].length= &length;
4576 
4577   rc= mysql_stmt_bind_param(stmt, my_bind);
4578   check_execute(stmt, rc);
4579 
4580   /* now, execute the prepared statement to insert 10 records.. */
4581   for (tiny_data= 0; tiny_data < 3; tiny_data++)
4582   {
4583     length= sprintf(str_data, "MySQL%d", tiny_data);
4584     rc= mysql_stmt_execute(stmt);
4585     check_execute(stmt, rc);
4586   }
4587 
4588   mysql_stmt_close(stmt);
4589 
4590   /* now fetch the results ..*/
4591   rc= mysql_commit(mysql);
4592   myquery(rc);
4593 
4594   /* test the results now, only one row should exist */
4595   rc= mysql_query(mysql, "SELECT * FROM test_prep_insert");
4596   myquery(rc);
4597 
4598   /* get the result */
4599   result= mysql_store_result(mysql);
4600   mytest(result);
4601 
4602   rc= my_process_result_set(result);
4603   DIE_UNLESS((int) tiny_data == rc);
4604   mysql_free_result(result);
4605 
4606 }
4607 
4608 
4609 /* Test simple prepare-resultset info */
4610 
test_prepare_resultset()4611 static void test_prepare_resultset()
4612 {
4613   MYSQL_STMT *stmt;
4614   int        rc;
4615   MYSQL_RES  *result;
4616 
4617   myheader("test_prepare_resultset");
4618 
4619   rc= mysql_autocommit(mysql, TRUE);
4620   myquery(rc);
4621 
4622   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_resultset");
4623   myquery(rc);
4624 
4625   rc= mysql_query(mysql, "CREATE TABLE test_prepare_resultset(id int, \
4626                                 name varchar(50), extra double)");
4627   myquery(rc);
4628 
4629   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_prepare_resultset");
4630   check_stmt(stmt);
4631 
4632   verify_param_count(stmt, 0);
4633 
4634   result= mysql_stmt_result_metadata(stmt);
4635   mytest(result);
4636   my_print_result_metadata(result);
4637   mysql_free_result(result);
4638   mysql_stmt_close(stmt);
4639 }
4640 
4641 
4642 /* Test field flags (verify .NET provider) */
4643 
test_field_flags()4644 static void test_field_flags()
4645 {
4646   int          rc;
4647   MYSQL_RES    *result;
4648   MYSQL_FIELD  *field;
4649   unsigned int i;
4650 
4651 
4652   myheader("test_field_flags");
4653 
4654   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_flags");
4655   myquery(rc);
4656 
4657   rc= mysql_query(mysql, "CREATE TABLE test_field_flags(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, \
4658                                                         id1 int NOT NULL, \
4659                                                         id2 int UNIQUE, \
4660                                                         id3 int, \
4661                                                         id4 int NOT NULL, \
4662                                                         id5 int, \
4663                                                         KEY(id3, id4))");
4664   myquery(rc);
4665 
4666   /* with table name included with TRUE column name */
4667   rc= mysql_query(mysql, "SELECT * FROM test_field_flags");
4668   myquery(rc);
4669 
4670   result= mysql_use_result(mysql);
4671   mytest(result);
4672 
4673   mysql_field_seek(result, 0);
4674   if (!opt_silent)
4675     fputc('\n', stdout);
4676 
4677   for(i= 0; i< mysql_num_fields(result); i++)
4678   {
4679     field= mysql_fetch_field(result);
4680     if (!opt_silent)
4681     {
4682       fprintf(stdout, "\n field:%d", i);
4683       if (field->flags & NOT_NULL_FLAG)
4684         fprintf(stdout, "\n  NOT_NULL_FLAG");
4685       if (field->flags & PRI_KEY_FLAG)
4686         fprintf(stdout, "\n  PRI_KEY_FLAG");
4687       if (field->flags & UNIQUE_KEY_FLAG)
4688         fprintf(stdout, "\n  UNIQUE_KEY_FLAG");
4689       if (field->flags & MULTIPLE_KEY_FLAG)
4690         fprintf(stdout, "\n  MULTIPLE_KEY_FLAG");
4691       if (field->flags & AUTO_INCREMENT_FLAG)
4692         fprintf(stdout, "\n  AUTO_INCREMENT_FLAG");
4693       if (field->flags & CLUSTERING_FLAG)
4694         fprintf(stdout, "\n  CLUSTERING_FLAG");
4695     }
4696   }
4697   mysql_free_result(result);
4698 }
4699 
4700 
4701 /* Test mysql_stmt_close for open stmts */
4702 
test_stmt_close()4703 static void test_stmt_close()
4704 {
4705   MYSQL *lmysql;
4706   MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x;
4707   MYSQL_BIND  my_bind[1];
4708   MYSQL_RES   *result;
4709   unsigned int  count;
4710   int   rc;
4711   char query[MAX_TEST_QUERY_LENGTH];
4712 
4713   myheader("test_stmt_close");
4714 
4715   if (!opt_silent)
4716     fprintf(stdout, "\n Establishing a test connection ...");
4717   if (!(lmysql= mysql_client_init(NULL)))
4718   {
4719     myerror("mysql_client_init() failed");
4720     exit(1);
4721   }
4722   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
4723                            opt_password, current_db, opt_port,
4724                            opt_unix_socket, 0)))
4725   {
4726     myerror("connection failed");
4727     exit(1);
4728   }
4729   lmysql->reconnect= 1;
4730   if (!opt_silent)
4731     fprintf(stdout, "OK");
4732 
4733 
4734   /* set AUTOCOMMIT to ON*/
4735   mysql_autocommit(lmysql, TRUE);
4736 
4737   rc= mysql_query(lmysql, "SET SQL_MODE = ''");
4738   myquery(rc);
4739 
4740   rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close");
4741   myquery(rc);
4742 
4743   rc= mysql_query(lmysql, "CREATE TABLE test_stmt_close(id int)");
4744   myquery(rc);
4745 
4746   my_stpcpy(query, "DO \"nothing\"");
4747   stmt1= mysql_simple_prepare(lmysql, query);
4748   check_stmt(stmt1);
4749 
4750   verify_param_count(stmt1, 0);
4751 
4752   my_stpcpy(query, "INSERT INTO test_stmt_close(id) VALUES(?)");
4753   stmt_x= mysql_simple_prepare(mysql, query);
4754   check_stmt(stmt_x);
4755 
4756   verify_param_count(stmt_x, 1);
4757 
4758   my_stpcpy(query, "UPDATE test_stmt_close SET id= ? WHERE id= ?");
4759   stmt3= mysql_simple_prepare(lmysql, query);
4760   check_stmt(stmt3);
4761 
4762   verify_param_count(stmt3, 2);
4763 
4764   my_stpcpy(query, "SELECT * FROM test_stmt_close WHERE id= ?");
4765   stmt2= mysql_simple_prepare(lmysql, query);
4766   check_stmt(stmt2);
4767 
4768   verify_param_count(stmt2, 1);
4769 
4770   rc= mysql_stmt_close(stmt1);
4771   if (!opt_silent)
4772     fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
4773   DIE_UNLESS(rc == 0);
4774 
4775   /*
4776     Originally we were going to close all statements automatically in
4777     mysql_close(). This proved to not work well - users weren't able to
4778     close statements by hand once mysql_close() had been called.
4779     Now mysql_close() doesn't free any statements, so this test doesn't
4780     serve its original designation any more.
4781     Here we free stmt2 and stmt3 by hand to avoid memory leaks.
4782   */
4783   mysql_stmt_close(stmt2);
4784   mysql_stmt_close(stmt3);
4785   mysql_close(lmysql);
4786 
4787   /*
4788     We need to memset bind structure because mysql_stmt_bind_param checks all
4789     its members.
4790   */
4791   memset(my_bind, 0, sizeof(my_bind));
4792 
4793   my_bind[0].buffer= (void *)&count;
4794   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
4795   count= 100;
4796 
4797   rc= mysql_stmt_bind_param(stmt_x, my_bind);
4798   check_execute(stmt_x, rc);
4799 
4800   rc= mysql_stmt_execute(stmt_x);
4801   check_execute(stmt_x, rc);
4802 
4803   verify_st_affected_rows(stmt_x, 1);
4804 
4805   rc= mysql_stmt_close(stmt_x);
4806   if (!opt_silent)
4807     fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
4808   DIE_UNLESS( rc == 0);
4809 
4810   rc= mysql_query(mysql, "SELECT id FROM test_stmt_close");
4811   myquery(rc);
4812 
4813   result= mysql_store_result(mysql);
4814   mytest(result);
4815 
4816   rc= my_process_result_set(result);
4817   DIE_UNLESS(rc == 1);
4818   mysql_free_result(result);
4819 }
4820 
4821 
4822 /* Test simple set variable prepare */
4823 
test_set_variable()4824 static void test_set_variable()
4825 {
4826   MYSQL_STMT *stmt, *stmt1;
4827   int        rc;
4828   int        set_count, def_count, get_count;
4829   ulong      length;
4830   char       var[NAME_LEN+1];
4831   MYSQL_BIND set_bind[1], get_bind[2];
4832 
4833   myheader("test_set_variable");
4834 
4835   mysql_autocommit(mysql, TRUE);
4836 
4837   stmt1= mysql_simple_prepare(mysql, "show variables like 'max_error_count'");
4838   check_stmt(stmt1);
4839 
4840   /*
4841     We need to memset bind structure because mysql_stmt_bind_param checks all
4842     its members.
4843   */
4844   memset(get_bind, 0, sizeof(get_bind));
4845 
4846   get_bind[0].buffer_type= MYSQL_TYPE_STRING;
4847   get_bind[0].buffer= (void *)var;
4848   get_bind[0].length= &length;
4849   get_bind[0].buffer_length= (ulong)NAME_LEN;
4850   length= NAME_LEN;
4851 
4852   get_bind[1].buffer_type= MYSQL_TYPE_LONG;
4853   get_bind[1].buffer= (void *)&get_count;
4854 
4855   rc= mysql_stmt_execute(stmt1);
4856   check_execute(stmt1, rc);
4857 
4858   rc= mysql_stmt_bind_result(stmt1, get_bind);
4859   check_execute(stmt1, rc);
4860 
4861   rc= mysql_stmt_fetch(stmt1);
4862   check_execute(stmt1, rc);
4863 
4864   if (!opt_silent)
4865     fprintf(stdout, "\n max_error_count(default): %d", get_count);
4866   def_count= get_count;
4867 
4868   DIE_UNLESS(strcmp(var, "max_error_count") == 0);
4869   rc= mysql_stmt_fetch(stmt1);
4870   DIE_UNLESS(rc == MYSQL_NO_DATA);
4871 
4872   stmt= mysql_simple_prepare(mysql, "set max_error_count= ?");
4873   check_stmt(stmt);
4874 
4875   memset(set_bind, 0, sizeof(set_bind));
4876 
4877   set_bind[0].buffer_type= MYSQL_TYPE_LONG;
4878   set_bind[0].buffer= (void *)&set_count;
4879 
4880   rc= mysql_stmt_bind_param(stmt, set_bind);
4881   check_execute(stmt, rc);
4882 
4883   set_count= 31;
4884   rc= mysql_stmt_execute(stmt);
4885   check_execute(stmt, rc);
4886 
4887   mysql_commit(mysql);
4888 
4889   rc= mysql_stmt_execute(stmt1);
4890   check_execute(stmt1, rc);
4891 
4892   rc= mysql_stmt_fetch(stmt1);
4893   check_execute(stmt1, rc);
4894 
4895   if (!opt_silent)
4896     fprintf(stdout, "\n max_error_count         : %d", get_count);
4897   DIE_UNLESS(get_count == set_count);
4898 
4899   rc= mysql_stmt_fetch(stmt1);
4900   DIE_UNLESS(rc == MYSQL_NO_DATA);
4901 
4902   /* restore back to default */
4903   set_count= def_count;
4904   rc= mysql_stmt_execute(stmt);
4905   check_execute(stmt, rc);
4906 
4907   rc= mysql_stmt_execute(stmt1);
4908   check_execute(stmt1, rc);
4909 
4910   rc= mysql_stmt_fetch(stmt1);
4911   check_execute(stmt1, rc);
4912 
4913   if (!opt_silent)
4914     fprintf(stdout, "\n max_error_count(default): %d", get_count);
4915   DIE_UNLESS(get_count == set_count);
4916 
4917   rc= mysql_stmt_fetch(stmt1);
4918   DIE_UNLESS(rc == MYSQL_NO_DATA);
4919 
4920   mysql_stmt_close(stmt);
4921   mysql_stmt_close(stmt1);
4922 }
4923 
4924 /* Test FUNCTION field info / DATE_FORMAT() table_name . */
4925 
test_func_fields()4926 static void test_func_fields()
4927 {
4928   int        rc;
4929   MYSQL_RES  *result;
4930   MYSQL_FIELD *field;
4931 
4932   myheader("test_func_fields");
4933 
4934   rc= mysql_autocommit(mysql, TRUE);
4935   myquery(rc);
4936 
4937   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_dateformat");
4938   myquery(rc);
4939 
4940   rc= mysql_query(mysql, "CREATE TABLE test_dateformat(id int, \
4941                                                        ts timestamp)");
4942   myquery(rc);
4943 
4944   rc= mysql_query(mysql, "INSERT INTO test_dateformat(id) values(10)");
4945   myquery(rc);
4946 
4947   rc= mysql_query(mysql, "SELECT ts FROM test_dateformat");
4948   myquery(rc);
4949 
4950   result= mysql_store_result(mysql);
4951   mytest(result);
4952 
4953   field= mysql_fetch_field(result);
4954   mytest(field);
4955   if (!opt_silent)
4956     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table,
4957             "test_dateformat");
4958   DIE_UNLESS(strcmp(field->table, "test_dateformat") == 0);
4959 
4960   field= mysql_fetch_field(result);
4961   mytest_r(field); /* no more fields */
4962 
4963   mysql_free_result(result);
4964 
4965   /* DATE_FORMAT */
4966   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'venu' FROM test_dateformat");
4967   myquery(rc);
4968 
4969   result= mysql_store_result(mysql);
4970   mytest(result);
4971 
4972   field= mysql_fetch_field(result);
4973   mytest(field);
4974   if (!opt_silent)
4975     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table, "");
4976   DIE_UNLESS(field->table[0] == '\0');
4977 
4978   field= mysql_fetch_field(result);
4979   mytest_r(field); /* no more fields */
4980 
4981   mysql_free_result(result);
4982 
4983   /* FIELD ALIAS TEST */
4984   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y')  AS 'YEAR' FROM test_dateformat");
4985   myquery(rc);
4986 
4987   result= mysql_store_result(mysql);
4988   mytest(result);
4989 
4990   field= mysql_fetch_field(result);
4991   mytest(field);
4992   if (!opt_silent)
4993   {
4994     printf("\n field name: `%s` (expected: `%s`)", field->name, "YEAR");
4995     printf("\n field org name: `%s` (expected: `%s`)", field->org_name, "");
4996   }
4997   DIE_UNLESS(strcmp(field->name, "YEAR") == 0);
4998   DIE_UNLESS(field->org_name[0] == '\0');
4999 
5000   field= mysql_fetch_field(result);
5001   mytest_r(field); /* no more fields */
5002 
5003   mysql_free_result(result);
5004 }
5005 
5006 
5007 /* Multiple stmts .. */
5008 
test_multi_stmt()5009 static void test_multi_stmt()
5010 {
5011 
5012   MYSQL_STMT  *stmt, *stmt1, *stmt2;
5013   int         rc;
5014   uint32      id;
5015   char        name[50];
5016   MYSQL_BIND  my_bind[2];
5017   ulong       length[2];
5018   my_bool     is_null[2];
5019   myheader("test_multi_stmt");
5020 
5021   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_multi_table");
5022   myquery(rc);
5023 
5024   rc= mysql_query(mysql, "CREATE TABLE test_multi_table(id int, name char(20))");
5025   myquery(rc);
5026 
5027   rc= mysql_query(mysql, "INSERT INTO test_multi_table values(10, 'mysql')");
5028   myquery(rc);
5029 
5030   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_multi_table "
5031                                     "WHERE id= ?");
5032   check_stmt(stmt);
5033 
5034   stmt2= mysql_simple_prepare(mysql, "UPDATE test_multi_table "
5035                                      "SET name='updated' WHERE id=10");
5036   check_stmt(stmt2);
5037 
5038   verify_param_count(stmt, 1);
5039 
5040   /*
5041     We need to memset bind structure because mysql_stmt_bind_param checks all
5042     its members.
5043   */
5044   memset(my_bind, 0, sizeof(my_bind));
5045 
5046   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5047   my_bind[0].buffer= (void *)&id;
5048   my_bind[0].is_null= &is_null[0];
5049   my_bind[0].length= &length[0];
5050   is_null[0]= 0;
5051   length[0]= 0;
5052 
5053   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5054   my_bind[1].buffer= (void *)name;
5055   my_bind[1].buffer_length= (ulong)sizeof(name);
5056   my_bind[1].length= &length[1];
5057   my_bind[1].is_null= &is_null[1];
5058 
5059   rc= mysql_stmt_bind_param(stmt, my_bind);
5060   check_execute(stmt, rc);
5061 
5062   rc= mysql_stmt_bind_result(stmt, my_bind);
5063   check_execute(stmt, rc);
5064 
5065   id= 10;
5066   rc= mysql_stmt_execute(stmt);
5067   check_execute(stmt, rc);
5068 
5069   id= 999;
5070   rc= mysql_stmt_fetch(stmt);
5071   check_execute(stmt, rc);
5072 
5073   if (!opt_silent)
5074   {
5075     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5076     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5077   }
5078   DIE_UNLESS(id == 10);
5079   DIE_UNLESS(strcmp(name, "mysql") == 0);
5080 
5081   rc= mysql_stmt_fetch(stmt);
5082   DIE_UNLESS(rc == MYSQL_NO_DATA);
5083 
5084   /* alter the table schema now */
5085   stmt1= mysql_simple_prepare(mysql, "DELETE FROM test_multi_table "
5086                                      "WHERE id= ? AND "
5087                                      "CONVERT(name USING utf8)=?");
5088   check_stmt(stmt1);
5089 
5090   verify_param_count(stmt1, 2);
5091 
5092   rc= mysql_stmt_bind_param(stmt1, my_bind);
5093   check_execute(stmt1, rc);
5094 
5095   rc= mysql_stmt_execute(stmt2);
5096   check_execute(stmt2, rc);
5097 
5098   verify_st_affected_rows(stmt2, 1);
5099 
5100   rc= mysql_stmt_execute(stmt);
5101   check_execute(stmt, rc);
5102 
5103   rc= mysql_stmt_fetch(stmt);
5104   check_execute(stmt, rc);
5105 
5106   if (!opt_silent)
5107   {
5108     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5109     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5110   }
5111   DIE_UNLESS(id == 10);
5112   DIE_UNLESS(strcmp(name, "updated") == 0);
5113 
5114   rc= mysql_stmt_fetch(stmt);
5115   DIE_UNLESS(rc == MYSQL_NO_DATA);
5116 
5117   rc= mysql_stmt_execute(stmt1);
5118   check_execute(stmt1, rc);
5119 
5120   verify_st_affected_rows(stmt1, 1);
5121 
5122   mysql_stmt_close(stmt1);
5123 
5124   rc= mysql_stmt_execute(stmt);
5125   check_execute(stmt, rc);
5126 
5127   rc= mysql_stmt_fetch(stmt);
5128   DIE_UNLESS(rc == MYSQL_NO_DATA);
5129 
5130   rc= my_stmt_result("SELECT * FROM test_multi_table");
5131   DIE_UNLESS(rc == 0);
5132 
5133   mysql_stmt_close(stmt);
5134   mysql_stmt_close(stmt2);
5135 
5136 }
5137 
5138 
5139 /* Test simple sample - manual */
5140 
test_manual_sample()5141 static void test_manual_sample()
5142 {
5143   unsigned int param_count;
5144   MYSQL_STMT   *stmt;
5145   short        small_data;
5146   int          int_data;
5147   int          rc;
5148   char         str_data[50];
5149   ulonglong    affected_rows;
5150   MYSQL_BIND   my_bind[3];
5151   my_bool      is_null;
5152   char query[MAX_TEST_QUERY_LENGTH];
5153 
5154   myheader("test_manual_sample");
5155 
5156   /*
5157     Sample which is incorporated directly in the manual under Prepared
5158     statements section (Example from mysql_stmt_execute()
5159   */
5160 
5161   mysql_autocommit(mysql, 1);
5162   if (mysql_query(mysql, "DROP TABLE IF EXISTS test_table"))
5163   {
5164     fprintf(stderr, "\n drop table failed");
5165     fprintf(stderr, "\n %s", mysql_error(mysql));
5166     exit(1);
5167   }
5168   if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \
5169                                                  col3 smallint, \
5170                                                  col4 timestamp)"))
5171   {
5172     fprintf(stderr, "\n create table failed");
5173     fprintf(stderr, "\n %s", mysql_error(mysql));
5174     exit(1);
5175   }
5176 
5177   /* Prepare a insert query with 3 parameters */
5178   my_stpcpy(query, "INSERT INTO test_table(col1, col2, col3) values(?, ?, ?)");
5179   if (!(stmt= mysql_simple_prepare(mysql, query)))
5180   {
5181     fprintf(stderr, "\n prepare, insert failed");
5182     fprintf(stderr, "\n %s", mysql_error(mysql));
5183     exit(1);
5184   }
5185   if (!opt_silent)
5186     fprintf(stdout, "\n prepare, insert successful");
5187 
5188   /* Get the parameter count from the statement */
5189   param_count= mysql_stmt_param_count(stmt);
5190 
5191   if (!opt_silent)
5192     fprintf(stdout, "\n total parameters in insert: %d", param_count);
5193   if (param_count != 3) /* validate parameter count */
5194   {
5195     fprintf(stderr, "\n invalid parameter count returned by MySQL");
5196     exit(1);
5197   }
5198 
5199   /* Bind the data for the parameters */
5200 
5201   /*
5202     We need to memset bind structure because mysql_stmt_bind_param checks all
5203     its members.
5204   */
5205   memset(my_bind, 0, sizeof(my_bind));
5206   memset(str_data, 0, sizeof(str_data));
5207 
5208   /* INTEGER PART */
5209   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5210   my_bind[0].buffer= (void *)&int_data;
5211 
5212   /* STRING PART */
5213   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
5214   my_bind[1].buffer= (void *)str_data;
5215   my_bind[1].buffer_length= (ulong)sizeof(str_data);
5216 
5217   /* SMALLINT PART */
5218   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
5219   my_bind[2].buffer= (void *)&small_data;
5220   my_bind[2].is_null= &is_null;
5221   is_null= 0;
5222 
5223   /* Bind the buffers */
5224   if (mysql_stmt_bind_param(stmt, my_bind))
5225   {
5226     fprintf(stderr, "\n param bind failed");
5227     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5228     exit(1);
5229   }
5230 
5231   /* Specify the data */
5232   int_data= 10;             /* integer */
5233   my_stpcpy(str_data, "MySQL"); /* string  */
5234 
5235   /* INSERT SMALLINT data as NULL */
5236   is_null= 1;
5237 
5238   /* Execute the insert statement - 1*/
5239   if (mysql_stmt_execute(stmt))
5240   {
5241     fprintf(stderr, "\n execute 1 failed");
5242     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5243     exit(1);
5244   }
5245 
5246   /* Get the total rows affected */
5247   affected_rows= mysql_stmt_affected_rows(stmt);
5248 
5249   if (!opt_silent)
5250     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5251   if (affected_rows != 1) /* validate affected rows */
5252   {
5253     fprintf(stderr, "\n invalid affected rows by MySQL");
5254     exit(1);
5255   }
5256 
5257   /* Re-execute the insert, by changing the values */
5258   int_data= 1000;
5259   my_stpcpy(str_data, "The most popular open source database");
5260   small_data= 1000;         /* smallint */
5261   is_null= 0;               /* reset */
5262 
5263   /* Execute the insert statement - 2*/
5264   if (mysql_stmt_execute(stmt))
5265   {
5266     fprintf(stderr, "\n execute 2 failed");
5267     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5268     exit(1);
5269   }
5270 
5271   /* Get the total rows affected */
5272   affected_rows= mysql_stmt_affected_rows(stmt);
5273 
5274   if (!opt_silent)
5275     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5276   if (affected_rows != 1) /* validate affected rows */
5277   {
5278     fprintf(stderr, "\n invalid affected rows by MySQL");
5279     exit(1);
5280   }
5281 
5282   /* Close the statement */
5283   if (mysql_stmt_close(stmt))
5284   {
5285     fprintf(stderr, "\n failed while closing the statement");
5286     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5287     exit(1);
5288   }
5289   rc= my_stmt_result("SELECT * FROM test_table");
5290   DIE_UNLESS(rc == 2);
5291 
5292   /* DROP THE TABLE */
5293   if (mysql_query(mysql, "DROP TABLE test_table"))
5294   {
5295     fprintf(stderr, "\n drop table failed");
5296     fprintf(stderr, "\n %s", mysql_error(mysql));
5297     exit(1);
5298   }
5299   if (!opt_silent)
5300     fprintf(stdout, "Success !!!");
5301 }
5302 
5303 
5304 /* Test alter table scenario in the middle of prepare */
5305 
test_prepare_alter()5306 static void test_prepare_alter()
5307 {
5308   MYSQL_STMT  *stmt;
5309   int         rc, id;
5310   MYSQL_BIND  my_bind[1];
5311   my_bool     is_null;
5312 
5313   myheader("test_prepare_alter");
5314 
5315   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_alter");
5316   myquery(rc);
5317 
5318   rc= mysql_query(mysql, "CREATE TABLE test_prep_alter(id int, name char(20))");
5319   myquery(rc);
5320 
5321   rc= mysql_query(mysql, "INSERT INTO test_prep_alter values(10, 'venu'), (20, 'mysql')");
5322   myquery(rc);
5323 
5324   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?, 'monty')");
5325   check_stmt(stmt);
5326 
5327   verify_param_count(stmt, 1);
5328 
5329   /*
5330     We need to memset bind structure because mysql_stmt_bind_param checks all
5331     its members.
5332   */
5333   memset(my_bind, 0, sizeof(my_bind));
5334 
5335   is_null= 0;
5336   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
5337   my_bind[0].buffer= (void *)&id;
5338   my_bind[0].is_null= &is_null;
5339 
5340   rc= mysql_stmt_bind_param(stmt, my_bind);
5341   check_execute(stmt, rc);
5342 
5343   id= 30;
5344   rc= mysql_stmt_execute(stmt);
5345   check_execute(stmt, rc);
5346 
5347   if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)"))
5348     exit(1);
5349 
5350   is_null= 1;
5351   rc= mysql_stmt_execute(stmt);
5352   check_execute(stmt, rc);
5353 
5354   rc= my_stmt_result("SELECT * FROM test_prep_alter");
5355   DIE_UNLESS(rc == 4);
5356 
5357   mysql_stmt_close(stmt);
5358 }
5359 
5360 
5361 /* Test the support of multi-statement executions */
5362 
test_multi_statements()5363 static void test_multi_statements()
5364 {
5365   MYSQL *mysql_local;
5366   MYSQL_RES *result;
5367   int    rc;
5368 
5369   const char *query= "\
5370 DROP TABLE IF EXISTS test_multi_tab;\
5371 CREATE TABLE test_multi_tab(id int, name char(20));\
5372 INSERT INTO test_multi_tab(id) VALUES(10), (20);\
5373 INSERT INTO test_multi_tab VALUES(20, 'insert;comma');\
5374 SELECT * FROM test_multi_tab;\
5375 UPDATE test_multi_tab SET name='new;name' WHERE id=20;\
5376 DELETE FROM test_multi_tab WHERE name='new;name';\
5377 SELECT * FROM test_multi_tab;\
5378 DELETE FROM test_multi_tab WHERE id=10;\
5379 SELECT * FROM test_multi_tab;\
5380 DROP TABLE test_multi_tab;\
5381 select 1;\
5382 DROP TABLE IF EXISTS test_multi_tab";
5383   uint count, exp_value;
5384   uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0};
5385 
5386   myheader("test_multi_statements");
5387 
5388   /*
5389     First test that we get an error for multi statements
5390     (Because default connection is not opened with CLIENT_MULTI_STATEMENTS)
5391   */
5392   rc= mysql_query(mysql, query); /* syntax error */
5393   myquery_r(rc);
5394 
5395   rc= mysql_next_result(mysql);
5396   DIE_UNLESS(rc == -1);
5397   rc= mysql_more_results(mysql);
5398   DIE_UNLESS(rc == 0);
5399 
5400   if (!(mysql_local= mysql_client_init(NULL)))
5401   {
5402     fprintf(stdout, "\n mysql_client_init() failed");
5403     exit(1);
5404   }
5405 
5406   /* Create connection that supports multi statements */
5407   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5408                            opt_password, current_db, opt_port,
5409                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5410   {
5411     fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local));
5412     exit(1);
5413   }
5414   mysql_local->reconnect= 1;
5415 
5416   rc= mysql_query(mysql_local, query);
5417   myquery(rc);
5418 
5419   for (count= 0 ; count < array_elements(rows) ; count++)
5420   {
5421     if (!opt_silent)
5422       fprintf(stdout, "\n Query %d: ", count);
5423     if ((result= mysql_store_result(mysql_local)))
5424     {
5425       (void) my_process_result_set(result);
5426       mysql_free_result(result);
5427     }
5428     else if (!opt_silent)
5429       fprintf(stdout, "OK, %ld row(s) affected, %ld warning(s)\n",
5430               (ulong) mysql_affected_rows(mysql_local),
5431               (ulong) mysql_warning_count(mysql_local));
5432 
5433     exp_value= (uint) mysql_affected_rows(mysql_local);
5434     if (rows[count] !=  exp_value)
5435     {
5436       fprintf(stderr, "row %d  had affected rows: %d, should be %d\n",
5437               count, exp_value, rows[count]);
5438       exit(1);
5439     }
5440     if (count != array_elements(rows) -1)
5441     {
5442       if (!(rc= mysql_more_results(mysql_local)))
5443       {
5444         fprintf(stdout,
5445                 "mysql_more_result returned wrong value: %d for row %d\n",
5446                 rc, count);
5447         exit(1);
5448       }
5449       if ((rc= mysql_next_result(mysql_local)))
5450       {
5451         exp_value= mysql_errno(mysql_local);
5452 
5453         exit(1);
5454       }
5455     }
5456     else
5457     {
5458       rc= mysql_more_results(mysql_local);
5459       DIE_UNLESS(rc == 0);
5460       rc= mysql_next_result(mysql_local);
5461       DIE_UNLESS(rc == -1);
5462     }
5463   }
5464 
5465   /* check that errors abort multi statements */
5466 
5467   rc= mysql_query(mysql_local, "select 1+1+a;select 1+1");
5468   myquery_r(rc);
5469   rc= mysql_more_results(mysql_local);
5470   DIE_UNLESS(rc == 0);
5471   rc= mysql_next_result(mysql_local);
5472   DIE_UNLESS(rc == -1);
5473 
5474   rc= mysql_query(mysql_local, "select 1+1;select 1+1+a;select 1");
5475   myquery(rc);
5476   result= mysql_store_result(mysql_local);
5477   mytest(result);
5478   mysql_free_result(result);
5479   rc= mysql_more_results(mysql_local);
5480   DIE_UNLESS(rc == 1);
5481   rc= mysql_next_result(mysql_local);
5482   DIE_UNLESS(rc > 0);
5483 
5484   /*
5485     Ensure that we can now do a simple query (this checks that the server is
5486     not trying to send us the results for the last 'select 1'
5487   */
5488   rc= mysql_query(mysql_local, "select 1+1+1");
5489   myquery(rc);
5490   result= mysql_store_result(mysql_local);
5491   mytest(result);
5492   (void) my_process_result_set(result);
5493   mysql_free_result(result);
5494 
5495   /*
5496     Check if errors in one of the queries handled properly.
5497   */
5498   rc= mysql_query(mysql_local, "select 1; select * from not_existing_table");
5499   myquery(rc);
5500   result= mysql_store_result(mysql_local);
5501   mysql_free_result(result);
5502 
5503   rc= mysql_next_result(mysql_local);
5504   DIE_UNLESS(rc > 0);
5505 
5506   rc= mysql_next_result(mysql_local);
5507   DIE_UNLESS(rc < 0);
5508 
5509   mysql_close(mysql_local);
5510 }
5511 
5512 
5513 /*
5514   Check that Prepared statement cannot contain several
5515   SQL statements
5516 */
5517 
test_prepare_multi_statements()5518 static void test_prepare_multi_statements()
5519 {
5520   MYSQL *mysql_local;
5521   MYSQL_STMT *stmt;
5522   char query[MAX_TEST_QUERY_LENGTH];
5523   myheader("test_prepare_multi_statements");
5524 
5525   if (!(mysql_local= mysql_client_init(NULL)))
5526   {
5527     fprintf(stderr, "\n mysql_client_init() failed");
5528     exit(1);
5529   }
5530 
5531   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5532                            opt_password, current_db, opt_port,
5533                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5534   {
5535     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
5536     exit(1);
5537   }
5538   mysql_local->reconnect= 1;
5539   my_stpcpy(query, "select 1; select 'another value'");
5540   stmt= mysql_simple_prepare(mysql_local, query);
5541   check_stmt_r(stmt);
5542   mysql_close(mysql_local);
5543 }
5544 
5545 
5546 /* Test simple bind store result */
5547 
test_store_result()5548 static void test_store_result()
5549 {
5550   MYSQL_STMT *stmt;
5551   int        rc;
5552   int32      nData;
5553   char       szData[100];
5554   MYSQL_BIND my_bind[2];
5555   ulong      length, length1;
5556   my_bool    is_null[2];
5557 
5558   myheader("test_store_result");
5559 
5560   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5561   myquery(rc);
5562 
5563   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5564   myquery(rc);
5565 
5566   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5567   myquery(rc);
5568 
5569   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5570   myquery(rc);
5571 
5572   rc= mysql_commit(mysql);
5573   myquery(rc);
5574 
5575   /* fetch */
5576   memset(my_bind, 0, sizeof(my_bind));
5577   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5578   my_bind[0].buffer= (void *) &nData;       /* integer data */
5579   my_bind[0].length= &length;
5580   my_bind[0].is_null= &is_null[0];
5581 
5582   length= 0;
5583   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5584   my_bind[1].buffer= szData;                /* string data */
5585   my_bind[1].buffer_length= (ulong)sizeof(szData);
5586   my_bind[1].length= &length1;
5587   my_bind[1].is_null= &is_null[1];
5588   length1= 0;
5589 
5590   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5591   check_stmt(stmt);
5592 
5593   rc= mysql_stmt_bind_result(stmt, my_bind);
5594   check_execute(stmt, rc);
5595 
5596   rc= mysql_stmt_execute(stmt);
5597   check_execute(stmt, rc);
5598 
5599   rc= mysql_stmt_store_result(stmt);
5600   check_execute(stmt, rc);
5601 
5602   rc= mysql_stmt_fetch(stmt);
5603   check_execute(stmt, rc);
5604 
5605   if (!opt_silent)
5606     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5607   DIE_UNLESS(nData == 10);
5608   DIE_UNLESS(strcmp(szData, "venu") == 0);
5609   DIE_UNLESS(length1 == 4);
5610 
5611   rc= mysql_stmt_fetch(stmt);
5612   check_execute(stmt, rc);
5613 
5614   if (!opt_silent)
5615     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5616   DIE_UNLESS(nData == 20);
5617   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5618   DIE_UNLESS(length1 == 5);
5619 
5620   length= 99;
5621   rc= mysql_stmt_fetch(stmt);
5622   check_execute(stmt, rc);
5623 
5624   if (!opt_silent && is_null[0])
5625     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5626   DIE_UNLESS(is_null[0]);
5627   DIE_UNLESS(strcmp(szData, "monty") == 0);
5628   DIE_UNLESS(length1 == 5);
5629 
5630   rc= mysql_stmt_fetch(stmt);
5631   DIE_UNLESS(rc == MYSQL_NO_DATA);
5632 
5633   rc= mysql_stmt_execute(stmt);
5634   check_execute(stmt, rc);
5635 
5636   rc= mysql_stmt_store_result(stmt);
5637   check_execute(stmt, rc);
5638 
5639   rc= mysql_stmt_fetch(stmt);
5640   check_execute(stmt, rc);
5641 
5642   if (!opt_silent)
5643     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5644   DIE_UNLESS(nData == 10);
5645   DIE_UNLESS(strcmp(szData, "venu") == 0);
5646   DIE_UNLESS(length1 == 4);
5647 
5648   rc= mysql_stmt_fetch(stmt);
5649   check_execute(stmt, rc);
5650 
5651   if (!opt_silent)
5652     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5653   DIE_UNLESS(nData == 20);
5654   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5655   DIE_UNLESS(length1 == 5);
5656 
5657   length= 99;
5658   rc= mysql_stmt_fetch(stmt);
5659   check_execute(stmt, rc);
5660 
5661   if (!opt_silent && is_null[0])
5662     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5663   DIE_UNLESS(is_null[0]);
5664   DIE_UNLESS(strcmp(szData, "monty") == 0);
5665   DIE_UNLESS(length1 == 5);
5666 
5667   rc= mysql_stmt_fetch(stmt);
5668   DIE_UNLESS(rc == MYSQL_NO_DATA);
5669 
5670   mysql_stmt_close(stmt);
5671 }
5672 
5673 
5674 /* Test simple bind store result */
5675 
test_store_result1()5676 static void test_store_result1()
5677 {
5678   MYSQL_STMT *stmt;
5679   int        rc;
5680 
5681   myheader("test_store_result1");
5682 
5683   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5684   myquery(rc);
5685 
5686   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5687   myquery(rc);
5688 
5689   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5690   myquery(rc);
5691 
5692   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5693   myquery(rc);
5694 
5695   rc= mysql_commit(mysql);
5696   myquery(rc);
5697 
5698   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5699   check_stmt(stmt);
5700 
5701   rc= mysql_stmt_execute(stmt);
5702   check_execute(stmt, rc);
5703 
5704   rc= mysql_stmt_store_result(stmt);
5705   check_execute(stmt, rc);
5706 
5707   rc= 0;
5708   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5709     rc++;
5710   if (!opt_silent)
5711     fprintf(stdout, "\n total rows: %d", rc);
5712   DIE_UNLESS(rc == 3);
5713 
5714   rc= mysql_stmt_execute(stmt);
5715   check_execute(stmt, rc);
5716 
5717   rc= mysql_stmt_store_result(stmt);
5718   check_execute(stmt, rc);
5719 
5720   rc= 0;
5721   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5722     rc++;
5723   if (!opt_silent)
5724     fprintf(stdout, "\n total rows: %d", rc);
5725   DIE_UNLESS(rc == 3);
5726 
5727   mysql_stmt_close(stmt);
5728 }
5729 
5730 
5731 /* Another test for bind and store result */
5732 
test_store_result2()5733 static void test_store_result2()
5734 {
5735   MYSQL_STMT *stmt;
5736   int        rc;
5737   int        nData;
5738   ulong      length;
5739   MYSQL_BIND my_bind[1];
5740   char query[MAX_TEST_QUERY_LENGTH];
5741 
5742   myheader("test_store_result2");
5743 
5744   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5745   myquery(rc);
5746 
5747   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5748   myquery(rc);
5749 
5750   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5751   myquery(rc);
5752 
5753   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5754   myquery(rc);
5755 
5756   rc= mysql_commit(mysql);
5757   myquery(rc);
5758 
5759   /*
5760     We need to memset bind structure because mysql_stmt_bind_param checks all
5761     its members.
5762   */
5763   memset(my_bind, 0, sizeof(my_bind));
5764 
5765   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5766   my_bind[0].buffer= (void *) &nData;      /* integer data */
5767   my_bind[0].length= &length;
5768   my_bind[0].is_null= 0;
5769 
5770   my_stpcpy((char *)query , "SELECT col1 FROM test_store_result where col1= ?");
5771   stmt= mysql_simple_prepare(mysql, query);
5772   check_stmt(stmt);
5773 
5774   rc= mysql_stmt_bind_param(stmt, my_bind);
5775   check_execute(stmt, rc);
5776 
5777   rc= mysql_stmt_bind_result(stmt, my_bind);
5778   check_execute(stmt, rc);
5779 
5780   nData= 10; length= 0;
5781   rc= mysql_stmt_execute(stmt);
5782   check_execute(stmt, rc);
5783 
5784   nData= 0;
5785   rc= mysql_stmt_store_result(stmt);
5786   check_execute(stmt, rc);
5787 
5788   rc= mysql_stmt_fetch(stmt);
5789   check_execute(stmt, rc);
5790 
5791   if (!opt_silent)
5792     fprintf(stdout, "\n row 1: %d", nData);
5793   DIE_UNLESS(nData == 10);
5794 
5795   rc= mysql_stmt_fetch(stmt);
5796   DIE_UNLESS(rc == MYSQL_NO_DATA);
5797 
5798   nData= 20;
5799   rc= mysql_stmt_execute(stmt);
5800   check_execute(stmt, rc);
5801 
5802   nData= 0;
5803   rc= mysql_stmt_store_result(stmt);
5804   check_execute(stmt, rc);
5805 
5806   rc= mysql_stmt_fetch(stmt);
5807   check_execute(stmt, rc);
5808 
5809   if (!opt_silent)
5810     fprintf(stdout, "\n row 1: %d", nData);
5811   DIE_UNLESS(nData == 20);
5812 
5813   rc= mysql_stmt_fetch(stmt);
5814   DIE_UNLESS(rc == MYSQL_NO_DATA);
5815   mysql_stmt_close(stmt);
5816 }
5817 
5818 
5819 /* Test simple subselect prepare */
5820 
test_subselect()5821 static void test_subselect()
5822 {
5823 
5824   MYSQL_STMT *stmt;
5825   int        rc, id;
5826   MYSQL_BIND my_bind[1];
5827   DBUG_ENTER("test_subselect");
5828 
5829   myheader("test_subselect");
5830 
5831   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub1");
5832   myquery(rc);
5833 
5834   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub2");
5835   myquery(rc);
5836 
5837   rc= mysql_query(mysql, "CREATE TABLE test_sub1(id int)");
5838   myquery(rc);
5839 
5840   rc= mysql_query(mysql, "CREATE TABLE test_sub2(id int, id1 int)");
5841   myquery(rc);
5842 
5843   rc= mysql_query(mysql, "INSERT INTO test_sub1 values(2)");
5844   myquery(rc);
5845 
5846   rc= mysql_query(mysql, "INSERT INTO test_sub2 VALUES(1, 7), (2, 7)");
5847   myquery(rc);
5848 
5849   rc= mysql_commit(mysql);
5850   myquery(rc);
5851 
5852   /* fetch */
5853   /*
5854     We need to memset bind structure because mysql_stmt_bind_param checks all
5855     its members.
5856   */
5857   memset(my_bind, 0, sizeof(my_bind));
5858 
5859   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5860   my_bind[0].buffer= (void *) &id;
5861   my_bind[0].length= 0;
5862   my_bind[0].is_null= 0;
5863 
5864   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id= ?");
5865   check_stmt(stmt);
5866 
5867   rc= mysql_stmt_bind_param(stmt, my_bind);
5868   check_execute(stmt, rc);
5869 
5870   id= 2;
5871   rc= mysql_stmt_execute(stmt);
5872   check_execute(stmt, rc);
5873 
5874   verify_st_affected_rows(stmt, 1);
5875 
5876   id= 9;
5877   rc= mysql_stmt_execute(stmt);
5878   check_execute(stmt, rc);
5879 
5880   verify_st_affected_rows(stmt, 0);
5881 
5882   mysql_stmt_close(stmt);
5883 
5884   rc= my_stmt_result("SELECT * FROM test_sub2");
5885   DIE_UNLESS(rc == 3);
5886 
5887   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
5888                      "from test_sub2 WHERE id1= 8)");
5889   DIE_UNLESS(rc == 1);
5890   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
5891                      "from test_sub2 WHERE id1= 7)");
5892   DIE_UNLESS(rc == 1);
5893 
5894   stmt= mysql_simple_prepare(mysql, ("SELECT ROW(1, 7) IN (select id, id1 "
5895                                      "from test_sub2 WHERE id1= ?)"));
5896   check_stmt(stmt);
5897 
5898   rc= mysql_stmt_bind_param(stmt, my_bind);
5899   check_execute(stmt, rc);
5900 
5901   rc= mysql_stmt_bind_result(stmt, my_bind);
5902   check_execute(stmt, rc);
5903 
5904   id= 7;
5905   rc= mysql_stmt_execute(stmt);
5906   check_execute(stmt, rc);
5907 
5908   rc= mysql_stmt_fetch(stmt);
5909   check_execute(stmt, rc);
5910 
5911   if (!opt_silent)
5912     fprintf(stdout, "\n row 1: %d", id);
5913   DIE_UNLESS(id == 1);
5914 
5915   rc= mysql_stmt_fetch(stmt);
5916   DIE_UNLESS(rc == MYSQL_NO_DATA);
5917 
5918   id= 8;
5919   rc= mysql_stmt_execute(stmt);
5920   check_execute(stmt, rc);
5921 
5922   rc= mysql_stmt_fetch(stmt);
5923   check_execute(stmt, rc);
5924 
5925   if (!opt_silent)
5926     fprintf(stdout, "\n row 1: %d", id);
5927   DIE_UNLESS(id == 0);
5928 
5929   rc= mysql_stmt_fetch(stmt);
5930   DIE_UNLESS(rc == MYSQL_NO_DATA);
5931 
5932   mysql_stmt_close(stmt);
5933   DBUG_VOID_RETURN;
5934 }
5935 
5936 
5937 /*
5938   Generalized conversion routine to handle DATE, TIME and DATETIME
5939   conversion using MYSQL_TIME structure
5940 */
5941 
bind_date_conv(uint row_count,my_bool preserveFractions)5942 static void bind_date_conv(uint row_count, my_bool preserveFractions)
5943 {
5944   MYSQL_STMT   *stmt= 0;
5945   uint         rc, i, count= row_count;
5946   ulong        length[4];
5947   MYSQL_BIND   my_bind[4];
5948   my_bool      is_null[4]= {0};
5949   MYSQL_TIME   tm[4];
5950   ulong        second_part;
5951   uint         year, month, day, hour, minute, sec;
5952   uint         now_year= 1990, now_month= 3, now_day= 13;
5953 
5954   rc= mysql_query(mysql, "SET timestamp=UNIX_TIMESTAMP('1990-03-13')");
5955   myquery(rc);
5956 
5957   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_date VALUES(?, ?, ?, ?)");
5958   check_stmt(stmt);
5959 
5960   verify_param_count(stmt, 4);
5961 
5962   /*
5963     We need to memset bind structure because mysql_stmt_bind_param checks all
5964     its members.
5965   */
5966   memset(my_bind, 0, sizeof(my_bind));
5967 
5968   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
5969   my_bind[1].buffer_type= MYSQL_TYPE_TIME;
5970   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
5971   my_bind[3].buffer_type= MYSQL_TYPE_DATE;
5972 
5973   for (i= 0; i < (int) array_elements(my_bind); i++)
5974   {
5975     my_bind[i].buffer= (void *) &tm[i];
5976     my_bind[i].is_null= &is_null[i];
5977     my_bind[i].length= &length[i];
5978     my_bind[i].buffer_length= 30;
5979     length[i]= 20;
5980   }
5981 
5982   second_part= 0;
5983 
5984   year= 2000;
5985   month= 01;
5986   day= 10;
5987 
5988   hour= 11;
5989   minute= 16;
5990   sec= 20;
5991 
5992   rc= mysql_stmt_bind_param(stmt, my_bind);
5993   check_execute(stmt, rc);
5994 
5995   for (count= 0; count < row_count; count++)
5996   {
5997     for (i= 0; i < (int) array_elements(my_bind); i++)
5998     {
5999       tm[i].neg= 0;
6000       tm[i].second_part= second_part+count;
6001       if (my_bind[i].buffer_type != MYSQL_TYPE_TIME)
6002       {
6003         tm[i].year= year+count;
6004         tm[i].month= month+count;
6005         tm[i].day= day+count;
6006       }
6007       else
6008         tm[i].year= tm[i].month= tm[i].day= 0;
6009       if (my_bind[i].buffer_type != MYSQL_TYPE_DATE)
6010       {
6011         tm[i].hour= hour+count;
6012         tm[i].minute= minute+count;
6013         tm[i].second= sec+count;
6014       }
6015       else
6016         tm[i].hour= tm[i].minute= tm[i].second= 0;
6017     }
6018     rc= mysql_stmt_execute(stmt);
6019     check_execute(stmt, rc);
6020   }
6021 
6022   rc= mysql_commit(mysql);
6023   myquery(rc);
6024 
6025   mysql_stmt_close(stmt);
6026 
6027   rc= my_stmt_result("SELECT * FROM test_date");
6028   DIE_UNLESS(row_count == rc);
6029 
6030   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_date");
6031   check_stmt(stmt);
6032 
6033   rc= mysql_stmt_bind_result(stmt, my_bind);
6034   check_execute(stmt, rc);
6035 
6036   rc= mysql_stmt_execute(stmt);
6037   check_execute(stmt, rc);
6038 
6039   rc= mysql_stmt_store_result(stmt);
6040   check_execute(stmt, rc);
6041 
6042   for (count= 0; count < row_count; count++)
6043   {
6044     rc= mysql_stmt_fetch(stmt);
6045     DIE_UNLESS(rc == 0 || rc == MYSQL_DATA_TRUNCATED);
6046 
6047     if (!opt_silent)
6048       fprintf(stdout, "\n");
6049     for (i= 0; i < array_elements(my_bind); i++)
6050     {
6051       if (!opt_silent)
6052         fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d %02d:%02d:%02d.%06lu",
6053                 i, tm[i].year, tm[i].month, tm[i].day,
6054                 tm[i].hour, tm[i].minute, tm[i].second,
6055                 tm[i].second_part);
6056       DIE_UNLESS(tm[i].year == 0 || tm[i].year == year + count ||
6057                  (tm[i].year == now_year &&
6058                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6059       DIE_UNLESS(tm[i].month == 0 || tm[i].month == month + count ||
6060                  (tm[i].month == now_month &&
6061                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6062       DIE_UNLESS(tm[i].day == 0 || tm[i].day == day + count ||
6063                  (tm[i].day == now_day &&
6064                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6065 
6066       DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count);
6067       DIE_UNLESS(tm[i].minute == 0 || tm[i].minute == minute+count);
6068       DIE_UNLESS(tm[i].second == 0 || tm[i].second == sec+count);
6069       if (preserveFractions) {
6070         if (i == 3) { /* Dates dont have fractions */
6071           DIE_UNLESS(tm[i].second_part == 0);
6072         } else {
6073           DIE_UNLESS(tm[i].second_part == second_part+count);
6074         }
6075       } else {
6076         DIE_UNLESS((tm[i].second_part == 0)||
6077                    tm[i].second_part == second_part+count);
6078       }
6079     }
6080   }
6081   rc= mysql_stmt_fetch(stmt);
6082   DIE_UNLESS(rc == MYSQL_NO_DATA);
6083 
6084   mysql_stmt_close(stmt);
6085 
6086   /* set the timestamp back to default */
6087   rc= mysql_query(mysql, "SET timestamp=DEFAULT");
6088   myquery(rc);
6089 }
6090 
6091 
6092 /* Test DATE, TIME, DATETIME and TS with MYSQL_TIME conversion */
6093 
test_date()6094 static void test_date()
6095 {
6096   int        rc;
6097 
6098   myheader("test_date");
6099 
6100   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6101   myquery(rc);
6102 
6103   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6104                                                  c2 TIME, \
6105                                                  c3 DATETIME, \
6106                                                  c4 DATE)");
6107 
6108   myquery(rc);
6109 
6110   bind_date_conv(5,FALSE);
6111 }
6112 
6113 
6114 /* Test DATE, TIME(6), DATETIME(6) and TS(6) with MYSQL_TIME conversion */
6115 
test_date_frac()6116 static void test_date_frac()
6117 {
6118   int        rc;
6119 
6120   myheader("test_date");
6121 
6122   if (mysql_get_server_version(mysql) < 50604)
6123   {
6124     if (!opt_silent)
6125       fprintf(stdout, "Skipping test_date_frac: fractinal seconds implemented "
6126               "in MySQL 5.6.4\n");
6127     return;
6128   }
6129 
6130   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6131   myquery(rc);
6132 
6133   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP(6), \
6134                                                  c2 TIME(6), \
6135                                                  c3 DATETIME(6), \
6136                                                  c4 DATE)");
6137 
6138   myquery(rc);
6139 
6140   bind_date_conv(5,TRUE);
6141 }
6142 
6143 
6144 /* Test all time types to DATE and DATE to all types */
6145 
test_date_date()6146 static void test_date_date()
6147 {
6148   int        rc;
6149 
6150   myheader("test_date_date");
6151 
6152   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6153   myquery(rc);
6154 
6155   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 DATE, \
6156                                                  c2 DATE, \
6157                                                  c3 DATE, \
6158                                                  c4 DATE)");
6159 
6160   myquery(rc);
6161 
6162   bind_date_conv(3,FALSE);
6163 }
6164 
6165 
6166 /* Test all time types to TIME and TIME to all types */
6167 
test_date_time()6168 static void test_date_time()
6169 {
6170   int        rc;
6171 
6172   myheader("test_date_time");
6173 
6174   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6175   myquery(rc);
6176 
6177   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIME, \
6178                                                  c2 TIME, \
6179                                                  c3 TIME, \
6180                                                  c4 TIME)");
6181 
6182   myquery(rc);
6183 
6184   bind_date_conv(3, FALSE);
6185 }
6186 
6187 
6188 /* Test all time types to TIMESTAMP and TIMESTAMP to all types */
6189 
test_date_ts()6190 static void test_date_ts()
6191 {
6192   int        rc;
6193 
6194   myheader("test_date_ts");
6195 
6196   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6197   myquery(rc);
6198 
6199   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6200                                                  c2 TIMESTAMP, \
6201                                                  c3 TIMESTAMP, \
6202                                                  c4 TIMESTAMP)");
6203 
6204   myquery(rc);
6205 
6206   bind_date_conv(2, FALSE);
6207 }
6208 
6209 
6210 /* Test all time types to DATETIME and DATETIME to all types */
6211 
test_date_dt()6212 static void test_date_dt()
6213 {
6214   int rc;
6215 
6216   myheader("test_date_dt");
6217 
6218   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6219   myquery(rc);
6220 
6221   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 datetime, "
6222                          " c2 datetime, c3 datetime, c4 date)");
6223   myquery(rc);
6224 
6225   bind_date_conv(2, FALSE);
6226 }
6227 
6228 
6229 /*
6230   Test TIME/DATETIME parameters to cover the following methods:
6231     Item_param::val_int()
6232     Item_param::val_real()
6233     Item_param::val_decimal()
6234 */
test_temporal_param()6235 static void test_temporal_param()
6236 {
6237 #define N_PARAMS 3
6238   MYSQL_STMT   *stmt= 0;
6239   uint         rc;
6240   ulong        length[N_PARAMS],  length2[N_PARAMS];
6241   MYSQL_BIND   my_bind[N_PARAMS], my_bind2[N_PARAMS];
6242   my_bool      is_null[N_PARAMS], is_null2[N_PARAMS];
6243   MYSQL_TIME   tm;
6244   longlong     bigint= 123;
6245   double       real= 123;
6246   char         dec[40];
6247 
6248   if (mysql_get_server_version(mysql) < 50600)
6249   {
6250     if (!opt_silent)
6251       fprintf(stdout, "Skipping test_temporal_param: this test cannot be "
6252               "executed on servers prior to 5.6 until bug#16328037 is fixed\n");
6253     return;
6254   }
6255 
6256   /* Initialize param/fetch buffers for data, null flags, lengths */
6257   memset(&my_bind, 0, sizeof(my_bind));
6258   memset(&my_bind2, 0, sizeof(my_bind2));
6259   memset(&length, 0, sizeof(length));
6260   memset(&length2, 0, sizeof(length2));
6261   memset(&is_null, 0, sizeof(is_null));
6262   memset(&is_null2, 0, sizeof(is_null2));
6263 
6264   /* Initialize the first input parameter */
6265   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
6266   my_bind[0].buffer= (void *) &tm;
6267   my_bind[0].is_null= &is_null[0];
6268   my_bind[0].length= &length[0];
6269   my_bind[0].buffer_length= (ulong)sizeof(tm);
6270 
6271   /* Clone the second and the third input parameter */
6272   my_bind[2]= my_bind[1]= my_bind[0];
6273 
6274   /* Initialize fetch parameters */
6275   my_bind2[0].buffer_type= MYSQL_TYPE_LONGLONG;
6276   my_bind2[0].length= &length2[0];
6277   my_bind2[0].is_null= &is_null2[0];
6278   my_bind2[0].buffer_length= (ulong)sizeof(bigint);
6279   my_bind2[0].buffer= (void *) &bigint;
6280 
6281   my_bind2[1].buffer_type= MYSQL_TYPE_DOUBLE;
6282   my_bind2[1].length= &length2[1];
6283   my_bind2[1].is_null= &is_null2[1];
6284   my_bind2[1].buffer_length= (ulong)sizeof(real);
6285   my_bind2[1].buffer= (void *) &real;
6286 
6287   my_bind2[2].buffer_type= MYSQL_TYPE_STRING;
6288   my_bind2[2].length= &length2[2];
6289   my_bind2[2].is_null= &is_null2[2];
6290   my_bind2[2].buffer_length= (ulong)sizeof(dec);
6291   my_bind2[2].buffer= (void *) &dec;
6292 
6293 
6294   /* Prepare and bind input and output parameters */
6295   stmt= mysql_simple_prepare(mysql, "SELECT CAST(? AS SIGNED), ?+0e0, ?+0.0");
6296   check_stmt(stmt);
6297   verify_param_count(stmt, N_PARAMS);
6298 
6299   rc= mysql_stmt_bind_param(stmt, my_bind);
6300   check_execute(stmt, rc);
6301 
6302   rc= mysql_stmt_bind_result(stmt, my_bind2);
6303   check_execute(stmt, rc);
6304 
6305   /* Initialize DATETIME value */
6306   tm.neg= 0;
6307   tm.time_type= MYSQL_TIMESTAMP_DATETIME;
6308   tm.year= 2001;
6309   tm.month= 10;
6310   tm.day= 20;
6311   tm.hour= 10;
6312   tm.minute= 10;
6313   tm.second= 59;
6314   tm.second_part= 500000;
6315 
6316   /* Execute and fetch */
6317   rc= mysql_stmt_execute(stmt);
6318   check_execute(stmt, rc);
6319 
6320   rc= mysql_stmt_store_result(stmt);
6321   check_execute(stmt, rc);
6322 
6323   rc= mysql_stmt_fetch(stmt);
6324   check_execute(stmt, rc);
6325 
6326   if (!opt_silent)
6327     printf("\n%lld %f '%s'\n", bigint, real, dec);
6328 
6329   /* Check values.  */
6330   DIE_UNLESS(bigint ==  20011020101100LL);
6331   DIE_UNLESS(real == 20011020101059.5);
6332   DIE_UNLESS(!strcmp(dec, "20011020101059.500000"));
6333 
6334   mysql_stmt_close(stmt);
6335 
6336   /* Re-initialize input parameters to TIME data type */
6337   my_bind[0].buffer_type= my_bind[1].buffer_type=
6338                           my_bind[2].buffer_type= MYSQL_TYPE_TIME;
6339 
6340   /* Prepare and bind intput and output parameters */
6341   stmt= mysql_simple_prepare(mysql, "SELECT CAST(? AS SIGNED), ?+0e0, ?+0.0");
6342   check_stmt(stmt);
6343   verify_param_count(stmt, N_PARAMS);
6344 
6345   rc= mysql_stmt_bind_param(stmt, my_bind);
6346   check_execute(stmt, rc);
6347 
6348   rc= mysql_stmt_bind_result(stmt, my_bind2);
6349   check_execute(stmt, rc);
6350 
6351   /* Initialize TIME value */
6352   tm.neg= 0;
6353   tm.time_type= MYSQL_TIMESTAMP_TIME;
6354   tm.year= tm.month= tm.day= 0;
6355   tm.hour= 10;
6356   tm.minute= 10;
6357   tm.second= 59;
6358   tm.second_part= 500000;
6359 
6360   /* Execute and fetch */
6361   rc= mysql_stmt_execute(stmt);
6362   check_execute(stmt, rc);
6363 
6364   rc= mysql_stmt_store_result(stmt);
6365   check_execute(stmt, rc);
6366 
6367   rc= mysql_stmt_fetch(stmt);
6368   check_execute(stmt, rc);
6369 
6370   if (!opt_silent)
6371     printf("\n%lld %f '%s'\n", bigint, real, dec);
6372 
6373   /* Check returned values */
6374   DIE_UNLESS(bigint ==  101100);
6375   DIE_UNLESS(real ==  101059.5);
6376   DIE_UNLESS(!strcmp(dec, "101059.500000"));
6377 
6378   mysql_stmt_close(stmt);
6379 }
6380 
6381 
6382 
6383 
6384 /* Misc tests to keep pure coverage happy */
6385 
test_pure_coverage()6386 static void test_pure_coverage()
6387 {
6388   MYSQL_STMT *stmt;
6389   MYSQL_BIND my_bind[2];
6390   int        rc;
6391   ulong      length;
6392 
6393   myheader("test_pure_coverage");
6394 
6395   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_pure");
6396   myquery(rc);
6397 
6398   rc= mysql_query(mysql, "CREATE TABLE test_pure(c1 int, c2 varchar(20))");
6399   myquery(rc);
6400 
6401   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c67788) values(10)");
6402   check_stmt_r(stmt);
6403 
6404   /* Query without params and result should allow to bind 0 arrays */
6405   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(10)");
6406   check_stmt(stmt);
6407 
6408   rc= mysql_stmt_bind_param(stmt, (MYSQL_BIND*)0);
6409   check_execute(stmt, rc);
6410 
6411   rc= mysql_stmt_execute(stmt);
6412   check_execute(stmt, rc);
6413 
6414   rc= mysql_stmt_bind_result(stmt, (MYSQL_BIND*)0);
6415   DIE_UNLESS(rc == 1);
6416 
6417   mysql_stmt_close(stmt);
6418 
6419   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(?)");
6420   check_stmt(stmt);
6421 
6422   /*
6423     We need to memset bind structure because mysql_stmt_bind_param checks all
6424     its members.
6425   */
6426   memset(my_bind, 0, sizeof(my_bind));
6427 
6428   my_bind[0].length= &length;
6429   my_bind[0].is_null= 0;
6430   my_bind[0].buffer_length= 0;
6431 
6432   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6433   rc= mysql_stmt_bind_param(stmt, my_bind);
6434   check_execute_r(stmt, rc); /* unsupported buffer type */
6435 
6436   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6437   rc= mysql_stmt_bind_param(stmt, my_bind);
6438   check_execute(stmt, rc);
6439 
6440   rc= mysql_stmt_store_result(stmt);
6441   check_execute(stmt, rc);
6442 
6443   mysql_stmt_close(stmt);
6444 
6445   stmt= mysql_simple_prepare(mysql, "select * from test_pure");
6446   check_execute(stmt, rc);
6447 
6448   rc= mysql_stmt_execute(stmt);
6449   check_execute(stmt, rc);
6450 
6451   // NOTE: stmt now has two columns, but only my_bind[0] is initialized.
6452   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6453   rc= mysql_stmt_bind_result(stmt, my_bind);
6454   check_execute_r(stmt, rc); /* unsupported buffer type */
6455 
6456   rc= mysql_stmt_store_result(stmt);
6457   DIE_UNLESS(rc);
6458 
6459   rc= mysql_stmt_store_result(stmt);
6460   DIE_UNLESS(rc); /* Old error must be reset first */
6461 
6462   mysql_stmt_close(stmt);
6463 
6464   mysql_query(mysql, "DROP TABLE test_pure");
6465 }
6466 
6467 
6468 /* Test for string buffer fetch */
6469 
test_buffers()6470 static void test_buffers()
6471 {
6472   MYSQL_STMT *stmt;
6473   // The test_pure table has two columns.
6474   MYSQL_BIND my_bind[2];
6475   int        rc;
6476   ulong      length;
6477   my_bool    is_null;
6478   char       buffer[20];
6479 
6480   myheader("test_buffers");
6481 
6482   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_buffer");
6483   myquery(rc);
6484 
6485   rc= mysql_query(mysql, "CREATE TABLE test_buffer(str varchar(20))");
6486   myquery(rc);
6487 
6488   rc= mysql_query(mysql, "insert into test_buffer values('MySQL')\
6489                           , ('Database'), ('Open-Source'), ('Popular')");
6490   myquery(rc);
6491 
6492   stmt= mysql_simple_prepare(mysql, "select str from test_buffer");
6493   check_stmt(stmt);
6494 
6495   rc= mysql_stmt_execute(stmt);
6496   check_execute(stmt, rc);
6497 
6498   memset(buffer, 0, sizeof(buffer));  /* Avoid overruns in printf() */
6499 
6500   memset(my_bind, 0, sizeof(my_bind));
6501   my_bind[0].length= &length;
6502   my_bind[0].is_null= &is_null;
6503   my_bind[0].buffer_length= 1;
6504   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6505   my_bind[0].buffer= (void *)buffer;
6506   my_bind[0].error= &my_bind[0].error_value;
6507 
6508   rc= mysql_stmt_bind_result(stmt, my_bind);
6509   check_execute(stmt, rc);
6510 
6511   rc= mysql_stmt_store_result(stmt);
6512   check_execute(stmt, rc);
6513 
6514   buffer[1]= 'X';
6515   rc= mysql_stmt_fetch(stmt);
6516   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6517   DIE_UNLESS(my_bind[0].error_value);
6518   if (!opt_silent)
6519     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6520   DIE_UNLESS(buffer[0] == 'M');
6521   DIE_UNLESS(buffer[1] == 'X');
6522   DIE_UNLESS(length == 5);
6523 
6524   my_bind[0].buffer_length= 8;
6525   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6526   check_execute(stmt, rc);
6527 
6528   rc= mysql_stmt_fetch(stmt);
6529   check_execute(stmt, rc);
6530   if (!opt_silent)
6531     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6532   DIE_UNLESS(strncmp(buffer, "Database", 8) == 0);
6533   DIE_UNLESS(length == 8);
6534 
6535   my_bind[0].buffer_length= 12;
6536   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6537   check_execute(stmt, rc);
6538 
6539   rc= mysql_stmt_fetch(stmt);
6540   check_execute(stmt, rc);
6541   if (!opt_silent)
6542     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6543   DIE_UNLESS(strcmp(buffer, "Open-Source") == 0);
6544   DIE_UNLESS(length == 11);
6545 
6546   my_bind[0].buffer_length= 6;
6547   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6548   check_execute(stmt, rc);
6549 
6550   rc= mysql_stmt_fetch(stmt);
6551   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6552   DIE_UNLESS(my_bind[0].error_value);
6553   if (!opt_silent)
6554     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6555   DIE_UNLESS(strncmp(buffer, "Popula", 6) == 0);
6556   DIE_UNLESS(length == 7);
6557 
6558   mysql_stmt_close(stmt);
6559 }
6560 
6561 
6562 /* Test the direct query execution in the middle of open stmts */
6563 
test_open_direct()6564 static void test_open_direct()
6565 {
6566   MYSQL_STMT  *stmt;
6567   MYSQL_RES   *result;
6568   int         rc;
6569 
6570   myheader("test_open_direct");
6571 
6572   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_open_direct");
6573   myquery(rc);
6574 
6575   rc= mysql_query(mysql, "CREATE TABLE test_open_direct(id int, name char(6))");
6576   myquery(rc);
6577 
6578   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_open_direct values(10, 'mysql')");
6579   check_stmt(stmt);
6580 
6581   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6582   myquery(rc);
6583 
6584   result= mysql_store_result(mysql);
6585   mytest(result);
6586 
6587   rc= my_process_result_set(result);
6588   DIE_UNLESS(rc == 0);
6589   mysql_free_result(result);
6590 
6591   rc= mysql_stmt_execute(stmt);
6592   check_execute(stmt, rc);
6593 
6594   verify_st_affected_rows(stmt, 1);
6595 
6596   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6597   myquery(rc);
6598 
6599   result= mysql_store_result(mysql);
6600   mytest(result);
6601 
6602   rc= my_process_result_set(result);
6603   DIE_UNLESS(rc == 1);
6604   mysql_free_result(result);
6605 
6606   rc= mysql_stmt_execute(stmt);
6607   check_execute(stmt, rc);
6608 
6609   verify_st_affected_rows(stmt, 1);
6610 
6611   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6612   myquery(rc);
6613 
6614   result= mysql_store_result(mysql);
6615   mytest(result);
6616 
6617   rc= my_process_result_set(result);
6618   DIE_UNLESS(rc == 2);
6619   mysql_free_result(result);
6620 
6621   mysql_stmt_close(stmt);
6622 
6623   /* run a direct query in the middle of a fetch */
6624   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6625   check_stmt(stmt);
6626 
6627   rc= mysql_stmt_execute(stmt);
6628   check_execute(stmt, rc);
6629 
6630   rc= mysql_stmt_fetch(stmt);
6631   check_execute(stmt, rc);
6632 
6633   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6634   myquery_r(rc);
6635 
6636   rc= mysql_stmt_close(stmt);
6637   check_execute(stmt, rc);
6638 
6639   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6640   myquery(rc);
6641 
6642   /* run a direct query with store result */
6643   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6644   check_stmt(stmt);
6645 
6646   rc= mysql_stmt_execute(stmt);
6647   check_execute(stmt, rc);
6648 
6649   rc= mysql_stmt_store_result(stmt);
6650   check_execute(stmt, rc);
6651 
6652   rc= mysql_stmt_fetch(stmt);
6653   check_execute(stmt, rc);
6654 
6655   rc= mysql_query(mysql, "drop table test_open_direct");
6656   myquery(rc);
6657 
6658   rc= mysql_stmt_close(stmt);
6659   check_execute(stmt, rc);
6660 }
6661 
6662 
6663 /* Test fetch without prior bound buffers */
6664 
test_fetch_nobuffs()6665 static void test_fetch_nobuffs()
6666 {
6667   MYSQL_STMT *stmt;
6668   MYSQL_BIND my_bind[4];
6669   char       str[4][50];
6670   int        rc;
6671 
6672   myheader("test_fetch_nobuffs");
6673 
6674   stmt= mysql_simple_prepare(mysql, "SELECT DATABASE(), CURRENT_USER(), \
6675                               CURRENT_DATE(), CURRENT_TIME()");
6676   check_stmt(stmt);
6677 
6678   rc= mysql_stmt_execute(stmt);
6679   check_execute(stmt, rc);
6680 
6681   rc= 0;
6682   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6683     rc++;
6684 
6685   if (!opt_silent)
6686     fprintf(stdout, "\n total rows        : %d", rc);
6687   DIE_UNLESS(rc == 1);
6688 
6689   memset(my_bind, 0, sizeof(MYSQL_BIND));
6690   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6691   my_bind[0].buffer= (void *)str[0];
6692   my_bind[0].buffer_length= (ulong)sizeof(str[0]);
6693   my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0];
6694   my_bind[1].buffer= (void *)str[1];
6695   my_bind[2].buffer= (void *)str[2];
6696   my_bind[3].buffer= (void *)str[3];
6697 
6698   rc= mysql_stmt_bind_result(stmt, my_bind);
6699   check_execute(stmt, rc);
6700 
6701   rc= mysql_stmt_execute(stmt);
6702   check_execute(stmt, rc);
6703 
6704   rc= 0;
6705   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6706   {
6707     rc++;
6708     if (!opt_silent)
6709     {
6710       fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
6711       fprintf(stdout, "\n CURRENT_USER()    : %s", str[1]);
6712       fprintf(stdout, "\n CURRENT_DATE()    : %s", str[2]);
6713       fprintf(stdout, "\n CURRENT_TIME()    : %s", str[3]);
6714     }
6715   }
6716   if (!opt_silent)
6717     fprintf(stdout, "\n total rows        : %d", rc);
6718   DIE_UNLESS(rc == 1);
6719 
6720   mysql_stmt_close(stmt);
6721 }
6722 
6723 
6724 /* Test a misc bug */
6725 
test_ushort_bug()6726 static void test_ushort_bug()
6727 {
6728   MYSQL_STMT *stmt;
6729   MYSQL_BIND my_bind[4];
6730   ushort     short_value;
6731   uint32     long_value;
6732   ulong      s_length, l_length, ll_length, t_length;
6733   ulonglong  longlong_value;
6734   int        rc;
6735   uchar      tiny_value;
6736   char       llbuf[22];
6737   myheader("test_ushort_bug");
6738 
6739   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ushort");
6740   myquery(rc);
6741 
6742   rc= mysql_query(mysql, "CREATE TABLE test_ushort(a smallint unsigned, \
6743                                                   b smallint unsigned, \
6744                                                   c smallint unsigned, \
6745                                                   d smallint unsigned)");
6746   myquery(rc);
6747 
6748   rc= mysql_query(mysql,
6749                   "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)");
6750   myquery(rc);
6751 
6752 
6753   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ushort");
6754   check_stmt(stmt);
6755 
6756   rc= mysql_stmt_execute(stmt);
6757   check_execute(stmt, rc);
6758 
6759   memset(my_bind, 0, sizeof(my_bind));
6760   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6761   my_bind[0].buffer= (void *)&short_value;
6762   my_bind[0].is_unsigned= TRUE;
6763   my_bind[0].length= &s_length;
6764 
6765   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6766   my_bind[1].buffer= (void *)&long_value;
6767   my_bind[1].length= &l_length;
6768 
6769   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6770   my_bind[2].buffer= (void *)&longlong_value;
6771   my_bind[2].length= &ll_length;
6772 
6773   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6774   my_bind[3].buffer= (void *)&tiny_value;
6775   my_bind[3].is_unsigned= TRUE;
6776   my_bind[3].length= &t_length;
6777 
6778   rc= mysql_stmt_bind_result(stmt, my_bind);
6779   check_execute(stmt, rc);
6780 
6781   rc= mysql_stmt_fetch(stmt);
6782   check_execute(stmt, rc);
6783 
6784   if (!opt_silent)
6785   {
6786     fprintf(stdout, "\n ushort   : %d (%ld)", short_value, (long)s_length);
6787     fprintf(stdout, "\n ulong    : %lu (%ld)", (ulong) long_value, (long)l_length);
6788     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6789             (long)ll_length);
6790     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, (long)t_length);
6791   }
6792 
6793   DIE_UNLESS(short_value == 35999);
6794   DIE_UNLESS(s_length == 2);
6795 
6796   DIE_UNLESS(long_value == 35999);
6797   DIE_UNLESS(l_length == 4);
6798 
6799   DIE_UNLESS(longlong_value == 35999);
6800   DIE_UNLESS(ll_length == 8);
6801 
6802   DIE_UNLESS(tiny_value == 200);
6803   DIE_UNLESS(t_length == 1);
6804 
6805   rc= mysql_stmt_fetch(stmt);
6806   DIE_UNLESS(rc == MYSQL_NO_DATA);
6807 
6808   mysql_stmt_close(stmt);
6809 }
6810 
6811 
6812 /* Test a misc smallint-signed conversion bug */
6813 
test_sshort_bug()6814 static void test_sshort_bug()
6815 {
6816   MYSQL_STMT *stmt;
6817   MYSQL_BIND my_bind[4];
6818   short      short_value;
6819   int32      long_value;
6820   ulong      s_length, l_length, ll_length, t_length;
6821   ulonglong  longlong_value;
6822   int        rc;
6823   uchar      tiny_value;
6824   char       llbuf[22];
6825 
6826   myheader("test_sshort_bug");
6827 
6828   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sshort");
6829   myquery(rc);
6830 
6831   rc= mysql_query(mysql, "CREATE TABLE test_sshort(a smallint signed, \
6832                                                   b smallint signed, \
6833                                                   c smallint unsigned, \
6834                                                   d smallint unsigned)");
6835   myquery(rc);
6836 
6837   rc= mysql_query(mysql, "INSERT INTO test_sshort VALUES(-5999, -5999, 35999, 200)");
6838   myquery(rc);
6839 
6840 
6841   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_sshort");
6842   check_stmt(stmt);
6843 
6844   rc= mysql_stmt_execute(stmt);
6845   check_execute(stmt, rc);
6846 
6847   memset(my_bind, 0, sizeof(my_bind));
6848   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6849   my_bind[0].buffer= (void *)&short_value;
6850   my_bind[0].length= &s_length;
6851 
6852   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6853   my_bind[1].buffer= (void *)&long_value;
6854   my_bind[1].length= &l_length;
6855 
6856   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6857   my_bind[2].buffer= (void *)&longlong_value;
6858   my_bind[2].length= &ll_length;
6859 
6860   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6861   my_bind[3].buffer= (void *)&tiny_value;
6862   my_bind[3].is_unsigned= TRUE;
6863   my_bind[3].length= &t_length;
6864 
6865   rc= mysql_stmt_bind_result(stmt, my_bind);
6866   check_execute(stmt, rc);
6867 
6868   rc= mysql_stmt_fetch(stmt);
6869   check_execute(stmt, rc);
6870 
6871   if (!opt_silent)
6872   {
6873     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, (long)s_length);
6874     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, (long)l_length);
6875     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6876             (long)ll_length);
6877     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, (long)t_length);
6878   }
6879 
6880   DIE_UNLESS(short_value == -5999);
6881   DIE_UNLESS(s_length == 2);
6882 
6883   DIE_UNLESS(long_value == -5999);
6884   DIE_UNLESS(l_length == 4);
6885 
6886   DIE_UNLESS(longlong_value == 35999);
6887   DIE_UNLESS(ll_length == 8);
6888 
6889   DIE_UNLESS(tiny_value == 200);
6890   DIE_UNLESS(t_length == 1);
6891 
6892   rc= mysql_stmt_fetch(stmt);
6893   DIE_UNLESS(rc == MYSQL_NO_DATA);
6894 
6895   mysql_stmt_close(stmt);
6896 }
6897 
6898 
6899 /* Test a misc tinyint-signed conversion bug */
6900 
test_stiny_bug()6901 static void test_stiny_bug()
6902 {
6903   MYSQL_STMT *stmt;
6904   MYSQL_BIND my_bind[4];
6905   short      short_value;
6906   int32      long_value;
6907   ulong      s_length, l_length, ll_length, t_length;
6908   ulonglong  longlong_value;
6909   int        rc;
6910   uchar      tiny_value;
6911   char       llbuf[22];
6912 
6913   myheader("test_stiny_bug");
6914 
6915   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_stiny");
6916   myquery(rc);
6917 
6918   rc= mysql_query(mysql, "CREATE TABLE test_stiny(a tinyint signed, \
6919                                                   b tinyint signed, \
6920                                                   c tinyint unsigned, \
6921                                                   d tinyint unsigned)");
6922   myquery(rc);
6923 
6924   rc= mysql_query(mysql, "INSERT INTO test_stiny VALUES(-128, -127, 255, 0)");
6925   myquery(rc);
6926 
6927 
6928   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_stiny");
6929   check_stmt(stmt);
6930 
6931   rc= mysql_stmt_execute(stmt);
6932   check_execute(stmt, rc);
6933 
6934   memset(my_bind, 0, sizeof(my_bind));
6935   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6936   my_bind[0].buffer= (void *)&short_value;
6937   my_bind[0].length= &s_length;
6938 
6939   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6940   my_bind[1].buffer= (void *)&long_value;
6941   my_bind[1].length= &l_length;
6942 
6943   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6944   my_bind[2].buffer= (void *)&longlong_value;
6945   my_bind[2].length= &ll_length;
6946 
6947   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6948   my_bind[3].buffer= (void *)&tiny_value;
6949   my_bind[3].length= &t_length;
6950 
6951   rc= mysql_stmt_bind_result(stmt, my_bind);
6952   check_execute(stmt, rc);
6953 
6954   rc= mysql_stmt_fetch(stmt);
6955   check_execute(stmt, rc);
6956 
6957   if (!opt_silent)
6958   {
6959     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, (long)s_length);
6960     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, (long)l_length);
6961     fprintf(stdout, "\n longlong : %s  (%ld)", llstr(longlong_value, llbuf),
6962             (long)ll_length);
6963     fprintf(stdout, "\n tinyint  : %d    (%ld)", tiny_value, (long)t_length);
6964   }
6965 
6966   DIE_UNLESS(short_value == -128);
6967   DIE_UNLESS(s_length == 2);
6968 
6969   DIE_UNLESS(long_value == -127);
6970   DIE_UNLESS(l_length == 4);
6971 
6972   DIE_UNLESS(longlong_value == 255);
6973   DIE_UNLESS(ll_length == 8);
6974 
6975   DIE_UNLESS(tiny_value == 0);
6976   DIE_UNLESS(t_length == 1);
6977 
6978   rc= mysql_stmt_fetch(stmt);
6979   DIE_UNLESS(rc == MYSQL_NO_DATA);
6980 
6981   mysql_stmt_close(stmt);
6982 }
6983 
6984 
6985 /* Test misc field information, bug: #74 */
6986 
test_field_misc()6987 static void test_field_misc()
6988 {
6989   MYSQL_STMT  *stmt;
6990   MYSQL_RES   *result;
6991   int         rc;
6992 
6993   myheader("test_field_misc");
6994 
6995   rc= mysql_query(mysql, "SELECT @@autocommit");
6996   myquery(rc);
6997 
6998   result= mysql_store_result(mysql);
6999   mytest(result);
7000 
7001   rc= my_process_result_set(result);
7002   DIE_UNLESS(rc == 1);
7003 
7004   verify_prepare_field(result, 0,
7005                        "@@autocommit", "",  /* field and its org name */
7006                        MYSQL_TYPE_LONGLONG, /* field type */
7007                        "", "",              /* table and its org name */
7008                        "", 1, 0);           /* db name, length(its bool flag)*/
7009 
7010   mysql_free_result(result);
7011 
7012   stmt= mysql_simple_prepare(mysql, "SELECT @@autocommit");
7013   check_stmt(stmt);
7014 
7015   rc= mysql_stmt_execute(stmt);
7016   check_execute(stmt, rc);
7017 
7018   result= mysql_stmt_result_metadata(stmt);
7019   mytest(result);
7020 
7021   rc= my_process_stmt_result(stmt);
7022   DIE_UNLESS(rc == 1);
7023 
7024   verify_prepare_field(result, 0,
7025                        "@@autocommit", "",  /* field and its org name */
7026                        MYSQL_TYPE_LONGLONG, /* field type */
7027                        "", "",              /* table and its org name */
7028                        "", 1, 0);           /* db name, length(its bool flag)*/
7029 
7030   mysql_free_result(result);
7031   mysql_stmt_close(stmt);
7032 
7033   stmt= mysql_simple_prepare(mysql, "SELECT @@max_error_count");
7034   check_stmt(stmt);
7035 
7036   result= mysql_stmt_result_metadata(stmt);
7037   mytest(result);
7038 
7039   rc= mysql_stmt_execute(stmt);
7040   check_execute(stmt, rc);
7041 
7042   rc= my_process_stmt_result(stmt);
7043   DIE_UNLESS(rc == 1);
7044 
7045   verify_prepare_field(result, 0,
7046                        "@@max_error_count", "",   /* field and its org name */
7047                        MYSQL_TYPE_LONGLONG, /* field type */
7048                        "", "",              /* table and its org name */
7049                        /* db name, length */
7050                        "", MY_INT64_NUM_DECIMAL_DIGITS , 0);
7051 
7052   mysql_free_result(result);
7053   mysql_stmt_close(stmt);
7054 
7055   stmt= mysql_simple_prepare(mysql, "SELECT @@max_allowed_packet");
7056   check_stmt(stmt);
7057 
7058   result= mysql_stmt_result_metadata(stmt);
7059   mytest(result);
7060 
7061   rc= mysql_stmt_execute(stmt);
7062   check_execute(stmt, rc);
7063 
7064   DIE_UNLESS(1 == my_process_stmt_result(stmt));
7065 
7066   verify_prepare_field(result, 0,
7067                        "@@max_allowed_packet", "", /* field and its org name */
7068                        MYSQL_TYPE_LONGLONG, /* field type */
7069                        "", "",              /* table and its org name */
7070                        /* db name, length */
7071                        "", MY_INT64_NUM_DECIMAL_DIGITS, 0);
7072 
7073   mysql_free_result(result);
7074   mysql_stmt_close(stmt);
7075 
7076   stmt= mysql_simple_prepare(mysql, "SELECT @@sql_warnings");
7077   check_stmt(stmt);
7078 
7079   result= mysql_stmt_result_metadata(stmt);
7080   mytest(result);
7081 
7082   rc= mysql_stmt_execute(stmt);
7083   check_execute(stmt, rc);
7084 
7085   rc= my_process_stmt_result(stmt);
7086   DIE_UNLESS(rc == 1);
7087 
7088   verify_prepare_field(result, 0,
7089                        "@@sql_warnings", "",  /* field and its org name */
7090                        MYSQL_TYPE_LONGLONG,   /* field type */
7091                        "", "",                /* table and its org name */
7092                        "", 1, 0);             /* db name, length */
7093 
7094   mysql_free_result(result);
7095   mysql_stmt_close(stmt);
7096 }
7097 
7098 
7099 /*
7100   Test SET feature with prepare stmts
7101   bug #85 (reported by mark@mysql.com)
7102 */
7103 
test_set_option()7104 static void test_set_option()
7105 {
7106   MYSQL_STMT *stmt;
7107   MYSQL_RES  *result;
7108   int        rc;
7109 
7110   myheader("test_set_option");
7111 
7112   mysql_autocommit(mysql, TRUE);
7113 
7114   /* LIMIT the rows count to 2 */
7115   rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT= 2");
7116   myquery(rc);
7117 
7118   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_limit");
7119   myquery(rc);
7120 
7121   rc= mysql_query(mysql, "CREATE TABLE test_limit(a tinyint)");
7122   myquery(rc);
7123 
7124   rc= mysql_query(mysql, "INSERT INTO test_limit VALUES(10), (20), (30), (40)");
7125   myquery(rc);
7126 
7127   if (!opt_silent)
7128     fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)");
7129   rc= mysql_query(mysql, "SELECT * FROM test_limit");
7130   myquery(rc);
7131 
7132   result= mysql_store_result(mysql);
7133   mytest(result);
7134 
7135   rc= my_process_result_set(result);
7136   DIE_UNLESS(rc == 2);
7137 
7138   mysql_free_result(result);
7139 
7140   if (!opt_silent)
7141     fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)");
7142   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7143   check_stmt(stmt);
7144 
7145   rc= mysql_stmt_execute(stmt);
7146   check_execute(stmt, rc);
7147 
7148   rc= my_process_stmt_result(stmt);
7149   DIE_UNLESS(rc == 2);
7150 
7151   mysql_stmt_close(stmt);
7152 
7153   /* RESET the LIMIT the rows count to 0 */
7154   if (!opt_silent)
7155     fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)");
7156   rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT=DEFAULT");
7157   myquery(rc);
7158 
7159   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7160   check_stmt(stmt);
7161 
7162   rc= mysql_stmt_execute(stmt);
7163   check_execute(stmt, rc);
7164 
7165   rc= my_process_stmt_result(stmt);
7166   DIE_UNLESS(rc == 4);
7167 
7168   mysql_stmt_close(stmt);
7169 }
7170 
7171 
7172 #ifdef EMBEDDED_LIBRARY
test_embedded_start_stop()7173 static void test_embedded_start_stop()
7174 {
7175   MYSQL *mysql_emb=NULL;
7176   int i, j;
7177   int argc= original_argc;                    // Start with the original args
7178   char **argv, **my_argv;
7179   char test_name[]= "test_embedded_start_stop";
7180   const unsigned int drop_db= opt_drop_db;
7181 #define EMBEDDED_RESTARTS 64
7182 
7183   myheader("test_embedded_start_stop");
7184 
7185   /* Must stop the main embedded server, since we use the same config. */
7186   opt_drop_db= 0;
7187   client_disconnect(mysql);    /* disconnect from server */
7188   free_defaults(defaults_argv);
7189   mysql_server_end();
7190   /* Free everything allocated by my_once_alloc */
7191   my_end(0);
7192   opt_drop_db= drop_db;
7193 
7194   /*
7195     Use a copy of the original arguments.
7196     The arguments will be altered when reading the configs and parsing
7197     options.
7198   */
7199   my_argv= malloc((argc + 1) * sizeof(char*));
7200   if (!my_argv)
7201     exit(1);
7202 
7203   /* Test restarting the embedded library many times. */
7204   for (i= 1; i <= EMBEDDED_RESTARTS; i++)
7205   {
7206     argv= my_argv;
7207     argv[0]= test_name;
7208     for (j= 1; j < argc; j++)
7209       argv[j]= original_argv[j];
7210 
7211     /* Initialize everything again. */
7212     MY_INIT(argv[0]);
7213 
7214     /* Load the client defaults from the .cnf file[s]. */
7215     if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
7216     {
7217       myerror("load_defaults failed");
7218       exit(1);
7219     }
7220 
7221     /* Parse the options (including the ones given from defaults files). */
7222     get_options(&argc, &argv);
7223 
7224     /* mysql_library_init is the same as mysql_server_init. */
7225     if (mysql_library_init(embedded_server_arg_count,
7226                            embedded_server_args,
7227                            (char**) embedded_server_groups))
7228     {
7229       myerror("mysql_library_init failed");
7230       exit(1);
7231     }
7232 
7233     /* Create a client connection. */
7234     if (!(mysql_emb= mysql_client_init(NULL)))
7235     {
7236       myerror("mysql_client_init failed");
7237       exit(1);
7238     }
7239 
7240     /* Connect it and see if we can use the database. */
7241     if (!(mysql_real_connect(mysql_emb, opt_host, opt_user,
7242                              opt_password, current_db, 0,
7243                              NULL, 0)))
7244     {
7245       myerror("mysql_real_connect failed");
7246     }
7247 
7248     /* Close the client connection */
7249     mysql_close(mysql_emb);
7250     mysql_emb = NULL;
7251     /* Free arguments allocated for defaults files. */
7252     free_defaults(defaults_argv);
7253     /* mysql_library_end is a define for mysql_server_end. */
7254     mysql_library_end();
7255     /* Free everything allocated by my_once_alloc */
7256     my_end(0);
7257   }
7258 
7259   argc= original_argc;
7260   argv= my_argv;
7261   argv[0]= test_name;
7262   for (j= 1; j < argc; j++)
7263     argv[j]= original_argv[j];
7264 
7265   MY_INIT(argv[0]);
7266 
7267   if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
7268   {
7269     myerror("load_defaults failed \n ");
7270     exit(1);
7271   }
7272 
7273   get_options(&argc, &argv);
7274 
7275   /* Must start the main embedded server again after the test. */
7276   if (mysql_server_init(embedded_server_arg_count,
7277                         embedded_server_args,
7278                         (char**) embedded_server_groups))
7279     DIE("Can't initialize MySQL server");
7280 
7281   /* connect to server with no flags, default protocol, auto reconnect true */
7282   mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
7283   free(my_argv);
7284 }
7285 #endif /* EMBEDDED_LIBRARY */
7286 
7287 
7288 /*
7289   Test a misc GRANT option
7290   bug #89 (reported by mark@mysql.com)
7291 */
7292 
7293 #ifndef EMBEDDED_LIBRARY
test_prepare_grant()7294 static void test_prepare_grant()
7295 {
7296   int rc;
7297   char query[MAX_TEST_QUERY_LENGTH];
7298 
7299   myheader("test_prepare_grant");
7300 
7301   mysql_autocommit(mysql, TRUE);
7302 
7303   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_grant");
7304   myquery(rc);
7305 
7306   rc= mysql_query(mysql, "CREATE TABLE test_grant(a tinyint primary key auto_increment)");
7307   myquery(rc);
7308 
7309   strxmov(query, "GRANT INSERT, UPDATE, SELECT ON ", current_db,
7310                 ".test_grant TO 'test_grant'@",
7311                 opt_host ? opt_host : "'localhost'", NullS);
7312 
7313   if (mysql_query(mysql, query))
7314   {
7315     myerror("GRANT failed");
7316 
7317     /*
7318        If server started with --skip-grant-tables, skip this test, else
7319        exit to indicate an error
7320 
7321        ER_UNKNOWN_COM_ERROR= 1047
7322      */
7323     if (mysql_errno(mysql) != 1047)
7324       exit(1);
7325   }
7326   else
7327   {
7328     MYSQL *org_mysql= mysql, *lmysql;
7329     MYSQL_STMT *stmt;
7330 
7331     if (!opt_silent)
7332       fprintf(stdout, "\n Establishing a test connection ...");
7333     if (!(lmysql= mysql_client_init(NULL)))
7334     {
7335       myerror("mysql_client_init() failed");
7336       exit(1);
7337     }
7338     if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
7339                              "", current_db, opt_port,
7340                              opt_unix_socket, 0)))
7341     {
7342       myerror("connection failed");
7343       mysql_close(lmysql);
7344       exit(1);
7345     }
7346     lmysql->reconnect= 1;
7347     if (!opt_silent)
7348       fprintf(stdout, "OK");
7349 
7350     mysql= lmysql;
7351     rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)");
7352     myquery(rc);
7353 
7354     rc= mysql_query(mysql, "INSERT INTO test_grant(a) VALUES(NULL)");
7355     myquery(rc);
7356 
7357     execute_prepare_query("INSERT INTO test_grant(a) VALUES(NULL)", 1);
7358     execute_prepare_query("INSERT INTO test_grant VALUES(NULL)", 1);
7359     execute_prepare_query("UPDATE test_grant SET a=9 WHERE a=1", 1);
7360     rc= my_stmt_result("SELECT a FROM test_grant");
7361     DIE_UNLESS(rc == 4);
7362 
7363     /* Both DELETE expected to fail as user does not have DELETE privs */
7364 
7365     rc= mysql_query(mysql, "DELETE FROM test_grant");
7366     myquery_r(rc);
7367 
7368     stmt= mysql_simple_prepare(mysql, "DELETE FROM test_grant");
7369     check_stmt_r(stmt);
7370 
7371     rc= my_stmt_result("SELECT * FROM test_grant");
7372     DIE_UNLESS(rc == 4);
7373 
7374     mysql_close(lmysql);
7375     mysql= org_mysql;
7376 
7377     rc= mysql_query(mysql, "delete from mysql.user where User='test_grant'");
7378     myquery(rc);
7379     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7380 
7381     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_grant'");
7382     myquery(rc);
7383     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7384 
7385   }
7386 }
7387 #endif /* EMBEDDED_LIBRARY */
7388 
7389 /*
7390   Test a crash when invalid/corrupted .frm is used in the
7391   SHOW TABLE STATUS
7392   bug #93 (reported by serg@mysql.com).
7393 */
7394 
test_frm_bug()7395 static void test_frm_bug()
7396 {
7397   MYSQL_STMT *stmt;
7398   MYSQL_BIND my_bind[2];
7399   MYSQL_RES  *result;
7400   MYSQL_ROW  row;
7401   FILE       *test_file;
7402   char       data_dir[FN_REFLEN];
7403   char       test_frm[FN_REFLEN];
7404   int        rc;
7405 
7406   myheader("test_frm_bug");
7407 
7408   mysql_autocommit(mysql, TRUE);
7409 
7410   rc= mysql_query(mysql, "drop table if exists test_frm_bug");
7411   myquery(rc);
7412 
7413   rc= mysql_query(mysql, "flush tables");
7414   myquery(rc);
7415 
7416   stmt= mysql_simple_prepare(mysql, "show variables like 'datadir'");
7417   check_stmt(stmt);
7418 
7419   rc= mysql_stmt_execute(stmt);
7420   check_execute(stmt, rc);
7421 
7422   memset(my_bind, 0, sizeof(my_bind));
7423   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
7424   my_bind[0].buffer= data_dir;
7425   my_bind[0].buffer_length= FN_REFLEN;
7426   my_bind[1]= my_bind[0];
7427 
7428   rc= mysql_stmt_bind_result(stmt, my_bind);
7429   check_execute(stmt, rc);
7430 
7431   rc= mysql_stmt_fetch(stmt);
7432   check_execute(stmt, rc);
7433 
7434   if (!opt_silent)
7435     fprintf(stdout, "\n data directory: %s", data_dir);
7436 
7437   rc= mysql_stmt_fetch(stmt);
7438   DIE_UNLESS(rc == MYSQL_NO_DATA);
7439 
7440   strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS);
7441 
7442   if (!opt_silent)
7443     fprintf(stdout, "\n test_frm: %s", test_frm);
7444 
7445   if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
7446   {
7447     fprintf(stdout, "\n ERROR: my_fopen failed for '%s'", test_frm);
7448     fprintf(stdout, "\n test cancelled");
7449     exit(1);
7450   }
7451   if (!opt_silent)
7452     fprintf(test_file, "this is a junk file for test");
7453 
7454   rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'");
7455   myquery(rc);
7456 
7457   result= mysql_store_result(mysql);
7458   mytest(result);/* It can't be NULL */
7459 
7460   rc= my_process_result_set(result);
7461   DIE_UNLESS(rc == 1);
7462 
7463   mysql_data_seek(result, 0);
7464 
7465   row= mysql_fetch_row(result);
7466   mytest(row);
7467 
7468   if (!opt_silent)
7469     fprintf(stdout, "\n Comment: %s", row[17]);
7470   DIE_UNLESS(row[17] != 0);
7471 
7472   mysql_free_result(result);
7473   mysql_stmt_close(stmt);
7474 
7475   my_fclose(test_file, MYF(0));
7476   mysql_query(mysql, "drop table if exists test_frm_bug");
7477 }
7478 
7479 
7480 /* Test DECIMAL conversion */
7481 
test_decimal_bug()7482 static void test_decimal_bug()
7483 {
7484   MYSQL_STMT *stmt;
7485   MYSQL_BIND my_bind[1];
7486   char       data[30];
7487   int        rc;
7488   my_bool    is_null;
7489 
7490   myheader("test_decimal_bug");
7491 
7492   mysql_autocommit(mysql, TRUE);
7493 
7494   rc= mysql_query(mysql, "drop table if exists test_decimal_bug");
7495   myquery(rc);
7496 
7497   rc= mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10, 2))");
7498   myquery(rc);
7499 
7500   rc= mysql_query(mysql, "insert into test_decimal_bug value(8), (10.22), (5.61)");
7501   myquery(rc);
7502 
7503   stmt= mysql_simple_prepare(mysql, "select c1 from test_decimal_bug where c1= ?");
7504   check_stmt(stmt);
7505 
7506   /*
7507     We need to memset bind structure because mysql_stmt_bind_param checks all
7508     its members.
7509   */
7510   memset(my_bind, 0, sizeof(my_bind));
7511   memset(data, 0, sizeof(data));
7512 
7513   my_bind[0].buffer_type= MYSQL_TYPE_NEWDECIMAL;
7514   my_bind[0].buffer= (void *)data;
7515   my_bind[0].buffer_length= 25;
7516   my_bind[0].is_null= &is_null;
7517 
7518   is_null= 0;
7519   rc= mysql_stmt_bind_param(stmt, my_bind);
7520   check_execute(stmt, rc);
7521 
7522   my_stpcpy(data, "8.0");
7523   rc= mysql_stmt_execute(stmt);
7524   check_execute(stmt, rc);
7525 
7526   data[0]= 0;
7527   rc= mysql_stmt_bind_result(stmt, my_bind);
7528   check_execute(stmt, rc);
7529 
7530   rc= mysql_stmt_fetch(stmt);
7531   check_execute(stmt, rc);
7532 
7533   if (!opt_silent)
7534     fprintf(stdout, "\n data: %s", data);
7535   DIE_UNLESS(strcmp(data, "8.00") == 0);
7536 
7537   rc= mysql_stmt_fetch(stmt);
7538   DIE_UNLESS(rc == MYSQL_NO_DATA);
7539 
7540   my_stpcpy(data, "5.61");
7541   rc= mysql_stmt_execute(stmt);
7542   check_execute(stmt, rc);
7543 
7544   data[0]= 0;
7545   rc= mysql_stmt_bind_result(stmt, my_bind);
7546   check_execute(stmt, rc);
7547 
7548   rc= mysql_stmt_fetch(stmt);
7549   check_execute(stmt, rc);
7550 
7551   if (!opt_silent)
7552     fprintf(stdout, "\n data: %s", data);
7553   DIE_UNLESS(strcmp(data, "5.61") == 0);
7554 
7555   rc= mysql_stmt_fetch(stmt);
7556   DIE_UNLESS(rc == MYSQL_NO_DATA);
7557 
7558   is_null= 1;
7559   rc= mysql_stmt_execute(stmt);
7560   check_execute(stmt, rc);
7561 
7562   rc= mysql_stmt_fetch(stmt);
7563   DIE_UNLESS(rc == MYSQL_NO_DATA);
7564 
7565   my_stpcpy(data, "10.22"); is_null= 0;
7566   rc= mysql_stmt_execute(stmt);
7567   check_execute(stmt, rc);
7568 
7569   data[0]= 0;
7570   rc= mysql_stmt_bind_result(stmt, my_bind);
7571   check_execute(stmt, rc);
7572 
7573   rc= mysql_stmt_fetch(stmt);
7574   check_execute(stmt, rc);
7575 
7576   if (!opt_silent)
7577     fprintf(stdout, "\n data: %s", data);
7578   DIE_UNLESS(strcmp(data, "10.22") == 0);
7579 
7580   rc= mysql_stmt_fetch(stmt);
7581   DIE_UNLESS(rc == MYSQL_NO_DATA);
7582 
7583   mysql_stmt_close(stmt);
7584 }
7585 
7586 
7587 /* Test EXPLAIN bug (#115, reported by mark@mysql.com & georg@php.net). */
7588 
test_explain_bug()7589 static void test_explain_bug()
7590 {
7591   MYSQL_STMT *stmt;
7592   MYSQL_RES  *result;
7593   int        rc;
7594   int        no;
7595 
7596   myheader("test_explain_bug");
7597 
7598   mysql_autocommit(mysql, TRUE);
7599 
7600   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_explain");
7601   myquery(rc);
7602 
7603   rc= mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))");
7604   myquery(rc);
7605 
7606   stmt= mysql_simple_prepare(mysql, "explain test_explain");
7607   check_stmt(stmt);
7608 
7609   rc= mysql_stmt_execute(stmt);
7610   check_execute(stmt, rc);
7611 
7612   rc= my_process_stmt_result(stmt);
7613   DIE_UNLESS(rc == 2);
7614 
7615   result= mysql_stmt_result_metadata(stmt);
7616   mytest(result);
7617 
7618   if (!opt_silent)
7619     fprintf(stdout, "\n total fields in the result: %d",
7620             mysql_num_fields(result));
7621   DIE_UNLESS(6 == mysql_num_fields(result));
7622 
7623   verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
7624                        mysql_get_server_version(mysql) <= 50000 ?
7625                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7626                        0, 0, "information_schema", 64, 0);
7627 
7628   verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
7629                        0, 0, "information_schema", 0, 0);
7630 
7631   verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
7632                        mysql_get_server_version(mysql) <= 50000 ?
7633                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7634                        0, 0, "information_schema", 3, 0);
7635 
7636   verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
7637                        mysql_get_server_version(mysql) <= 50000 ?
7638                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7639                        0, 0, "information_schema", 3, 0);
7640 
7641   if ( mysql_get_server_version(mysql) >= 50027 )
7642   {
7643     /*  The patch for bug#23037 changes column type of DEAULT to blob */
7644     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7645                          MYSQL_TYPE_BLOB, 0, 0, "information_schema", 0, 0);
7646   }
7647   else
7648   {
7649     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7650                          mysql_get_server_version(mysql) >= 50027 ?
7651                          MYSQL_TYPE_BLOB :
7652                          mysql_get_server_version(mysql) <= 50000 ?
7653                          MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7654                          0, 0, "information_schema",
7655                          mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
7656   }
7657 
7658   verify_prepare_field(result, 5, "Extra", "EXTRA",
7659                        mysql_get_server_version(mysql) <= 50000 ?
7660                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7661                        0, 0, "information_schema",
7662                        mysql_get_server_version(mysql) <= 50602 ? 27 : 30,
7663                        0);
7664 
7665   mysql_free_result(result);
7666   mysql_stmt_close(stmt);
7667 
7668   stmt= mysql_simple_prepare(mysql, "explain select id, name FROM test_explain");
7669   check_stmt(stmt);
7670 
7671   rc= mysql_stmt_execute(stmt);
7672   check_execute(stmt, rc);
7673 
7674   rc= my_process_stmt_result(stmt);
7675   DIE_UNLESS(rc == 1);
7676 
7677   result= mysql_stmt_result_metadata(stmt);
7678   mytest(result);
7679 
7680   if (!opt_silent)
7681     fprintf(stdout, "\n total fields in the result: %d",
7682             mysql_num_fields(result));
7683   if (mysql_get_server_version(mysql) <= 50702)
7684     DIE_UNLESS(10 == mysql_num_fields(result));
7685   else
7686     DIE_UNLESS(12 == mysql_num_fields(result));
7687 
7688   no= 0;
7689 
7690   verify_prepare_field(result, no++, "id", "", MYSQL_TYPE_LONGLONG,
7691                        "", "", "", 3, 0);
7692 
7693   verify_prepare_field(result, no++, "select_type", "", MYSQL_TYPE_VAR_STRING,
7694                        "", "", "", 19, 0);
7695 
7696   verify_prepare_field(result, no++, "table", "", MYSQL_TYPE_VAR_STRING,
7697                        "", "", "", NAME_CHAR_LEN, 0);
7698 
7699   if (mysql_get_server_version(mysql) > 50702)
7700     no++;
7701 
7702   verify_prepare_field(result, no++, "type", "", MYSQL_TYPE_VAR_STRING,
7703                        "", "", "", 10, 0);
7704 
7705   verify_prepare_field(result, no++, "possible_keys", "", MYSQL_TYPE_VAR_STRING,
7706                        "", "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7707 
7708   verify_prepare_field(result, no++, "key", "", MYSQL_TYPE_VAR_STRING,
7709                        "", "", "", NAME_CHAR_LEN, 0);
7710 
7711   if (mysql_get_server_version(mysql) <= 50000)
7712   {
7713     verify_prepare_field(result, no++, "key_len", "", MYSQL_TYPE_LONGLONG, "",
7714                          "", "", 3, 0);
7715   }
7716   else
7717   {
7718     verify_prepare_field(result, no++, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
7719                          "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7720   }
7721 
7722   verify_prepare_field(result, no++, "ref", "", MYSQL_TYPE_VAR_STRING,
7723                        "", "", "", NAME_CHAR_LEN*16, 0);
7724 
7725   verify_prepare_field(result, no++, "rows", "", MYSQL_TYPE_LONGLONG,
7726                        "", "", "", 10, 0);
7727 
7728   if (mysql_get_server_version(mysql) > 50702)
7729     no++;
7730 
7731   verify_prepare_field(result, no++, "Extra", "", MYSQL_TYPE_VAR_STRING,
7732                        "", "", "", 255, 0);
7733 
7734   mysql_free_result(result);
7735   mysql_stmt_close(stmt);
7736 }
7737 
7738 #ifdef NOT_YET_WORKING
7739 
7740 /*
7741   Test math functions.
7742   Bug #148 (reported by salle@mysql.com).
7743 */
7744 
7745 #define myerrno(n) check_errcode(n)
7746 
check_errcode(const unsigned int err)7747 static void check_errcode(const unsigned int err)
7748 {
7749   if (!opt_silent || mysql_errno(mysql) != err)
7750   {
7751     if (mysql->server_version)
7752       fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
7753     else
7754       fprintf(stdout, "\n [MySQL]");
7755     fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
7756   }
7757   DIE_UNLESS(mysql_errno(mysql) == err);
7758 }
7759 
7760 
test_drop_temp()7761 static void test_drop_temp()
7762 {
7763   int rc;
7764 
7765   myheader("test_drop_temp");
7766 
7767   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS test_drop_temp_db");
7768   myquery(rc);
7769 
7770   rc= mysql_query(mysql, "CREATE DATABASE test_drop_temp_db");
7771   myquery(rc);
7772 
7773   rc= mysql_query(mysql, "CREATE TABLE test_drop_temp_db.t1(c1 int, c2 char(1))");
7774   myquery(rc);
7775 
7776   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7777   myquery(rc);
7778 
7779   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7780   myquery(rc);
7781 
7782   strxmov(query, "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@",
7783                 opt_host ? opt_host : "localhost", NullS);
7784 
7785   if (mysql_query(mysql, query))
7786   {
7787     myerror("GRANT failed");
7788 
7789     /*
7790        If server started with --skip-grant-tables, skip this test, else
7791        exit to indicate an error
7792 
7793        ER_UNKNOWN_COM_ERROR= 1047
7794      */
7795     if (mysql_errno(mysql) != 1047)
7796       exit(1);
7797   }
7798   else
7799   {
7800     MYSQL *org_mysql= mysql, *lmysql;
7801 
7802     if (!opt_silent)
7803       fprintf(stdout, "\n Establishing a test connection ...");
7804     if (!(lmysql= mysql_client_init(NULL)))
7805     {
7806       myerror("mysql_client_init() failed");
7807       exit(1);
7808     }
7809 
7810     rc= mysql_query(mysql, "flush privileges");
7811     myquery(rc);
7812 
7813     if (!(mysql_real_connect(lmysql, opt_host ? opt_host : "localhost", "test_temp",
7814                              "", "test_drop_temp_db", opt_port,
7815                              opt_unix_socket, 0)))
7816     {
7817       mysql= lmysql;
7818       myerror("connection failed");
7819       mysql_close(lmysql);
7820       exit(1);
7821     }
7822     lmysql->reconnect= 1;
7823     if (!opt_silent)
7824       fprintf(stdout, "OK");
7825 
7826     mysql= lmysql;
7827     rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')");
7828     myerrno((uint)1142);
7829 
7830     rc= mysql_query(mysql, "DROP TABLE t1");
7831     myerrno((uint)1142);
7832 
7833     mysql= org_mysql;
7834     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t1(c1 int)");
7835     myquery(rc);
7836 
7837     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t2 LIKE test_drop_temp_db.t1");
7838     myquery(rc);
7839 
7840     mysql= lmysql;
7841 
7842     rc= mysql_query(mysql, "DROP TABLE t1, t2");
7843     myquery_r(rc);
7844 
7845     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t1");
7846     myquery_r(rc);
7847 
7848     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t2");
7849     myquery_r(rc);
7850 
7851     mysql_close(lmysql);
7852     mysql= org_mysql;
7853 
7854     rc= mysql_query(mysql, "drop database test_drop_temp_db");
7855     myquery(rc);
7856     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7857 
7858     rc= mysql_query(mysql, "delete from mysql.user where User='test_temp'");
7859     myquery(rc);
7860     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7861 
7862 
7863     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_temp'");
7864     myquery(rc);
7865     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7866   }
7867 }
7868 #endif
7869 
7870 
7871 /* Test warnings for cuted rows */
7872 
test_cuted_rows()7873 static void test_cuted_rows()
7874 {
7875   int        rc, count;
7876   MYSQL_RES  *result;
7877 
7878   myheader("test_cuted_rows");
7879 
7880   mysql_query(mysql, "DROP TABLE if exists t1");
7881   mysql_query(mysql, "DROP TABLE if exists t2");
7882 
7883   rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)");
7884   myquery(rc);
7885 
7886   rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)");
7887   myquery(rc);
7888 
7889   rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)");
7890   myquery(rc);
7891 
7892   count= mysql_warning_count(mysql);
7893   if (!opt_silent)
7894     fprintf(stdout, "\n total warnings: %d", count);
7895   DIE_UNLESS(count == 0);
7896 
7897   rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
7898   myquery(rc);
7899 
7900   count= mysql_warning_count(mysql);
7901   if (!opt_silent)
7902     fprintf(stdout, "\n total warnings: %d", count);
7903   // Number of warnings changed in mysql-5.7
7904   DIE_UNLESS(count == (mysql_get_server_version(mysql) < 50700 ? 2 : 1));
7905 
7906   rc= mysql_query(mysql, "SHOW WARNINGS");
7907   myquery(rc);
7908 
7909   result= mysql_store_result(mysql);
7910   mytest(result);
7911 
7912   rc= my_process_result_set(result);
7913   // Number of warnings changed in mysql-5.7
7914   DIE_UNLESS(rc == (mysql_get_server_version(mysql) < 50700 ? 2 : 1));
7915   mysql_free_result(result);
7916 
7917   rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)");
7918   myquery(rc);
7919 
7920   count= mysql_warning_count(mysql);
7921   if (!opt_silent)
7922     fprintf(stdout, "\n total warnings: %d", count);
7923   DIE_UNLESS(count == 2);
7924 
7925   rc= mysql_query(mysql, "SHOW WARNINGS");
7926   myquery(rc);
7927 
7928   result= mysql_store_result(mysql);
7929   mytest(result);
7930 
7931   rc= my_process_result_set(result);
7932   DIE_UNLESS(rc == 2);
7933   mysql_free_result(result);
7934 }
7935 
7936 
7937 /* Test update/binary logs */
7938 
test_logs()7939 static void test_logs()
7940 {
7941   MYSQL_STMT *stmt;
7942   MYSQL_BIND my_bind[2];
7943   char       data[255];
7944   ulong      length;
7945   int        rc;
7946   short      id;
7947 
7948   myheader("test_logs");
7949 
7950 
7951   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs");
7952   myquery(rc);
7953 
7954   rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))");
7955   myquery(rc);
7956 
7957   my_stpcpy((char *)data, "INSERT INTO test_logs VALUES(?, ?)");
7958   stmt= mysql_simple_prepare(mysql, data);
7959   check_stmt(stmt);
7960 
7961   /*
7962     We need to memset bind structure because mysql_stmt_bind_param checks all
7963     its members.
7964   */
7965   memset(my_bind, 0, sizeof(my_bind));
7966 
7967   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
7968   my_bind[0].buffer= (void *)&id;
7969 
7970   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
7971   my_bind[1].buffer= (void *)&data;
7972   my_bind[1].buffer_length= 255;
7973   my_bind[1].length= &length;
7974 
7975   id= 9876;
7976   length= (ulong)(my_stpcpy((char *)data, "MySQL - Open Source Database")- data);
7977 
7978   rc= mysql_stmt_bind_param(stmt, my_bind);
7979   check_execute(stmt, rc);
7980 
7981   rc= mysql_stmt_execute(stmt);
7982   check_execute(stmt, rc);
7983 
7984   my_stpcpy((char *)data, "'");
7985   length= 1;
7986 
7987   rc= mysql_stmt_execute(stmt);
7988   check_execute(stmt, rc);
7989 
7990   my_stpcpy((char *)data, "\"");
7991   length= 1;
7992 
7993   rc= mysql_stmt_execute(stmt);
7994   check_execute(stmt, rc);
7995 
7996   length= (ulong)(my_stpcpy((char *)data, "my\'sql\'")-data);
7997   rc= mysql_stmt_execute(stmt);
7998   check_execute(stmt, rc);
7999 
8000   length= (ulong)(my_stpcpy((char *)data, "my\"sql\"")-data);
8001   rc= mysql_stmt_execute(stmt);
8002   check_execute(stmt, rc);
8003 
8004   mysql_stmt_close(stmt);
8005 
8006   my_stpcpy((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')");
8007   stmt= mysql_simple_prepare(mysql, data);
8008   check_stmt(stmt);
8009 
8010   rc= mysql_stmt_execute(stmt);
8011   check_execute(stmt, rc);
8012 
8013   rc= mysql_stmt_execute(stmt);
8014   check_execute(stmt, rc);
8015 
8016   mysql_stmt_close(stmt);
8017 
8018   my_stpcpy((char *)data, "SELECT * FROM test_logs WHERE id=?");
8019   stmt= mysql_simple_prepare(mysql, data);
8020   check_stmt(stmt);
8021 
8022   rc= mysql_stmt_bind_param(stmt, my_bind);
8023   check_execute(stmt, rc);
8024 
8025   rc= mysql_stmt_execute(stmt);
8026   check_execute(stmt, rc);
8027 
8028   my_bind[1].buffer_length= 255;
8029   rc= mysql_stmt_bind_result(stmt, my_bind);
8030   check_execute(stmt, rc);
8031 
8032   rc= mysql_stmt_fetch(stmt);
8033   check_execute(stmt, rc);
8034 
8035   if (!opt_silent)
8036   {
8037     fprintf(stdout, "id    : %d\n", id);
8038     fprintf(stdout, "name  : %s(%ld)\n", data, (long)length);
8039   }
8040 
8041   DIE_UNLESS(id == 9876);
8042   DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */
8043   DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1);
8044 
8045   rc= mysql_stmt_fetch(stmt);
8046   check_execute(stmt, rc);
8047 
8048   if (!opt_silent)
8049     fprintf(stdout, "\n name  : %s(%ld)", data, (long)length);
8050 
8051   DIE_UNLESS(length == 1);
8052   DIE_UNLESS(strcmp(data, "'") == 0);
8053 
8054   rc= mysql_stmt_fetch(stmt);
8055   check_execute(stmt, rc);
8056 
8057   if (!opt_silent)
8058     fprintf(stdout, "\n name  : %s(%ld)", data, (long)length);
8059 
8060   DIE_UNLESS(length == 1);
8061   DIE_UNLESS(strcmp(data, "\"") == 0);
8062 
8063   rc= mysql_stmt_fetch(stmt);
8064   check_execute(stmt, rc);
8065 
8066   if (!opt_silent)
8067     fprintf(stdout, "\n name  : %s(%ld)", data, (long)length);
8068 
8069   DIE_UNLESS(length == 7);
8070   DIE_UNLESS(strcmp(data, "my\'sql\'") == 0);
8071 
8072   rc= mysql_stmt_fetch(stmt);
8073   check_execute(stmt, rc);
8074 
8075   if (!opt_silent)
8076     fprintf(stdout, "\n name  : %s(%ld)", data, (long)length);
8077 
8078   DIE_UNLESS(length == 7);
8079   /*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */
8080 
8081   rc= mysql_stmt_fetch(stmt);
8082   DIE_UNLESS(rc == MYSQL_NO_DATA);
8083 
8084   mysql_stmt_close(stmt);
8085 
8086   rc= mysql_query(mysql, "DROP TABLE test_logs");
8087   myquery(rc);
8088 }
8089 
8090 
8091 /* Test 'n' statements create and close */
8092 
test_nstmts()8093 static void test_nstmts()
8094 {
8095   MYSQL_STMT  *stmt;
8096   char        query[255];
8097   int         rc;
8098   static uint i, total_stmts= 2000;
8099   MYSQL_BIND  my_bind[1];
8100 
8101   myheader("test_nstmts");
8102 
8103   mysql_autocommit(mysql, TRUE);
8104 
8105   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_nstmts");
8106   myquery(rc);
8107 
8108   rc= mysql_query(mysql, "CREATE TABLE test_nstmts(id int)");
8109   myquery(rc);
8110 
8111   /*
8112     We need to memset bind structure because mysql_stmt_bind_param checks all
8113     its members.
8114   */
8115   memset(my_bind, 0, sizeof(my_bind));
8116 
8117   my_bind[0].buffer= (void *)&i;
8118   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8119 
8120   for (i= 0; i < total_stmts; i++)
8121   {
8122     if (!opt_silent)
8123       fprintf(stdout, "\r stmt: %d", i);
8124 
8125     my_stpcpy(query, "insert into test_nstmts values(?)");
8126     stmt= mysql_simple_prepare(mysql, query);
8127     check_stmt(stmt);
8128 
8129     rc= mysql_stmt_bind_param(stmt, my_bind);
8130     check_execute(stmt, rc);
8131 
8132     rc= mysql_stmt_execute(stmt);
8133     check_execute(stmt, rc);
8134 
8135     mysql_stmt_close(stmt);
8136   }
8137 
8138   stmt= mysql_simple_prepare(mysql, " select count(*) from test_nstmts");
8139   check_stmt(stmt);
8140 
8141   rc= mysql_stmt_execute(stmt);
8142   check_execute(stmt, rc);
8143 
8144   i= 0;
8145   rc= mysql_stmt_bind_result(stmt, my_bind);
8146   check_execute(stmt, rc);
8147 
8148   rc= mysql_stmt_fetch(stmt);
8149   check_execute(stmt, rc);
8150   if (!opt_silent)
8151     fprintf(stdout, "\n total rows: %d", i);
8152   DIE_UNLESS( i == total_stmts);
8153 
8154   rc= mysql_stmt_fetch(stmt);
8155   DIE_UNLESS(rc == MYSQL_NO_DATA);
8156 
8157   mysql_stmt_close(stmt);
8158 
8159   rc= mysql_query(mysql, "DROP TABLE test_nstmts");
8160   myquery(rc);
8161 }
8162 
8163 
8164 /* Test stmt seek() functions */
8165 
test_fetch_seek()8166 static void test_fetch_seek()
8167 {
8168   MYSQL_STMT *stmt;
8169   MYSQL_BIND my_bind[3];
8170   MYSQL_ROW_OFFSET row;
8171   int        rc;
8172   int32      c1;
8173   char       c2[11], c3[20];
8174 
8175   myheader("test_fetch_seek");
8176   rc= mysql_query(mysql, "drop table if exists t1");
8177 
8178   myquery(rc);
8179 
8180   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
8181   myquery(rc);
8182 
8183   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
8184   myquery(rc);
8185 
8186   stmt= mysql_simple_prepare(mysql, "select * from t1");
8187   check_stmt(stmt);
8188 
8189   memset(my_bind, 0, sizeof(my_bind));
8190   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8191   my_bind[0].buffer= (void *)&c1;
8192 
8193   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8194   my_bind[1].buffer= (void *)c2;
8195   my_bind[1].buffer_length= (ulong)sizeof(c2);
8196 
8197   my_bind[2]= my_bind[1];
8198   my_bind[2].buffer= (void *)c3;
8199   my_bind[2].buffer_length= (ulong)sizeof(c3);
8200 
8201   rc= mysql_stmt_execute(stmt);
8202   check_execute(stmt, rc);
8203 
8204   rc= mysql_stmt_bind_result(stmt, my_bind);
8205   check_execute(stmt, rc);
8206 
8207   rc= mysql_stmt_store_result(stmt);
8208   check_execute(stmt, rc);
8209 
8210   rc= mysql_stmt_fetch(stmt);
8211   check_execute(stmt, rc);
8212 
8213   if (!opt_silent)
8214     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8215 
8216   row= mysql_stmt_row_tell(stmt);
8217 
8218   row= mysql_stmt_row_seek(stmt, row);
8219 
8220   rc= mysql_stmt_fetch(stmt);
8221   check_execute(stmt, rc);
8222 
8223   if (!opt_silent)
8224     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8225 
8226   row= mysql_stmt_row_seek(stmt, row);
8227 
8228   rc= mysql_stmt_fetch(stmt);
8229   check_execute(stmt, rc);
8230 
8231   if (!opt_silent)
8232     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8233 
8234   mysql_stmt_data_seek(stmt, 0);
8235 
8236   rc= mysql_stmt_fetch(stmt);
8237   check_execute(stmt, rc);
8238 
8239   if (!opt_silent)
8240     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8241 
8242   rc= mysql_stmt_fetch(stmt);
8243   check_execute(stmt, rc);
8244 
8245   rc= mysql_stmt_fetch(stmt);
8246   check_execute(stmt, rc);
8247 
8248   rc= mysql_stmt_fetch(stmt);
8249   check_execute(stmt, rc);
8250 
8251   rc= mysql_stmt_fetch(stmt);
8252   DIE_UNLESS(rc == MYSQL_NO_DATA);
8253 
8254   mysql_stmt_close(stmt);
8255   myquery(mysql_query(mysql, "drop table t1"));
8256 }
8257 
8258 
8259 /* Test mysql_stmt_fetch_column() with offset */
8260 
test_fetch_offset()8261 static void test_fetch_offset()
8262 {
8263   MYSQL_STMT *stmt;
8264   MYSQL_BIND my_bind[1];
8265   char       data[11];
8266   ulong      length;
8267   int        rc;
8268   my_bool    is_null;
8269 
8270 
8271   myheader("test_fetch_offset");
8272 
8273   rc= mysql_query(mysql, "drop table if exists t1");
8274   myquery(rc);
8275 
8276   rc= mysql_query(mysql, "create table t1(a char(10))");
8277   myquery(rc);
8278 
8279   rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)");
8280   myquery(rc);
8281 
8282   stmt= mysql_simple_prepare(mysql, "select * from t1");
8283   check_stmt(stmt);
8284 
8285   memset(my_bind, 0, sizeof(my_bind));
8286   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8287   my_bind[0].buffer= (void *)data;
8288   my_bind[0].buffer_length= 11;
8289   my_bind[0].is_null= &is_null;
8290   my_bind[0].length= &length;
8291 
8292   rc= mysql_stmt_execute(stmt);
8293   check_execute(stmt, rc);
8294 
8295   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8296   check_execute_r(stmt, rc);
8297 
8298   rc= mysql_stmt_execute(stmt);
8299   check_execute(stmt, rc);
8300 
8301   rc= mysql_stmt_bind_result(stmt, my_bind);
8302   check_execute(stmt, rc);
8303 
8304   rc= mysql_stmt_store_result(stmt);
8305   check_execute(stmt, rc);
8306 
8307   rc= mysql_stmt_fetch(stmt);
8308   check_execute(stmt, rc);
8309 
8310   data[0]= '\0';
8311   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8312   check_execute(stmt, rc);
8313   if (!opt_silent)
8314     fprintf(stdout, "\n col 1: %s (%ld)", data, (long)length);
8315   DIE_UNLESS(strncmp(data, "abcd", 4) == 0 && length == 10);
8316 
8317   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5);
8318   check_execute(stmt, rc);
8319   if (!opt_silent)
8320     fprintf(stdout, "\n col 1: %s (%ld)", data, (long)length);
8321   DIE_UNLESS(strncmp(data, "fg", 2) == 0 && length == 10);
8322 
8323   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9);
8324   check_execute(stmt, rc);
8325   if (!opt_silent)
8326     fprintf(stdout, "\n col 0: %s (%ld)", data, (long)length);
8327   DIE_UNLESS(strncmp(data, "j", 1) == 0 && length == 10);
8328 
8329   rc= mysql_stmt_fetch(stmt);
8330   check_execute(stmt, rc);
8331 
8332   is_null= 0;
8333 
8334   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8335   check_execute(stmt, rc);
8336 
8337   DIE_UNLESS(is_null == 1);
8338 
8339   rc= mysql_stmt_fetch(stmt);
8340   DIE_UNLESS(rc == MYSQL_NO_DATA);
8341 
8342   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8343   check_execute_r(stmt, rc);
8344 
8345   mysql_stmt_close(stmt);
8346 
8347   myquery(mysql_query(mysql, "drop table t1"));
8348 }
8349 
8350 
8351 /* Test mysql_stmt_fetch_column() */
8352 
test_fetch_column()8353 static void test_fetch_column()
8354 {
8355   MYSQL_STMT *stmt;
8356   MYSQL_BIND my_bind[2];
8357   char       c2[20], bc2[20];
8358   ulong      l1, l2, bl1, bl2;
8359   int        rc, c1, bc1;
8360 
8361   myheader("test_fetch_column");
8362 
8363   rc= mysql_query(mysql, "drop table if exists t1");
8364   myquery(rc);
8365 
8366   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
8367   myquery(rc);
8368 
8369   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
8370   myquery(rc);
8371 
8372   stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc");
8373   check_stmt(stmt);
8374 
8375   memset(my_bind, 0, sizeof(my_bind));
8376   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8377   my_bind[0].buffer= (void *)&bc1;
8378   my_bind[0].buffer_length= 0;
8379   my_bind[0].is_null= 0;
8380   my_bind[0].length= &bl1;
8381   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8382   my_bind[1].buffer= (void *)bc2;
8383   my_bind[1].buffer_length= 7;
8384   my_bind[1].is_null= 0;
8385   my_bind[1].length= &bl2;
8386 
8387   rc= mysql_stmt_execute(stmt);
8388   check_execute(stmt, rc);
8389 
8390   rc= mysql_stmt_bind_result(stmt, my_bind);
8391   check_execute(stmt, rc);
8392 
8393   rc= mysql_stmt_store_result(stmt);
8394   check_execute(stmt, rc);
8395 
8396   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */
8397   check_execute_r(stmt, rc);
8398 
8399   rc= mysql_stmt_fetch(stmt);
8400   check_execute(stmt, rc);
8401 
8402   if (!opt_silent)
8403     fprintf(stdout, "\n row 0: %d, %s", bc1, bc2);
8404 
8405   c2[0]= '\0'; l2= 0;
8406   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8407   my_bind[0].buffer= (void *)c2;
8408   my_bind[0].buffer_length= 7;
8409   my_bind[0].is_null= 0;
8410   my_bind[0].length= &l2;
8411 
8412   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8413   check_execute(stmt, rc);
8414   if (!opt_silent)
8415     fprintf(stdout, "\n col 1: %s(%ld)", c2, (long)l2);
8416   DIE_UNLESS(strncmp(c2, "venu", 4) == 0 && l2 == 4);
8417 
8418   c2[0]= '\0'; l2= 0;
8419   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8420   check_execute(stmt, rc);
8421   if (!opt_silent)
8422     fprintf(stdout, "\n col 1: %s(%ld)", c2, (long)l2);
8423   DIE_UNLESS(strcmp(c2, "venu") == 0 && l2 == 4);
8424 
8425   c1= 0;
8426   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8427   my_bind[0].buffer= (void *)&c1;
8428   my_bind[0].buffer_length= 0;
8429   my_bind[0].is_null= 0;
8430   my_bind[0].length= &l1;
8431 
8432   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8433   check_execute(stmt, rc);
8434   if (!opt_silent)
8435     fprintf(stdout, "\n col 0: %d(%ld)", c1, (long)l1);
8436   DIE_UNLESS(c1 == 1 && l1 == 4);
8437 
8438   rc= mysql_stmt_fetch(stmt);
8439   check_execute(stmt, rc);
8440 
8441   if (!opt_silent)
8442     fprintf(stdout, "\n row 1: %d, %s", bc1, bc2);
8443 
8444   c2[0]= '\0'; l2= 0;
8445   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8446   my_bind[0].buffer= (void *)c2;
8447   my_bind[0].buffer_length= 7;
8448   my_bind[0].is_null= 0;
8449   my_bind[0].length= &l2;
8450 
8451   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8452   check_execute(stmt, rc);
8453   if (!opt_silent)
8454     fprintf(stdout, "\n col 1: %s(%ld)", c2, (long)l2);
8455   DIE_UNLESS(strncmp(c2, "mysq", 4) == 0 && l2 == 5);
8456 
8457   c2[0]= '\0'; l2= 0;
8458   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8459   check_execute(stmt, rc);
8460   if (!opt_silent)
8461     fprintf(stdout, "\n col 1: %si(%ld)", c2, (long)l2);
8462   DIE_UNLESS(strcmp(c2, "mysql") == 0 && l2 == 5);
8463 
8464   c1= 0;
8465   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8466   my_bind[0].buffer= (void *)&c1;
8467   my_bind[0].buffer_length= 0;
8468   my_bind[0].is_null= 0;
8469   my_bind[0].length= &l1;
8470 
8471   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8472   check_execute(stmt, rc);
8473   if (!opt_silent)
8474     fprintf(stdout, "\n col 0: %d(%ld)", c1, (long)l1);
8475   DIE_UNLESS(c1 == 2 && l1 == 4);
8476 
8477   rc= mysql_stmt_fetch(stmt);
8478   DIE_UNLESS(rc == MYSQL_NO_DATA);
8479 
8480   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8481   check_execute_r(stmt, rc);
8482 
8483   mysql_stmt_close(stmt);
8484   myquery(mysql_query(mysql, "drop table t1"));
8485 }
8486 
8487 
8488 /* Test mysql_list_fields() */
8489 
test_list_fields()8490 static void test_list_fields()
8491 {
8492   MYSQL_RES *result;
8493   int rc;
8494   myheader("test_list_fields");
8495 
8496   rc= mysql_query(mysql, "drop table if exists t1");
8497   myquery(rc);
8498 
8499   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10) default 'mysql')");
8500   myquery(rc);
8501 
8502   result= mysql_list_fields(mysql, "t1", NULL);
8503   mytest(result);
8504 
8505   rc= my_process_result_set(result);
8506   DIE_UNLESS(rc == 0);
8507 
8508   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_LONG,
8509                        "t1", "t1",
8510                        current_db, 11, "0");
8511 
8512   verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_STRING,
8513                        "t1", "t1",
8514                        current_db, 10, "mysql");
8515 
8516   mysql_free_result(result);
8517   myquery(mysql_query(mysql, "drop table t1"));
8518 }
8519 
8520 
test_bug19671()8521 static void test_bug19671()
8522 {
8523   MYSQL_RES *result;
8524   int rc;
8525   myheader("test_bug19671");
8526 
8527   mysql_query(mysql, "set sql_mode=''");
8528   rc= mysql_query(mysql, "drop table if exists t1");
8529   myquery(rc);
8530 
8531   rc= mysql_query(mysql, "drop view if exists v1");
8532   myquery(rc);
8533 
8534   rc= mysql_query(mysql, "create table t1(f1 int)");
8535   myquery(rc);
8536 
8537   rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
8538   myquery(rc);
8539 
8540   result= mysql_list_fields(mysql, "v1", NULL);
8541   mytest(result);
8542 
8543   rc= my_process_result_set(result);
8544   DIE_UNLESS(rc == 0);
8545 
8546   verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
8547                        "v1", "v1", current_db, 11, "0");
8548 
8549   mysql_free_result(result);
8550   myquery(mysql_query(mysql, "drop view v1"));
8551   myquery(mysql_query(mysql, "drop table t1"));
8552 }
8553 
8554 
8555 /* Test a memory ovverun bug */
8556 
test_mem_overun()8557 static void test_mem_overun()
8558 {
8559   char       buffer[10000], field[10];
8560   MYSQL_STMT *stmt;
8561   MYSQL_RES  *field_res;
8562   int        rc, i;
8563   ulong      length;
8564 
8565   myheader("test_mem_overun");
8566 
8567   /*
8568     Test a memory ovverun bug when a table had 1000 fields with
8569     a row of data
8570   */
8571   rc= mysql_query(mysql, "drop table if exists t_mem_overun");
8572   myquery(rc);
8573 
8574   strxmov(buffer, "create table t_mem_overun(", NullS);
8575   for (i= 0; i < 1000; i++)
8576   {
8577     sprintf(field, "c%d int", i);
8578     strxmov(buffer, buffer, field, ", ", NullS);
8579   }
8580   length= (ulong)strlen(buffer);
8581   buffer[length-2]= ')';
8582   buffer[--length]= '\0';
8583 
8584   strcat(buffer," ENGINE = MyISAM ");
8585   length= (ulong)strlen(buffer);
8586   rc= mysql_real_query(mysql, buffer, length);
8587   myquery(rc);
8588 
8589   strxmov(buffer, "insert into t_mem_overun values(", NullS);
8590   for (i= 0; i < 1000; i++)
8591   {
8592     strxmov(buffer, buffer, "1, ", NullS);
8593   }
8594   length= (ulong)strlen(buffer);
8595   buffer[length-2]= ')';
8596   buffer[--length]= '\0';
8597 
8598   rc= mysql_real_query(mysql, buffer, length);
8599   myquery(rc);
8600 
8601   rc= mysql_query(mysql, "select * from t_mem_overun");
8602   myquery(rc);
8603 
8604   rc= my_process_result(mysql);
8605   DIE_UNLESS(rc == 1);
8606 
8607   stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun");
8608   check_stmt(stmt);
8609 
8610   rc= mysql_stmt_execute(stmt);
8611   check_execute(stmt, rc);
8612 
8613   field_res= mysql_stmt_result_metadata(stmt);
8614   mytest(field_res);
8615 
8616   if (!opt_silent)
8617     fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
8618   DIE_UNLESS( 1000 == mysql_num_fields(field_res));
8619 
8620   rc= mysql_stmt_store_result(stmt);
8621   check_execute(stmt, rc);
8622 
8623   rc= mysql_stmt_fetch(stmt);
8624   check_execute(stmt, rc);
8625 
8626   rc= mysql_stmt_fetch(stmt);
8627   DIE_UNLESS(rc == MYSQL_NO_DATA);
8628 
8629   mysql_free_result(field_res);
8630 
8631   mysql_stmt_close(stmt);
8632 }
8633 
8634 
8635 /* Test mysql_stmt_free_result() */
8636 
test_free_result()8637 static void test_free_result()
8638 {
8639   MYSQL_STMT *stmt;
8640   MYSQL_BIND my_bind[1];
8641   char       c2[5];
8642   ulong      bl1, l2;
8643   int        rc, c1, bc1;
8644 
8645   myheader("test_free_result");
8646 
8647   rc= mysql_query(mysql, "drop table if exists test_free_result");
8648   myquery(rc);
8649 
8650   rc= mysql_query(mysql, "create table test_free_result("
8651                          "c1 int primary key auto_increment)");
8652   myquery(rc);
8653 
8654   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8655   myquery(rc);
8656 
8657   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8658   check_stmt(stmt);
8659 
8660   memset(my_bind, 0, sizeof(my_bind));
8661   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8662   my_bind[0].buffer= (void *)&bc1;
8663   my_bind[0].length= &bl1;
8664 
8665   rc= mysql_stmt_execute(stmt);
8666   check_execute(stmt, rc);
8667 
8668   rc= mysql_stmt_bind_result(stmt, my_bind);
8669   check_execute(stmt, rc);
8670 
8671   rc= mysql_stmt_fetch(stmt);
8672   check_execute(stmt, rc);
8673 
8674   c2[0]= '\0'; l2= 0;
8675   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8676   my_bind[0].buffer= (void *)c2;
8677   my_bind[0].buffer_length= 7;
8678   my_bind[0].is_null= 0;
8679   my_bind[0].length= &l2;
8680 
8681   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8682   check_execute(stmt, rc);
8683   if (!opt_silent)
8684     fprintf(stdout, "\n col 0: %s(%ld)", c2, (long)l2);
8685   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8686 
8687   rc= mysql_stmt_fetch(stmt);
8688   check_execute(stmt, rc);
8689 
8690   c1= 0, l2= 0;
8691   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8692   my_bind[0].buffer= (void *)&c1;
8693   my_bind[0].buffer_length= 0;
8694   my_bind[0].is_null= 0;
8695   my_bind[0].length= &l2;
8696 
8697   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8698   check_execute(stmt, rc);
8699   if (!opt_silent)
8700     fprintf(stdout, "\n col 0: %d(%ld)", c1, (long)l2);
8701   DIE_UNLESS(c1 == 2 && l2 == 4);
8702 
8703   rc= mysql_query(mysql, "drop table test_free_result");
8704   myquery_r(rc); /* error should be, COMMANDS OUT OF SYNC */
8705 
8706   rc= mysql_stmt_free_result(stmt);
8707   check_execute(stmt, rc);
8708 
8709   rc= mysql_query(mysql, "drop table test_free_result");
8710   myquery(rc);  /* should be successful */
8711 
8712   mysql_stmt_close(stmt);
8713 }
8714 
8715 
8716 /* Test mysql_stmt_store_result() */
8717 
test_free_store_result()8718 static void test_free_store_result()
8719 {
8720   MYSQL_STMT *stmt;
8721   MYSQL_BIND my_bind[1];
8722   char       c2[5];
8723   ulong      bl1, l2;
8724   int        rc, c1, bc1;
8725 
8726   myheader("test_free_store_result");
8727 
8728   rc= mysql_query(mysql, "drop table if exists test_free_result");
8729   myquery(rc);
8730 
8731   rc= mysql_query(mysql, "create table test_free_result(c1 int primary key auto_increment)");
8732   myquery(rc);
8733 
8734   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8735   myquery(rc);
8736 
8737   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8738   check_stmt(stmt);
8739 
8740   memset(my_bind, 0, sizeof(my_bind));
8741   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8742   my_bind[0].buffer= (void *)&bc1;
8743   my_bind[0].buffer_length= 0;
8744   my_bind[0].is_null= 0;
8745   my_bind[0].length= &bl1;
8746 
8747   rc= mysql_stmt_execute(stmt);
8748   check_execute(stmt, rc);
8749 
8750   rc= mysql_stmt_bind_result(stmt, my_bind);
8751   check_execute(stmt, rc);
8752 
8753   rc= mysql_stmt_store_result(stmt);
8754   check_execute(stmt, rc);
8755 
8756   rc= mysql_stmt_fetch(stmt);
8757   check_execute(stmt, rc);
8758 
8759   c2[0]= '\0'; l2= 0;
8760   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8761   my_bind[0].buffer= (void *)c2;
8762   my_bind[0].buffer_length= 7;
8763   my_bind[0].is_null= 0;
8764   my_bind[0].length= &l2;
8765 
8766   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8767   check_execute(stmt, rc);
8768   if (!opt_silent)
8769     fprintf(stdout, "\n col 1: %s(%ld)", c2, (long)l2);
8770   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8771 
8772   rc= mysql_stmt_fetch(stmt);
8773   check_execute(stmt, rc);
8774 
8775   c1= 0, l2= 0;
8776   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8777   my_bind[0].buffer= (void *)&c1;
8778   my_bind[0].buffer_length= 0;
8779   my_bind[0].is_null= 0;
8780   my_bind[0].length= &l2;
8781 
8782   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8783   check_execute(stmt, rc);
8784   if (!opt_silent)
8785     fprintf(stdout, "\n col 0: %d(%ld)", c1, (long)l2);
8786   DIE_UNLESS(c1 == 2 && l2 == 4);
8787 
8788   rc= mysql_stmt_free_result(stmt);
8789   check_execute(stmt, rc);
8790 
8791   rc= mysql_query(mysql, "drop table test_free_result");
8792   myquery(rc);
8793 
8794   mysql_stmt_close(stmt);
8795 }
8796 
8797 
8798 /* Test SQLmode */
8799 
test_sqlmode()8800 static void test_sqlmode()
8801 {
8802   MYSQL_STMT *stmt;
8803   MYSQL_BIND my_bind[2];
8804   char       c1[5], c2[5];
8805   int        rc;
8806   char query[MAX_TEST_QUERY_LENGTH];
8807 
8808   myheader("test_sqlmode");
8809 
8810   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping");
8811   myquery(rc);
8812 
8813   rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))");
8814   myquery(rc);
8815 
8816   /* PIPES_AS_CONCAT */
8817   my_stpcpy(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
8818   if (!opt_silent)
8819     fprintf(stdout, "\n With %s", query);
8820   rc= mysql_query(mysql, query);
8821   myquery(rc);
8822 
8823   my_stpcpy(query, "INSERT INTO test_piping VALUES(?||?)");
8824   if (!opt_silent)
8825     fprintf(stdout, "\n  query: %s", query);
8826   stmt= mysql_simple_prepare(mysql, query);
8827   check_stmt(stmt);
8828 
8829   if (!opt_silent)
8830     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8831 
8832   /*
8833     We need to memset bind structure because mysql_stmt_bind_param checks all
8834     its members.
8835   */
8836   memset(my_bind, 0, sizeof(my_bind));
8837 
8838   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8839   my_bind[0].buffer= (void *)c1;
8840   my_bind[0].buffer_length= 2;
8841 
8842   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8843   my_bind[1].buffer= (void *)c2;
8844   my_bind[1].buffer_length= 3;
8845 
8846   rc= mysql_stmt_bind_param(stmt, my_bind);
8847   check_execute(stmt, rc);
8848 
8849   my_stpcpy(c1, "My"); my_stpcpy(c2, "SQL");
8850   rc= mysql_stmt_execute(stmt);
8851   check_execute(stmt, rc);
8852   mysql_stmt_close(stmt);
8853 
8854   verify_col_data("test_piping", "name", "MySQL");
8855 
8856   rc= mysql_query(mysql, "DELETE FROM test_piping");
8857   myquery(rc);
8858 
8859   my_stpcpy(query, "SELECT connection_id    ()");
8860   if (!opt_silent)
8861     fprintf(stdout, "\n  query: %s", query);
8862   stmt= mysql_simple_prepare(mysql, query);
8863   check_stmt(stmt);
8864   mysql_stmt_close(stmt);
8865 
8866   /* ANSI */
8867   my_stpcpy(query, "SET SQL_MODE= \"ANSI\"");
8868   if (!opt_silent)
8869     fprintf(stdout, "\n With %s", query);
8870   rc= mysql_query(mysql, query);
8871   myquery(rc);
8872 
8873   my_stpcpy(query, "INSERT INTO test_piping VALUES(?||?)");
8874   if (!opt_silent)
8875     fprintf(stdout, "\n  query: %s", query);
8876   stmt= mysql_simple_prepare(mysql, query);
8877   check_stmt(stmt);
8878   if (!opt_silent)
8879     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8880 
8881   rc= mysql_stmt_bind_param(stmt, my_bind);
8882   check_execute(stmt, rc);
8883 
8884   my_stpcpy(c1, "My"); my_stpcpy(c2, "SQL");
8885   rc= mysql_stmt_execute(stmt);
8886   check_execute(stmt, rc);
8887 
8888   mysql_stmt_close(stmt);
8889   verify_col_data("test_piping", "name", "MySQL");
8890 
8891   /* ANSI mode spaces ... */
8892   my_stpcpy(query, "SELECT connection_id    ()");
8893   if (!opt_silent)
8894     fprintf(stdout, "\n  query: %s", query);
8895   stmt= mysql_simple_prepare(mysql, query);
8896   check_stmt(stmt);
8897 
8898   rc= mysql_stmt_execute(stmt);
8899   check_execute(stmt, rc);
8900 
8901   rc= mysql_stmt_fetch(stmt);
8902   check_execute(stmt, rc);
8903 
8904   rc= mysql_stmt_fetch(stmt);
8905   DIE_UNLESS(rc == MYSQL_NO_DATA);
8906   if (!opt_silent)
8907     fprintf(stdout, "\n  returned 1 row\n");
8908 
8909   mysql_stmt_close(stmt);
8910 
8911   /* IGNORE SPACE MODE */
8912   my_stpcpy(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
8913   if (!opt_silent)
8914     fprintf(stdout, "\n With %s", query);
8915   rc= mysql_query(mysql, query);
8916   myquery(rc);
8917 
8918   my_stpcpy(query, "SELECT connection_id    ()");
8919   if (!opt_silent)
8920     fprintf(stdout, "\n  query: %s", query);
8921   stmt= mysql_simple_prepare(mysql, query);
8922   check_stmt(stmt);
8923 
8924   rc= mysql_stmt_execute(stmt);
8925   check_execute(stmt, rc);
8926 
8927   rc= mysql_stmt_fetch(stmt);
8928   check_execute(stmt, rc);
8929 
8930   rc= mysql_stmt_fetch(stmt);
8931   DIE_UNLESS(rc == MYSQL_NO_DATA);
8932   if (!opt_silent)
8933     fprintf(stdout, "\n  returned 1 row");
8934 
8935   mysql_stmt_close(stmt);
8936 }
8937 
8938 
8939 /* Test for timestamp handling */
8940 
test_ts()8941 static void test_ts()
8942 {
8943   MYSQL_STMT *stmt;
8944   MYSQL_BIND my_bind[6];
8945   MYSQL_TIME ts;
8946   MYSQL_RES  *prep_res;
8947   char       strts[30];
8948   ulong      length;
8949   int        rc, field_count;
8950   char       name;
8951   char query[MAX_TEST_QUERY_LENGTH];
8952   const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
8953                             "SELECT a, b, c FROM test_ts WHERE %c=?",
8954                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
8955   myheader("test_ts");
8956 
8957   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts");
8958   myquery(rc);
8959 
8960   rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)");
8961   myquery(rc);
8962 
8963   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)");
8964   check_stmt(stmt);
8965 
8966   ts.year= 2003;
8967   ts.month= 07;
8968   ts.day= 12;
8969   ts.hour= 21;
8970   ts.minute= 07;
8971   ts.second= 46;
8972   ts.second_part= 0;
8973   length= (long)(my_stpcpy(strts, "2003-07-12 21:07:46") - strts);
8974 
8975   /*
8976     We need to memset bind structure because mysql_stmt_bind_param checks all
8977     its members.
8978   */
8979   memset(my_bind, 0, sizeof(my_bind));
8980 
8981   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
8982   my_bind[0].buffer= (void *)&ts;
8983   my_bind[0].buffer_length= (ulong)sizeof(ts);
8984 
8985   my_bind[2]= my_bind[1]= my_bind[0];
8986 
8987   my_bind[3].buffer_type= MYSQL_TYPE_STRING;
8988   my_bind[3].buffer= (void *)strts;
8989   my_bind[3].buffer_length= (ulong)sizeof(strts);
8990   my_bind[3].length= &length;
8991 
8992   my_bind[5]= my_bind[4]= my_bind[3];
8993 
8994   rc= mysql_stmt_bind_param(stmt, my_bind);
8995   check_execute(stmt, rc);
8996 
8997   rc= mysql_stmt_execute(stmt);
8998   check_execute(stmt, rc);
8999 
9000   mysql_stmt_close(stmt);
9001 
9002   verify_col_data("test_ts", "a", "2003-07-12");
9003   verify_col_data("test_ts", "b", "21:07:46");
9004   verify_col_data("test_ts", "c", "2003-07-12 21:07:46");
9005 
9006   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts");
9007   check_stmt(stmt);
9008 
9009   prep_res= mysql_stmt_result_metadata(stmt);
9010   mytest(prep_res);
9011 
9012   rc= mysql_stmt_execute(stmt);
9013   check_execute(stmt, rc);
9014 
9015   rc= my_process_stmt_result(stmt);
9016   DIE_UNLESS(rc == 2);
9017   field_count= mysql_num_fields(prep_res);
9018 
9019   mysql_free_result(prep_res);
9020   mysql_stmt_close(stmt);
9021 
9022   for (name= 'a'; field_count--; name++)
9023   {
9024     int row_count= 0;
9025 
9026     sprintf(query, queries[field_count], name);
9027 
9028     if (!opt_silent)
9029       fprintf(stdout, "\n  %s", query);
9030     stmt= mysql_simple_prepare(mysql, query);
9031     check_stmt(stmt);
9032 
9033     rc= mysql_stmt_bind_param(stmt, my_bind);
9034     check_execute(stmt, rc);
9035 
9036     rc= mysql_stmt_execute(stmt);
9037     check_execute(stmt, rc);
9038 
9039     while (mysql_stmt_fetch(stmt) == 0)
9040       row_count++;
9041 
9042     if (!opt_silent)
9043       fprintf(stdout, "\n   returned '%d' rows", row_count);
9044     DIE_UNLESS(row_count == 2);
9045     mysql_stmt_close(stmt);
9046   }
9047 }
9048 
9049 
9050 /* Test for bug #1500. */
9051 
test_bug1500()9052 static void test_bug1500()
9053 {
9054   MYSQL_STMT *stmt;
9055   MYSQL_BIND my_bind[3];
9056   int        rc;
9057   int32 int_data[3]= {2, 3, 4};
9058   const char *data;
9059 
9060   myheader("test_bug1500");
9061 
9062   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
9063   myquery(rc);
9064 
9065   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (i INT)");
9066   myquery(rc);
9067 
9068   rc= mysql_query(mysql, "INSERT INTO test_bg1500 VALUES (1), (2)");
9069   myquery(rc);
9070 
9071   rc= mysql_commit(mysql);
9072   myquery(rc);
9073 
9074   stmt= mysql_simple_prepare(mysql, "SELECT i FROM test_bg1500 WHERE i IN (?, ?, ?)");
9075   check_stmt(stmt);
9076   verify_param_count(stmt, 3);
9077 
9078   /*
9079     We need to memset bind structure because mysql_stmt_bind_param checks all
9080     its members.
9081   */
9082   memset(my_bind, 0, sizeof(my_bind));
9083 
9084   my_bind[0].buffer= (void *)int_data;
9085   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9086   my_bind[2]= my_bind[1]= my_bind[0];
9087   my_bind[1].buffer= (void *)(int_data + 1);
9088   my_bind[2].buffer= (void *)(int_data + 2);
9089 
9090   rc= mysql_stmt_bind_param(stmt, my_bind);
9091   check_execute(stmt, rc);
9092 
9093   rc= mysql_stmt_execute(stmt);
9094   check_execute(stmt, rc);
9095 
9096   rc= my_process_stmt_result(stmt);
9097   DIE_UNLESS(rc == 1);
9098 
9099   mysql_stmt_close(stmt);
9100 
9101   rc= mysql_query(mysql, "DROP TABLE test_bg1500");
9102   myquery(rc);
9103 
9104   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM");
9105   myquery(rc);
9106 
9107   rc= mysql_query(mysql,
9108         "INSERT INTO test_bg1500 VALUES ('Gravedigger'), ('Greed'), ('Hollow Dogs')");
9109   myquery(rc);
9110 
9111   rc= mysql_commit(mysql);
9112   myquery(rc);
9113 
9114   stmt= mysql_simple_prepare(mysql,
9115           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)");
9116   check_stmt(stmt);
9117 
9118   verify_param_count(stmt, 1);
9119 
9120   data= "Dogs";
9121   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9122   my_bind[0].buffer= (void *) data;
9123   my_bind[0].buffer_length= (ulong)strlen(data);
9124   my_bind[0].is_null= 0;
9125   my_bind[0].length= 0;
9126 
9127   rc= mysql_stmt_bind_param(stmt, my_bind);
9128   check_execute(stmt, rc);
9129 
9130   rc= mysql_stmt_execute(stmt);
9131   check_execute(stmt, rc);
9132 
9133   rc= my_process_stmt_result(stmt);
9134   DIE_UNLESS(rc == 1);
9135 
9136   mysql_stmt_close(stmt);
9137 
9138   /* This should work too */
9139   stmt= mysql_simple_prepare(mysql,
9140           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?, 'digger'))");
9141   check_stmt(stmt);
9142 
9143   verify_param_count(stmt, 1);
9144 
9145   data= "Grave";
9146   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9147   my_bind[0].buffer= (void *) data;
9148   my_bind[0].buffer_length= (ulong)strlen(data);
9149 
9150   rc= mysql_stmt_bind_param(stmt, my_bind);
9151   check_execute(stmt, rc);
9152 
9153   rc= mysql_stmt_execute(stmt);
9154   check_execute(stmt, rc);
9155 
9156   rc= my_process_stmt_result(stmt);
9157   DIE_UNLESS(rc == 1);
9158 
9159   mysql_stmt_close(stmt);
9160 }
9161 
9162 
test_bug1946()9163 static void test_bug1946()
9164 {
9165   MYSQL_STMT *stmt;
9166   int rc;
9167   const char *query= "INSERT INTO prepare_command VALUES (?)";
9168 
9169   myheader("test_bug1946");
9170 
9171   rc= mysql_query(mysql, "DROP TABLE IF EXISTS prepare_command");
9172   myquery(rc);
9173 
9174   rc= mysql_query(mysql, "CREATE TABLE prepare_command(ID INT)");
9175   myquery(rc);
9176 
9177   stmt= mysql_simple_prepare(mysql, query);
9178   check_stmt(stmt);
9179   rc= mysql_real_query(mysql, query, (ulong)strlen(query));
9180   DIE_UNLESS(rc != 0);
9181   if (!opt_silent)
9182     fprintf(stdout, "Got error (as expected):\n");
9183   myerror(NULL);
9184 
9185   mysql_stmt_close(stmt);
9186   rc= mysql_query(mysql, "DROP TABLE prepare_command");
9187 }
9188 
9189 
test_parse_error_and_bad_length()9190 static void test_parse_error_and_bad_length()
9191 {
9192   MYSQL_STMT *stmt;
9193   int rc;
9194 
9195   /* check that we get 4 syntax errors over the 4 calls */
9196   myheader("test_parse_error_and_bad_length");
9197 
9198   rc= mysql_query(mysql, "SHOW DATABAAAA");
9199   DIE_UNLESS(rc);
9200   if (!opt_silent)
9201     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9202   rc= mysql_real_query(mysql, "SHOW DATABASES", 12); // Incorrect length.
9203   DIE_UNLESS(rc);
9204   if (!opt_silent)
9205     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9206 
9207   stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA");
9208   DIE_UNLESS(!stmt);
9209   if (!opt_silent)
9210     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9211   stmt= mysql_stmt_init(mysql);
9212   DIE_UNLESS(stmt);
9213   rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 12); // Incorrect length.
9214   DIE_UNLESS(rc != 0);
9215   if (!opt_silent)
9216     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
9217   mysql_stmt_close(stmt);
9218 }
9219 
9220 
test_bug2247()9221 static void test_bug2247()
9222 {
9223   MYSQL_STMT *stmt;
9224   MYSQL_RES *res;
9225   int rc;
9226   int i;
9227   const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)";
9228   const char *insert= "INSERT INTO bug2247 VALUES (NULL)";
9229   const char *SELECT= "SELECT id FROM bug2247";
9230   const char *update= "UPDATE bug2247 SET id=id+10";
9231   const char *drop= "DROP TABLE IF EXISTS bug2247";
9232   ulonglong exp_count;
9233   enum { NUM_ROWS= 5 };
9234 
9235   myheader("test_bug2247");
9236 
9237   if (!opt_silent)
9238     fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
9239                   "mysql_query ... ");
9240   /* create table and insert few rows */
9241   rc= mysql_query(mysql, drop);
9242   myquery(rc);
9243 
9244   rc= mysql_query(mysql, create);
9245   myquery(rc);
9246 
9247   stmt= mysql_simple_prepare(mysql, insert);
9248   check_stmt(stmt);
9249   for (i= 0; i < NUM_ROWS; ++i)
9250   {
9251     rc= mysql_stmt_execute(stmt);
9252     check_execute(stmt, rc);
9253   }
9254   exp_count= mysql_stmt_affected_rows(stmt);
9255   DIE_UNLESS(exp_count == 1);
9256 
9257   rc= mysql_query(mysql, SELECT);
9258   myquery(rc);
9259   /*
9260     mysql_store_result overwrites mysql->affected_rows. Check that
9261     mysql_stmt_affected_rows() returns the same value, whereas
9262     mysql_affected_rows() value is correct.
9263   */
9264   res= mysql_store_result(mysql);
9265   mytest(res);
9266 
9267   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9268   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9269 
9270   rc= mysql_query(mysql, update);
9271   myquery(rc);
9272   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9273   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9274 
9275   mysql_free_result(res);
9276   mysql_stmt_close(stmt);
9277 
9278   /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */
9279   stmt= mysql_simple_prepare(mysql, SELECT);
9280   check_stmt(stmt);
9281 
9282   rc= mysql_stmt_execute(stmt);
9283   check_execute(stmt, rc);
9284   rc= mysql_stmt_store_result(stmt);
9285   check_execute(stmt, rc);
9286   exp_count= mysql_stmt_affected_rows(stmt);
9287   DIE_UNLESS(exp_count == NUM_ROWS);
9288 
9289   rc= mysql_query(mysql, insert);
9290   myquery(rc);
9291   DIE_UNLESS(mysql_affected_rows(mysql) == 1);
9292   DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count);
9293 
9294   mysql_stmt_close(stmt);
9295   if (!opt_silent)
9296     fprintf(stdout, "OK");
9297 }
9298 
9299 
test_subqueries()9300 static void test_subqueries()
9301 {
9302   MYSQL_STMT *stmt;
9303   int rc, i;
9304   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";
9305 
9306   myheader("test_subqueries");
9307 
9308   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9309   myquery(rc);
9310 
9311   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9312   myquery(rc);
9313 
9314   rc= mysql_query(mysql,
9315                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9316   myquery(rc);
9317 
9318   rc= mysql_query(mysql, "create table t2 select * from t1;");
9319   myquery(rc);
9320 
9321   stmt= mysql_simple_prepare(mysql, query);
9322   check_stmt(stmt);
9323   for (i= 0; i < 3; i++)
9324   {
9325     rc= mysql_stmt_execute(stmt);
9326     check_execute(stmt, rc);
9327     rc= my_process_stmt_result(stmt);
9328     DIE_UNLESS(rc == 5);
9329   }
9330   mysql_stmt_close(stmt);
9331 
9332   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9333   myquery(rc);
9334 }
9335 
9336 
test_bad_union()9337 static void test_bad_union()
9338 {
9339   MYSQL_STMT *stmt;
9340   const char *query= "SELECT 1, 2 union SELECT 1";
9341 
9342   myheader("test_bad_union");
9343 
9344   stmt= mysql_simple_prepare(mysql, query);
9345   DIE_UNLESS(stmt == 0);
9346   myerror(NULL);
9347 }
9348 
9349 
test_distinct()9350 static void test_distinct()
9351 {
9352   MYSQL_STMT *stmt;
9353   int rc, i;
9354   const char *query=
9355     "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a";
9356 
9357   myheader("test_distinct");
9358 
9359   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9360   myquery(rc);
9361 
9362   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9363   myquery(rc);
9364 
9365   rc= mysql_query(mysql,
9366                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), \
9367 (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);");
9368   myquery(rc);
9369 
9370   for (i= 0; i < 3; i++)
9371   {
9372     stmt= mysql_simple_prepare(mysql, query);
9373     check_stmt(stmt);
9374     rc= mysql_stmt_execute(stmt);
9375     check_execute(stmt, rc);
9376     rc= my_process_stmt_result(stmt);
9377     DIE_UNLESS(rc == 5);
9378     mysql_stmt_close(stmt);
9379   }
9380 
9381   rc= mysql_query(mysql, "DROP TABLE t1");
9382   myquery(rc);
9383 }
9384 
9385 
9386 /*
9387   Test for bug#2248 "mysql_fetch without prior mysql_stmt_execute hangs"
9388 */
9389 
test_bug2248()9390 static void test_bug2248()
9391 {
9392   MYSQL_STMT *stmt;
9393   int rc;
9394   const char *query1= "SELECT DATABASE()";
9395   const char *query2= "INSERT INTO test_bug2248 VALUES (10)";
9396 
9397   myheader("test_bug2248");
9398 
9399   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248");
9400   myquery(rc);
9401 
9402   rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)");
9403   myquery(rc);
9404 
9405   stmt= mysql_simple_prepare(mysql, query1);
9406   check_stmt(stmt);
9407 
9408   /* This should not hang */
9409   rc= mysql_stmt_fetch(stmt);
9410   check_execute_r(stmt, rc);
9411 
9412   /* And this too */
9413   rc= mysql_stmt_store_result(stmt);
9414   check_execute_r(stmt, rc);
9415 
9416   mysql_stmt_close(stmt);
9417 
9418   stmt= mysql_simple_prepare(mysql, query2);
9419   check_stmt(stmt);
9420 
9421   rc= mysql_stmt_execute(stmt);
9422   check_execute(stmt, rc);
9423 
9424   /* This too should not hang but should return proper error */
9425   rc= mysql_stmt_fetch(stmt);
9426   DIE_UNLESS(rc == 1);
9427 
9428   /* This too should not hang but should not bark */
9429   rc= mysql_stmt_store_result(stmt);
9430   check_execute(stmt, rc);
9431 
9432   /* This should return proper error */
9433   rc= mysql_stmt_fetch(stmt);
9434   check_execute_r(stmt, rc);
9435   DIE_UNLESS(rc == 1);
9436 
9437   mysql_stmt_close(stmt);
9438 
9439   rc= mysql_query(mysql, "DROP TABLE test_bug2248");
9440   myquery(rc);
9441 }
9442 
9443 
test_subqueries_ref()9444 static void test_subqueries_ref()
9445 {
9446   MYSQL_STMT *stmt;
9447   int rc, i;
9448   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)";
9449 
9450   myheader("test_subqueries_ref");
9451 
9452   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9453   myquery(rc);
9454 
9455   rc= mysql_query(mysql, "CREATE TABLE t1 (a int);");
9456   myquery(rc);
9457 
9458   rc= mysql_query(mysql,
9459                   "insert into t1 values (1), (2), (3), (4), (5);");
9460   myquery(rc);
9461 
9462   stmt= mysql_simple_prepare(mysql, query);
9463   check_stmt(stmt);
9464   for (i= 0; i < 3; i++)
9465   {
9466     rc= mysql_stmt_execute(stmt);
9467     check_execute(stmt, rc);
9468     rc= my_process_stmt_result(stmt);
9469     DIE_UNLESS(rc == 1);
9470   }
9471   mysql_stmt_close(stmt);
9472 
9473   rc= mysql_query(mysql, "DROP TABLE t1");
9474   myquery(rc);
9475 }
9476 
9477 
test_union()9478 static void test_union()
9479 {
9480   MYSQL_STMT *stmt;
9481   int rc;
9482 
9483   myheader("test_union");
9484 
9485   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9486   myquery(rc);
9487 
9488   rc= mysql_query(mysql,
9489                   "CREATE TABLE t1 "
9490                   "(id INTEGER NOT NULL PRIMARY KEY, "
9491                   " name VARCHAR(20) NOT NULL)");
9492   myquery(rc);
9493   rc= mysql_query(mysql,
9494                   "INSERT INTO t1 (id, name) VALUES "
9495                   "(2, 'Ja'), (3, 'Ede'), "
9496                   "(4, 'Haag'), (5, 'Kabul'), "
9497                   "(6, 'Almere'), (7, 'Utrecht'), "
9498                   "(8, 'Qandahar'), (9, 'Amsterdam'), "
9499                   "(10, 'Amersfoort'), (11, 'Constantine')");
9500   myquery(rc);
9501   rc= mysql_query(mysql,
9502                   "CREATE TABLE t2 "
9503                   "(id INTEGER NOT NULL PRIMARY KEY, "
9504                   " name VARCHAR(20) NOT NULL)");
9505   myquery(rc);
9506   rc= mysql_query(mysql,
9507                   "INSERT INTO t2 (id, name) VALUES "
9508                   "(4, 'Guam'), (5, 'Aruba'), "
9509                   "(6, 'Angola'), (7, 'Albania'), "
9510                   "(8, 'Anguilla'), (9, 'Argentina'), "
9511                   "(10, 'Azerbaijan'), (11, 'Afghanistan'), "
9512                   "(12, 'Burkina Faso'), (13, 'Faroe Islands')");
9513   myquery(rc);
9514 
9515   stmt= mysql_simple_prepare(mysql,
9516                              "SELECT t1.name FROM t1 UNION "
9517                              "SELECT t2.name FROM t2");
9518   check_stmt(stmt);
9519 
9520   rc= mysql_stmt_execute(stmt);
9521   check_execute(stmt, rc);
9522   rc= my_process_stmt_result(stmt);
9523   DIE_UNLESS(rc == 20);
9524   mysql_stmt_close(stmt);
9525 
9526   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9527   myquery(rc);
9528 }
9529 
9530 
test_bug3117()9531 static void test_bug3117()
9532 {
9533   MYSQL_STMT *stmt;
9534   MYSQL_BIND buffer;
9535   longlong lii;
9536   ulong length;
9537   my_bool is_null;
9538   int rc;
9539 
9540   myheader("test_bug3117");
9541 
9542   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9543   myquery(rc);
9544 
9545   rc= mysql_query(mysql, "CREATE TABLE t1 (id int auto_increment primary key)");
9546   myquery(rc);
9547 
9548   stmt= mysql_simple_prepare(mysql, "SELECT LAST_INSERT_ID()");
9549   check_stmt(stmt);
9550 
9551   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9552   myquery(rc);
9553 
9554   rc= mysql_stmt_execute(stmt);
9555   check_execute(stmt, rc);
9556 
9557   memset(&buffer, 0, sizeof(buffer));
9558   buffer.buffer_type= MYSQL_TYPE_LONGLONG;
9559   buffer.buffer_length= (ulong)sizeof(lii);
9560   buffer.buffer= (void *)&lii;
9561   buffer.length= &length;
9562   buffer.is_null= &is_null;
9563 
9564   rc= mysql_stmt_bind_result(stmt, &buffer);
9565   check_execute(stmt, rc);
9566 
9567   rc= mysql_stmt_store_result(stmt);
9568   check_execute(stmt, rc);
9569 
9570   rc= mysql_stmt_fetch(stmt);
9571   check_execute(stmt, rc);
9572 
9573   DIE_UNLESS(is_null == 0 && lii == 1);
9574   if (!opt_silent)
9575     fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
9576 
9577   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9578   myquery(rc);
9579 
9580   rc= mysql_stmt_execute(stmt);
9581   check_execute(stmt, rc);
9582 
9583   rc= mysql_stmt_fetch(stmt);
9584   check_execute(stmt, rc);
9585 
9586   DIE_UNLESS(is_null == 0 && lii == 2);
9587   if (!opt_silent)
9588     fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
9589 
9590   mysql_stmt_close(stmt);
9591 
9592   rc= mysql_query(mysql, "DROP TABLE t1");
9593   myquery(rc);
9594 }
9595 
9596 
test_join()9597 static void test_join()
9598 {
9599   MYSQL_STMT *stmt;
9600   int rc, i, j;
9601   const char *query[]= {"SELECT * FROM t2 join t1 on (t1.a=t2.a)",
9602                         "SELECT * FROM t2 natural join t1",
9603                         "SELECT * FROM t2 join t1 using(a)",
9604                         "SELECT * FROM t2 left join t1 on(t1.a=t2.a)",
9605                         "SELECT * FROM t2 natural left join t1",
9606                         "SELECT * FROM t2 left join t1 using(a)",
9607                         "SELECT * FROM t2 right join t1 on(t1.a=t2.a)",
9608                         "SELECT * FROM t2 natural right join t1",
9609                         "SELECT * FROM t2 right join t1 using(a)"};
9610 
9611   myheader("test_join");
9612 
9613   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9614   myquery(rc);
9615 
9616   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9617   myquery(rc);
9618 
9619   rc= mysql_query(mysql,
9620                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9621   myquery(rc);
9622 
9623   rc= mysql_query(mysql, "CREATE TABLE t2 (a int , c int);");
9624   myquery(rc);
9625 
9626   rc= mysql_query(mysql,
9627                   "insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9628   myquery(rc);
9629 
9630   for (j= 0; j < 9; j++)
9631   {
9632     stmt= mysql_simple_prepare(mysql, query[j]);
9633     check_stmt(stmt);
9634     for (i= 0; i < 3; i++)
9635     {
9636       rc= mysql_stmt_execute(stmt);
9637       check_execute(stmt, rc);
9638       rc= my_process_stmt_result(stmt);
9639       DIE_UNLESS(rc == 5);
9640     }
9641     mysql_stmt_close(stmt);
9642   }
9643 
9644   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9645   myquery(rc);
9646 }
9647 
9648 
test_selecttmp()9649 static void test_selecttmp()
9650 {
9651   MYSQL_STMT *stmt;
9652   int rc, i;
9653   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";
9654 
9655   myheader("test_select_tmp");
9656 
9657   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3");
9658   myquery(rc);
9659 
9660   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9661   myquery(rc);
9662 
9663   rc= mysql_query(mysql, "create table t2 (a int, b int);");
9664   myquery(rc);
9665 
9666   rc= mysql_query(mysql, "create table t3 (a int, b int);");
9667   myquery(rc);
9668 
9669   rc= mysql_query(mysql,
9670                   "insert into t1 values (0, 100), (1, 2), (1, 3), (2, 2), (2, 7), \
9671 (2, -1), (3, 10);");
9672   myquery(rc);
9673   rc= mysql_query(mysql,
9674                   "insert into t2 values (0, 0), (1, 1), (2, 1), (3, 1), (4, 1);");
9675   myquery(rc);
9676   rc= mysql_query(mysql,
9677                   "insert into t3 values (3, 3), (2, 2), (1, 1);");
9678   myquery(rc);
9679 
9680   stmt= mysql_simple_prepare(mysql, query);
9681   check_stmt(stmt);
9682   for (i= 0; i < 3; i++)
9683   {
9684     rc= mysql_stmt_execute(stmt);
9685     check_execute(stmt, rc);
9686     rc= my_process_stmt_result(stmt);
9687     DIE_UNLESS(rc == 3);
9688   }
9689   mysql_stmt_close(stmt);
9690 
9691   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3");
9692   myquery(rc);
9693 }
9694 
9695 
test_create_drop()9696 static void test_create_drop()
9697 {
9698   MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select;
9699   char *query;
9700   int rc, i;
9701   myheader("test_table_manipulation");
9702 
9703   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9704   myquery(rc);
9705 
9706   rc= mysql_query(mysql, "create table t2 (a int);");
9707   myquery(rc);
9708 
9709   rc= mysql_query(mysql, "create table t1 (a int);");
9710   myquery(rc);
9711 
9712   rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);");
9713   myquery(rc);
9714 
9715   query= (char*)"create table t1 (a int)";
9716   stmt_create= mysql_simple_prepare(mysql, query);
9717   check_stmt(stmt_create);
9718 
9719   query= (char*)"drop table t1";
9720   stmt_drop= mysql_simple_prepare(mysql, query);
9721   check_stmt(stmt_drop);
9722 
9723   query= (char*)"select a in (select a from t2) from t1";
9724   stmt_select= mysql_simple_prepare(mysql, query);
9725   check_stmt(stmt_select);
9726 
9727   rc= mysql_query(mysql, "DROP TABLE t1");
9728   myquery(rc);
9729 
9730   query= (char*)"create table t1 select a from t2";
9731   stmt_create_select= mysql_simple_prepare(mysql, query);
9732   check_stmt(stmt_create_select);
9733 
9734   for (i= 0; i < 3; i++)
9735   {
9736     rc= mysql_stmt_execute(stmt_create);
9737     check_execute(stmt_create, rc);
9738     if (!opt_silent)
9739       fprintf(stdout, "created %i\n", i);
9740 
9741     rc= mysql_stmt_execute(stmt_select);
9742     check_execute(stmt_select, rc);
9743     rc= my_process_stmt_result(stmt_select);
9744     DIE_UNLESS(rc == 0);
9745 
9746     rc= mysql_stmt_execute(stmt_drop);
9747     check_execute(stmt_drop, rc);
9748     if (!opt_silent)
9749       fprintf(stdout, "dropped %i\n", i);
9750 
9751     rc= mysql_stmt_execute(stmt_create_select);
9752     check_execute(stmt_create, rc);
9753     if (!opt_silent)
9754       fprintf(stdout, "created select %i\n", i);
9755 
9756     rc= mysql_stmt_execute(stmt_select);
9757     check_execute(stmt_select, rc);
9758     rc= my_process_stmt_result(stmt_select);
9759     DIE_UNLESS(rc == 3);
9760 
9761     rc= mysql_stmt_execute(stmt_drop);
9762     check_execute(stmt_drop, rc);
9763     if (!opt_silent)
9764       fprintf(stdout, "dropped %i\n", i);
9765   }
9766 
9767   mysql_stmt_close(stmt_create);
9768   mysql_stmt_close(stmt_drop);
9769   mysql_stmt_close(stmt_select);
9770   mysql_stmt_close(stmt_create_select);
9771 
9772   rc= mysql_query(mysql, "DROP TABLE t2");
9773   myquery(rc);
9774 }
9775 
9776 
test_rename()9777 static void test_rename()
9778 {
9779   MYSQL_STMT *stmt;
9780   const char *query= "rename table t1 to t2, t3 to t4";
9781   int rc;
9782   myheader("test_table_rename");
9783 
9784   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
9785   myquery(rc);
9786 
9787   stmt= mysql_simple_prepare(mysql, query);
9788   check_stmt(stmt);
9789 
9790   rc= mysql_query(mysql, "create table t1 (a int)");
9791   myquery(rc);
9792 
9793   rc= mysql_stmt_execute(stmt);
9794   check_execute_r(stmt, rc);
9795   if (!opt_silent)
9796     fprintf(stdout, "rename without t3\n");
9797 
9798   rc= mysql_query(mysql, "create table t3 (a int)");
9799   myquery(rc);
9800 
9801   rc= mysql_stmt_execute(stmt);
9802   check_execute(stmt, rc);
9803   if (!opt_silent)
9804     fprintf(stdout, "rename with t3\n");
9805 
9806   rc= mysql_stmt_execute(stmt);
9807   check_execute_r(stmt, rc);
9808   if (!opt_silent)
9809     fprintf(stdout, "rename renamed\n");
9810 
9811   rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3");
9812   myquery(rc);
9813 
9814   rc= mysql_stmt_execute(stmt);
9815   check_execute(stmt, rc);
9816   if (!opt_silent)
9817     fprintf(stdout, "rename reverted\n");
9818 
9819   mysql_stmt_close(stmt);
9820 
9821   rc= mysql_query(mysql, "DROP TABLE t2, t4");
9822   myquery(rc);
9823 }
9824 
9825 
test_do_set()9826 static void test_do_set()
9827 {
9828   MYSQL_STMT *stmt_do, *stmt_set;
9829   char *query;
9830   int rc, i;
9831   myheader("test_do_set");
9832 
9833   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9834   myquery(rc);
9835 
9836   rc= mysql_query(mysql, "create table t1 (a int)");
9837   myquery(rc);
9838 
9839   query= (char*)"do @var:=(1 in (select * from t1))";
9840   stmt_do= mysql_simple_prepare(mysql, query);
9841   check_stmt(stmt_do);
9842 
9843   query= (char*)"set @var=(1 in (select * from t1))";
9844   stmt_set= mysql_simple_prepare(mysql, query);
9845   check_stmt(stmt_set);
9846 
9847   for (i= 0; i < 3; i++)
9848   {
9849     rc= mysql_stmt_execute(stmt_do);
9850     check_execute(stmt_do, rc);
9851     if (!opt_silent)
9852       fprintf(stdout, "do %i\n", i);
9853     rc= mysql_stmt_execute(stmt_set);
9854     check_execute(stmt_set, rc);
9855     if (!opt_silent)
9856       fprintf(stdout, "set %i\n", i);
9857   }
9858 
9859   mysql_stmt_close(stmt_do);
9860   mysql_stmt_close(stmt_set);
9861 }
9862 
9863 
test_multi()9864 static void test_multi()
9865 {
9866   MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2;
9867   char *query;
9868   MYSQL_BIND my_bind[1];
9869   int rc, i;
9870   int32 param= 1;
9871   ulong length= 1;
9872   myheader("test_multi");
9873 
9874   /*
9875     We need to memset bind structure because mysql_stmt_bind_param checks all
9876     its members.
9877   */
9878   memset(my_bind, 0, sizeof(my_bind));
9879 
9880   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9881   my_bind[0].buffer= (void *)&param;
9882   my_bind[0].length= &length;
9883 
9884   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9885   myquery(rc);
9886 
9887   rc= mysql_query(mysql, "create table t1 (a int, b int)");
9888   myquery(rc);
9889 
9890   rc= mysql_query(mysql, "create table t2 (a int, b int)");
9891   myquery(rc);
9892 
9893   rc= mysql_query(mysql, "insert into t1 values (3, 3), (2, 2), (1, 1)");
9894   myquery(rc);
9895 
9896   rc= mysql_query(mysql, "insert into t2 values (3, 3), (2, 2), (1, 1)");
9897   myquery(rc);
9898 
9899   query= (char*)"delete t1, t2 from t1, t2 where t1.a=t2.a and t1.b=10";
9900   stmt_delete= mysql_simple_prepare(mysql, query);
9901   check_stmt(stmt_delete);
9902 
9903   query= (char*)"update t1, t2 set t1.b=10, t2.b=10 where t1.a=t2.a and t1.b=?";
9904   stmt_update= mysql_simple_prepare(mysql, query);
9905   check_stmt(stmt_update);
9906 
9907   query= (char*)"select * from t1";
9908   stmt_select1= mysql_simple_prepare(mysql, query);
9909   check_stmt(stmt_select1);
9910 
9911   query= (char*)"select * from t2";
9912   stmt_select2= mysql_simple_prepare(mysql, query);
9913   check_stmt(stmt_select2);
9914 
9915   for(i= 0; i < 3; i++)
9916   {
9917     rc= mysql_stmt_bind_param(stmt_update, my_bind);
9918     check_execute(stmt_update, rc);
9919 
9920     rc= mysql_stmt_execute(stmt_update);
9921     check_execute(stmt_update, rc);
9922     if (!opt_silent)
9923       fprintf(stdout, "update %ld\n", (long) param);
9924 
9925     rc= mysql_stmt_execute(stmt_delete);
9926     check_execute(stmt_delete, rc);
9927     if (!opt_silent)
9928       fprintf(stdout, "delete %ld\n", (long) param);
9929 
9930     rc= mysql_stmt_execute(stmt_select1);
9931     check_execute(stmt_select1, rc);
9932     rc= my_process_stmt_result(stmt_select1);
9933     DIE_UNLESS(rc == 3-param);
9934 
9935     rc= mysql_stmt_execute(stmt_select2);
9936     check_execute(stmt_select2, rc);
9937     rc= my_process_stmt_result(stmt_select2);
9938     DIE_UNLESS(rc == 3-param);
9939 
9940     param++;
9941   }
9942 
9943   mysql_stmt_close(stmt_delete);
9944   mysql_stmt_close(stmt_update);
9945   mysql_stmt_close(stmt_select1);
9946   mysql_stmt_close(stmt_select2);
9947   rc= mysql_query(mysql, "drop table t1, t2");
9948   myquery(rc);
9949 }
9950 
9951 
test_insert_select()9952 static void test_insert_select()
9953 {
9954   MYSQL_STMT *stmt_insert, *stmt_select;
9955   char *query;
9956   int rc;
9957   uint i;
9958   myheader("test_insert_select");
9959 
9960   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9961   myquery(rc);
9962 
9963   rc= mysql_query(mysql, "create table t1 (a int)");
9964   myquery(rc);
9965 
9966   rc= mysql_query(mysql, "create table t2 (a int)");
9967   myquery(rc);
9968 
9969   rc= mysql_query(mysql, "insert into t2 values (1)");
9970   myquery(rc);
9971 
9972   query= (char*)"insert into t1 select a from t2";
9973   stmt_insert= mysql_simple_prepare(mysql, query);
9974   check_stmt(stmt_insert);
9975 
9976   query= (char*)"select * from t1";
9977   stmt_select= mysql_simple_prepare(mysql, query);
9978   check_stmt(stmt_select);
9979 
9980   for(i= 0; i < 3; i++)
9981   {
9982     rc= mysql_stmt_execute(stmt_insert);
9983     check_execute(stmt_insert, rc);
9984     if (!opt_silent)
9985       fprintf(stdout, "insert %u\n", i);
9986 
9987     rc= mysql_stmt_execute(stmt_select);
9988     check_execute(stmt_select, rc);
9989     rc= my_process_stmt_result(stmt_select);
9990     DIE_UNLESS(rc == (int)(i+1));
9991   }
9992 
9993   mysql_stmt_close(stmt_insert);
9994   mysql_stmt_close(stmt_select);
9995   rc= mysql_query(mysql, "drop table t1, t2");
9996   myquery(rc);
9997 }
9998 
9999 
test_bind_nagative()10000 static void test_bind_nagative()
10001 {
10002   MYSQL_STMT *stmt_insert;
10003   char *query;
10004   int rc;
10005   MYSQL_BIND      my_bind[1];
10006   int32           my_val= 0;
10007   ulong           my_length= 0L;
10008   my_bool         my_null= FALSE;
10009   myheader("test_insert_select");
10010 
10011   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10012   myquery(rc);
10013 
10014   rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)");
10015   myquery(rc);
10016 
10017   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)");
10018   myquery(rc);
10019 
10020   query= (char*)"INSERT INTO t1 VALUES (?)";
10021   stmt_insert= mysql_simple_prepare(mysql, query);
10022   check_stmt(stmt_insert);
10023 
10024   /* bind parameters */
10025   memset(my_bind, 0, sizeof(my_bind));
10026 
10027   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10028   my_bind[0].buffer= (void *)&my_val;
10029   my_bind[0].length= &my_length;
10030   my_bind[0].is_null= (char*)&my_null;
10031 
10032   rc= mysql_stmt_bind_param(stmt_insert, my_bind);
10033   check_execute(stmt_insert, rc);
10034 
10035   my_val= -1;
10036   rc= mysql_stmt_execute(stmt_insert);
10037   check_execute(stmt_insert, rc);
10038 
10039   mysql_stmt_close(stmt_insert);
10040   rc= mysql_query(mysql, "drop table t1");
10041   myquery(rc);
10042 }
10043 
10044 
test_derived()10045 static void test_derived()
10046 {
10047   MYSQL_STMT *stmt;
10048   int rc, i;
10049   MYSQL_BIND      my_bind[1];
10050   int32           my_val= 0;
10051   ulong           my_length= 0L;
10052   my_bool         my_null= FALSE;
10053   const char *query=
10054     "select count(1) from (select f.id from t1 f where f.id=?) as x";
10055 
10056   myheader("test_derived");
10057 
10058   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10059   myquery(rc);
10060 
10061   rc= mysql_query(mysql, "create table t1 (id  int(8), primary key (id)) \
10062 ENGINE=InnoDB DEFAULT CHARSET=utf8");
10063   myquery(rc);
10064 
10065   rc= mysql_query(mysql, "insert into t1 values (1)");
10066   myquery(rc);
10067 
10068   stmt= mysql_simple_prepare(mysql, query);
10069   check_stmt(stmt);
10070   /*
10071     We need to memset bind structure because mysql_stmt_bind_param checks all
10072     its members.
10073   */
10074   memset(my_bind, 0, sizeof(my_bind));
10075 
10076   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10077   my_bind[0].buffer= (void *)&my_val;
10078   my_bind[0].length= &my_length;
10079   my_bind[0].is_null= (char*)&my_null;
10080   my_val= 1;
10081   rc= mysql_stmt_bind_param(stmt, my_bind);
10082   check_execute(stmt, rc);
10083 
10084   for (i= 0; i < 3; i++)
10085   {
10086     rc= mysql_stmt_execute(stmt);
10087     check_execute(stmt, rc);
10088     rc= my_process_stmt_result(stmt);
10089     DIE_UNLESS(rc == 1);
10090   }
10091   mysql_stmt_close(stmt);
10092 
10093   rc= mysql_query(mysql, "DROP TABLE t1");
10094   myquery(rc);
10095 }
10096 
10097 
test_xjoin()10098 static void test_xjoin()
10099 {
10100   MYSQL_STMT *stmt;
10101   int rc, i;
10102   const char *query=
10103     "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";
10104 
10105   myheader("test_xjoin");
10106 
10107   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
10108   myquery(rc);
10109 
10110   rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10111   myquery(rc);
10112 
10113   rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10114   myquery(rc);
10115 
10116   rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
10117   myquery(rc);
10118 
10119   rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10120   myquery(rc);
10121 
10122   rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)");
10123   myquery(rc);
10124 
10125   rc= mysql_query(mysql, "insert into t1 values (1, 1, 'aaa'), (2, null, 'bbb')");
10126   myquery(rc);
10127 
10128   rc= mysql_query(mysql, "insert into t2 values (1, 2, 'ccc')");
10129   myquery(rc);
10130 
10131   rc= mysql_query(mysql, "insert into t4 values (1, 'Name1'), (2, null)");
10132   myquery(rc);
10133 
10134   stmt= mysql_simple_prepare(mysql, query);
10135   check_stmt(stmt);
10136 
10137   for (i= 0; i < 3; i++)
10138   {
10139     rc= mysql_stmt_execute(stmt);
10140     check_execute(stmt, rc);
10141     rc= my_process_stmt_result(stmt);
10142     DIE_UNLESS(rc == 1);
10143   }
10144   mysql_stmt_close(stmt);
10145 
10146   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3, t4");
10147   myquery(rc);
10148 }
10149 
10150 
test_bug3035()10151 static void test_bug3035()
10152 {
10153   MYSQL_STMT *stmt;
10154   int rc;
10155   MYSQL_BIND bind_array[12], *my_bind= bind_array, *bind_end= my_bind + 12;
10156   int8 int8_val;
10157   uint8 uint8_val;
10158   int16 int16_val;
10159   uint16 uint16_val;
10160   int32 int32_val;
10161   uint32 uint32_val;
10162   longlong int64_val;
10163   ulonglong uint64_val;
10164   double double_val, udouble_val, double_tmp;
10165   char longlong_as_string[22], ulonglong_as_string[22];
10166 
10167   /* mins and maxes */
10168   const int8 int8_min= -128;
10169   const int8 int8_max= 127;
10170   const uint8 uint8_min= 0;
10171   const uint8 uint8_max= 255;
10172 
10173   const int16 int16_min= -32768;
10174   const int16 int16_max= 32767;
10175   const uint16 uint16_min= 0;
10176   const uint16 uint16_max= 65535;
10177 
10178   const int32 int32_max= 2147483647L;
10179   const int32 int32_min= -int32_max - 1;
10180   const uint32 uint32_min= 0;
10181   const uint32 uint32_max= 4294967295U;
10182 
10183   /* it might not work okay everyplace */
10184   const longlong int64_max= 9223372036854775807LL;
10185   const longlong int64_min= -int64_max - 1;
10186 
10187   const ulonglong uint64_min= 0U;
10188   const ulonglong uint64_max= 18446744073709551615ULL;
10189 
10190   const char *stmt_text;
10191 
10192   myheader("test_bug3035");
10193 
10194   stmt_text= "DROP TABLE IF EXISTS t1";
10195   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10196   myquery(rc);
10197 
10198   stmt_text= "CREATE TABLE t1 (i8 TINYINT, ui8 TINYINT UNSIGNED, "
10199                               "i16 SMALLINT, ui16 SMALLINT UNSIGNED, "
10200                               "i32 INT, ui32 INT UNSIGNED, "
10201                               "i64 BIGINT, ui64 BIGINT UNSIGNED, "
10202                               "id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT)";
10203   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10204   myquery(rc);
10205 
10206   memset(bind_array, 0, sizeof(bind_array));
10207 
10208   for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10209     my_bind->error= &my_bind->error_value;
10210 
10211   bind_array[0].buffer_type= MYSQL_TYPE_TINY;
10212   bind_array[0].buffer= (void *) &int8_val;
10213 
10214   bind_array[1].buffer_type= MYSQL_TYPE_TINY;
10215   bind_array[1].buffer= (void *) &uint8_val;
10216   bind_array[1].is_unsigned= 1;
10217 
10218   bind_array[2].buffer_type= MYSQL_TYPE_SHORT;
10219   bind_array[2].buffer= (void *) &int16_val;
10220 
10221   bind_array[3].buffer_type= MYSQL_TYPE_SHORT;
10222   bind_array[3].buffer= (void *) &uint16_val;
10223   bind_array[3].is_unsigned= 1;
10224 
10225   bind_array[4].buffer_type= MYSQL_TYPE_LONG;
10226   bind_array[4].buffer= (void *) &int32_val;
10227 
10228   bind_array[5].buffer_type= MYSQL_TYPE_LONG;
10229   bind_array[5].buffer= (void *) &uint32_val;
10230   bind_array[5].is_unsigned= 1;
10231 
10232   bind_array[6].buffer_type= MYSQL_TYPE_LONGLONG;
10233   bind_array[6].buffer= (void *) &int64_val;
10234 
10235   bind_array[7].buffer_type= MYSQL_TYPE_LONGLONG;
10236   bind_array[7].buffer= (void *) &uint64_val;
10237   bind_array[7].is_unsigned= 1;
10238 
10239   stmt= mysql_stmt_init(mysql);
10240   check_stmt(stmt);
10241 
10242   stmt_text= "INSERT INTO t1 (i8, ui8, i16, ui16, i32, ui32, i64, ui64) "
10243                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
10244   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10245   check_execute(stmt, rc);
10246 
10247   mysql_stmt_bind_param(stmt, bind_array);
10248 
10249   int8_val= int8_min;
10250   uint8_val= uint8_min;
10251   int16_val= int16_min;
10252   uint16_val= uint16_min;
10253   int32_val= int32_min;
10254   uint32_val= uint32_min;
10255   int64_val= int64_min;
10256   uint64_val= uint64_min;
10257 
10258   rc= mysql_stmt_execute(stmt);
10259   check_execute(stmt, rc);
10260 
10261   int8_val= int8_max;
10262   uint8_val= uint8_max;
10263   int16_val= int16_max;
10264   uint16_val= uint16_max;
10265   int32_val= int32_max;
10266   uint32_val= uint32_max;
10267   int64_val= int64_max;
10268   uint64_val= uint64_max;
10269 
10270   rc= mysql_stmt_execute(stmt);
10271   check_execute(stmt, rc);
10272 
10273   stmt_text= "SELECT i8, ui8, i16, ui16, i32, ui32, i64, ui64, ui64, "
10274              "cast(ui64 as signed), ui64, cast(ui64 as signed)"
10275              "FROM t1 ORDER BY id ASC";
10276 
10277   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10278   check_execute(stmt, rc);
10279 
10280   rc= mysql_stmt_execute(stmt);
10281   check_execute(stmt, rc);
10282 
10283   bind_array[8].buffer_type= MYSQL_TYPE_DOUBLE;
10284   bind_array[8].buffer= (void *) &udouble_val;
10285 
10286   bind_array[9].buffer_type= MYSQL_TYPE_DOUBLE;
10287   bind_array[9].buffer= (void *) &double_val;
10288 
10289   bind_array[10].buffer_type= MYSQL_TYPE_STRING;
10290   bind_array[10].buffer= (void *) &ulonglong_as_string;
10291   bind_array[10].buffer_length= (ulong)sizeof(ulonglong_as_string);
10292 
10293   bind_array[11].buffer_type= MYSQL_TYPE_STRING;
10294   bind_array[11].buffer= (void *) &longlong_as_string;
10295   bind_array[11].buffer_length= (ulong)sizeof(longlong_as_string);
10296 
10297   mysql_stmt_bind_result(stmt, bind_array);
10298 
10299   rc= mysql_stmt_fetch(stmt);
10300   check_execute(stmt, rc);
10301 
10302   DIE_UNLESS(int8_val == int8_min);
10303   DIE_UNLESS(uint8_val == uint8_min);
10304   DIE_UNLESS(int16_val == int16_min);
10305   DIE_UNLESS(uint16_val == uint16_min);
10306   DIE_UNLESS(int32_val == int32_min);
10307   DIE_UNLESS(uint32_val == uint32_min);
10308   DIE_UNLESS(int64_val == int64_min);
10309   DIE_UNLESS(uint64_val == uint64_min);
10310   DIE_UNLESS(double_val == (longlong) uint64_min);
10311   double_tmp= ulonglong2double(uint64_val);
10312   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10313   DIE_UNLESS(!strcmp(longlong_as_string, "0"));
10314   DIE_UNLESS(!strcmp(ulonglong_as_string, "0"));
10315 
10316   rc= mysql_stmt_fetch(stmt);
10317 
10318   if (!opt_silent)
10319   {
10320     printf("Truncation mask: ");
10321     for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10322       printf("%d", (int) my_bind->error_value);
10323     printf("\n");
10324   }
10325   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0);
10326 
10327   DIE_UNLESS(int8_val == int8_max);
10328   DIE_UNLESS(uint8_val == uint8_max);
10329   DIE_UNLESS(int16_val == int16_max);
10330   DIE_UNLESS(uint16_val == uint16_max);
10331   DIE_UNLESS(int32_val == int32_max);
10332   DIE_UNLESS(uint32_val == uint32_max);
10333   DIE_UNLESS(int64_val == int64_max);
10334   DIE_UNLESS(uint64_val == uint64_max);
10335   DIE_UNLESS(double_val == (longlong) uint64_val);
10336   double_tmp= ulonglong2double(uint64_val);
10337   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10338   DIE_UNLESS(!strcmp(longlong_as_string, "-1"));
10339   DIE_UNLESS(!strcmp(ulonglong_as_string, "18446744073709551615"));
10340 
10341   rc= mysql_stmt_fetch(stmt);
10342   DIE_UNLESS(rc == MYSQL_NO_DATA);
10343 
10344   mysql_stmt_close(stmt);
10345 
10346   stmt_text= "DROP TABLE t1";
10347   mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10348 }
10349 
10350 
test_union2()10351 static void test_union2()
10352 {
10353   MYSQL_STMT *stmt;
10354   int rc, i;
10355 
10356   myheader("test_union2");
10357 
10358   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10359   myquery(rc);
10360 
10361   rc= mysql_query(mysql, "CREATE TABLE t1(col1 INT, \
10362                                          col2 VARCHAR(40),      \
10363                                          col3 SMALLINT, \
10364                                          col4 TIMESTAMP)");
10365   myquery(rc);
10366 
10367   stmt= mysql_simple_prepare(mysql,
10368                              "select col1 FROM t1 where col1=1 union distinct "
10369                              "select col1 FROM t1 where col1=2");
10370   check_stmt(stmt);
10371 
10372   for (i= 0; i < 3; i++)
10373   {
10374     rc= mysql_stmt_execute(stmt);
10375     check_execute(stmt, rc);
10376     rc= my_process_stmt_result(stmt);
10377     DIE_UNLESS(rc == 0);
10378   }
10379 
10380   mysql_stmt_close(stmt);
10381 
10382   rc= mysql_query(mysql, "DROP TABLE t1");
10383   myquery(rc);
10384 }
10385 
10386 
10387 /*
10388   This tests for various mysql_stmt_send_long_data bugs described in #1664
10389 */
10390 
test_bug1664()10391 static void test_bug1664()
10392 {
10393     MYSQL_STMT *stmt;
10394     int        rc, int_data;
10395     const char *data;
10396     const char *str_data= "Simple string";
10397     MYSQL_BIND my_bind[2];
10398     const char *query= "INSERT INTO test_long_data(col2, col1) VALUES(?, ?)";
10399 
10400     myheader("test_bug1664");
10401 
10402     rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
10403     myquery(rc);
10404 
10405     rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, col2 long varchar)");
10406     myquery(rc);
10407 
10408     stmt= mysql_stmt_init(mysql);
10409     check_stmt(stmt);
10410     rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
10411     check_execute(stmt, rc);
10412 
10413     verify_param_count(stmt, 2);
10414 
10415     memset(my_bind, 0, sizeof(my_bind));
10416 
10417     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10418     my_bind[0].buffer= (void *)str_data;
10419     my_bind[0].buffer_length= (ulong)strlen(str_data);
10420 
10421     my_bind[1].buffer= (void *)&int_data;
10422     my_bind[1].buffer_type= MYSQL_TYPE_LONG;
10423 
10424     rc= mysql_stmt_bind_param(stmt, my_bind);
10425     check_execute(stmt, rc);
10426 
10427     int_data= 1;
10428 
10429     /*
10430       Let us supply empty long_data. This should work and should
10431       not break following execution.
10432     */
10433     data= "";
10434     rc= mysql_stmt_send_long_data(stmt, 0, data, (ulong)strlen(data));
10435     check_execute(stmt, rc);
10436 
10437     rc= mysql_stmt_execute(stmt);
10438     check_execute(stmt, rc);
10439 
10440     verify_col_data("test_long_data", "col1", "1");
10441     verify_col_data("test_long_data", "col2", "");
10442 
10443     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10444     myquery(rc);
10445 
10446     /* This should pass OK */
10447     data= (char *)"Data";
10448     rc= mysql_stmt_send_long_data(stmt, 0, data, (ulong)strlen(data));
10449     check_execute(stmt, rc);
10450 
10451     rc= mysql_stmt_execute(stmt);
10452     check_execute(stmt, rc);
10453 
10454     verify_col_data("test_long_data", "col1", "1");
10455     verify_col_data("test_long_data", "col2", "Data");
10456 
10457     /* clean up */
10458     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10459     myquery(rc);
10460 
10461     /*
10462       Now we are changing int parameter and don't do anything
10463       with first parameter. Second mysql_stmt_execute() should run
10464       OK treating this first parameter as string parameter.
10465     */
10466 
10467     int_data= 2;
10468     /* execute */
10469     rc= mysql_stmt_execute(stmt);
10470     check_execute(stmt, rc);
10471 
10472     verify_col_data("test_long_data", "col1", "2");
10473     verify_col_data("test_long_data", "col2", str_data);
10474 
10475     /* clean up */
10476     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10477     myquery(rc);
10478 
10479     /*
10480       Now we are sending other long data. It should not be
10481       concatened to previous.
10482     */
10483 
10484     data= (char *)"SomeOtherData";
10485     rc= mysql_stmt_send_long_data(stmt, 0, data, (ulong)strlen(data));
10486     check_execute(stmt, rc);
10487 
10488     rc= mysql_stmt_execute(stmt);
10489     check_execute(stmt, rc);
10490 
10491     verify_col_data("test_long_data", "col1", "2");
10492     verify_col_data("test_long_data", "col2", "SomeOtherData");
10493 
10494     mysql_stmt_close(stmt);
10495 
10496     /* clean up */
10497     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10498     myquery(rc);
10499 
10500     /* Now let us test how mysql_stmt_reset works. */
10501     stmt= mysql_stmt_init(mysql);
10502     check_stmt(stmt);
10503     rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
10504     check_execute(stmt, rc);
10505     rc= mysql_stmt_bind_param(stmt, my_bind);
10506     check_execute(stmt, rc);
10507 
10508     data= (char *)"SomeData";
10509     rc= mysql_stmt_send_long_data(stmt, 0, data, (ulong)strlen(data));
10510     check_execute(stmt, rc);
10511 
10512     rc= mysql_stmt_reset(stmt);
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", "2");
10519     verify_col_data("test_long_data", "col2", str_data);
10520 
10521     mysql_stmt_close(stmt);
10522 
10523     /* Final clean up */
10524     rc= mysql_query(mysql, "DROP TABLE test_long_data");
10525     myquery(rc);
10526 }
10527 
10528 
test_order_param()10529 static void test_order_param()
10530 {
10531   MYSQL_STMT *stmt;
10532   int rc;
10533 
10534   myheader("test_order_param");
10535 
10536   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10537   myquery(rc);
10538 
10539   rc= mysql_query(mysql, "CREATE TABLE t1(a INT, b char(10))");
10540   myquery(rc);
10541 
10542   stmt= mysql_simple_prepare(mysql,
10543                              "select sum(a) + 200, 1 from t1 "
10544                              " union distinct "
10545                              "select sum(a) + 200, 1 from t1 group by b ");
10546   check_stmt(stmt);
10547   mysql_stmt_close(stmt);
10548 
10549   stmt= mysql_simple_prepare(mysql,
10550                              "select sum(a) + 200, ? from t1 group by b "
10551                              " union distinct "
10552                              "select sum(a) + 200, 1 from t1 group by b ");
10553   check_stmt(stmt);
10554   mysql_stmt_close(stmt);
10555 
10556   stmt= mysql_simple_prepare(mysql,
10557                              "select sum(a) + 200, ? from t1 "
10558                              " union distinct "
10559                              "select sum(a) + 200, 1 from t1 group by b ");
10560   check_stmt(stmt);
10561   mysql_stmt_close(stmt);
10562 
10563   rc= mysql_query(mysql, "DROP TABLE t1");
10564   myquery(rc);
10565 }
10566 
10567 
test_union_param()10568 static void test_union_param()
10569 {
10570   MYSQL_STMT *stmt;
10571   char *query;
10572   int rc, i;
10573   MYSQL_BIND      my_bind[2];
10574   char            my_val[4];
10575   ulong           my_length= 3L;
10576   my_bool         my_null= FALSE;
10577   myheader("test_union_param");
10578 
10579   my_stpcpy(my_val, "abc");
10580 
10581   query= (char*)"select ? as my_col union distinct select ?";
10582   stmt= mysql_simple_prepare(mysql, query);
10583   check_stmt(stmt);
10584 
10585   /*
10586     We need to memset bind structure because mysql_stmt_bind_param checks all
10587     its members.
10588   */
10589   memset(my_bind, 0, sizeof(my_bind));
10590 
10591   /* bind parameters */
10592   my_bind[0].buffer_type=    MYSQL_TYPE_STRING;
10593   my_bind[0].buffer=         (char*) &my_val;
10594   my_bind[0].buffer_length=  4;
10595   my_bind[0].length=         &my_length;
10596   my_bind[0].is_null=        (char*)&my_null;
10597   my_bind[1].buffer_type=    MYSQL_TYPE_STRING;
10598   my_bind[1].buffer=         (char*) &my_val;
10599   my_bind[1].buffer_length=  4;
10600   my_bind[1].length=         &my_length;
10601   my_bind[1].is_null=        (char*)&my_null;
10602 
10603   rc= mysql_stmt_bind_param(stmt, my_bind);
10604   check_execute(stmt, rc);
10605 
10606   for (i= 0; i < 3; i++)
10607   {
10608     rc= mysql_stmt_execute(stmt);
10609     check_execute(stmt, rc);
10610     rc= my_process_stmt_result(stmt);
10611     DIE_UNLESS(rc == 1);
10612   }
10613 
10614   mysql_stmt_close(stmt);
10615 }
10616 
10617 
test_ps_i18n()10618 static void test_ps_i18n()
10619 {
10620   MYSQL_STMT *stmt;
10621   int rc;
10622   const char *stmt_text;
10623   MYSQL_BIND bind_array[2];
10624 
10625   /* Represented as numbers to keep UTF8 tools from clobbering them. */
10626   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
10627   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
10628   char buf1[16], buf2[16];
10629   ulong buf1_len, buf2_len;
10630 
10631 
10632   myheader("test_ps_i18n");
10633 
10634   stmt_text= "DROP TABLE IF EXISTS t1";
10635   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10636   myquery(rc);
10637 
10638   /*
10639     Create table with binary columns, set session character set to cp1251,
10640     client character set to koi8, and make sure that there is conversion
10641     on insert and no conversion on select
10642   */
10643 
10644   stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
10645 
10646   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10647   myquery(rc);
10648 
10649   stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
10650                  "CHARACTER_SET_CONNECTION=cp1251, "
10651                  "CHARACTER_SET_RESULTS=koi8r";
10652 
10653   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10654   myquery(rc);
10655 
10656   memset(bind_array, 0, sizeof(bind_array));
10657 
10658   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10659   bind_array[0].buffer= (void *) koi8;
10660   bind_array[0].buffer_length= (ulong)strlen(koi8);
10661 
10662   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10663   bind_array[1].buffer= (void *) koi8;
10664   bind_array[1].buffer_length= (ulong)strlen(koi8);
10665 
10666   stmt= mysql_stmt_init(mysql);
10667   check_stmt(stmt);
10668 
10669   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10670 
10671   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10672   check_execute(stmt, rc);
10673 
10674   mysql_stmt_bind_param(stmt, bind_array);
10675 
10676   mysql_stmt_send_long_data(stmt, 0, koi8, (ulong)strlen(koi8));
10677 
10678   rc= mysql_stmt_execute(stmt);
10679   check_execute(stmt, rc);
10680 
10681   stmt_text= "SELECT c1, c2 FROM t1";
10682 
10683   /* c1 and c2 are binary so no conversion will be done on select */
10684   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10685   check_execute(stmt, rc);
10686 
10687   rc= mysql_stmt_execute(stmt);
10688   check_execute(stmt, rc);
10689 
10690   bind_array[0].buffer= buf1;
10691   bind_array[0].buffer_length= (ulong)sizeof(buf1);
10692   bind_array[0].length= &buf1_len;
10693 
10694   bind_array[1].buffer= buf2;
10695   bind_array[1].buffer_length= (ulong)sizeof(buf2);
10696   bind_array[1].length= &buf2_len;
10697 
10698   mysql_stmt_bind_result(stmt, bind_array);
10699 
10700   rc= mysql_stmt_fetch(stmt);
10701   check_execute(stmt, rc);
10702 
10703   DIE_UNLESS(buf1_len == strlen(cp1251));
10704   DIE_UNLESS(buf2_len == strlen(cp1251));
10705   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
10706   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
10707 
10708   rc= mysql_stmt_fetch(stmt);
10709   DIE_UNLESS(rc == MYSQL_NO_DATA);
10710 
10711   stmt_text= "DROP TABLE IF EXISTS t1";
10712   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10713   myquery(rc);
10714 
10715   /*
10716     Now create table with two cp1251 columns, set client character
10717     set to koi8 and supply columns of one row as string and another as
10718     binary data. Binary data must not be converted on insert, and both
10719     columns must be converted to client character set on select.
10720   */
10721 
10722   stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
10723                               "c2 VARCHAR(255) CHARACTER SET cp1251)";
10724 
10725   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10726   myquery(rc);
10727 
10728   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10729 
10730   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10731   check_execute(stmt, rc);
10732 
10733   /* this data must be converted */
10734   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10735   bind_array[0].buffer= (void *) koi8;
10736   bind_array[0].buffer_length= (ulong)strlen(koi8);
10737 
10738   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10739   bind_array[1].buffer= (void *) koi8;
10740   bind_array[1].buffer_length= (ulong)strlen(koi8);
10741 
10742   mysql_stmt_bind_param(stmt, bind_array);
10743 
10744   mysql_stmt_send_long_data(stmt, 0, koi8, (ulong)strlen(koi8));
10745 
10746   rc= mysql_stmt_execute(stmt);
10747   check_execute(stmt, rc);
10748 
10749   /* this data must not be converted */
10750   bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
10751   bind_array[0].buffer= (void *) cp1251;
10752   bind_array[0].buffer_length= (ulong)strlen(cp1251);
10753 
10754   bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
10755   bind_array[1].buffer= (void *) cp1251;
10756   bind_array[1].buffer_length= (ulong)strlen(cp1251);
10757 
10758   mysql_stmt_bind_param(stmt, bind_array);
10759 
10760   mysql_stmt_send_long_data(stmt, 0, cp1251, (ulong)strlen(cp1251));
10761 
10762   rc= mysql_stmt_execute(stmt);
10763   check_execute(stmt, rc);
10764 
10765   /* Fetch data and verify that rows are in koi8 */
10766 
10767   stmt_text= "SELECT c1, c2 FROM t1";
10768 
10769   /* c1 and c2 are binary so no conversion will be done on select */
10770   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10771   check_execute(stmt, rc);
10772 
10773   rc= mysql_stmt_execute(stmt);
10774   check_execute(stmt, rc);
10775 
10776   bind_array[0].buffer= buf1;
10777   bind_array[0].buffer_length= (ulong)sizeof(buf1);
10778   bind_array[0].length= &buf1_len;
10779 
10780   bind_array[1].buffer= buf2;
10781   bind_array[1].buffer_length= (ulong)sizeof(buf2);
10782   bind_array[1].length= &buf2_len;
10783 
10784   mysql_stmt_bind_result(stmt, bind_array);
10785 
10786   while ((rc= mysql_stmt_fetch(stmt)) == 0)
10787   {
10788     DIE_UNLESS(buf1_len == strlen(koi8));
10789     DIE_UNLESS(buf2_len == strlen(koi8));
10790     DIE_UNLESS(!memcmp(buf1, koi8, buf1_len));
10791     DIE_UNLESS(!memcmp(buf2, koi8, buf1_len));
10792   }
10793   DIE_UNLESS(rc == MYSQL_NO_DATA);
10794   mysql_stmt_close(stmt);
10795 
10796   stmt_text= "DROP TABLE t1";
10797   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10798   myquery(rc);
10799   stmt_text= "SET NAMES DEFAULT";
10800   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10801   myquery(rc);
10802 }
10803 
10804 
test_bug3796()10805 static void test_bug3796()
10806 {
10807   MYSQL_STMT *stmt;
10808   MYSQL_BIND my_bind[1];
10809   const char *concat_arg0= "concat_with_";
10810   enum { OUT_BUFF_SIZE= 30 };
10811   char out_buff[OUT_BUFF_SIZE];
10812   char canonical_buff[OUT_BUFF_SIZE];
10813   ulong out_length;
10814   const char *stmt_text;
10815   int rc;
10816 
10817   myheader("test_bug3796");
10818 
10819   /* Create and fill test table */
10820   stmt_text= "DROP TABLE IF EXISTS t1";
10821   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10822   myquery(rc);
10823 
10824   stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))";
10825   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10826   myquery(rc);
10827 
10828   stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')";
10829   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10830   myquery(rc);
10831 
10832   /* Create statement handle and prepare it with select */
10833   stmt= mysql_stmt_init(mysql);
10834   stmt_text= "SELECT concat(?, b) FROM t1";
10835 
10836   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10837   check_execute(stmt, rc);
10838 
10839   /* Bind input buffers */
10840   memset(my_bind, 0, sizeof(my_bind));
10841 
10842   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10843   my_bind[0].buffer= (void *) concat_arg0;
10844   my_bind[0].buffer_length= (ulong)strlen(concat_arg0);
10845 
10846   mysql_stmt_bind_param(stmt, my_bind);
10847 
10848   /* Execute the select statement */
10849   rc= mysql_stmt_execute(stmt);
10850   check_execute(stmt, rc);
10851 
10852   my_bind[0].buffer= (void *) out_buff;
10853   my_bind[0].buffer_length= OUT_BUFF_SIZE;
10854   my_bind[0].length= &out_length;
10855 
10856   mysql_stmt_bind_result(stmt, my_bind);
10857 
10858   rc= mysql_stmt_fetch(stmt);
10859   if (!opt_silent)
10860     printf("Concat result: '%s'\n", out_buff);
10861   check_execute(stmt, rc);
10862   my_stpcpy(canonical_buff, concat_arg0);
10863   strcat(canonical_buff, "ONE");
10864   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10865          strncmp(out_buff, canonical_buff, out_length) == 0);
10866 
10867   rc= mysql_stmt_fetch(stmt);
10868   check_execute(stmt, rc);
10869   my_stpcpy(canonical_buff + strlen(concat_arg0), "TWO");
10870   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10871          strncmp(out_buff, canonical_buff, out_length) == 0);
10872   if (!opt_silent)
10873     printf("Concat result: '%s'\n", out_buff);
10874 
10875   rc= mysql_stmt_fetch(stmt);
10876   DIE_UNLESS(rc == MYSQL_NO_DATA);
10877 
10878   mysql_stmt_close(stmt);
10879 
10880   stmt_text= "DROP TABLE IF EXISTS t1";
10881   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10882   myquery(rc);
10883 }
10884 
10885 
test_bug4026()10886 static void test_bug4026()
10887 {
10888   MYSQL_STMT *stmt;
10889   MYSQL_BIND my_bind[2];
10890   MYSQL_TIME time_in, time_out;
10891   MYSQL_TIME datetime_in, datetime_out;
10892   const char *stmt_text;
10893   int rc;
10894 
10895   myheader("test_bug4026");
10896 
10897   /* Check that microseconds are inserted and selected successfully */
10898 
10899   /* Create a statement handle and prepare it with select */
10900   stmt= mysql_stmt_init(mysql);
10901   stmt_text= "SELECT ?, ?";
10902 
10903   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10904   check_execute(stmt, rc);
10905 
10906   /* Bind input buffers */
10907   memset(my_bind, 0, sizeof(my_bind));
10908   memset(&time_in, 0, sizeof(time_in));
10909   memset(&time_out, 0, sizeof(time_out));
10910   memset(&datetime_in, 0, sizeof(datetime_in));
10911   memset(&datetime_out, 0, sizeof(datetime_out));
10912 
10913   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
10914   my_bind[0].buffer= (void *) &time_in;
10915   my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
10916   my_bind[1].buffer= (void *) &datetime_in;
10917 
10918   time_in.hour= 23;
10919   time_in.minute= 59;
10920   time_in.second= 59;
10921   time_in.second_part= 123456;
10922   /*
10923     This is not necessary, just to make DIE_UNLESS below work: this field
10924     is filled in when time is received from server
10925   */
10926   time_in.time_type= MYSQL_TIMESTAMP_TIME;
10927 
10928   datetime_in= time_in;
10929   datetime_in.year= 2003;
10930   datetime_in.month= 12;
10931   datetime_in.day= 31;
10932   datetime_in.time_type= MYSQL_TIMESTAMP_DATETIME;
10933 
10934   mysql_stmt_bind_param(stmt, my_bind);
10935 
10936   /* Execute the select statement */
10937   rc= mysql_stmt_execute(stmt);
10938   check_execute(stmt, rc);
10939 
10940   my_bind[0].buffer= (void *) &time_out;
10941   my_bind[1].buffer= (void *) &datetime_out;
10942 
10943   mysql_stmt_bind_result(stmt, my_bind);
10944 
10945   rc= mysql_stmt_fetch(stmt);
10946   DIE_UNLESS(rc == 0);
10947   if (!opt_silent)
10948   {
10949     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
10950            time_out.second_part);
10951     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
10952            datetime_out.day, datetime_out.hour,
10953            datetime_out.minute, datetime_out.second,
10954            datetime_out.second_part);
10955   }
10956   DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0);
10957   DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0);
10958   mysql_stmt_close(stmt);
10959 }
10960 
10961 
test_bug4079()10962 static void test_bug4079()
10963 {
10964   MYSQL_STMT *stmt;
10965   MYSQL_BIND my_bind[1];
10966   const char *stmt_text;
10967   uint32 res;
10968   int rc;
10969 
10970   myheader("test_bug4079");
10971 
10972   /* Create and fill table */
10973   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10974   mysql_query(mysql, "CREATE TABLE t1 (a int)");
10975   mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2)");
10976 
10977   /* Prepare erroneous statement */
10978   stmt= mysql_stmt_init(mysql);
10979   stmt_text= "SELECT 1 < (SELECT a FROM t1)";
10980 
10981   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10982   check_execute(stmt, rc);
10983 
10984   /* Execute the select statement */
10985   rc= mysql_stmt_execute(stmt);
10986   check_execute(stmt, rc);
10987 
10988   /* Bind input buffers */
10989   memset(my_bind, 0, sizeof(my_bind));
10990 
10991   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10992   my_bind[0].buffer= (void *) &res;
10993 
10994   mysql_stmt_bind_result(stmt, my_bind);
10995 
10996   rc= mysql_stmt_fetch(stmt);
10997   DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA);
10998   if (!opt_silent)
10999     printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
11000            mysql_stmt_error(stmt));
11001   /* buggy version of libmysql hanged up here */
11002   mysql_stmt_close(stmt);
11003 }
11004 
11005 
test_bug4236()11006 static void test_bug4236()
11007 {
11008   MYSQL_STMT *stmt;
11009   const char *stmt_text;
11010   int rc;
11011   MYSQL_STMT backup;
11012 
11013   myheader("test_bug4236");
11014 
11015   stmt= mysql_stmt_init(mysql);
11016 
11017   /* mysql_stmt_execute() of statement with statement id= 0 crashed server */
11018   stmt_text= "SELECT 1";
11019   /* We need to prepare statement to pass by possible check in libmysql */
11020   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11021   check_execute(stmt, rc);
11022   /* Hack to check that server works OK if statement wasn't found */
11023   backup.stmt_id= stmt->stmt_id;
11024   stmt->stmt_id= 0;
11025   rc= mysql_stmt_execute(stmt);
11026   DIE_UNLESS(rc);
11027   /* Restore original statement id to be able to reprepare it */
11028   stmt->stmt_id= backup.stmt_id;
11029 
11030   mysql_stmt_close(stmt);
11031 }
11032 
11033 
test_bug4030()11034 static void test_bug4030()
11035 {
11036   MYSQL_STMT *stmt;
11037   MYSQL_BIND my_bind[3];
11038   MYSQL_TIME time_canonical, time_out;
11039   MYSQL_TIME date_canonical, date_out;
11040   MYSQL_TIME datetime_canonical, datetime_out;
11041   const char *stmt_text;
11042   int rc;
11043 
11044   myheader("test_bug4030");
11045 
11046   /* Check that microseconds are inserted and selected successfully */
11047 
11048   /* Execute a query with time values in prepared mode */
11049   stmt= mysql_stmt_init(mysql);
11050   stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
11051              "'2003-12-31 23:59:59.123456'";
11052   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11053   check_execute(stmt, rc);
11054   rc= mysql_stmt_execute(stmt);
11055   check_execute(stmt, rc);
11056 
11057   /* Bind output buffers */
11058   memset(my_bind, 0, sizeof(my_bind));
11059   memset(&time_canonical, 0, sizeof(time_canonical));
11060   memset(&time_out, 0, sizeof(time_out));
11061   memset(&date_canonical, 0, sizeof(date_canonical));
11062   memset(&date_out, 0, sizeof(date_out));
11063   memset(&datetime_canonical, 0, sizeof(datetime_canonical));
11064   memset(&datetime_out, 0, sizeof(datetime_out));
11065 
11066   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
11067   my_bind[0].buffer= (void *) &time_out;
11068   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11069   my_bind[1].buffer= (void *) &date_out;
11070   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
11071   my_bind[2].buffer= (void *) &datetime_out;
11072 
11073   time_canonical.hour= 23;
11074   time_canonical.minute= 59;
11075   time_canonical.second= 59;
11076   time_canonical.second_part= 123456;
11077   time_canonical.time_type= MYSQL_TIMESTAMP_TIME;
11078 
11079   date_canonical.year= 2003;
11080   date_canonical.month= 12;
11081   date_canonical.day= 31;
11082   date_canonical.time_type= MYSQL_TIMESTAMP_DATE;
11083 
11084   datetime_canonical= time_canonical;
11085   datetime_canonical.year= 2003;
11086   datetime_canonical.month= 12;
11087   datetime_canonical.day= 31;
11088   datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME;
11089 
11090   mysql_stmt_bind_result(stmt, my_bind);
11091 
11092   rc= mysql_stmt_fetch(stmt);
11093   DIE_UNLESS(rc == 0);
11094   if (!opt_silent)
11095   {
11096     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
11097            time_out.second_part);
11098     printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
11099     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
11100            datetime_out.day, datetime_out.hour,
11101            datetime_out.minute, datetime_out.second,
11102            datetime_out.second_part);
11103   }
11104   DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
11105   DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
11106   DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
11107   mysql_stmt_close(stmt);
11108 }
11109 
test_view()11110 static void test_view()
11111 {
11112   MYSQL_STMT *stmt;
11113   int rc, i;
11114   MYSQL_BIND      my_bind[1];
11115   char            str_data[50];
11116   ulong           length = 0L;
11117   long            is_null = 0L;
11118   const char *query=
11119     "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
11120 
11121   myheader("test_view");
11122 
11123   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
11124   myquery(rc);
11125 
11126   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
11127   myquery(rc);
11128   rc= mysql_query(mysql,"CREATE TABLE t1 ("
11129                         " SERVERGRP varchar(20) NOT NULL default '', "
11130                         " DBINSTANCE varchar(20) NOT NULL default '', "
11131                         " PRIMARY KEY  (SERVERGRP)) "
11132                         " CHARSET=latin1 collate=latin1_bin");
11133   myquery(rc);
11134   rc= mysql_query(mysql,"CREATE TABLE t2 ("
11135                         " SERVERNAME varchar(20) NOT NULL, "
11136                         " SERVERGRP varchar(20) NOT NULL, "
11137                         " PRIMARY KEY (SERVERNAME)) "
11138                         " CHARSET=latin1 COLLATE latin1_bin");
11139   myquery(rc);
11140   rc= mysql_query(mysql,
11141                   "CREATE TABLE t3 ("
11142                   " SERVERGRP varchar(20) BINARY NOT NULL, "
11143                   " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
11144                   " ACTSTATE char(1) NOT NULL , "
11145                   " LOCAL_NAME varchar(30) NOT NULL, "
11146                   " CHG_DATE varchar(8) NOT NULL default '00000000', "
11147                   " CHG_TIME varchar(6) NOT NULL default '000000', "
11148                   " MXUSER varchar(12) NOT NULL default '', "
11149                   " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
11150                   " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
11151   myquery(rc);
11152   rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
11153                   " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
11154                   " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
11155                   " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
11156                   " ((T0002.SERVERGRP = T0001.SERVERGRP) and"
11157                   " (T0002.SERVERGRP = T0003.SERVERGRP)"
11158                   " and (T0003.MAPSTATE = _latin1'A') and"
11159                   " (T0003.ACTSTATE = _latin1' '))");
11160   myquery(rc);
11161 
11162   stmt= mysql_stmt_init(mysql);
11163   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11164   check_execute(stmt, rc);
11165 
11166   my_stpcpy(str_data, "TEST");
11167   memset(my_bind, 0, sizeof(my_bind));
11168   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
11169   my_bind[0].buffer= (char *)&str_data;
11170   my_bind[0].buffer_length= 50;
11171   my_bind[0].length= &length;
11172   length= 4;
11173   my_bind[0].is_null= (char*)&is_null;
11174   rc= mysql_stmt_bind_param(stmt, my_bind);
11175   check_execute(stmt,rc);
11176 
11177   for (i= 0; i < 3; i++)
11178   {
11179     rc= mysql_stmt_execute(stmt);
11180     check_execute(stmt, rc);
11181     rc= my_process_stmt_result(stmt);
11182     DIE_UNLESS(1 == rc);
11183   }
11184   mysql_stmt_close(stmt);
11185 
11186   rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
11187   myquery(rc);
11188   rc= mysql_query(mysql, "DROP VIEW v1");
11189   myquery(rc);
11190 }
11191 
11192 
test_view_where()11193 static void test_view_where()
11194 {
11195   MYSQL_STMT *stmt;
11196   int rc, i;
11197   const char *query=
11198     "select v1.c,v2.c from v1, v2";
11199 
11200   myheader("test_view_where");
11201 
11202   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2");
11203   myquery(rc);
11204 
11205   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1");
11206   myquery(rc);
11207   rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)");
11208   myquery(rc);
11209   rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)");
11210   myquery(rc);
11211   rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3");
11212   myquery(rc);
11213   rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3");
11214   myquery(rc);
11215 
11216   stmt= mysql_stmt_init(mysql);
11217   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11218   check_execute(stmt, rc);
11219 
11220   for (i= 0; i < 3; i++)
11221   {
11222     rc= mysql_stmt_execute(stmt);
11223     check_execute(stmt, rc);
11224     rc= my_process_stmt_result(stmt);
11225     DIE_UNLESS(4 == rc);
11226   }
11227   mysql_stmt_close(stmt);
11228 
11229   rc= mysql_query(mysql, "DROP TABLE t1");
11230   myquery(rc);
11231   rc= mysql_query(mysql, "DROP VIEW v1, v2");
11232   myquery(rc);
11233 }
11234 
11235 
test_view_2where()11236 static void test_view_2where()
11237 {
11238   MYSQL_STMT *stmt;
11239   int rc, i;
11240   MYSQL_BIND      my_bind[8];
11241   char            parms[8][100];
11242   ulong           length[8];
11243   const char *query=
11244     "select relid, report, handle, log_group, username, variant, type, "
11245     "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
11246     "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
11247     "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";
11248 
11249   myheader("test_view_2where");
11250 
11251   rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
11252   myquery(rc);
11253   rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
11254   myquery(rc);
11255   rc= mysql_query(mysql,
11256                   "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
11257                   " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
11258                   " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
11259                   " USERNAME varchar(12) NOT NULL,"
11260                   " VARIANT varchar(12) NOT NULL,"
11261                   " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
11262                   " VERSION varchar(6) NOT NULL default '000000',"
11263                   " ERFDAT varchar(8) NOT NULL default '00000000',"
11264                   " ERFTIME varchar(6) NOT NULL default '000000',"
11265                   " ERFNAME varchar(12) NOT NULL,"
11266                   " AEDAT varchar(8) NOT NULL default '00000000',"
11267                   " AETIME varchar(6) NOT NULL default '000000',"
11268                   " AENAME varchar(12) NOT NULL,"
11269                   " DEPENDVARS varchar(10) NOT NULL,"
11270                   " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
11271                   " CLUSTD blob,"
11272                   " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
11273                                 "USERNAME, VARIANT, TYPE, SRTF2))"
11274                  " CHARSET=latin1 COLLATE latin1_bin");
11275   myquery(rc);
11276   rc= mysql_query(mysql,
11277                   "CREATE VIEW V_LTDX AS select T0001.MANDT AS "
11278                   " MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
11279                   " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
11280                   " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
11281                   " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
11282                   " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
11283                   " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
11284                   " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
11285                   " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
11286                   " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
11287   myquery(rc);
11288   memset(my_bind, 0, sizeof(my_bind));
11289   for (i=0; i < 8; i++) {
11290     my_stpcpy(parms[i], "1");
11291     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11292     my_bind[i].buffer = (char *)&parms[i];
11293     my_bind[i].buffer_length = 100;
11294     my_bind[i].is_null = 0;
11295     my_bind[i].length = &length[i];
11296     length[i] = 1;
11297   }
11298   stmt= mysql_stmt_init(mysql);
11299   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11300   check_execute(stmt, rc);
11301 
11302   rc= mysql_stmt_bind_param(stmt, my_bind);
11303   check_execute(stmt,rc);
11304 
11305   rc= mysql_stmt_execute(stmt);
11306   check_execute(stmt, rc);
11307   rc= my_process_stmt_result(stmt);
11308   DIE_UNLESS(0 == rc);
11309 
11310   mysql_stmt_close(stmt);
11311 
11312   rc= mysql_query(mysql, "DROP VIEW V_LTDX");
11313   myquery(rc);
11314   rc= mysql_query(mysql, "DROP TABLE LTDX");
11315   myquery(rc);
11316 }
11317 
11318 
test_view_star()11319 static void test_view_star()
11320 {
11321   MYSQL_STMT *stmt;
11322   int rc, i;
11323   MYSQL_BIND      my_bind[8];
11324   char            parms[8][100];
11325   ulong           length[8];
11326   const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)";
11327 
11328   myheader("test_view_star");
11329 
11330   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1");
11331   myquery(rc);
11332   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1");
11333   myquery(rc);
11334   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
11335   myquery(rc);
11336   rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1");
11337   myquery(rc);
11338   memset(my_bind, 0, sizeof(my_bind));
11339   for (i= 0; i < 2; i++) {
11340     sprintf((char *)&parms[i], "%d", i);
11341     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11342     my_bind[i].buffer = (char *)&parms[i];
11343     my_bind[i].buffer_length = 100;
11344     my_bind[i].is_null = 0;
11345     my_bind[i].length = &length[i];
11346     length[i] = 1;
11347   }
11348 
11349   stmt= mysql_stmt_init(mysql);
11350   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11351   check_execute(stmt, rc);
11352 
11353   rc= mysql_stmt_bind_param(stmt, my_bind);
11354   check_execute(stmt,rc);
11355 
11356   for (i= 0; i < 3; i++)
11357   {
11358     rc= mysql_stmt_execute(stmt);
11359     check_execute(stmt, rc);
11360     rc= my_process_stmt_result(stmt);
11361     DIE_UNLESS(0 == rc);
11362   }
11363 
11364   mysql_stmt_close(stmt);
11365 
11366   rc= mysql_query(mysql, "DROP TABLE t1");
11367   myquery(rc);
11368   rc= mysql_query(mysql, "DROP VIEW vt1");
11369   myquery(rc);
11370 }
11371 
11372 
test_view_insert()11373 static void test_view_insert()
11374 {
11375   MYSQL_STMT *insert_stmt, *select_stmt;
11376   int rc, i;
11377   MYSQL_BIND      my_bind[1];
11378   int             my_val = 0;
11379   ulong           my_length = 0L;
11380   long            my_null = 0L;
11381   const char *query=
11382     "insert into v1 values (?)";
11383 
11384   myheader("test_view_insert");
11385 
11386   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11387   myquery(rc);
11388   rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1");
11389   myquery(rc);
11390 
11391   rc= mysql_query(mysql,"create table t1 (a int, primary key (a))");
11392   myquery(rc);
11393 
11394   rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1");
11395   myquery(rc);
11396 
11397   insert_stmt= mysql_stmt_init(mysql);
11398   rc= mysql_stmt_prepare(insert_stmt, query, (ulong)strlen(query));
11399   check_execute(insert_stmt, rc);
11400   query= "select * from t1";
11401   select_stmt= mysql_stmt_init(mysql);
11402   rc= mysql_stmt_prepare(select_stmt, query, (ulong)strlen(query));
11403   check_execute(select_stmt, rc);
11404 
11405   memset(my_bind, 0, sizeof(my_bind));
11406   my_bind[0].buffer_type = MYSQL_TYPE_LONG;
11407   my_bind[0].buffer = (char *)&my_val;
11408   my_bind[0].length = &my_length;
11409   my_bind[0].is_null = (char*)&my_null;
11410   rc= mysql_stmt_bind_param(insert_stmt, my_bind);
11411   check_execute(insert_stmt, rc);
11412 
11413   for (i= 0; i < 3; i++)
11414   {
11415     int rowcount= 0;
11416     my_val= i;
11417 
11418     rc= mysql_stmt_execute(insert_stmt);
11419     check_execute(insert_stmt, rc);
11420 
11421     rc= mysql_stmt_execute(select_stmt);
11422     check_execute(select_stmt, rc);
11423     rowcount= (int)my_process_stmt_result(select_stmt);
11424     DIE_UNLESS((i+1) == rowcount);
11425   }
11426   mysql_stmt_close(insert_stmt);
11427   mysql_stmt_close(select_stmt);
11428 
11429   rc= mysql_query(mysql, "DROP VIEW v1");
11430   myquery(rc);
11431   rc= mysql_query(mysql, "DROP TABLE t1");
11432   myquery(rc);
11433 }
11434 
11435 
test_left_join_view()11436 static void test_left_join_view()
11437 {
11438   MYSQL_STMT *stmt;
11439   int rc, i;
11440   const char *query=
11441     "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);";
11442 
11443   myheader("test_left_join_view");
11444 
11445   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11446   myquery(rc);
11447 
11448   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1");
11449   myquery(rc);
11450   rc= mysql_query(mysql,"CREATE TABLE t1 (a int)");
11451   myquery(rc);
11452   rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)");
11453   myquery(rc);
11454   rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1");
11455   myquery(rc);
11456   stmt= mysql_stmt_init(mysql);
11457   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11458   check_execute(stmt, rc);
11459 
11460   for (i= 0; i < 3; i++)
11461   {
11462     rc= mysql_stmt_execute(stmt);
11463     check_execute(stmt, rc);
11464     rc= my_process_stmt_result(stmt);
11465     DIE_UNLESS(3 == rc);
11466   }
11467   mysql_stmt_close(stmt);
11468 
11469   rc= mysql_query(mysql, "DROP VIEW v1");
11470   myquery(rc);
11471   rc= mysql_query(mysql, "DROP TABLE t1");
11472   myquery(rc);
11473 }
11474 
11475 
test_view_insert_fields()11476 static void test_view_insert_fields()
11477 {
11478   MYSQL_STMT	*stmt;
11479   char		parm[11][1000];
11480   ulong         l[11];
11481   int		rc, i;
11482   MYSQL_BIND	my_bind[11];
11483   const char    *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";
11484 
11485   myheader("test_view_insert_fields");
11486 
11487   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
11488   myquery(rc);
11489   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
11490   myquery(rc);
11491   rc= mysql_query(mysql,
11492                   "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
11493                   "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
11494                   "K4N4 varchar(4) NOT NULL default '0000',"
11495                   "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
11496                   "F3N5 varchar(5) NOT NULL default '00000',"
11497                   "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
11498                   "F6N4 varchar(4) NOT NULL default '0000',"
11499                   "F7F8 double NOT NULL default '0',"
11500                   "F8F8 double NOT NULL default '0',"
11501                   "F9D8 decimal(8,2) NOT NULL default '0.00',"
11502                   "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
11503                   "CHARSET=latin1 COLLATE latin1_bin");
11504   myquery(rc);
11505   rc= mysql_query(mysql,
11506                   "CREATE VIEW v1 AS select sql_no_cache "
11507                   " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
11508                   " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
11509                   " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
11510                   " from t1 T0001");
11511 
11512   memset(my_bind, 0, sizeof(my_bind));
11513   memset(parm, 0, sizeof(parm));
11514   for (i= 0; i < 11; i++)
11515   {
11516     l[i]= 20;
11517     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
11518     my_bind[i].is_null= 0;
11519     my_bind[i].buffer= (char *)&parm[i];
11520 
11521     my_stpcpy(parm[i], "1");
11522     my_bind[i].buffer_length= 2;
11523     my_bind[i].length= &l[i];
11524   }
11525   stmt= mysql_stmt_init(mysql);
11526   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11527   check_execute(stmt, rc);
11528   rc= mysql_stmt_bind_param(stmt, my_bind);
11529   check_execute(stmt, rc);
11530 
11531   rc= mysql_stmt_execute(stmt);
11532   check_execute(stmt, rc);
11533   mysql_stmt_close(stmt);
11534 
11535   query= "select * from t1";
11536   stmt= mysql_stmt_init(mysql);
11537   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11538   check_execute(stmt, rc);
11539   rc= mysql_stmt_execute(stmt);
11540   check_execute(stmt, rc);
11541   rc= my_process_stmt_result(stmt);
11542   DIE_UNLESS(1 == rc);
11543 
11544   mysql_stmt_close(stmt);
11545   rc= mysql_query(mysql, "DROP VIEW v1");
11546   myquery(rc);
11547   rc= mysql_query(mysql, "DROP TABLE t1");
11548   myquery(rc);
11549 
11550 }
11551 
test_bug5126()11552 static void test_bug5126()
11553 {
11554   MYSQL_STMT *stmt;
11555   MYSQL_BIND my_bind[2];
11556   int32 c1, c2;
11557   const char *stmt_text;
11558   int rc;
11559 
11560   myheader("test_bug5126");
11561 
11562   stmt_text= "DROP TABLE IF EXISTS t1";
11563   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11564   myquery(rc);
11565 
11566   stmt_text= "CREATE TABLE t1 (a mediumint, b int)";
11567   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11568   myquery(rc);
11569 
11570   stmt_text= "INSERT INTO t1 VALUES (8386608, 1)";
11571   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11572   myquery(rc);
11573 
11574   stmt= mysql_stmt_init(mysql);
11575   stmt_text= "SELECT a, b FROM t1";
11576   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11577   check_execute(stmt, rc);
11578   rc= mysql_stmt_execute(stmt);
11579   check_execute(stmt, rc);
11580 
11581   /* Bind output buffers */
11582   memset(my_bind, 0, sizeof(my_bind));
11583 
11584   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11585   my_bind[0].buffer= &c1;
11586   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
11587   my_bind[1].buffer= &c2;
11588 
11589   mysql_stmt_bind_result(stmt, my_bind);
11590 
11591   rc= mysql_stmt_fetch(stmt);
11592   DIE_UNLESS(rc == 0);
11593   DIE_UNLESS(c1 == 8386608 && c2 == 1);
11594   if (!opt_silent)
11595     printf("%ld, %ld\n", (long) c1, (long) c2);
11596   mysql_stmt_close(stmt);
11597 }
11598 
11599 
test_bug4231()11600 static void test_bug4231()
11601 {
11602   MYSQL_STMT *stmt;
11603   MYSQL_BIND my_bind[2];
11604   MYSQL_TIME tm[2];
11605   const char *stmt_text;
11606   int rc;
11607 
11608   myheader("test_bug4231");
11609 
11610   stmt_text= "DROP TABLE IF EXISTS t1";
11611   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11612   myquery(rc);
11613 
11614   stmt_text= "CREATE TABLE t1 (a int)";
11615   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11616   myquery(rc);
11617 
11618   stmt_text= "INSERT INTO t1 VALUES (1)";
11619   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11620   myquery(rc);
11621 
11622   stmt= mysql_stmt_init(mysql);
11623   stmt_text= "SELECT a FROM t1 WHERE ? = ?";
11624   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11625   check_execute(stmt, rc);
11626 
11627   /* Bind input buffers */
11628   memset(my_bind, 0, sizeof(my_bind));
11629   memset(tm, 0, sizeof(tm));
11630 
11631   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
11632   my_bind[0].buffer= &tm[0];
11633   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11634   my_bind[1].buffer= &tm[1];
11635 
11636   mysql_stmt_bind_param(stmt, my_bind);
11637   check_execute(stmt, rc);
11638 
11639   /*
11640     First set server-side params to some non-zero non-equal values:
11641     then we will check that they are not used when client sends
11642     new (zero) times.
11643   */
11644   tm[0].time_type = MYSQL_TIMESTAMP_DATE;
11645   tm[0].year = 2000;
11646   tm[0].month = 1;
11647   tm[0].day = 1;
11648   tm[1]= tm[0];
11649   --tm[1].year;                                 /* tm[0] != tm[1] */
11650 
11651   rc= mysql_stmt_execute(stmt);
11652   check_execute(stmt, rc);
11653 
11654   rc= mysql_stmt_fetch(stmt);
11655 
11656   /* binds are unequal, no rows should be returned */
11657   DIE_UNLESS(rc == MYSQL_NO_DATA);
11658 
11659   /* Set one of the dates to zero */
11660   tm[0].year= tm[0].month= tm[0].day= 0;
11661   tm[1]= tm[0];
11662   mysql_stmt_execute(stmt);
11663   rc= mysql_stmt_fetch(stmt);
11664   DIE_UNLESS(rc == 0);
11665 
11666   mysql_stmt_close(stmt);
11667   stmt_text= "DROP TABLE t1";
11668   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11669   myquery(rc);
11670 }
11671 
11672 
test_bug5399()11673 static void test_bug5399()
11674 {
11675   /*
11676     Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
11677     statement id hash in the server uses binary collation.
11678   */
11679 #define NUM_OF_USED_STMT 97
11680   MYSQL_STMT *stmt_list[NUM_OF_USED_STMT];
11681   MYSQL_STMT **stmt;
11682   MYSQL_BIND my_bind[1];
11683   char buff[600];
11684   int rc;
11685   int32 no;
11686 
11687   myheader("test_bug5399");
11688 
11689   memset(my_bind, 0, sizeof(my_bind));
11690   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11691   my_bind[0].buffer= &no;
11692 
11693   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11694   {
11695     sprintf(buff, "select %d", (int) (stmt - stmt_list));
11696     *stmt= mysql_stmt_init(mysql);
11697     rc= mysql_stmt_prepare(*stmt, buff, (ulong)strlen(buff));
11698     check_execute(*stmt, rc);
11699     mysql_stmt_bind_result(*stmt, my_bind);
11700   }
11701   if (!opt_silent)
11702     printf("%d statements prepared.\n", NUM_OF_USED_STMT);
11703 
11704   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11705   {
11706     rc= mysql_stmt_execute(*stmt);
11707     check_execute(*stmt, rc);
11708     rc= mysql_stmt_store_result(*stmt);
11709     check_execute(*stmt, rc);
11710     rc= mysql_stmt_fetch(*stmt);
11711     DIE_UNLESS(rc == 0);
11712     DIE_UNLESS((int32) (stmt - stmt_list) == no);
11713   }
11714 
11715   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11716     mysql_stmt_close(*stmt);
11717 #undef NUM_OF_USED_STMT
11718 }
11719 
11720 
test_bug5194()11721 static void test_bug5194()
11722 {
11723   MYSQL_STMT *stmt;
11724   MYSQL_BIND *my_bind;
11725   char *query;
11726   char *param_str;
11727   ulong param_str_length;
11728   const char *stmt_text;
11729   int rc;
11730   float float_array[250] =
11731   {
11732     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11733     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11734     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11735     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11736     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11737     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11738     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11739     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11740     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11741     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11742     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11743     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11744     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11745     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11746     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11747     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11748     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11749     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11750     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11751     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11752     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11753     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11754     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11755     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11756     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25
11757   };
11758   float *fa_ptr= float_array;
11759   /* Number of columns per row */
11760   const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array);
11761   /* Number of rows per bulk insert to start with */
11762   const int MIN_ROWS_PER_INSERT= 262;
11763   /* Max number of rows per bulk insert to end with */
11764   const int MAX_ROWS_PER_INSERT= 300;
11765   const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT;
11766   const char *query_template= "insert into t1 values %s";
11767   const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */
11768   const int uint16_max= 65535;
11769   int nrows, i;
11770 
11771   myheader("test_bug5194");
11772 
11773   stmt_text= "drop table if exists t1";
11774   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11775 
11776   stmt_text= "create table if not exists t1"
11777    "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, "
11778    "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, "
11779    "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, "
11780    "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, "
11781    "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, "
11782    "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, "
11783    "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, "
11784    "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, "
11785    "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, "
11786    "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, "
11787    "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, "
11788    "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, "
11789    "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, "
11790    "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, "
11791    "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, "
11792    "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, "
11793    "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, "
11794    "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, "
11795    "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, "
11796    "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, "
11797    "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, "
11798    "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, "
11799    "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, "
11800    "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, "
11801    "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, "
11802    "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, "
11803    "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, "
11804    "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, "
11805    "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, "
11806    "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, "
11807    "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, "
11808    "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, "
11809    "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, "
11810    "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, "
11811    "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, "
11812    "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, "
11813    "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, "
11814    "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, "
11815    "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, "
11816    "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, "
11817    "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, "
11818    "c247 float, c248 float, c249 float, c250 float)";
11819   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11820   myquery(rc);
11821 
11822   my_bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11823   query= (char*) malloc(strlen(query_template) +
11824                         MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
11825   param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
11826 
11827   if (my_bind == 0 || query == 0 || param_str == 0)
11828   {
11829     fprintf(stderr, "Can't allocate enough memory for query structs\n");
11830     if (my_bind)
11831       free(my_bind);
11832     if (query)
11833       free(query);
11834     if (param_str)
11835       free(param_str);
11836     return;
11837   }
11838 
11839   stmt= mysql_stmt_init(mysql);
11840 
11841   /* setup a template for one row of parameters */
11842   sprintf(param_str, "(");
11843   for (i= 1; i < COLUMN_COUNT; ++i)
11844     strcat(param_str, "?, ");
11845   strcat(param_str, "?)");
11846   param_str_length= (ulong)strlen(param_str);
11847 
11848   /* setup bind array */
11849   memset(my_bind, 0, MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11850   for (i= 0; i < MAX_PARAM_COUNT; ++i)
11851   {
11852     my_bind[i].buffer_type= MYSQL_TYPE_FLOAT;
11853     my_bind[i].buffer= fa_ptr;
11854     if (++fa_ptr == float_array + COLUMN_COUNT)
11855       fa_ptr= float_array;
11856   }
11857 
11858   /*
11859     Test each number of rows per bulk insert, so that we can see where
11860     MySQL fails.
11861   */
11862   for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows)
11863   {
11864     char *query_ptr;
11865     /* Create statement text for current number of rows */
11866     sprintf(query, query_template, param_str);
11867     query_ptr= query + strlen(query);
11868     for (i= 1; i < nrows; ++i)
11869     {
11870       memcpy(query_ptr, ", ", 2);
11871       query_ptr+= 2;
11872       memcpy(query_ptr, param_str, param_str_length);
11873       query_ptr+= param_str_length;
11874     }
11875     *query_ptr= '\0';
11876 
11877     rc= mysql_stmt_prepare(stmt, query, (ulong)(query_ptr - query));
11878     if (rc && nrows * COLUMN_COUNT > uint16_max)
11879     {
11880       if (!opt_silent)
11881         printf("Failed to prepare a statement with %d placeholders "
11882                "(as expected).\n", nrows * COLUMN_COUNT);
11883       break;
11884     }
11885     else
11886       check_execute(stmt, rc);
11887 
11888     if (!opt_silent)
11889       printf("Insert: query length= %d, row count= %d, param count= %lu\n",
11890              (int) strlen(query), nrows, mysql_stmt_param_count(stmt));
11891 
11892     /* bind the parameter array and execute the query */
11893     rc= mysql_stmt_bind_param(stmt, my_bind);
11894     check_execute(stmt, rc);
11895 
11896     rc= mysql_stmt_execute(stmt);
11897     check_execute(stmt, rc);
11898     mysql_stmt_reset(stmt);
11899   }
11900 
11901   mysql_stmt_close(stmt);
11902   free(my_bind);
11903   free(query);
11904   free(param_str);
11905   stmt_text= "drop table t1";
11906   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11907   myquery(rc);
11908 }
11909 
11910 
test_bug5315()11911 static void test_bug5315()
11912 {
11913   MYSQL_STMT *stmt;
11914   const char *stmt_text;
11915   int rc;
11916 
11917   myheader("test_bug5315");
11918 
11919   stmt_text= "SELECT 1";
11920   stmt= mysql_stmt_init(mysql);
11921   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11922   DIE_UNLESS(rc == 0);
11923   if (!opt_silent)
11924     printf("Excuting mysql_change_user\n");
11925   mysql_change_user(mysql, opt_user, opt_password, current_db);
11926   if (!opt_silent)
11927     printf("Excuting mysql_stmt_execute\n");
11928   rc= mysql_stmt_execute(stmt);
11929   DIE_UNLESS(rc != 0);
11930   if (rc)
11931   {
11932     if (!opt_silent)
11933       printf("Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
11934   }
11935   /* check that connection is OK */
11936   if (!opt_silent)
11937     printf("Excuting mysql_stmt_close\n");
11938   mysql_stmt_close(stmt);
11939   if (!opt_silent)
11940     printf("Excuting mysql_stmt_init\n");
11941   stmt= mysql_stmt_init(mysql);
11942   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11943   DIE_UNLESS(rc == 0);
11944   rc= mysql_stmt_execute(stmt);
11945   DIE_UNLESS(rc == 0);
11946   mysql_stmt_close(stmt);
11947 }
11948 
11949 
test_bug6049()11950 static void test_bug6049()
11951 {
11952   MYSQL_STMT *stmt;
11953   MYSQL_BIND my_bind[1];
11954   MYSQL_RES *res;
11955   MYSQL_ROW row;
11956   const char *stmt_text;
11957   char buffer[30];
11958   ulong length;
11959   int rc;
11960 
11961   myheader("test_bug6049");
11962 
11963   if (mysql_get_server_version(mysql) < 50600)
11964   {
11965     if (!opt_silent)
11966       fprintf(stdout, "Skipping test_bug6049: this test cannot be executed "
11967               "on servers prior to 5.6 until bug#16433596 is fixed\n");
11968     return;
11969   }
11970 
11971   stmt_text= "SELECT MAKETIME(-25, 12, 12)";
11972 
11973   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11974   myquery(rc);
11975   res= mysql_store_result(mysql);
11976   row= mysql_fetch_row(res);
11977 
11978   stmt= mysql_stmt_init(mysql);
11979   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11980   check_execute(stmt, rc);
11981   rc= mysql_stmt_execute(stmt);
11982   check_execute(stmt, rc);
11983 
11984   memset(my_bind, 0, sizeof(my_bind));
11985   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
11986   my_bind[0].buffer         = &buffer;
11987   my_bind[0].buffer_length  = (ulong)sizeof(buffer);
11988   my_bind[0].length         = &length;
11989 
11990   mysql_stmt_bind_result(stmt, my_bind);
11991   rc= mysql_stmt_fetch(stmt);
11992   DIE_UNLESS(rc == 0);
11993 
11994   if (!opt_silent)
11995   {
11996     printf("Result from query: %s\n", row[0]);
11997     printf("Result from prepared statement: %s\n", (char*) buffer);
11998   }
11999 
12000   DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);
12001 
12002   mysql_free_result(res);
12003   mysql_stmt_close(stmt);
12004 }
12005 
12006 
test_bug6058()12007 static void test_bug6058()
12008 {
12009   MYSQL_STMT *stmt;
12010   MYSQL_BIND my_bind[1];
12011   MYSQL_RES *res;
12012   MYSQL_ROW row;
12013   const char *stmt_text;
12014   char buffer[30];
12015   ulong length;
12016   int rc;
12017 
12018   myheader("test_bug6058");
12019 
12020   rc= mysql_query(mysql, "SET SQL_MODE=''");
12021   myquery(rc);
12022 
12023   stmt_text= "SELECT CAST('0000-00-00' AS DATE)";
12024 
12025   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12026   myquery(rc);
12027   res= mysql_store_result(mysql);
12028   row= mysql_fetch_row(res);
12029 
12030   stmt= mysql_stmt_init(mysql);
12031   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12032   check_execute(stmt, rc);
12033   rc= mysql_stmt_execute(stmt);
12034   check_execute(stmt, rc);
12035 
12036   memset(my_bind, 0, sizeof(my_bind));
12037   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
12038   my_bind[0].buffer         = &buffer;
12039   my_bind[0].buffer_length  = (ulong)sizeof(buffer);
12040   my_bind[0].length         = &length;
12041 
12042   mysql_stmt_bind_result(stmt, my_bind);
12043   rc= mysql_stmt_fetch(stmt);
12044   DIE_UNLESS(rc == 0);
12045 
12046   if (!opt_silent)
12047   {
12048     printf("Result from query: %s\n", row[0]);
12049     printf("Result from prepared statement: %s\n", buffer);
12050   }
12051 
12052   DIE_UNLESS(strcmp(row[0], buffer) == 0);
12053 
12054   mysql_free_result(res);
12055   mysql_stmt_close(stmt);
12056 }
12057 
12058 
test_bug6059()12059 static void test_bug6059()
12060 {
12061   MYSQL_STMT *stmt;
12062   const char *stmt_text;
12063 
12064   myheader("test_bug6059");
12065 
12066   stmt_text= "SELECT 'foo' INTO OUTFILE 'x.3'";
12067 
12068   stmt= mysql_stmt_init(mysql);
12069   (void) mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12070   DIE_UNLESS(mysql_stmt_field_count(stmt) == 0);
12071   mysql_stmt_close(stmt);
12072 }
12073 
12074 
test_bug6046()12075 static void test_bug6046()
12076 {
12077   MYSQL_STMT *stmt;
12078   const char *stmt_text;
12079   int rc;
12080   short b= 1;
12081   MYSQL_BIND my_bind[1];
12082 
12083   myheader("test_bug6046");
12084 
12085   stmt_text= "DROP TABLE IF EXISTS t1";
12086   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12087   myquery(rc);
12088   stmt_text= "CREATE TABLE t1 (a int, b int)";
12089   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12090   myquery(rc);
12091   stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)";
12092   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12093   myquery(rc);
12094 
12095   stmt= mysql_stmt_init(mysql);
12096 
12097   stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 "
12098              "WHERE t1.b > ? ORDER BY t1.a";
12099 
12100   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12101   check_execute(stmt, rc);
12102 
12103   b= 1;
12104   memset(my_bind, 0, sizeof(my_bind));
12105   my_bind[0].buffer= &b;
12106   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
12107 
12108   mysql_stmt_bind_param(stmt, my_bind);
12109 
12110   rc= mysql_stmt_execute(stmt);
12111   check_execute(stmt, rc);
12112   mysql_stmt_store_result(stmt);
12113 
12114   rc= mysql_stmt_execute(stmt);
12115   check_execute(stmt, rc);
12116 
12117   mysql_stmt_close(stmt);
12118 }
12119 
12120 
12121 
test_basic_cursors()12122 static void test_basic_cursors()
12123 {
12124   const char *basic_tables[]=
12125   {
12126     "DROP TABLE IF EXISTS t1, t2",
12127 
12128     "CREATE TABLE t1 "
12129     "(id INTEGER NOT NULL PRIMARY KEY, "
12130     " name VARCHAR(20) NOT NULL)",
12131 
12132     "INSERT INTO t1 (id, name) VALUES "
12133     "  (2, 'Ja'), (3, 'Ede'), "
12134     "  (4, 'Haag'), (5, 'Kabul'), "
12135     "  (6, 'Almere'), (7, 'Utrecht'), "
12136     "  (8, 'Qandahar'), (9, 'Amsterdam'), "
12137     "  (10, 'Amersfoort'), (11, 'Constantine')",
12138 
12139     "CREATE TABLE t2 "
12140     "(id INTEGER NOT NULL PRIMARY KEY, "
12141     " name VARCHAR(20) NOT NULL)",
12142 
12143     "INSERT INTO t2 (id, name) VALUES "
12144     "  (4, 'Guam'), (5, 'Aruba'), "
12145     "  (6, 'Angola'), (7, 'Albania'), "
12146     "  (8, 'Anguilla'), (9, 'Argentina'), "
12147     "  (10, 'Azerbaijan'), (11, 'Afghanistan'), "
12148     "  (12, 'Burkina Faso'), (13, 'Faroe Islands')"
12149   };
12150   const char *queries[]=
12151   {
12152     "SELECT * FROM t1",
12153     "SELECT * FROM t2"
12154   };
12155 
12156   DBUG_ENTER("test_basic_cursors");
12157   myheader("test_basic_cursors");
12158 
12159   fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
12160 
12161   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12162   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12163   DBUG_VOID_RETURN;
12164 }
12165 
12166 
test_cursors_with_union()12167 static void test_cursors_with_union()
12168 {
12169   const char *queries[]=
12170   {
12171     "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2",
12172     "SELECT t1.id FROM t1 WHERE t1.id < 5"
12173   };
12174   myheader("test_cursors_with_union");
12175   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12176   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12177 }
12178 
12179 
test_cursors_with_procedure()12180 static void test_cursors_with_procedure()
12181 {
12182   const char *queries[]=
12183   {
12184     "SELECT * FROM t1 procedure analyse()"
12185   };
12186   myheader("test_cursors_with_procedure");
12187   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12188   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12189 }
12190 
12191 
12192 /*
12193   Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
12194   should not crash server and should not hang in case of errors.
12195 
12196   Since those functions can't be seen in modern API we use simple_command() macro.
12197 */
test_bug6081()12198 static void test_bug6081()
12199 {
12200   int rc;
12201   myheader("test_bug6081");
12202 
12203   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12204                      (ulong)strlen(current_db), 0);
12205   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12206   {
12207     myerror(NULL);                                   /* purecov: inspected */
12208     die(__FILE__, __LINE__, "COM_DROP_DB failed");   /* purecov: inspected */
12209   }
12210   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12211                      (ulong)strlen(current_db), 0);
12212   myquery_r(rc);
12213   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12214                      (ulong)strlen(current_db), 0);
12215   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12216   {
12217     myerror(NULL);                                   /* purecov: inspected */
12218     die(__FILE__, __LINE__, "COM_CREATE_DB failed"); /* purecov: inspected */
12219   }
12220   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12221                      (ulong)strlen(current_db), 0);
12222   myquery_r(rc);
12223   rc= mysql_select_db(mysql, current_db);
12224   myquery(rc);
12225 }
12226 
12227 
test_bug6096()12228 static void test_bug6096()
12229 {
12230   MYSQL_STMT *stmt;
12231   MYSQL_RES *query_result, *stmt_metadata;
12232   const char *stmt_text;
12233   MYSQL_BIND my_bind[12];
12234   MYSQL_FIELD *query_field_list, *stmt_field_list;
12235   ulong query_field_count, stmt_field_count;
12236   int rc;
12237   my_bool update_max_length= TRUE;
12238   uint i;
12239 
12240   myheader("test_bug6096");
12241 
12242   stmt_text= "drop table if exists t1";
12243   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12244   myquery(rc);
12245 
12246   mysql_query(mysql, "set sql_mode=''");
12247   stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, "
12248                              " c_mediumint mediumint, c_int int, "
12249                              " c_bigint bigint, c_float float, "
12250                              " c_double double, c_varchar varchar(20), "
12251                              " c_char char(20), c_time time, c_date date, "
12252                              " c_datetime datetime)";
12253   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12254   myquery(rc);
12255   stmt_text= "insert into t1  values (-100, -20000, 30000000, 4, 8, 1.0, "
12256                                      "2.0, 'abc', 'def', now(), now(), now())";
12257   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12258   myquery(rc);
12259 
12260   stmt_text= "select * from t1";
12261 
12262   /* Run select in prepared and non-prepared mode and compare metadata */
12263   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12264   myquery(rc);
12265   query_result= mysql_store_result(mysql);
12266   query_field_list= mysql_fetch_fields(query_result);
12267   query_field_count= mysql_num_fields(query_result);
12268 
12269   stmt= mysql_stmt_init(mysql);
12270   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12271   check_execute(stmt, rc);
12272   rc= mysql_stmt_execute(stmt);
12273   check_execute(stmt, rc);
12274   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
12275                       (void*) &update_max_length);
12276   mysql_stmt_store_result(stmt);
12277   stmt_metadata= mysql_stmt_result_metadata(stmt);
12278   stmt_field_list= mysql_fetch_fields(stmt_metadata);
12279   stmt_field_count= mysql_num_fields(stmt_metadata);
12280   DIE_UNLESS(stmt_field_count == query_field_count);
12281 
12282   /* Print out and check the metadata */
12283 
12284   if (!opt_silent)
12285   {
12286     printf(" ------------------------------------------------------------\n");
12287     printf("             |                     Metadata \n");
12288     printf(" ------------------------------------------------------------\n");
12289     printf("             |         Query          |   Prepared statement \n");
12290     printf(" ------------------------------------------------------------\n");
12291     printf(" field name  |  length   | max_length |  length   |  max_length\n");
12292     printf(" ------------------------------------------------------------\n");
12293 
12294     for (i= 0; i < query_field_count; ++i)
12295     {
12296       MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
12297       printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
12298              f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
12299       DIE_UNLESS(f1->length == f2->length);
12300     }
12301     printf(" ---------------------------------------------------------------\n");
12302   }
12303 
12304   /* Bind and fetch the data */
12305 
12306   memset(my_bind, 0, sizeof(my_bind));
12307   for (i= 0; i < stmt_field_count; ++i)
12308   {
12309     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
12310     my_bind[i].buffer_length= stmt_field_list[i].max_length + 1;
12311     my_bind[i].buffer= malloc(my_bind[i].buffer_length);
12312   }
12313   mysql_stmt_bind_result(stmt, my_bind);
12314   rc= mysql_stmt_fetch(stmt);
12315   check_execute(stmt, rc);
12316   rc= mysql_stmt_fetch(stmt);
12317   DIE_UNLESS(rc == MYSQL_NO_DATA);
12318 
12319   /* Clean up */
12320 
12321   for (i= 0; i < stmt_field_count; ++i)
12322     free(my_bind[i].buffer);
12323   mysql_stmt_close(stmt);
12324   mysql_free_result(query_result);
12325   mysql_free_result(stmt_metadata);
12326   stmt_text= "drop table t1";
12327   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12328   myquery(rc);
12329 }
12330 
12331 
12332 /*
12333   Test of basic checks that are performed in server for components
12334   of MYSQL_TIME parameters.
12335 */
12336 
test_datetime_ranges()12337 static void test_datetime_ranges()
12338 {
12339   const char *stmt_text;
12340   int rc, i;
12341   MYSQL_STMT *stmt;
12342   MYSQL_BIND my_bind[6];
12343   MYSQL_TIME tm[6];
12344 
12345   myheader("test_datetime_ranges");
12346 
12347   stmt_text= "drop table if exists t1";
12348   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12349   myquery(rc);
12350 
12351   stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
12352                               "hour datetime, min datetime, sec datetime)";
12353   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12354   myquery(rc);
12355 
12356   stmt= mysql_simple_prepare(mysql,
12357                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
12358   check_stmt(stmt);
12359   verify_param_count(stmt, 6);
12360 
12361   memset(my_bind, 0, sizeof(my_bind));
12362   for (i= 0; i < 6; i++)
12363   {
12364     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12365     my_bind[i].buffer= &tm[i];
12366   }
12367   rc= mysql_stmt_bind_param(stmt, my_bind);
12368   check_execute(stmt, rc);
12369 
12370   tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
12371   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12372   tm[0].second_part= 0; tm[0].neg= 0;
12373 
12374   tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12375   tm[0].year= 10000;  tm[1].month= 13; tm[2].day= 32;
12376   tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;
12377 
12378   rc= mysql_stmt_execute(stmt);
12379   check_execute(stmt, rc);
12380   /* behaviour changed by WL#5928 */
12381   my_process_warnings(mysql, mysql_get_server_version(mysql) < 50702 ? 12 : 6);
12382 
12383   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12384   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12385   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12386   verify_col_data("t1", "hour", "0000-00-00 00:00:00");
12387   verify_col_data("t1", "min", "0000-00-00 00:00:00");
12388   verify_col_data("t1", "sec", "0000-00-00 00:00:00");
12389 
12390   mysql_stmt_close(stmt);
12391 
12392   stmt_text= "delete from t1";
12393   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12394   myquery(rc);
12395 
12396   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
12397                                     "VALUES (?, ?, ?)");
12398   check_stmt(stmt);
12399   verify_param_count(stmt, 3);
12400 
12401   /*
12402     We reuse contents of bind and tm arrays left from previous part of test.
12403   */
12404   for (i= 0; i < 3; i++)
12405     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12406 
12407   rc= mysql_stmt_bind_param(stmt, my_bind);
12408   check_execute(stmt, rc);
12409 
12410   rc= mysql_stmt_execute(stmt);
12411   check_execute(stmt, rc);
12412   /* behaviour changed by WL#5928 */
12413   my_process_warnings(mysql, mysql_get_server_version(mysql) < 50702 ? 6 : 3);
12414 
12415   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12416   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12417   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12418 
12419   mysql_stmt_close(stmt);
12420 
12421   stmt_text= "drop table t1";
12422   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12423   myquery(rc);
12424 
12425   stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
12426   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12427   myquery(rc);
12428 
12429   stmt= mysql_simple_prepare(mysql,
12430                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
12431   check_stmt(stmt);
12432   verify_param_count(stmt, 5);
12433 
12434   /*
12435     Again we reuse what we can from previous part of test.
12436   */
12437   for (i= 0; i < 5; i++)
12438     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12439 
12440   rc= mysql_stmt_bind_param(stmt, my_bind);
12441   check_execute(stmt, rc);
12442 
12443   tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
12444   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12445   tm[0].second_part= 0; tm[0].neg= 0;
12446 
12447   tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12448   tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;
12449 
12450   rc= mysql_stmt_execute(stmt);
12451   check_execute(stmt, rc);
12452   /* behaviour changed by WL#5928 */
12453   my_process_warnings(mysql, mysql_get_server_version(mysql) < 50702 ? 2 : 0);
12454 
12455   verify_col_data("t1", "day_ovfl", "838:59:59");
12456   verify_col_data("t1", "day", "828:30:30");
12457   verify_col_data("t1", "hour", "270:30:30");
12458   verify_col_data("t1", "min", "00:00:00");
12459   verify_col_data("t1", "sec", "00:00:00");
12460 
12461   mysql_stmt_close(stmt);
12462 
12463   stmt_text= "drop table t1";
12464   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12465   myquery(rc);
12466 }
12467 
12468 
test_bug4172()12469 static void test_bug4172()
12470 {
12471   MYSQL_STMT *stmt;
12472   MYSQL_BIND my_bind[3];
12473   const char *stmt_text;
12474   MYSQL_RES *res;
12475   MYSQL_ROW row;
12476   int rc;
12477   char f[100], d[100], e[100];
12478   ulong f_len, d_len, e_len;
12479 
12480   myheader("test_bug4172");
12481 
12482   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
12483   mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))");
12484   mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, "
12485                                             "123456.1234)");
12486 
12487   stmt= mysql_stmt_init(mysql);
12488   stmt_text= "SELECT f, d, e FROM t1";
12489 
12490   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12491   check_execute(stmt, rc);
12492   rc= mysql_stmt_execute(stmt);
12493   check_execute(stmt, rc);
12494 
12495   memset(my_bind, 0, sizeof(my_bind));
12496   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12497   my_bind[0].buffer= f;
12498   my_bind[0].buffer_length= (ulong)sizeof(f);
12499   my_bind[0].length= &f_len;
12500   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
12501   my_bind[1].buffer= d;
12502   my_bind[1].buffer_length= (ulong)sizeof(d);
12503   my_bind[1].length= &d_len;
12504   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
12505   my_bind[2].buffer= e;
12506   my_bind[2].buffer_length= (ulong)sizeof(e);
12507   my_bind[2].length= &e_len;
12508 
12509   mysql_stmt_bind_result(stmt, my_bind);
12510 
12511   mysql_stmt_store_result(stmt);
12512   rc= mysql_stmt_fetch(stmt);
12513   check_execute(stmt, rc);
12514 
12515   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12516   myquery(rc);
12517   res= mysql_store_result(mysql);
12518   row= mysql_fetch_row(res);
12519 
12520   if (!opt_silent)
12521   {
12522     printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n",
12523            f, d, e);
12524     printf("Text protocol:   float=%s, double=%s, decimal(10,4)=%s\n",
12525            row[0], row[1], row[2]);
12526   }
12527   DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]));
12528 
12529   mysql_free_result(res);
12530   mysql_stmt_close(stmt);
12531 }
12532 
12533 
test_conversion()12534 static void test_conversion()
12535 {
12536   MYSQL_STMT *stmt;
12537   const char *stmt_text;
12538   int rc;
12539   MYSQL_BIND my_bind[1];
12540   char buff[4];
12541   ulong length;
12542 
12543   myheader("test_conversion");
12544 
12545   stmt_text= "DROP TABLE IF EXISTS t1";
12546   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12547   myquery(rc);
12548   stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
12549   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12550   myquery(rc);
12551   stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
12552              " character_set_results=latin1";
12553   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12554   myquery(rc);
12555 
12556   stmt= mysql_stmt_init(mysql);
12557 
12558   stmt_text= "INSERT INTO t1 (a) VALUES (?)";
12559   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12560   check_execute(stmt, rc);
12561 
12562   memset(my_bind, 0, sizeof(my_bind));
12563   my_bind[0].buffer= buff;
12564   my_bind[0].length= &length;
12565   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12566 
12567   mysql_stmt_bind_param(stmt, my_bind);
12568 
12569   buff[0]= (uchar) 0xC3;
12570   buff[1]= (uchar) 0xA0;
12571   length= 2;
12572 
12573   rc= mysql_stmt_execute(stmt);
12574   check_execute(stmt, rc);
12575 
12576   stmt_text= "SELECT a FROM t1";
12577   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12578   check_execute(stmt, rc);
12579   rc= mysql_stmt_execute(stmt);
12580   check_execute(stmt, rc);
12581 
12582   my_bind[0].buffer_length= (ulong)sizeof(buff);
12583   mysql_stmt_bind_result(stmt, my_bind);
12584 
12585   rc= mysql_stmt_fetch(stmt);
12586   DIE_UNLESS(rc == 0);
12587   DIE_UNLESS(length == 1);
12588   DIE_UNLESS((uchar) buff[0] == 0xE0);
12589   rc= mysql_stmt_fetch(stmt);
12590   DIE_UNLESS(rc == MYSQL_NO_DATA);
12591 
12592   mysql_stmt_close(stmt);
12593   stmt_text= "DROP TABLE t1";
12594   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12595   myquery(rc);
12596   stmt_text= "SET NAMES DEFAULT";
12597   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12598   myquery(rc);
12599 }
12600 
test_rewind(void)12601 static void test_rewind(void)
12602 {
12603   MYSQL_STMT *stmt;
12604   MYSQL_BIND my_bind;
12605   int rc = 0;
12606   const char *stmt_text;
12607   ulong length= 4;
12608   long unsigned int Data= 0;
12609   my_bool isnull=0;
12610 
12611   myheader("test_rewind");
12612 
12613   stmt_text= "CREATE TABLE t1 (a int)";
12614   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12615   myquery(rc);
12616   stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)";
12617   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12618   myquery(rc);
12619 
12620   stmt= mysql_stmt_init(mysql);
12621 
12622   stmt_text= "SELECT * FROM t1";
12623   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12624   check_execute(stmt, rc);
12625 
12626   memset(&my_bind, 0, sizeof(MYSQL_BIND));
12627   my_bind.buffer_type= MYSQL_TYPE_LONG;
12628   my_bind.buffer= (void *)&Data; /* this buffer won't be altered */
12629   my_bind.length= &length;
12630   my_bind.is_null= &isnull;
12631 
12632   rc= mysql_stmt_execute(stmt);
12633   check_execute(stmt, rc);
12634 
12635   rc= mysql_stmt_store_result(stmt);
12636   DIE_UNLESS(rc == 0);
12637 
12638   rc= mysql_stmt_bind_result(stmt, &my_bind);
12639   DIE_UNLESS(rc == 0);
12640 
12641   /* retreive all result sets till we are at the end */
12642   while(!mysql_stmt_fetch(stmt))
12643     if (!opt_silent)
12644       printf("fetched result:%ld\n", Data);
12645 
12646   DIE_UNLESS(rc != MYSQL_NO_DATA);
12647 
12648   /* seek to the first row */
12649   mysql_stmt_data_seek(stmt, 0);
12650 
12651   /* now we should be able to fetch the results again */
12652   /* but mysql_stmt_fetch returns MYSQL_NO_DATA */
12653   while(!(rc= mysql_stmt_fetch(stmt)))
12654     if (!opt_silent)
12655       printf("fetched result after seek:%ld\n", Data);
12656 
12657   DIE_UNLESS(rc == MYSQL_NO_DATA);
12658 
12659   stmt_text= "DROP TABLE t1";
12660   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12661   myquery(rc);
12662   rc= mysql_stmt_free_result(stmt);
12663   rc= mysql_stmt_close(stmt);
12664 }
12665 
12666 
test_truncation()12667 static void test_truncation()
12668 {
12669   MYSQL_STMT *stmt;
12670   const char *stmt_text;
12671   int rc;
12672   uint bind_count;
12673   MYSQL_BIND *bind_array, *my_bind;
12674 
12675   myheader("test_truncation");
12676 
12677   /* Prepare the test table */
12678   rc= mysql_query(mysql, "drop table if exists t1");
12679   myquery(rc);
12680 
12681   stmt_text= "create table t1 ("
12682              "i8 tinyint, ui8 tinyint unsigned, "
12683              "i16 smallint, i16_1 smallint, "
12684              "ui16 smallint unsigned, i32 int, i32_1 int, "
12685              "d double, d_1 double, ch char(30), ch_1 char(30), "
12686              "tx text, tx_1 text, ch_2 char(30) "
12687              ")";
12688   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12689   myquery(rc);
12690 
12691   {
12692     const char insert_text[]=
12693              "insert into t1 VALUES ("
12694              "-10, "                            /* i8 */
12695              "200, "                            /* ui8 */
12696              "32000, "                          /* i16 */
12697              "-32767, "                         /* i16_1 */
12698              "64000, "                          /* ui16 */
12699              "1073741824, "                     /* i32 */
12700              "1073741825, "                     /* i32_1 */
12701              "123.456, "                        /* d */
12702              "-12345678910, "                   /* d_1 */
12703              "'111111111111111111111111111111',"/* ch */
12704              "'abcdef', "                       /* ch_1 */
12705              "'12345 	      ', "              /* tx */
12706              "'12345.67 	      ', "      /* tx_1 */
12707              "'12345.67abc'"                    /* ch_2 */
12708              ")";
12709     rc= mysql_real_query(mysql, insert_text, (ulong)strlen(insert_text));
12710     myquery(rc);
12711   }
12712 
12713   stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, "
12714              "       i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, "
12715              "       d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, "
12716              "       tx_1 c17, ch_2 c18 "
12717              "from t1";
12718 
12719   stmt= mysql_stmt_init(mysql);
12720   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12721   check_execute(stmt, rc);
12722   rc= mysql_stmt_execute(stmt);
12723   check_execute(stmt, rc);
12724   bind_count= (uint) mysql_stmt_field_count(stmt);
12725 
12726   /*************** Fill in the bind structure and bind it **************/
12727   bind_array= malloc(sizeof(MYSQL_BIND) * bind_count);
12728   memset(bind_array, 0, sizeof(MYSQL_BIND) * bind_count);
12729   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12730     my_bind->error= &my_bind->error_value;
12731   my_bind= bind_array;
12732 
12733   my_bind->buffer= malloc(sizeof(uint8));
12734   my_bind->buffer_type= MYSQL_TYPE_TINY;
12735   my_bind->is_unsigned= TRUE;
12736 
12737   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12738   my_bind->buffer= malloc(sizeof(uint32));
12739   my_bind->buffer_type= MYSQL_TYPE_LONG;
12740   my_bind->is_unsigned= TRUE;
12741 
12742   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12743   my_bind->buffer= malloc(sizeof(int8));
12744   my_bind->buffer_type= MYSQL_TYPE_TINY;
12745 
12746   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12747   my_bind->buffer= malloc(sizeof(uint16));
12748   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12749   my_bind->is_unsigned= TRUE;
12750 
12751   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12752   my_bind->buffer= malloc(sizeof(int16));
12753   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12754 
12755   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12756   my_bind->buffer= malloc(sizeof(uint16));
12757   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12758   my_bind->is_unsigned= TRUE;
12759 
12760   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12761   my_bind->buffer= malloc(sizeof(int8));
12762   my_bind->buffer_type= MYSQL_TYPE_TINY;
12763   my_bind->is_unsigned= TRUE;
12764 
12765   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12766   my_bind->buffer= malloc(sizeof(float));
12767   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12768 
12769   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12770   my_bind->buffer= malloc(sizeof(float));
12771   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12772 
12773   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12774   my_bind->buffer= malloc(sizeof(double));
12775   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12776 
12777   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12778   my_bind->buffer= malloc(sizeof(longlong));
12779   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12780 
12781   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12782   my_bind->buffer= malloc(sizeof(ulonglong));
12783   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12784   my_bind->is_unsigned= TRUE;
12785 
12786   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12787   my_bind->buffer= malloc(sizeof(longlong));
12788   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12789 
12790   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12791   my_bind->buffer= malloc(sizeof(longlong));
12792   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12793 
12794   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12795   my_bind->buffer= malloc(sizeof(longlong));
12796   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12797 
12798   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12799   my_bind->buffer= malloc(sizeof(longlong));
12800   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12801 
12802   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12803   my_bind->buffer= malloc(sizeof(double));
12804   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12805 
12806   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12807   my_bind->buffer= malloc(sizeof(double));
12808   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12809 
12810   rc= mysql_stmt_bind_result(stmt, bind_array);
12811   check_execute(stmt, rc);
12812   rc= mysql_stmt_fetch(stmt);
12813   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12814 
12815   /*************** Verify truncation results ***************************/
12816   my_bind= bind_array;
12817 
12818   /* signed tiny -> tiny */
12819   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == -10);
12820 
12821   /* signed tiny -> uint32 */
12822   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12823   DIE_UNLESS(*my_bind->error && * (int32*) my_bind->buffer == -10);
12824 
12825   /* unsigned tiny -> tiny */
12826   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12827   DIE_UNLESS(*my_bind->error && * (uint8*) my_bind->buffer == 200);
12828 
12829   /* short -> ushort */
12830   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12831   DIE_UNLESS(*my_bind->error && * (int16*) my_bind->buffer == -32767);
12832 
12833   /* ushort -> short */
12834   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12835   DIE_UNLESS(*my_bind->error && * (uint16*) my_bind->buffer == 64000);
12836 
12837   /* short -> ushort (no truncation, data is in the range of target type) */
12838   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12839   DIE_UNLESS(! *my_bind->error && * (uint16*) my_bind->buffer == 32000);
12840 
12841   /* ushort -> utiny */
12842   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12843   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == 0);
12844 
12845   /* int -> float: no truncation, the number is a power of two */
12846   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12847   DIE_UNLESS(! *my_bind->error && * (float*) my_bind->buffer == 1073741824);
12848 
12849   /* int -> float: truncation, not enough bits in float */
12850   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12851   DIE_UNLESS(*my_bind->error);
12852 
12853   /* int -> double: no truncation */
12854   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12855   DIE_UNLESS(! *my_bind->error && * (double*) my_bind->buffer == 1073741825);
12856 
12857   /* double -> longlong: fractional part is lost */
12858   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12859 
12860   /* double -> ulonglong, negative fp number to unsigned integer */
12861   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12862   /* Value in the buffer is not defined: don't test it */
12863   DIE_UNLESS(*my_bind->error);
12864 
12865   /* double -> longlong, negative fp number to signed integer: no loss */
12866   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12867   DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == -12345678910LL);
12868 
12869   /* big numeric string -> number */
12870   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12871   DIE_UNLESS(*my_bind->error);
12872 
12873   /* junk string -> number */
12874   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12875   DIE_UNLESS(*my_bind->error && *(longlong*) my_bind->buffer == 0);
12876 
12877   /* string with trailing spaces -> number */
12878   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12879   DIE_UNLESS(! *my_bind->error && *(longlong*) my_bind->buffer == 12345);
12880 
12881   /* string with trailing spaces -> double */
12882   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12883   DIE_UNLESS(! *my_bind->error && *(double*) my_bind->buffer == 12345.67);
12884 
12885   /* string with trailing junk -> double */
12886   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12887   /*
12888     XXX: There must be a truncation error: but it's not the way the server
12889     behaves, so let's leave it for now.
12890   */
12891   DIE_UNLESS(*(double*) my_bind->buffer == 12345.67);
12892   /*
12893     TODO: string -> double,  double -> time, double -> string (truncation
12894           errors are not supported here yet)
12895           longlong -> time/date/datetime
12896           date -> time, date -> timestamp, date -> number
12897           time -> string, time -> date, time -> timestamp,
12898           number -> date string -> date
12899   */
12900   /*************** Cleanup *********************************************/
12901 
12902   mysql_stmt_close(stmt);
12903 
12904   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12905     free(my_bind->buffer);
12906   free(bind_array);
12907 
12908   rc= mysql_query(mysql, "drop table t1");
12909   myquery(rc);
12910 }
12911 
test_truncation_option()12912 static void test_truncation_option()
12913 {
12914   MYSQL_STMT *stmt;
12915   const char *stmt_text;
12916   int rc;
12917   uint8 buf;
12918   my_bool option= 0;
12919   my_bool error;
12920   MYSQL_BIND my_bind;
12921 
12922   myheader("test_truncation_option");
12923 
12924   /* Prepare the test table */
12925   stmt_text= "select -1";
12926 
12927   stmt= mysql_stmt_init(mysql);
12928   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12929   check_execute(stmt, rc);
12930   rc= mysql_stmt_execute(stmt);
12931   check_execute(stmt, rc);
12932 
12933   memset(&my_bind, 0, sizeof(my_bind));
12934 
12935   my_bind.buffer= (void*) &buf;
12936   my_bind.buffer_type= MYSQL_TYPE_TINY;
12937   my_bind.is_unsigned= TRUE;
12938   my_bind.error= &error;
12939 
12940   rc= mysql_stmt_bind_result(stmt, &my_bind);
12941   check_execute(stmt, rc);
12942   rc= mysql_stmt_fetch(stmt);
12943   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12944   DIE_UNLESS(error);
12945   rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
12946   myquery(rc);
12947   /* need to rebind for the new setting to take effect */
12948   rc= mysql_stmt_bind_result(stmt, &my_bind);
12949   check_execute(stmt, rc);
12950   rc= mysql_stmt_execute(stmt);
12951   check_execute(stmt, rc);
12952   rc= mysql_stmt_fetch(stmt);
12953   check_execute(stmt, rc);
12954   /* The only change is rc - error pointers are still filled in */
12955   DIE_UNLESS(error == 1);
12956   /* restore back the defaults */
12957   option= 1;
12958   mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
12959 
12960   mysql_stmt_close(stmt);
12961 }
12962 
12963 
12964 /* Bug#6761 - mysql_list_fields doesn't work */
12965 
test_bug6761(void)12966 static void test_bug6761(void)
12967 {
12968   const char *stmt_text;
12969   MYSQL_RES *res;
12970   int rc;
12971   myheader("test_bug6761");
12972 
12973   stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
12974   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12975   myquery(rc);
12976 
12977   res= mysql_list_fields(mysql, "t1", "%");
12978   DIE_UNLESS(res && mysql_num_fields(res) == 3);
12979   mysql_free_result(res);
12980 
12981   stmt_text= "DROP TABLE t1";
12982   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12983   myquery(rc);
12984 }
12985 
12986 
12987 /* Bug#8330 - mysql_stmt_execute crashes (libmysql) */
12988 
test_bug8330()12989 static void test_bug8330()
12990 {
12991   const char *stmt_text;
12992   MYSQL_STMT *stmt[2];
12993   int i, rc;
12994   const char *query= "select a,b from t1 where a=?";
12995   MYSQL_BIND my_bind[2];
12996   long lval[2];
12997 
12998   myheader("test_bug8330");
12999 
13000   stmt_text= "drop table if exists t1";
13001   /* in case some previos test failed */
13002   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13003   myquery(rc);
13004   stmt_text= "create table t1 (a int, b int)";
13005   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13006   myquery(rc);
13007 
13008   memset(my_bind, 0, sizeof(my_bind));
13009   memset(lval, 0, sizeof(lval));
13010   for (i=0; i < 2; i++)
13011   {
13012     stmt[i]= mysql_stmt_init(mysql);
13013     rc= mysql_stmt_prepare(stmt[i], query, (ulong)strlen(query));
13014     check_execute(stmt[i], rc);
13015 
13016     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
13017     my_bind[i].buffer= (void*) &lval[i];
13018     my_bind[i].is_null= 0;
13019     mysql_stmt_bind_param(stmt[i], &my_bind[i]);
13020   }
13021 
13022   rc= mysql_stmt_execute(stmt[0]);
13023   check_execute(stmt[0], rc);
13024 
13025   rc= mysql_stmt_execute(stmt[1]);
13026   DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
13027   rc= mysql_stmt_execute(stmt[0]);
13028   check_execute(stmt[0], rc);
13029 
13030   mysql_stmt_close(stmt[0]);
13031   mysql_stmt_close(stmt[1]);
13032 
13033   stmt_text= "drop table t1";
13034   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13035   myquery(rc);
13036 }
13037 
13038 
13039 /* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */
13040 
test_bug7990()13041 static void test_bug7990()
13042 {
13043   MYSQL_STMT *stmt;
13044   int rc;
13045   myheader("test_bug7990");
13046 
13047   stmt= mysql_stmt_init(mysql);
13048   rc= mysql_stmt_prepare(stmt, "foo", 3);
13049   /*
13050     XXX: the fact that we store errno both in STMT and in
13051     MYSQL is not documented and is subject to change in 5.0
13052   */
13053   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql));
13054   mysql_stmt_close(stmt);
13055   DIE_UNLESS(!mysql_errno(mysql));
13056 }
13057 
13058 /*
13059   Bug #15518 - Reusing a stmt that has failed during prepare
13060   does not clear error
13061 */
13062 
test_bug15518()13063 static void test_bug15518()
13064 {
13065   MYSQL_STMT *stmt;
13066   MYSQL* mysql1;
13067   int rc;
13068   myheader("test_bug15518");
13069 
13070   mysql1= mysql_client_init(NULL);
13071 
13072   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13073                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13074                           CLIENT_MULTI_STATEMENTS))
13075   {
13076     fprintf(stderr, "Failed to connect to the database\n");
13077     DIE_UNLESS(0);
13078   }
13079 
13080   stmt= mysql_stmt_init(mysql1);
13081 
13082   /*
13083     The prepare of foo should fail with errno 1064 since
13084     it's not a valid query
13085   */
13086   rc= mysql_stmt_prepare(stmt, "foo", 3);
13087   if (!opt_silent)
13088     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13089             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13090   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13091 
13092   /*
13093     Use the same stmt and reprepare with another query that
13094     suceeds
13095   */
13096   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13097   if (!opt_silent)
13098     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13099             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13100   DIE_UNLESS(!rc || mysql_stmt_errno(stmt) || mysql_errno(mysql1));
13101 
13102   mysql_stmt_close(stmt);
13103   DIE_UNLESS(!mysql_errno(mysql1));
13104 
13105   /*
13106     part2, when connection to server has been closed
13107     after first prepare
13108   */
13109   stmt= mysql_stmt_init(mysql1);
13110   rc= mysql_stmt_prepare(stmt, "foo", 3);
13111   if (!opt_silent)
13112     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13113             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13114   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13115 
13116   /* Close connection to server */
13117   mysql_close(mysql1);
13118 
13119   /*
13120     Use the same stmt and reprepare with another query that
13121     suceeds. The prepare should fail with error 2013 since
13122     connection to server has been closed.
13123   */
13124   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13125   if (!opt_silent)
13126     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d\n",
13127             rc, mysql_stmt_errno(stmt));
13128   DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13129 
13130   mysql_stmt_close(stmt);
13131 }
13132 
13133 
disable_query_logs()13134 static void disable_query_logs()
13135 {
13136   int rc;
13137   rc= mysql_query(mysql, "set @@global.general_log=off");
13138   myquery(rc);
13139   rc= mysql_query(mysql, "set @@global.slow_query_log=off");
13140   myquery(rc);
13141 }
13142 
13143 
enable_query_logs(int truncate)13144 static void enable_query_logs(int truncate)
13145 {
13146   int rc;
13147 
13148   rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
13149   myquery(rc);
13150 
13151   rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log");
13152   myquery(rc);
13153 
13154   rc= mysql_query(mysql, "set @@global.general_log=on");
13155   myquery(rc);
13156 
13157   rc= mysql_query(mysql, "set @@global.slow_query_log=on");
13158   myquery(rc);
13159 
13160 
13161   if (truncate)
13162   {
13163     rc= mysql_query(mysql, "truncate mysql.general_log");
13164     myquery(rc);
13165 
13166     rc= mysql_query(mysql, "truncate mysql.slow_log");
13167     myquery(rc);
13168   }
13169 }
13170 
13171 
restore_query_logs()13172 static void restore_query_logs()
13173 {
13174   int rc;
13175   rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
13176   myquery(rc);
13177 
13178   rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log");
13179   myquery(rc);
13180 }
13181 
13182 
test_view_sp_list_fields()13183 static void test_view_sp_list_fields()
13184 {
13185   int		rc;
13186   MYSQL_RES     *res;
13187 
13188   myheader("test_view_sp_list_fields");
13189 
13190   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
13191   myquery(rc);
13192   rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
13193   myquery(rc);
13194   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
13195   myquery(rc);
13196   rc= mysql_query(mysql, "create function f1 () returns int return 5");
13197   myquery(rc);
13198   rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
13199   myquery(rc);
13200   rc= mysql_query(mysql, "create table t2 (s1 int);");
13201   myquery(rc);
13202   rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
13203 count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
13204 from t2);");
13205   myquery(rc);
13206   res= mysql_list_fields(mysql, "v1", NullS);
13207   DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0);
13208   rc= mysql_query(mysql, "DROP FUNCTION f1");
13209   myquery(rc);
13210   rc= mysql_query(mysql, "DROP VIEW v1");
13211   myquery(rc);
13212   rc= mysql_query(mysql, "DROP TABLE t1, t2");
13213   mysql_free_result(res);
13214   myquery(rc);
13215 
13216 }
13217 
13218 
13219 /*
13220  Test mysql_real_escape_string_quote() with gbk charset
13221 
13222  The important part is that 0x27 (') is the second-byte in a invalid
13223  two-byte GBK character here. But 0xbf5c is a valid GBK character, so
13224  it needs to be escaped as 0x5cbf27
13225 */
13226 #define TEST_BUG8378_IN  "\xef\xbb\xbf\x27\xbf\x10"
13227 #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
13228 
test_bug8378()13229 static void test_bug8378()
13230 {
13231 #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
13232   MYSQL *lmysql;
13233   char out[9]; /* strlen(TEST_BUG8378)*2+1 */
13234   char buf[256];
13235   int len, rc;
13236 
13237   myheader("test_bug8378");
13238 
13239   if (!opt_silent)
13240     fprintf(stdout, "\n Establishing a test connection ...");
13241   if (!(lmysql= mysql_client_init(NULL)))
13242   {
13243     myerror("mysql_client_init() failed");
13244     exit(1);
13245   }
13246   if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
13247   {
13248     myerror("mysql_options() failed");
13249     exit(1);
13250   }
13251   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
13252                            opt_password, current_db, opt_port,
13253                            opt_unix_socket, 0)))
13254   {
13255     myerror("connection failed");
13256     exit(1);
13257   }
13258   if (!opt_silent)
13259     fprintf(stdout, "OK");
13260 
13261   rc= mysql_query(lmysql, "SET SQL_MODE=''");
13262   myquery(rc);
13263 
13264   len= mysql_real_escape_string_quote(lmysql, out, TEST_BUG8378_IN, 4, '\'');
13265 
13266   /* No escaping should have actually happened. */
13267   DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
13268 
13269   sprintf(buf, "SELECT '%s'", out);
13270 
13271   rc=mysql_real_query(lmysql, buf, (ulong)strlen(buf));
13272   myquery(rc);
13273 
13274   mysql_close(lmysql);
13275 #endif
13276 }
13277 
13278 
test_bug8722()13279 static void test_bug8722()
13280 {
13281   MYSQL_STMT *stmt;
13282   int rc;
13283   const char *stmt_text;
13284 
13285   myheader("test_bug8722");
13286   /* Prepare test data */
13287   stmt_text= "drop table if exists t1, v1";
13288   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13289   myquery(rc);
13290   stmt_text= "CREATE TABLE t1 (c1 varchar(10), c2 varchar(10), c3 varchar(10),"
13291                              " c4 varchar(10), c5 varchar(10), c6 varchar(10),"
13292                              " c7 varchar(10), c8 varchar(10), c9 varchar(10),"
13293                              "c10 varchar(10))";
13294   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13295   myquery(rc);
13296   stmt_text= "INSERT INTO t1 VALUES (1,2,3,4,5,6,7,8,9,10)";
13297   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13298   myquery(rc);
13299   stmt_text= "CREATE VIEW v1 AS SELECT * FROM t1";
13300   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13301   myquery(rc);
13302   /* Note: if you uncomment following block everything works fine */
13303 /*
13304   rc= mysql_query(mysql, "sellect * from v1");
13305   myquery(rc);
13306   mysql_free_result(mysql_store_result(mysql));
13307 */
13308 
13309   stmt= mysql_stmt_init(mysql);
13310   stmt_text= "select * from v1";
13311   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13312   check_execute(stmt, rc);
13313   mysql_stmt_close(stmt);
13314   stmt_text= "drop table if exists t1, v1";
13315   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13316   myquery(rc);
13317 }
13318 
13319 
open_cursor(const char * query)13320 MYSQL_STMT *open_cursor(const char *query)
13321 {
13322   int rc;
13323   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
13324 
13325   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
13326   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
13327   check_execute(stmt, rc);
13328 
13329   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13330   return stmt;
13331 }
13332 
13333 
test_bug8880()13334 static void test_bug8880()
13335 {
13336   MYSQL_STMT *stmt_list[2], **stmt;
13337   MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
13338   int rc;
13339 
13340   myheader("test_bug8880");
13341 
13342   mysql_query(mysql, "drop table if exists t1");
13343   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13344   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13345   myquery(rc);                                  /* one check is enough */
13346   /*
13347     when inserting 2 rows everything works well
13348     mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
13349   */
13350   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13351     *stmt= open_cursor("select a from t1");
13352   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13353   {
13354     rc= mysql_stmt_execute(*stmt);
13355     check_execute(*stmt, rc);
13356   }
13357   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13358     mysql_stmt_close(*stmt);
13359 }
13360 
13361 
test_bug9159()13362 static void test_bug9159()
13363 {
13364   MYSQL_STMT *stmt;
13365   int rc;
13366   const char *stmt_text= "select a, b from t1";
13367   const unsigned long type= CURSOR_TYPE_READ_ONLY;
13368 
13369   myheader("test_bug9159");
13370 
13371   mysql_query(mysql, "drop table if exists t1");
13372   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13373   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13374   myquery(rc);
13375 
13376   stmt= mysql_stmt_init(mysql);
13377   mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13378   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
13379 
13380   mysql_stmt_execute(stmt);
13381   mysql_stmt_close(stmt);
13382   rc= mysql_query(mysql, "drop table if exists t1");
13383   myquery(rc);
13384 }
13385 
13386 
13387 /* Crash when opening a cursor to a query with DISTICNT and no key */
13388 
test_bug9520()13389 static void test_bug9520()
13390 {
13391   MYSQL_STMT *stmt;
13392   MYSQL_BIND my_bind[1];
13393   char a[6];
13394   ulong a_len;
13395   int rc, row_count= 0;
13396 
13397   myheader("test_bug9520");
13398 
13399   mysql_query(mysql, "drop table if exists t1");
13400   mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
13401                      " primary key (a, b, c))");
13402   rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
13403                   " ('a', 'b', 'c'), ('k', 'l', 'm')");
13404   myquery(rc);
13405 
13406   stmt= open_cursor("select distinct b from t1");
13407 
13408   /*
13409     Not crashes with:
13410     stmt= open_cursor("select distinct a from t1");
13411   */
13412 
13413   rc= mysql_stmt_execute(stmt);
13414   check_execute(stmt, rc);
13415 
13416   memset(my_bind, 0, sizeof(my_bind));
13417   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13418   my_bind[0].buffer= (char*) a;
13419   my_bind[0].buffer_length= (ulong)sizeof(a);
13420   my_bind[0].length= &a_len;
13421 
13422   mysql_stmt_bind_result(stmt, my_bind);
13423 
13424   while (!(rc= mysql_stmt_fetch(stmt)))
13425     row_count++;
13426 
13427   DIE_UNLESS(rc == MYSQL_NO_DATA);
13428 
13429   if (!opt_silent)
13430     printf("Fetched %d rows\n", row_count);
13431   assert(row_count == 3);
13432 
13433   mysql_stmt_close(stmt);
13434 
13435   rc= mysql_query(mysql, "drop table t1");
13436   myquery(rc);
13437 }
13438 
13439 
13440 /*
13441   We can't have more than one cursor open for a prepared statement.
13442   Test re-executions of a PS with cursor; mysql_stmt_reset must close
13443   the cursor attached to the statement, if there is one.
13444 */
13445 
test_bug9478()13446 static void test_bug9478()
13447 {
13448   MYSQL_STMT *stmt;
13449   MYSQL_BIND my_bind[1];
13450   char a[6];
13451   ulong a_len;
13452   int rc, i;
13453   DBUG_ENTER("test_bug9478");
13454 
13455   myheader("test_bug9478");
13456 
13457   mysql_query(mysql, "drop table if exists t1");
13458   mysql_query(mysql, "create table t1 (id integer not null primary key, "
13459                      " name varchar(20) not null)");
13460   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13461                          " (1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13462   myquery(rc);
13463 
13464   stmt= open_cursor("select name from t1 where id=2");
13465 
13466   memset(my_bind, 0, sizeof(my_bind));
13467   memset(a, 0, sizeof(a));
13468   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13469   my_bind[0].buffer= (char*) a;
13470   my_bind[0].buffer_length= (ulong)sizeof(a);
13471   my_bind[0].length= &a_len;
13472   mysql_stmt_bind_result(stmt, my_bind);
13473 
13474   for (i= 0; i < 5; i++)
13475   {
13476     rc= mysql_stmt_execute(stmt);
13477     check_execute(stmt, rc);
13478     rc= mysql_stmt_fetch(stmt);
13479     check_execute(stmt, rc);
13480     if (!opt_silent && i == 0)
13481       printf("Fetched row: %s\n", a);
13482 
13483     /*
13484       The query above is a one-row result set. Therefore, there is no
13485       cursor associated with it, as the server won't bother with opening
13486       a cursor for a one-row result set. The first row was read from the
13487       server in the fetch above. But there is eof packet pending in the
13488       network. mysql_stmt_execute will flush the packet and successfully
13489       execute the statement.
13490     */
13491 
13492     rc= mysql_stmt_execute(stmt);
13493     check_execute(stmt, rc);
13494 
13495     rc= mysql_stmt_fetch(stmt);
13496     check_execute(stmt, rc);
13497     if (!opt_silent && i == 0)
13498       printf("Fetched row: %s\n", a);
13499     rc= mysql_stmt_fetch(stmt);
13500     DIE_UNLESS(rc == MYSQL_NO_DATA);
13501 
13502     {
13503       uchar buff[8];
13504       memset(buff, 0, sizeof(buff));
13505       /* Fill in the fetch packet */
13506       int4store(buff, stmt->stmt_id);
13507       buff[4]= 1;                               /* prefetch rows */
13508       rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
13509                                                (uchar*) buff,
13510                                                sizeof(buff), 0,0,1,NULL) ||
13511            (*mysql->methods->read_query_result)(mysql));
13512       DIE_UNLESS(rc);
13513       if (!opt_silent && i == 0)
13514         printf("Got error (as expected): %s\n", mysql_error(mysql));
13515     }
13516 
13517     rc= mysql_stmt_execute(stmt);
13518     check_execute(stmt, rc);
13519 
13520     rc= mysql_stmt_fetch(stmt);
13521     check_execute(stmt, rc);
13522     if (!opt_silent && i == 0)
13523       printf("Fetched row: %s\n", a);
13524 
13525     rc= mysql_stmt_reset(stmt);
13526     check_execute(stmt, rc);
13527     rc= mysql_stmt_fetch(stmt);
13528     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13529     if (!opt_silent && i == 0)
13530       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13531   }
13532   rc= mysql_stmt_close(stmt);
13533   DIE_UNLESS(rc == 0);
13534 
13535   /* Test the case with a server side cursor */
13536   stmt= open_cursor("select name from t1");
13537 
13538   mysql_stmt_bind_result(stmt, my_bind);
13539 
13540   for (i= 0; i < 5; i++)
13541   {
13542     DBUG_PRINT("loop",("i: %d", i));
13543     rc= mysql_stmt_execute(stmt);
13544     check_execute(stmt, rc);
13545     rc= mysql_stmt_fetch(stmt);
13546     check_execute(stmt, rc);
13547     if (!opt_silent && i == 0)
13548       printf("Fetched row: %s\n", a);
13549     rc= mysql_stmt_execute(stmt);
13550     check_execute(stmt, rc);
13551 
13552     while (! (rc= mysql_stmt_fetch(stmt)))
13553     {
13554       if (!opt_silent && i == 0)
13555         printf("Fetched row: %s\n", a);
13556     }
13557     DIE_UNLESS(rc == MYSQL_NO_DATA);
13558 
13559     rc= mysql_stmt_execute(stmt);
13560     check_execute(stmt, rc);
13561 
13562     rc= mysql_stmt_fetch(stmt);
13563     check_execute(stmt, rc);
13564     if (!opt_silent && i == 0)
13565       printf("Fetched row: %s\n", a);
13566 
13567     rc= mysql_stmt_reset(stmt);
13568     check_execute(stmt, rc);
13569     rc= mysql_stmt_fetch(stmt);
13570     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13571     if (!opt_silent && i == 0)
13572       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13573   }
13574 
13575   rc= mysql_stmt_close(stmt);
13576   DIE_UNLESS(rc == 0);
13577 
13578   rc= mysql_query(mysql, "drop table t1");
13579   myquery(rc);
13580   DBUG_VOID_RETURN;
13581 }
13582 
13583 
13584 /*
13585   Error message is returned for unsupported features.
13586   Test also cursors with non-default PREFETCH_ROWS
13587 */
13588 
test_bug9643()13589 static void test_bug9643()
13590 {
13591   MYSQL_STMT *stmt;
13592   MYSQL_BIND my_bind[1];
13593   int32 a;
13594   int rc;
13595   const char *stmt_text;
13596   int num_rows= 0;
13597   ulong type;
13598   ulong prefetch_rows= 5;
13599 
13600   myheader("test_bug9643");
13601 
13602   mysql_query(mysql, "drop table if exists t1");
13603   mysql_query(mysql, "create table t1 (id integer not null primary key)");
13604   rc= mysql_query(mysql, "insert into t1 (id) values "
13605                          " (1), (2), (3), (4), (5), (6), (7), (8), (9)");
13606   myquery(rc);
13607 
13608   stmt= mysql_stmt_init(mysql);
13609   /* Not implemented in 5.0 */
13610   type= (ulong) CURSOR_TYPE_SCROLLABLE;
13611   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13612   DIE_UNLESS(rc);
13613   if (! opt_silent)
13614     printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13615 
13616   type= (ulong) CURSOR_TYPE_READ_ONLY;
13617   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13618   check_execute(stmt, rc);
13619   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
13620                           (void*) &prefetch_rows);
13621   check_execute(stmt, rc);
13622   stmt_text= "select * from t1";
13623   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13624   check_execute(stmt, rc);
13625 
13626   memset(my_bind, 0, sizeof(my_bind));
13627   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13628   my_bind[0].buffer= (void*) &a;
13629   my_bind[0].buffer_length= (ulong)sizeof(a);
13630   mysql_stmt_bind_result(stmt, my_bind);
13631 
13632   rc= mysql_stmt_execute(stmt);
13633   check_execute(stmt, rc);
13634 
13635   while ((rc= mysql_stmt_fetch(stmt)) == 0)
13636     ++num_rows;
13637   DIE_UNLESS(num_rows == 9);
13638 
13639   rc= mysql_stmt_close(stmt);
13640   DIE_UNLESS(rc == 0);
13641 
13642   rc= mysql_query(mysql, "drop table t1");
13643   myquery(rc);
13644 }
13645 
13646 /*
13647   Bug#11111: fetch from view returns wrong data
13648 */
13649 
test_bug11111()13650 static void test_bug11111()
13651 {
13652   MYSQL_STMT    *stmt;
13653   MYSQL_BIND    my_bind[2];
13654   char          buf[2][20];
13655   ulong         len[2];
13656   int i;
13657   int rc;
13658   const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
13659 
13660   myheader("test_bug11111");
13661 
13662   rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
13663   myquery(rc);
13664   rc= mysql_query(mysql, "drop view if exists t1, t2, v1");
13665   myquery(rc);
13666   rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)");
13667   myquery(rc);
13668   rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)");
13669   myquery(rc);
13670   rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1");
13671   myquery(rc);
13672   rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)");
13673   myquery(rc);
13674   rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
13675   myquery(rc);
13676 
13677   stmt= mysql_stmt_init(mysql);
13678 
13679   mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
13680   mysql_stmt_execute(stmt);
13681 
13682   memset(my_bind, 0, sizeof(my_bind));
13683   for (i=0; i < 2; i++)
13684   {
13685     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
13686     my_bind[i].buffer= (uchar* *)&buf[i];
13687     my_bind[i].buffer_length= 20;
13688     my_bind[i].length= &len[i];
13689   }
13690 
13691   rc= mysql_stmt_bind_result(stmt, my_bind);
13692   check_execute(stmt, rc);
13693 
13694   rc= mysql_stmt_fetch(stmt);
13695   check_execute(stmt, rc);
13696   if (!opt_silent)
13697     printf("return: %s", buf[1]);
13698   DIE_UNLESS(!strcmp(buf[1],"1"));
13699   mysql_stmt_close(stmt);
13700   rc= mysql_query(mysql, "drop view v1");
13701   myquery(rc);
13702   rc= mysql_query(mysql, "drop table t1, t2");
13703   myquery(rc);
13704 }
13705 
13706 /*
13707   Check that proper cleanups are done for prepared statement when
13708   fetching thorugh a cursor.
13709 */
13710 
test_bug10729()13711 static void test_bug10729()
13712 {
13713   MYSQL_STMT *stmt;
13714   MYSQL_BIND my_bind[1];
13715   char a[21];
13716   int rc;
13717   const char *stmt_text;
13718   int i= 0;
13719   const char *name_array[3]= { "aaa", "bbb", "ccc" };
13720   ulong type;
13721 
13722   myheader("test_bug10729");
13723 
13724   mysql_query(mysql, "drop table if exists t1");
13725   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13726                                       "name VARCHAR(20) NOT NULL)");
13727   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13728                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13729   myquery(rc);
13730 
13731   stmt= mysql_stmt_init(mysql);
13732 
13733   type= (ulong) CURSOR_TYPE_READ_ONLY;
13734   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13735   check_execute(stmt, rc);
13736   stmt_text= "select name from t1";
13737   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13738   check_execute(stmt, rc);
13739 
13740   memset(my_bind, 0, sizeof(my_bind));
13741   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13742   my_bind[0].buffer= (void*) a;
13743   my_bind[0].buffer_length= (ulong)sizeof(a);
13744   mysql_stmt_bind_result(stmt, my_bind);
13745 
13746   for (i= 0; i < 3; i++)
13747   {
13748     int row_no= 0;
13749     rc= mysql_stmt_execute(stmt);
13750     check_execute(stmt, rc);
13751     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13752     {
13753       DIE_UNLESS(strcmp(a, name_array[row_no]) == 0);
13754       if (!opt_silent)
13755         printf("%d: %s\n", row_no, a);
13756       ++row_no;
13757     }
13758     DIE_UNLESS(rc == MYSQL_NO_DATA);
13759   }
13760   rc= mysql_stmt_close(stmt);
13761   DIE_UNLESS(rc == 0);
13762 
13763   rc= mysql_query(mysql, "drop table t1");
13764   myquery(rc);
13765 }
13766 
13767 
13768 /*
13769   Check that mysql_next_result works properly in case when one of
13770   the statements used in a multi-statement query is erroneous
13771 */
13772 
test_bug9992()13773 static void test_bug9992()
13774 {
13775   MYSQL *mysql1;
13776   MYSQL_RES* res ;
13777   int   rc;
13778 
13779   myheader("test_bug9992");
13780 
13781   if (!opt_silent)
13782     printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
13783 
13784   mysql1= mysql_client_init(NULL);
13785 
13786   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13787                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13788                           CLIENT_MULTI_STATEMENTS))
13789   {
13790     fprintf(stderr, "Failed to connect to the database\n");
13791     DIE_UNLESS(0);
13792   }
13793 
13794 
13795   /* Sic: SHOW DATABASE is incorrect syntax. */
13796   rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;");
13797 
13798   if (rc)
13799   {
13800     fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1));
13801     DIE_UNLESS(0);
13802   }
13803 
13804   if (!opt_silent)
13805     printf("Testing mysql_store_result/mysql_next_result..\n");
13806 
13807   res= mysql_store_result(mysql1);
13808   DIE_UNLESS(res);
13809   mysql_free_result(res);
13810   rc= mysql_next_result(mysql1);
13811   DIE_UNLESS(rc == 1);                         /* Got errors, as expected */
13812 
13813   if (!opt_silent)
13814     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
13815             mysql_errno(mysql1), mysql_error(mysql1));
13816 
13817   mysql_close(mysql1);
13818 }
13819 
13820 /* Bug#10736: cursors and subqueries, memroot management */
13821 
test_bug10736()13822 static void test_bug10736()
13823 {
13824   MYSQL_STMT *stmt;
13825   MYSQL_BIND my_bind[1];
13826   char a[21];
13827   int rc;
13828   const char *stmt_text;
13829   int i= 0;
13830   ulong type;
13831 
13832   myheader("test_bug10736");
13833 
13834   mysql_query(mysql, "drop table if exists t1");
13835   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13836                                       "name VARCHAR(20) NOT NULL)");
13837   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13838                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13839   myquery(rc);
13840 
13841   stmt= mysql_stmt_init(mysql);
13842 
13843   type= (ulong) CURSOR_TYPE_READ_ONLY;
13844   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13845   check_execute(stmt, rc);
13846   stmt_text= "select name from t1 where name=(select name from t1 where id=2)";
13847   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13848   check_execute(stmt, rc);
13849 
13850   memset(my_bind, 0, sizeof(my_bind));
13851   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13852   my_bind[0].buffer= (void*) a;
13853   my_bind[0].buffer_length= (ulong)sizeof(a);
13854   mysql_stmt_bind_result(stmt, my_bind);
13855 
13856   for (i= 0; i < 3; i++)
13857   {
13858     int row_no= 0;
13859     rc= mysql_stmt_execute(stmt);
13860     check_execute(stmt, rc);
13861     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13862     {
13863       if (!opt_silent)
13864         printf("%d: %s\n", row_no, a);
13865       ++row_no;
13866     }
13867     DIE_UNLESS(rc == MYSQL_NO_DATA);
13868   }
13869   rc= mysql_stmt_close(stmt);
13870   DIE_UNLESS(rc == 0);
13871 
13872   rc= mysql_query(mysql, "drop table t1");
13873   myquery(rc);
13874 }
13875 
13876 /* Bug#10794: cursors, packets out of order */
13877 
test_bug10794()13878 static void test_bug10794()
13879 {
13880   MYSQL_STMT *stmt, *stmt1;
13881   MYSQL_BIND my_bind[2];
13882   char a[21];
13883   int id_val;
13884   ulong a_len;
13885   int rc;
13886   const char *stmt_text;
13887   int i= 0;
13888   ulong type;
13889 
13890   myheader("test_bug10794");
13891 
13892   mysql_query(mysql, "drop table if exists t1");
13893   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13894                                       "name varchar(20) not null)");
13895   stmt= mysql_stmt_init(mysql);
13896   stmt_text= "insert into t1 (id, name) values (?, ?)";
13897   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13898   check_execute(stmt, rc);
13899   memset(my_bind, 0, sizeof(my_bind));
13900   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13901   my_bind[0].buffer= (void*) &id_val;
13902   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
13903   my_bind[1].buffer= (void*) a;
13904   my_bind[1].length= &a_len;
13905   rc= mysql_stmt_bind_param(stmt, my_bind);
13906   check_execute(stmt, rc);
13907   for (i= 0; i < 42; i++)
13908   {
13909     id_val= (i+1)*10;
13910     sprintf(a, "a%d", i);
13911     a_len= (ulong)strlen(a); /* safety against broken sprintf */
13912     rc= mysql_stmt_execute(stmt);
13913     check_execute(stmt, rc);
13914   }
13915   stmt_text= "select name from t1";
13916   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13917   type= (ulong) CURSOR_TYPE_READ_ONLY;
13918   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13919   stmt1= mysql_stmt_init(mysql);
13920   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13921   memset(my_bind, 0, sizeof(my_bind));
13922   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13923   my_bind[0].buffer= (void*) a;
13924   my_bind[0].buffer_length= (ulong)sizeof(a);
13925   my_bind[0].length= &a_len;
13926   rc= mysql_stmt_bind_result(stmt, my_bind);
13927   check_execute(stmt, rc);
13928   rc= mysql_stmt_execute(stmt);
13929   check_execute(stmt, rc);
13930   rc= mysql_stmt_fetch(stmt);
13931   check_execute(stmt, rc);
13932   if (!opt_silent)
13933     printf("Fetched row from stmt: %s\n", a);
13934   /* Don't optimize: an attribute of the original test case */
13935   mysql_stmt_free_result(stmt);
13936   mysql_stmt_reset(stmt);
13937   stmt_text= "select name from t1 where id=10";
13938   rc= mysql_stmt_prepare(stmt1, stmt_text, (ulong)strlen(stmt_text));
13939   check_execute(stmt1, rc);
13940   rc= mysql_stmt_bind_result(stmt1, my_bind);
13941   check_execute(stmt1, rc);
13942   rc= mysql_stmt_execute(stmt1);
13943   while (1)
13944   {
13945     rc= mysql_stmt_fetch(stmt1);
13946     if (rc == MYSQL_NO_DATA)
13947     {
13948       if (!opt_silent)
13949         printf("End of data in stmt1\n");
13950       break;
13951     }
13952     check_execute(stmt1, rc);
13953     if (!opt_silent)
13954       printf("Fetched row from stmt1: %s\n", a);
13955   }
13956   mysql_stmt_close(stmt);
13957   mysql_stmt_close(stmt1);
13958 
13959   rc= mysql_query(mysql, "drop table t1");
13960   myquery(rc);
13961 }
13962 
13963 
13964 /* Bug#11172: cursors, crash on a fetch from a datetime column */
13965 
test_bug11172()13966 static void test_bug11172()
13967 {
13968   MYSQL_STMT *stmt;
13969   MYSQL_BIND bind_in[1], bind_out[2];
13970   MYSQL_TIME hired;
13971   int rc;
13972   const char *stmt_text;
13973   int i= 0, id;
13974   ulong type;
13975 
13976   myheader("test_bug11172");
13977 
13978   mysql_query(mysql, "drop table if exists t1");
13979   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13980                                       "hired date not null)");
13981   rc= mysql_query(mysql,
13982                   "insert into t1 (id, hired) values (1, '1933-08-24'), "
13983                   "(2, '1965-01-01'), (3, '1949-08-17'), (4, '1945-07-07'), "
13984                   "(5, '1941-05-15'), (6, '1978-09-15'), (7, '1936-03-28')");
13985   myquery(rc);
13986   stmt= mysql_stmt_init(mysql);
13987   stmt_text= "SELECT id, hired FROM t1 WHERE hired=?";
13988   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13989   check_execute(stmt, rc);
13990 
13991   type= (ulong) CURSOR_TYPE_READ_ONLY;
13992   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13993 
13994   memset(bind_in, 0, sizeof(bind_in));
13995   memset(bind_out, 0, sizeof(bind_out));
13996   memset(&hired, 0, sizeof(hired));
13997   hired.year= 1965;
13998   hired.month= 1;
13999   hired.day= 1;
14000   bind_in[0].buffer_type= MYSQL_TYPE_DATE;
14001   bind_in[0].buffer= (void*) &hired;
14002   bind_in[0].buffer_length= (ulong)sizeof(hired);
14003   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
14004   bind_out[0].buffer= (void*) &id;
14005   bind_out[1]= bind_in[0];
14006 
14007   for (i= 0; i < 3; i++)
14008   {
14009     rc= mysql_stmt_bind_param(stmt, bind_in);
14010     check_execute(stmt, rc);
14011     rc= mysql_stmt_bind_result(stmt, bind_out);
14012     check_execute(stmt, rc);
14013     rc= mysql_stmt_execute(stmt);
14014     check_execute(stmt, rc);
14015     while ((rc= mysql_stmt_fetch(stmt)) == 0)
14016     {
14017       if (!opt_silent)
14018         printf("fetched data %d:%d-%d-%d\n", id,
14019                hired.year, hired.month, hired.day);
14020     }
14021     DIE_UNLESS(rc == MYSQL_NO_DATA);
14022     if (!mysql_stmt_free_result(stmt))
14023       mysql_stmt_reset(stmt);
14024   }
14025   mysql_stmt_close(stmt);
14026   mysql_rollback(mysql);
14027   mysql_rollback(mysql);
14028 
14029   rc= mysql_query(mysql, "drop table t1");
14030   myquery(rc);
14031 }
14032 
14033 
14034 /* Bug#11656: cursors, crash on a fetch from a query with distinct. */
14035 
test_bug11656()14036 static void test_bug11656()
14037 {
14038   MYSQL_STMT *stmt;
14039   MYSQL_BIND my_bind[2];
14040   int rc;
14041   const char *stmt_text;
14042   char buf[2][20];
14043   int i= 0;
14044   ulong type;
14045 
14046   myheader("test_bug11656");
14047 
14048   mysql_query(mysql, "drop table if exists t1");
14049 
14050   rc= mysql_query(mysql, "create table t1 ("
14051                   "server varchar(40) not null, "
14052                   "test_kind varchar(1) not null, "
14053                   "test_id varchar(30) not null , "
14054                   "primary key (server,test_kind,test_id))");
14055   myquery(rc);
14056 
14057   stmt_text= "select distinct test_kind, test_id from t1 "
14058              "where server in (?, ?)";
14059   stmt= mysql_stmt_init(mysql);
14060   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14061   check_execute(stmt, rc);
14062   type= (ulong) CURSOR_TYPE_READ_ONLY;
14063   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14064 
14065   memset(my_bind, 0, sizeof(my_bind));
14066   my_stpcpy(buf[0], "pcint502_MY2");
14067   my_stpcpy(buf[1], "*");
14068   for (i=0; i < 2; i++)
14069   {
14070     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
14071     my_bind[i].buffer= (uchar* *)&buf[i];
14072     my_bind[i].buffer_length= (ulong)strlen(buf[i]);
14073   }
14074   mysql_stmt_bind_param(stmt, my_bind);
14075 
14076   rc= mysql_stmt_execute(stmt);
14077   check_execute(stmt, rc);
14078 
14079   rc= mysql_stmt_fetch(stmt);
14080   DIE_UNLESS(rc == MYSQL_NO_DATA);
14081 
14082   mysql_stmt_close(stmt);
14083   rc= mysql_query(mysql, "drop table t1");
14084   myquery(rc);
14085 }
14086 
14087 
14088 /*
14089   Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
14090   and mysql_real_escape_string_quote() does the right thing as a result.
14091 */
14092 
test_bug10214()14093 static void test_bug10214()
14094 {
14095   int   len;
14096   char  out[8];
14097 
14098   myheader("test_bug10214");
14099 
14100   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
14101 
14102   len= mysql_real_escape_string_quote(mysql, out, "a'b\\c", 5, '\'');
14103   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14104 
14105   mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
14106   DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
14107 
14108   len= mysql_real_escape_string_quote(mysql, out, "a'b\\c", 5, '\'');
14109   DIE_UNLESS(memcmp(out, "a''b\\c", len) == 0);
14110 
14111   mysql_query(mysql, "set sql_mode=''");
14112 }
14113 
14114 /*
14115   Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
14116   a deprecated mysql_real_escape_string() function exits with error and the
14117   mysql_real_escape_string_quote() does the right thing as a result.
14118 */
14119 
test_bug21246()14120 static void test_bug21246()
14121 {
14122   int   len;
14123   char  out[11];
14124 
14125   myheader("test_bug21246");
14126 
14127   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
14128 
14129   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14130   DIE_UNLESS(len == 7);
14131   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14132 
14133   len = mysql_real_escape_string_quote(mysql, out, "a'b\\c", 5, '\'');
14134   DIE_UNLESS(len == 7);
14135   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14136 
14137   len = mysql_real_escape_string_quote(mysql, out, "`a'b\\c`", 7, '\'');
14138   DIE_UNLESS(len == 9);
14139   DIE_UNLESS(memcmp(out, "`a\\'b\\\\c`", len) == 0);
14140 
14141   len = mysql_real_escape_string_quote(mysql, out, "`a'b\\c`", 7, '`');
14142   DIE_UNLESS(len == 9);
14143   DIE_UNLESS(memcmp(out, "``a'b\\c``", len) == 0);
14144 
14145   len = mysql_real_escape_string_quote(mysql, out, "`a'b\\c\"", 7, '"');
14146   DIE_UNLESS(len == 10);
14147   DIE_UNLESS(memcmp(out, "`a\\'b\\\\c\\\"", len) == 0);
14148 
14149   mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
14150   DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
14151 
14152   len = mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14153   DIE_UNLESS(len == -1);
14154 
14155   len= mysql_real_escape_string_quote(mysql, out, "a'b\"c", 5, '\'');
14156   DIE_UNLESS(len == 6);
14157   DIE_UNLESS(memcmp(out, "a''b\"c", len) == 0);
14158 
14159   len = mysql_real_escape_string_quote(mysql, out, "a'b\"c", 5, '\"');
14160   DIE_UNLESS(len == 6);
14161   DIE_UNLESS(memcmp(out, "a'b\"\"c", len) == 0);
14162 
14163   len = mysql_real_escape_string_quote(mysql, out, "`a'b\"c`\"", 8, '\"');
14164   DIE_UNLESS(len == 10);
14165   DIE_UNLESS(memcmp(out, "`a'b\"\"c`\"\"", len) == 0);
14166 
14167   len = mysql_real_escape_string_quote(mysql, out, "`a'b\"c`\"", 8, '`');
14168   DIE_UNLESS(len == 10);
14169   DIE_UNLESS(memcmp(out, "``a'b\"c``\"", len) == 0);
14170 
14171   len = mysql_real_escape_string_quote(mysql, out, "\"a'b\"c\"\"", 8, '`');
14172   DIE_UNLESS(len == 8);
14173   DIE_UNLESS(memcmp(out, "\"a'b\"c\"\"", len) == 0);
14174 
14175   mysql_query(mysql, "set sql_mode=''");
14176 }
14177 
test_client_character_set()14178 static void test_client_character_set()
14179 {
14180   MY_CHARSET_INFO cs;
14181   char *csname= (char*) "utf8";
14182   char *csdefault= (char*)mysql_character_set_name(mysql);
14183   int rc;
14184 
14185   myheader("test_client_character_set");
14186 
14187   rc= mysql_set_character_set(mysql, csname);
14188   DIE_UNLESS(rc == 0);
14189 
14190   mysql_get_character_set_info(mysql, &cs);
14191   DIE_UNLESS(!strcmp(cs.csname, "utf8"));
14192   DIE_UNLESS(!strcmp(cs.name, "utf8_general_ci"));
14193   /* Restore the default character set */
14194   rc= mysql_set_character_set(mysql, csdefault);
14195   myquery(rc);
14196 }
14197 
14198 /* Test correct max length for MEDIUMTEXT and LONGTEXT columns */
14199 
test_bug9735()14200 static void test_bug9735()
14201 {
14202   MYSQL_RES *res;
14203   int rc;
14204 
14205   myheader("test_bug9735");
14206 
14207   rc= mysql_query(mysql, "drop table if exists t1");
14208   myquery(rc);
14209   rc= mysql_query(mysql, "create table t1 (a mediumtext, b longtext) "
14210                          "character set latin1");
14211   myquery(rc);
14212   rc= mysql_query(mysql, "select * from t1");
14213   myquery(rc);
14214   res= mysql_store_result(mysql);
14215   verify_prepare_field(res, 0, "a", "a", MYSQL_TYPE_BLOB,
14216                        "t1", "t1", current_db, (1U << 24)-1, 0);
14217   verify_prepare_field(res, 1, "b", "b", MYSQL_TYPE_BLOB,
14218                        "t1", "t1", current_db, ~0U, 0);
14219   mysql_free_result(res);
14220   rc= mysql_query(mysql, "drop table t1");
14221   myquery(rc);
14222 }
14223 
14224 
14225 /* Bug#11183 "mysql_stmt_reset() doesn't reset information about error" */
14226 
test_bug11183()14227 static void test_bug11183()
14228 {
14229   int rc;
14230   MYSQL_STMT *stmt;
14231   char bug_statement[]= "insert into t1 values (1)";
14232 
14233   myheader("test_bug11183");
14234 
14235   mysql_query(mysql, "drop table t1 if exists");
14236   mysql_query(mysql, "create table t1 (a int)");
14237 
14238   stmt= mysql_stmt_init(mysql);
14239   DIE_UNLESS(stmt != 0);
14240 
14241   rc= mysql_stmt_prepare(stmt, bug_statement, (ulong)strlen(bug_statement));
14242   check_execute(stmt, rc);
14243 
14244   rc= mysql_query(mysql, "drop table t1");
14245   myquery(rc);
14246 
14247   /* Trying to execute statement that should fail on execute stage */
14248   rc= mysql_stmt_execute(stmt);
14249   DIE_UNLESS(rc);
14250 
14251   mysql_stmt_reset(stmt);
14252   DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14253 
14254   mysql_query(mysql, "create table t1 (a int)");
14255 
14256   /* Trying to execute statement that should pass ok */
14257   if (mysql_stmt_execute(stmt))
14258   {
14259     mysql_stmt_reset(stmt);
14260     DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14261   }
14262 
14263   mysql_stmt_close(stmt);
14264 
14265   rc= mysql_query(mysql, "drop table t1");
14266   myquery(rc);
14267 }
14268 
test_bug11037()14269 static void test_bug11037()
14270 {
14271   MYSQL_STMT *stmt;
14272   int rc;
14273   const char *stmt_text;
14274 
14275   myheader("test_bug11037");
14276 
14277   mysql_query(mysql, "drop table if exists t1");
14278 
14279   rc= mysql_query(mysql, "create table t1 (id int not null)");
14280   myquery(rc);
14281 
14282   rc= mysql_query(mysql, "insert into t1 values (1)");
14283   myquery(rc);
14284 
14285   stmt_text= "select id FROM t1";
14286   stmt= mysql_stmt_init(mysql);
14287   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14288 
14289   /* expected error */
14290   rc = mysql_stmt_fetch(stmt);
14291   DIE_UNLESS(rc==1);
14292   if (!opt_silent)
14293     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
14294             mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
14295 
14296   rc= mysql_stmt_execute(stmt);
14297   check_execute(stmt, rc);
14298 
14299   rc= mysql_stmt_fetch(stmt);
14300   DIE_UNLESS(rc==0);
14301 
14302   rc= mysql_stmt_fetch(stmt);
14303   DIE_UNLESS(rc==MYSQL_NO_DATA);
14304 
14305   rc= mysql_stmt_fetch(stmt);
14306   DIE_UNLESS(rc==MYSQL_NO_DATA);
14307 
14308   mysql_stmt_close(stmt);
14309   rc= mysql_query(mysql, "drop table t1");
14310   myquery(rc);
14311 }
14312 
14313 /* Bug#10760: cursors, crash in a fetch after rollback. */
14314 
test_bug10760()14315 static void test_bug10760()
14316 {
14317   MYSQL_STMT *stmt;
14318   MYSQL_BIND my_bind[1];
14319   int rc;
14320   const char *stmt_text;
14321   char id_buf[20];
14322   ulong id_len;
14323   int i= 0;
14324   ulong type;
14325 
14326   myheader("test_bug10760");
14327 
14328   mysql_query(mysql, "drop table if exists t1, t2");
14329 
14330   /* create tables */
14331   rc= mysql_query(mysql, "create table t1 (id integer not null primary key)"
14332                          " engine=MyISAM");
14333   myquery(rc);
14334   for (; i < 42; ++i)
14335   {
14336     char buf[100];
14337     sprintf(buf, "insert into t1 (id) values (%d)", i+1);
14338     rc= mysql_query(mysql, buf);
14339     myquery(rc);
14340   }
14341   mysql_autocommit(mysql, FALSE);
14342   /* create statement */
14343   stmt= mysql_stmt_init(mysql);
14344   type= (ulong) CURSOR_TYPE_READ_ONLY;
14345   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14346 
14347   /*
14348     1: check that a deadlock within the same connection
14349     is resolved and an error is returned. The deadlock is modelled
14350     as follows:
14351     con1: open cursor for select * from t1;
14352     con1: insert into t1 (id) values (1)
14353   */
14354   stmt_text= "select id from t1 order by 1";
14355   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14356   check_execute(stmt, rc);
14357   rc= mysql_stmt_execute(stmt);
14358   check_execute(stmt, rc);
14359   rc= mysql_query(mysql, "update t1 set id=id+100");
14360   /*
14361     If cursors are not materialized, the update will return an error;
14362     we mainly test that it won't deadlock.
14363   */
14364   if (rc && !opt_silent)
14365     printf("Got error (as expected): %s\n", mysql_error(mysql));
14366   /*
14367     2: check that MyISAM tables used in cursors survive
14368     COMMIT/ROLLBACK.
14369   */
14370   rc= mysql_rollback(mysql);                  /* should not close the cursor */
14371   myquery(rc);
14372   rc= mysql_stmt_fetch(stmt);
14373   check_execute(stmt, rc);
14374 
14375   /*
14376     3: check that cursors to InnoDB tables are closed (for now) by
14377     COMMIT/ROLLBACK.
14378   */
14379     stmt_text= "select id from t1 order by 1";
14380     rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14381     check_execute(stmt, rc);
14382 
14383     rc= mysql_query(mysql, "alter table t1 engine=InnoDB");
14384     myquery(rc);
14385 
14386     memset(my_bind, 0, sizeof(my_bind));
14387     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14388     my_bind[0].buffer= (void*) id_buf;
14389     my_bind[0].buffer_length= (ulong)sizeof(id_buf);
14390     my_bind[0].length= &id_len;
14391     check_execute(stmt, rc);
14392     mysql_stmt_bind_result(stmt, my_bind);
14393 
14394     rc= mysql_stmt_execute(stmt);
14395     rc= mysql_stmt_fetch(stmt);
14396     DIE_UNLESS(rc == 0);
14397     if (!opt_silent)
14398       printf("Fetched row %s\n", id_buf);
14399     rc= mysql_rollback(mysql);                  /* should close the cursor */
14400     myquery(rc);
14401 #if 0
14402     rc= mysql_stmt_fetch(stmt);
14403     DIE_UNLESS(rc);
14404     if (!opt_silent)
14405       printf("Got error (as expected): %s\n", mysql_error(mysql));
14406 #endif
14407 
14408   mysql_stmt_close(stmt);
14409   rc= mysql_query(mysql, "drop table t1");
14410   myquery(rc);
14411   mysql_autocommit(mysql, TRUE);                /* restore default */
14412 }
14413 
test_bug12001()14414 static void test_bug12001()
14415 {
14416   MYSQL *mysql_local;
14417   MYSQL_RES *result;
14418   const char *query= "DROP TABLE IF EXISTS test_table;"
14419                      "CREATE TABLE test_table(id INT);"
14420                      "INSERT INTO test_table VALUES(10);"
14421                      "UPDATE test_table SET id=20 WHERE id=10;"
14422                      "SELECT * FROM test_table;"
14423                      "INSERT INTO non_existent_table VALUES(11);";
14424   int rc, res;
14425 
14426   myheader("test_bug12001");
14427 
14428   if (!(mysql_local= mysql_client_init(NULL)))
14429   {
14430     fprintf(stdout, "\n mysql_client_init() failed");
14431     exit(1);
14432   }
14433 
14434   /* Create connection that supports multi statements */
14435   if (!mysql_real_connect(mysql_local, opt_host, opt_user,
14436                           opt_password, current_db, opt_port,
14437                           opt_unix_socket, CLIENT_MULTI_STATEMENTS))
14438   {
14439     fprintf(stdout, "\n mysql_real_connect() failed");
14440     exit(1);
14441   }
14442 
14443   rc= mysql_query(mysql_local, query);
14444   myquery(rc);
14445 
14446   do
14447   {
14448     if (mysql_field_count(mysql_local) &&
14449         (result= mysql_use_result(mysql_local)))
14450     {
14451       mysql_free_result(result);
14452     }
14453   }
14454   while (!(res= mysql_next_result(mysql_local)));
14455 
14456   rc= mysql_query(mysql_local, "DROP TABLE IF EXISTS test_table");
14457   myquery(rc);
14458 
14459   mysql_close(mysql_local);
14460   DIE_UNLESS(res==1);
14461 }
14462 
14463 
14464 /* Bug#11909: wrong metadata if fetching from two cursors */
14465 
test_bug11909()14466 static void test_bug11909()
14467 {
14468   MYSQL_STMT *stmt1, *stmt2;
14469   MYSQL_BIND my_bind[7];
14470   int rc;
14471   char firstname[20], midinit[20], lastname[20], workdept[20];
14472   ulong firstname_len, midinit_len, lastname_len, workdept_len;
14473   uint32 empno;
14474   double salary;
14475   float bonus;
14476   const char *stmt_text;
14477 
14478   myheader("test_bug11909");
14479 
14480   stmt_text= "drop table if exists t1";
14481   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14482   myquery(rc);
14483 
14484   stmt_text= "create table t1 ("
14485     "  empno int(11) not null, firstname varchar(20) not null,"
14486     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14487     "  workdept varchar(6) not null, salary double not null,"
14488     "  bonus float not null, primary key (empno)"
14489     ") default charset=latin1 collate=latin1_bin";
14490   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14491   myquery(rc);
14492 
14493   stmt_text= "insert into t1 values "
14494     "(10, 'CHRISTINE', 'I', 'HAAS',     'A00', 52750, 1000), "
14495     "(20, 'MICHAEL',   'L', 'THOMPSON', 'B01', 41250, 800),"
14496     "(30, 'SALLY',     'A', 'KWAN',     'C01', 38250, 800),"
14497     "(50, 'JOHN',      'B', 'GEYER',    'E01', 40175, 800), "
14498     "(60, 'IRVING',    'F', 'STERN',    'D11', 32250, 500)";
14499   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14500   myquery(rc);
14501 
14502   /* ****** Begin of trace ****** */
14503 
14504   stmt1= open_cursor("SELECT empno, firstname, midinit, lastname,"
14505                      "workdept, salary, bonus FROM t1");
14506 
14507   memset(my_bind, 0, sizeof(my_bind));
14508   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14509   my_bind[0].buffer= (void*) &empno;
14510 
14511   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14512   my_bind[1].buffer= (void*) firstname;
14513   my_bind[1].buffer_length= (ulong)sizeof(firstname);
14514   my_bind[1].length= &firstname_len;
14515 
14516   my_bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;
14517   my_bind[2].buffer= (void*) midinit;
14518   my_bind[2].buffer_length= (ulong)sizeof(midinit);
14519   my_bind[2].length= &midinit_len;
14520 
14521   my_bind[3].buffer_type= MYSQL_TYPE_VAR_STRING;
14522   my_bind[3].buffer= (void*) lastname;
14523   my_bind[3].buffer_length= (ulong)sizeof(lastname);
14524   my_bind[3].length= &lastname_len;
14525 
14526   my_bind[4].buffer_type= MYSQL_TYPE_VAR_STRING;
14527   my_bind[4].buffer= (void*) workdept;
14528   my_bind[4].buffer_length= (ulong)sizeof(workdept);
14529   my_bind[4].length= &workdept_len;
14530 
14531   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
14532   my_bind[5].buffer= (void*) &salary;
14533 
14534   my_bind[6].buffer_type= MYSQL_TYPE_FLOAT;
14535   my_bind[6].buffer= (void*) &bonus;
14536   rc= mysql_stmt_bind_result(stmt1, my_bind);
14537   check_execute(stmt1, rc);
14538 
14539   rc= mysql_stmt_execute(stmt1);
14540   check_execute(stmt1, rc);
14541 
14542   rc= mysql_stmt_fetch(stmt1);
14543   DIE_UNLESS(rc == 0);
14544   DIE_UNLESS(empno == 10);
14545   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14546   DIE_UNLESS(strcmp(midinit, "I") == 0);
14547   DIE_UNLESS(strcmp(lastname, "HAAS") == 0);
14548   DIE_UNLESS(strcmp(workdept, "A00") == 0);
14549   DIE_UNLESS(salary == (double) 52750.0);
14550   DIE_UNLESS(bonus == (float) 1000.0);
14551 
14552   stmt2= open_cursor("SELECT empno, firstname FROM t1");
14553   rc= mysql_stmt_bind_result(stmt2, my_bind);
14554   check_execute(stmt2, rc);
14555 
14556   rc= mysql_stmt_execute(stmt2);
14557   check_execute(stmt2, rc);
14558 
14559   rc= mysql_stmt_fetch(stmt2);
14560   DIE_UNLESS(rc == 0);
14561 
14562   DIE_UNLESS(empno == 10);
14563   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14564 
14565   rc= mysql_stmt_reset(stmt2);
14566   check_execute(stmt2, rc);
14567 
14568   /* ERROR: next statement should return 0 */
14569 
14570   rc= mysql_stmt_fetch(stmt1);
14571   DIE_UNLESS(rc == 0);
14572 
14573   mysql_stmt_close(stmt1);
14574   mysql_stmt_close(stmt2);
14575   rc= mysql_rollback(mysql);
14576   myquery(rc);
14577 
14578   rc= mysql_query(mysql, "drop table t1");
14579   myquery(rc);
14580 }
14581 
14582 /* Cursors: opening a cursor to a compilicated query with ORDER BY */
14583 
test_bug11901()14584 static void test_bug11901()
14585 {
14586 /*  MYSQL_STMT *stmt;
14587   MYSQL_BIND my_bind[2]; */
14588   int rc;
14589 /*  char workdept[20];
14590   ulong workdept_len;
14591   uint32 empno; */
14592   const char *stmt_text;
14593 
14594   myheader("test_bug11901");
14595 
14596   stmt_text= "drop table if exists t1, t2";
14597   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14598   myquery(rc);
14599 
14600   stmt_text= "create table t1 ("
14601     "  empno int(11) not null, firstname varchar(20) not null,"
14602     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14603     "  workdept varchar(6) not null, salary double not null,"
14604     "  bonus float not null, primary key (empno), "
14605     " unique key (workdept, empno) "
14606     ") default charset=latin1 collate=latin1_bin";
14607   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14608   myquery(rc);
14609 
14610   stmt_text= "insert into t1 values "
14611      "(10,  'CHRISTINE', 'I', 'HAAS',      'A00', 52750, 1000),"
14612      "(20,  'MICHAEL',   'L', 'THOMPSON',  'B01', 41250, 800), "
14613      "(30,  'SALLY',     'A', 'KWAN',      'C01', 38250, 800), "
14614      "(50,  'JOHN',      'B', 'GEYER',     'E01', 40175, 800), "
14615      "(60,  'IRVING',    'F', 'STERN',     'D11', 32250, 500), "
14616      "(70,  'EVA',       'D', 'PULASKI',   'D21', 36170, 700), "
14617      "(90,  'EILEEN',    'W', 'HENDERSON', 'E11', 29750, 600), "
14618      "(100, 'THEODORE',  'Q', 'SPENSER',   'E21', 26150, 500), "
14619      "(110, 'VINCENZO',  'G', 'LUCCHESSI', 'A00', 46500, 900), "
14620      "(120, 'SEAN',      '',  'O\\'CONNELL', 'A00', 29250, 600), "
14621      "(130, 'DOLORES',   'M', 'QUINTANA',  'C01', 23800, 500), "
14622      "(140, 'HEATHER',   'A', 'NICHOLLS',  'C01', 28420, 600), "
14623      "(150, 'BRUCE',     '',  'ADAMSON',   'D11', 25280, 500), "
14624      "(160, 'ELIZABETH', 'R', 'PIANKA',    'D11', 22250, 400), "
14625      "(170, 'MASATOSHI', 'J', 'YOSHIMURA', 'D11', 24680, 500), "
14626      "(180, 'MARILYN',   'S', 'SCOUTTEN',  'D11', 21340, 500), "
14627      "(190, 'JAMES',     'H', 'WALKER',    'D11', 20450, 400), "
14628      "(200, 'DAVID',     '',  'BROWN',     'D11', 27740, 600), "
14629      "(210, 'WILLIAM',   'T', 'JONES',     'D11', 18270, 400), "
14630      "(220, 'JENNIFER',  'K', 'LUTZ',      'D11', 29840, 600), "
14631      "(230, 'JAMES',     'J', 'JEFFERSON', 'D21', 22180, 400), "
14632      "(240, 'SALVATORE', 'M', 'MARINO',    'D21', 28760, 600), "
14633      "(250, 'DANIEL',    'S', 'SMITH',     'D21', 19180, 400), "
14634      "(260, 'SYBIL',     'P', 'JOHNSON',   'D21', 17250, 300), "
14635      "(270, 'MARIA',     'L', 'PEREZ',     'D21', 27380, 500), "
14636      "(280, 'ETHEL',     'R', 'SCHNEIDER', 'E11', 26250, 500), "
14637      "(290, 'JOHN',      'R', 'PARKER',    'E11', 15340, 300), "
14638      "(300, 'PHILIP',    'X', 'SMITH',     'E11', 17750, 400), "
14639      "(310, 'MAUDE',     'F', 'SETRIGHT',  'E11', 15900, 300), "
14640      "(320, 'RAMLAL',    'V', 'MEHTA',     'E21', 19950, 400), "
14641      "(330, 'WING',      '',  'LEE',       'E21', 25370, 500), "
14642      "(340, 'JASON',     'R', 'GOUNOT',    'E21', 23840, 500)";
14643 
14644   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14645   myquery(rc);
14646 
14647   stmt_text= "create table t2 ("
14648     " deptno varchar(6) not null, deptname varchar(20) not null,"
14649     " mgrno int(11) not null, location varchar(20) not null,"
14650     " admrdept varchar(6) not null, refcntd int(11) not null,"
14651     " refcntu int(11) not null, primary key (deptno)"
14652     ") default charset=latin1 collate=latin1_bin";
14653   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14654   myquery(rc);
14655 
14656   stmt_text= "insert into t2 values "
14657     "('A00', 'SPIFFY COMPUTER SERV', 10, '', 'A00', 0, 0), "
14658     "('B01', 'PLANNING',             20, '', 'A00', 0, 0), "
14659     "('C01', 'INFORMATION CENTER',   30, '', 'A00', 0, 0), "
14660     "('D01', 'DEVELOPMENT CENTER',   0,  '', 'A00', 0, 0),"
14661     "('D11', 'MANUFACTURING SYSTEM', 60, '', 'D01', 0, 0), "
14662     "('D21', 'ADMINISTRATION SYSTE', 70, '', 'D01', 0, 0), "
14663     "('E01', 'SUPPORT SERVICES',     50, '', 'A00', 0, 0), "
14664     "('E11', 'OPERATIONS',           90, '', 'E01', 0, 0), "
14665     "('E21', 'SOFTWARE SUPPORT',     100,'', 'E01', 0, 0)";
14666   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14667   myquery(rc);
14668 
14669   /* ****** Begin of trace ****** */
14670 /* WL#1110 - disabled test case failure - crash. */
14671 /*
14672   stmt= open_cursor("select t1.emp, t1.workdept "
14673                     "from (t1 left join t2 on t2.deptno = t1.workdept) "
14674                     "where t2.deptno in "
14675                     "   (select t2.deptno "
14676                     "    from (t1 left join t2 on t2.deptno = t1.workdept) "
14677                     "    where t1.empno = ?) "
14678                     "order by 1");
14679   memset(my_bind, 0, sizeof(my_bind));
14680 
14681   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14682   my_bind[0].buffer= &empno;
14683   rc= mysql_stmt_bind_param(stmt, my_bind);
14684   check_execute(stmt, rc);
14685 
14686   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14687   my_bind[1].buffer= (void*) workdept;
14688   my_bind[1].buffer_length= sizeof(workdept);
14689   my_bind[1].length= &workdept_len;
14690 
14691   rc= mysql_stmt_bind_result(stmt, my_bind);
14692   check_execute(stmt, rc);
14693 
14694   empno= 10;
14695 */
14696   /* ERROR: next statement causes a server crash */
14697 /*
14698   rc= mysql_stmt_execute(stmt);
14699   check_execute(stmt, rc);
14700 
14701   mysql_stmt_close(stmt);
14702 
14703   rc= mysql_query(mysql, "drop table t1, t2");
14704   myquery(rc);
14705 */
14706 }
14707 
14708 /* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */
14709 
test_bug11904()14710 static void test_bug11904()
14711 {
14712   MYSQL_STMT *stmt1;
14713   int rc;
14714   const char *stmt_text;
14715   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
14716   MYSQL_BIND my_bind[2];
14717   int country_id=0;
14718   char row_data[11]= {0};
14719 
14720   myheader("test_bug11904");
14721 
14722   /* create tables */
14723   rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b");
14724   myquery(rc);
14725   rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))");
14726   myquery(rc);
14727 
14728   rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv'),"
14729                           " (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg'),"
14730                           " (3,'berlin'), (3, 'frankfurt')");
14731 
14732   myquery(rc);
14733   mysql_commit(mysql);
14734   /* create statement */
14735   stmt1= mysql_stmt_init(mysql);
14736   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14737 
14738   stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id";
14739 
14740   rc= mysql_stmt_prepare(stmt1, stmt_text, (ulong)strlen(stmt_text));
14741   check_execute(stmt1, rc);
14742 
14743   memset(my_bind, 0, sizeof(my_bind));
14744   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14745   my_bind[0].buffer=& country_id;
14746   my_bind[0].buffer_length= 0;
14747   my_bind[0].length= 0;
14748 
14749   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14750   my_bind[1].buffer=& row_data;
14751   my_bind[1].buffer_length= (ulong)(sizeof(row_data) - 1);
14752   my_bind[1].length= 0;
14753 
14754   rc= mysql_stmt_bind_result(stmt1, my_bind);
14755   check_execute(stmt1, rc);
14756 
14757   rc= mysql_stmt_execute(stmt1);
14758   check_execute(stmt1, rc);
14759 
14760   rc= mysql_stmt_fetch(stmt1);
14761   check_execute(stmt1, rc);
14762   DIE_UNLESS(country_id == 1);
14763   DIE_UNLESS(memcmp(row_data, "plovdiv", 7) == 0);
14764 
14765   rc= mysql_stmt_fetch(stmt1);
14766   check_execute(stmt1, rc);
14767   DIE_UNLESS(country_id == 2);
14768   DIE_UNLESS(memcmp(row_data, "LA", 2) == 0);
14769 
14770   rc= mysql_stmt_fetch(stmt1);
14771   check_execute(stmt1, rc);
14772   DIE_UNLESS(country_id == 3);
14773   DIE_UNLESS(memcmp(row_data, "berlin", 6) == 0);
14774 
14775   rc= mysql_stmt_close(stmt1);
14776   check_execute(stmt1, rc);
14777 
14778   rc= mysql_query(mysql, "drop table bug11904b");
14779   myquery(rc);
14780 }
14781 
14782 
14783 /* Bug#12243: multiple cursors, crash in a fetch after commit. */
14784 
test_bug12243()14785 static void test_bug12243()
14786 {
14787   MYSQL_STMT *stmt1, *stmt2;
14788   int rc;
14789   const char *stmt_text;
14790   ulong type;
14791 
14792   myheader("test_bug12243");
14793 
14794 
14795   /* create tables */
14796   mysql_query(mysql, "drop table if exists t1");
14797   mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
14798   rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
14799   myquery(rc);
14800   mysql_autocommit(mysql, FALSE);
14801   /* create statement */
14802   stmt1= mysql_stmt_init(mysql);
14803   stmt2= mysql_stmt_init(mysql);
14804   type= (ulong) CURSOR_TYPE_READ_ONLY;
14805   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14806   mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14807 
14808   stmt_text= "select a from t1";
14809 
14810   rc= mysql_stmt_prepare(stmt1, stmt_text, (ulong)strlen(stmt_text));
14811   check_execute(stmt1, rc);
14812   rc= mysql_stmt_execute(stmt1);
14813   check_execute(stmt1, rc);
14814   rc= mysql_stmt_fetch(stmt1);
14815   check_execute(stmt1, rc);
14816 
14817   rc= mysql_stmt_prepare(stmt2, stmt_text, (ulong)strlen(stmt_text));
14818   check_execute(stmt2, rc);
14819   rc= mysql_stmt_execute(stmt2);
14820   check_execute(stmt2, rc);
14821   rc= mysql_stmt_fetch(stmt2);
14822   check_execute(stmt2, rc);
14823 
14824   rc= mysql_stmt_close(stmt1);
14825   check_execute(stmt1, rc);
14826   rc= mysql_commit(mysql);
14827   myquery(rc);
14828   rc= mysql_stmt_fetch(stmt2);
14829   check_execute(stmt2, rc);
14830 
14831   mysql_stmt_close(stmt2);
14832   rc= mysql_query(mysql, "drop table t1");
14833   myquery(rc);
14834   mysql_autocommit(mysql, TRUE);                /* restore default */
14835 }
14836 
14837 
14838 /*
14839   Bug#11718: query with function, join and order by returns wrong type
14840 */
14841 
test_bug11718()14842 static void test_bug11718()
14843 {
14844   MYSQL_RES	*res;
14845   int rc;
14846   const char *query= "select str_to_date(concat(f3),'%Y%m%d') from t1,t2 "
14847                      "where f1=f2 order by f1";
14848 
14849   myheader("test_bug11718");
14850 
14851   rc= mysql_query(mysql, "drop table if exists t1, t2");
14852   myquery(rc);
14853   rc= mysql_query(mysql, "create table t1 (f1 int)");
14854   myquery(rc);
14855   rc= mysql_query(mysql, "create table t2 (f2 int, f3 numeric(8))");
14856   myquery(rc);
14857   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14858   myquery(rc);
14859   rc= mysql_query(mysql, "insert into t2 values (1,20050101), (2,20050202)");
14860   myquery(rc);
14861   rc= mysql_query(mysql, query);
14862   myquery(rc);
14863   res = mysql_store_result(mysql);
14864 
14865   if (!opt_silent)
14866     printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
14867            "not DATE");
14868   DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
14869   mysql_free_result(res);
14870   rc= mysql_query(mysql, "drop table t1, t2");
14871   myquery(rc);
14872 }
14873 
14874 
14875 /*
14876   Bug #12925: Bad handling of maximum values in getopt
14877 */
test_bug12925()14878 static void test_bug12925()
14879 {
14880   myheader("test_bug12925");
14881   if (opt_getopt_ll_test)
14882     DIE_UNLESS(opt_getopt_ll_test == 25600*1024*1024LL);
14883 }
14884 
14885 
14886 /*
14887   Bug#14210 "Simple query with > operator on large table gives server
14888   crash"
14889 */
14890 
test_bug14210()14891 static void test_bug14210()
14892 {
14893   MYSQL_STMT *stmt;
14894   int rc, i;
14895   const char *stmt_text;
14896   ulong type;
14897 
14898   myheader("test_bug14210");
14899 
14900   mysql_query(mysql, "drop table if exists t1");
14901   /*
14902     To trigger the problem the table must be InnoDB, although the problem
14903     itself is not InnoDB related. In case the table is MyISAM this test
14904     is harmless.
14905   */
14906   mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB");
14907   rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
14908   myquery(rc);
14909   rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
14910   /* Create a big enough table (more than max_heap_table_size) */
14911   for (i= 0; i < 8; i++)
14912   {
14913     rc= mysql_query(mysql, "insert into t1 (a) select a from t1");
14914     myquery(rc);
14915   }
14916   /* create statement */
14917   stmt= mysql_stmt_init(mysql);
14918   type= (ulong) CURSOR_TYPE_READ_ONLY;
14919   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14920 
14921   stmt_text= "select a from t1";
14922 
14923   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14924   check_execute(stmt, rc);
14925   rc= mysql_stmt_execute(stmt);
14926   while ((rc= mysql_stmt_fetch(stmt)) == 0)
14927     ;
14928   DIE_UNLESS(rc == MYSQL_NO_DATA);
14929 
14930   rc= mysql_stmt_close(stmt);
14931 
14932   rc= mysql_query(mysql, "drop table t1");
14933   myquery(rc);
14934   rc= mysql_query(mysql, "set @@session.max_heap_table_size=default");
14935   myquery(rc);
14936 }
14937 
14938 /* Bug#13488: wrong column metadata when fetching from cursor */
14939 
test_bug13488()14940 static void test_bug13488()
14941 {
14942   MYSQL_BIND my_bind[3];
14943   MYSQL_STMT *stmt1;
14944   int rc, f1, f2, f3, i;
14945   const ulong type= CURSOR_TYPE_READ_ONLY;
14946   const char *query= "select * from t1 left join t2 on f1=f2 where f1=1";
14947 
14948   myheader("test_bug13488");
14949 
14950   rc= mysql_query(mysql, "drop table if exists t1, t2");
14951   myquery(rc);
14952   rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)");
14953   myquery(rc);
14954   rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, "
14955                   "f3 int not null)");
14956   myquery(rc);
14957   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14958   myquery(rc);
14959   rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)");
14960   myquery(rc);
14961 
14962   memset(my_bind, 0, sizeof(my_bind));
14963   for (i= 0; i < 3; i++)
14964   {
14965     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
14966     my_bind[i].buffer_length= 4;
14967     my_bind[i].length= 0;
14968   }
14969   my_bind[0].buffer=&f1;
14970   my_bind[1].buffer=&f2;
14971   my_bind[2].buffer=&f3;
14972 
14973   stmt1= mysql_stmt_init(mysql);
14974   rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type);
14975   check_execute(stmt1, rc);
14976 
14977   rc= mysql_stmt_prepare(stmt1, query, (ulong)strlen(query));
14978   check_execute(stmt1, rc);
14979 
14980   rc= mysql_stmt_execute(stmt1);
14981   check_execute(stmt1, rc);
14982 
14983   rc= mysql_stmt_bind_result(stmt1, my_bind);
14984   check_execute(stmt1, rc);
14985 
14986   rc= mysql_stmt_fetch(stmt1);
14987   check_execute(stmt1, rc);
14988 
14989   rc= mysql_stmt_free_result(stmt1);
14990   check_execute(stmt1, rc);
14991 
14992   rc= mysql_stmt_reset(stmt1);
14993   check_execute(stmt1, rc);
14994 
14995   rc= mysql_stmt_close(stmt1);
14996   check_execute(stmt1, rc);
14997 
14998   if (!opt_silent)
14999   {
15000     printf("data: f1: %d; f2: %d; f3: %d\n", f1, f2, f3);
15001     printf("data is: %s\n",
15002            (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong");
15003   }
15004   DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
15005   rc= mysql_query(mysql, "drop table t1, t2");
15006   myquery(rc);
15007 }
15008 
15009 /*
15010   Bug#13524: warnings of a previous command are not reset when fetching
15011   from a cursor.
15012 */
15013 
test_bug13524()15014 static void test_bug13524()
15015 {
15016   MYSQL_STMT *stmt;
15017   int rc;
15018   unsigned int warning_count;
15019   const ulong type= CURSOR_TYPE_READ_ONLY;
15020   const char *query= "select * from t1";
15021 
15022   myheader("test_bug13524");
15023 
15024   rc= mysql_query(mysql, "drop table if exists t1, t2");
15025   myquery(rc);
15026   rc= mysql_query(mysql, "create table t1 (a int not null primary key)");
15027   myquery(rc);
15028   rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
15029   myquery(rc);
15030 
15031   stmt= mysql_stmt_init(mysql);
15032   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15033   check_execute(stmt, rc);
15034 
15035   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
15036   check_execute(stmt, rc);
15037 
15038   rc= mysql_stmt_execute(stmt);
15039   check_execute(stmt, rc);
15040 
15041   rc= mysql_stmt_fetch(stmt);
15042   check_execute(stmt, rc);
15043 
15044   warning_count= mysql_warning_count(mysql);
15045   DIE_UNLESS(warning_count == 0);
15046 
15047   /* Check that DROP TABLE produced a warning (no such table) */
15048   rc= mysql_query(mysql, "drop table if exists t2");
15049   myquery(rc);
15050   warning_count= mysql_warning_count(mysql);
15051   DIE_UNLESS(warning_count == 1);
15052 
15053   /*
15054     Check that fetch from a cursor cleared the warning from the previous
15055     command.
15056   */
15057   rc= mysql_stmt_fetch(stmt);
15058   check_execute(stmt, rc);
15059   warning_count= mysql_warning_count(mysql);
15060   DIE_UNLESS(warning_count == 0);
15061 
15062   /* Cleanup */
15063   mysql_stmt_close(stmt);
15064   rc= mysql_query(mysql, "drop table t1");
15065   myquery(rc);
15066 }
15067 
15068 /*
15069   Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
15070 */
15071 
test_bug14845()15072 static void test_bug14845()
15073 {
15074   MYSQL_STMT *stmt;
15075   int rc;
15076   const ulong type= CURSOR_TYPE_READ_ONLY;
15077   const char *query= "select count(*) from t1 where 1 = 0";
15078 
15079   myheader("test_bug14845");
15080 
15081   rc= mysql_query(mysql, "drop table if exists t1");
15082   myquery(rc);
15083   rc= mysql_query(mysql, "create table t1 (id int(11) default null, "
15084                          "name varchar(20) default null)"
15085                          "engine=MyISAM DEFAULT CHARSET=utf8");
15086   myquery(rc);
15087   rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')");
15088   myquery(rc);
15089 
15090   stmt= mysql_stmt_init(mysql);
15091   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15092   check_execute(stmt, rc);
15093 
15094   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
15095   check_execute(stmt, rc);
15096 
15097   rc= mysql_stmt_execute(stmt);
15098   check_execute(stmt, rc);
15099 
15100   rc= mysql_stmt_fetch(stmt);
15101   DIE_UNLESS(rc == 0);
15102 
15103   rc= mysql_stmt_fetch(stmt);
15104   DIE_UNLESS(rc == MYSQL_NO_DATA);
15105 
15106   /* Cleanup */
15107   mysql_stmt_close(stmt);
15108   rc= mysql_query(mysql, "drop table t1");
15109   myquery(rc);
15110 }
15111 
15112 
15113 /*
15114   Bug #15510: mysql_warning_count returns 0 after mysql_stmt_fetch which
15115   should warn
15116 */
test_bug15510()15117 static void test_bug15510()
15118 {
15119   MYSQL_STMT *stmt;
15120   int rc;
15121   const char *query= "select 1 from dual where 1/0";
15122 
15123   myheader("test_bug15510");
15124 
15125   rc= mysql_query(mysql, "set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'");
15126   myquery(rc);
15127 
15128   stmt= mysql_stmt_init(mysql);
15129 
15130   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
15131   check_execute(stmt, rc);
15132 
15133   rc= mysql_stmt_execute(stmt);
15134   check_execute(stmt, rc);
15135 
15136   rc= mysql_stmt_fetch(stmt);
15137   DIE_UNLESS(mysql_warning_count(mysql));
15138 
15139   /* Cleanup */
15140   mysql_stmt_close(stmt);
15141   rc= mysql_query(mysql, "set @@sql_mode=''");
15142   myquery(rc);
15143 }
15144 
15145 
15146 /* Test MYSQL_OPT_RECONNECT, Bug#15719 */
15147 
test_opt_reconnect()15148 static void test_opt_reconnect()
15149 {
15150   MYSQL *lmysql;
15151   my_bool my_true= TRUE;
15152 
15153   myheader("test_opt_reconnect");
15154 
15155   if (!(lmysql= mysql_client_init(NULL)))
15156   {
15157     myerror("mysql_client_init() failed");
15158     exit(1);
15159   }
15160 
15161   if (!opt_silent)
15162     fprintf(stdout, "reconnect before mysql_options: %d\n", lmysql->reconnect);
15163   DIE_UNLESS(lmysql->reconnect == 0);
15164 
15165   if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
15166   {
15167     myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
15168     DIE_UNLESS(0);
15169   }
15170 
15171   /* reconnect should be 1 */
15172   if (!opt_silent)
15173     fprintf(stdout, "reconnect after mysql_options: %d\n", lmysql->reconnect);
15174   DIE_UNLESS(lmysql->reconnect == 1);
15175 
15176   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15177                            opt_password, current_db, opt_port,
15178                            opt_unix_socket, 0)))
15179   {
15180     myerror("connection failed");
15181     DIE_UNLESS(0);
15182   }
15183 
15184   /* reconnect should still be 1 */
15185   if (!opt_silent)
15186     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15187 	    lmysql->reconnect);
15188   DIE_UNLESS(lmysql->reconnect == 1);
15189 
15190   mysql_close(lmysql);
15191 
15192   if (!(lmysql= mysql_client_init(NULL)))
15193   {
15194     myerror("mysql_client_init() failed");
15195     DIE_UNLESS(0);
15196   }
15197 
15198   if (!opt_silent)
15199     fprintf(stdout, "reconnect before mysql_real_connect: %d\n", lmysql->reconnect);
15200   DIE_UNLESS(lmysql->reconnect == 0);
15201 
15202   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15203                            opt_password, current_db, opt_port,
15204                            opt_unix_socket, 0)))
15205   {
15206     myerror("connection failed");
15207     DIE_UNLESS(0);
15208   }
15209 
15210   /* reconnect should still be 0 */
15211   if (!opt_silent)
15212     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15213 	    lmysql->reconnect);
15214   DIE_UNLESS(lmysql->reconnect == 0);
15215 
15216   mysql_close(lmysql);
15217 }
15218 
15219 
15220 #ifndef EMBEDDED_LIBRARY
15221 
test_bug12744()15222 static void test_bug12744()
15223 {
15224   MYSQL_STMT *prep_stmt = NULL;
15225   MYSQL *lmysql;
15226   int rc;
15227   myheader("test_bug12744");
15228 
15229   lmysql= mysql_client_init(NULL);
15230   DIE_UNLESS(lmysql);
15231 
15232   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
15233                           current_db, opt_port, opt_unix_socket, 0))
15234   {
15235     fprintf(stderr, "Failed to connect to the database\n");
15236     DIE_UNLESS(0);
15237   }
15238 
15239   prep_stmt= mysql_stmt_init(lmysql);
15240   rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
15241   DIE_UNLESS(rc == 0);
15242 
15243   mysql_close(lmysql);
15244 
15245   rc= mysql_stmt_execute(prep_stmt);
15246   DIE_UNLESS(rc);
15247   rc= mysql_stmt_reset(prep_stmt);
15248   DIE_UNLESS(rc);
15249   rc= mysql_stmt_close(prep_stmt);
15250   DIE_UNLESS(rc == 0);
15251 }
15252 
15253 #endif /* EMBEDDED_LIBRARY */
15254 
15255 /* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
15256 
test_bug16143()15257 static void test_bug16143()
15258 {
15259   MYSQL_STMT *stmt;
15260   myheader("test_bug16143");
15261 
15262   stmt= mysql_stmt_init(mysql);
15263   /* Check mysql_stmt_sqlstate return "no error" */
15264   DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0);
15265 
15266   mysql_stmt_close(stmt);
15267 }
15268 
15269 
15270 /* Bug #16144: mysql_stmt_attr_get type error */
15271 
test_bug16144()15272 static void test_bug16144()
15273 {
15274   const my_bool flag_orig= (my_bool) 0xde;
15275   my_bool flag= flag_orig;
15276   MYSQL_STMT *stmt;
15277   myheader("test_bug16144");
15278 
15279   /* Check that attr_get returns correct data on little and big endian CPUs */
15280   stmt= mysql_stmt_init(mysql);
15281   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
15282   mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
15283   DIE_UNLESS(flag == flag_orig);
15284 
15285   mysql_stmt_close(stmt);
15286 }
15287 
15288 /*
15289   Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
15290   field length"
15291 */
15292 
test_bug15613()15293 static void test_bug15613()
15294 {
15295   MYSQL_STMT *stmt;
15296   const char *stmt_text;
15297   MYSQL_RES *metadata;
15298   MYSQL_FIELD *field;
15299   int rc;
15300   myheader("test_bug15613");
15301 
15302   /* I. Prepare the table */
15303   rc= mysql_query(mysql, "set names latin1");
15304   myquery(rc);
15305   mysql_query(mysql, "drop table if exists t1");
15306   rc= mysql_query(mysql,
15307                   "create table t1 (t text character set utf8, "
15308                                    "tt tinytext character set utf8, "
15309                                    "mt mediumtext character set utf8, "
15310                                    "lt longtext character set utf8, "
15311                                    "vl varchar(255) character set latin1,"
15312                                    "vb varchar(255) character set binary,"
15313                                    "vu varchar(255) character set utf8)");
15314   myquery(rc);
15315 
15316   stmt= mysql_stmt_init(mysql);
15317 
15318   /* II. Check SELECT metadata */
15319   stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
15320   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
15321   metadata= mysql_stmt_result_metadata(stmt);
15322   field= mysql_fetch_fields(metadata);
15323   if (!opt_silent)
15324   {
15325     printf("Field lengths (client character set is latin1):\n"
15326            "text character set utf8:\t\t%lu\n"
15327            "tinytext character set utf8:\t\t%lu\n"
15328            "mediumtext character set utf8:\t\t%lu\n"
15329            "longtext character set utf8:\t\t%lu\n"
15330            "varchar(255) character set latin1:\t%lu\n"
15331            "varchar(255) character set binary:\t%lu\n"
15332            "varchar(255) character set utf8:\t%lu\n",
15333            field[0].length, field[1].length, field[2].length, field[3].length,
15334            field[4].length, field[5].length, field[6].length);
15335   }
15336   DIE_UNLESS(field[0].length == 65535);
15337   DIE_UNLESS(field[1].length == 255);
15338   DIE_UNLESS(field[2].length == 16777215);
15339   DIE_UNLESS(field[3].length == 4294967295UL);
15340   DIE_UNLESS(field[4].length == 255);
15341   DIE_UNLESS(field[5].length == 255);
15342   DIE_UNLESS(field[6].length == 255);
15343   mysql_free_result(metadata);
15344   mysql_stmt_free_result(stmt);
15345 
15346   /* III. Cleanup */
15347   rc= mysql_query(mysql, "drop table t1");
15348   myquery(rc);
15349   rc= mysql_query(mysql, "set names default");
15350   myquery(rc);
15351   mysql_stmt_close(stmt);
15352 }
15353 
15354 /*
15355   Bug#17667: An attacker has the opportunity to bypass query logging.
15356 
15357   Note! Also tests Bug#21813, where prepared statements are used to
15358   run queries
15359 */
test_bug17667()15360 static void test_bug17667()
15361 {
15362   int rc;
15363   MYSQL_STMT *stmt;
15364   enum query_type { QT_NORMAL, QT_PREPARED};
15365   struct buffer_and_length {
15366     enum query_type qt;
15367     const char *buffer;
15368     const ulong length;
15369   } statements[]= {
15370     { QT_NORMAL, "drop table if exists bug17667", 29 },
15371     { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
15372     { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
15373     { QT_PREPARED,
15374       "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
15375     { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
15376     { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
15377     { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
15378     { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
15379     { QT_NORMAL, "drop table bug17667", 19 },
15380     { QT_NORMAL, NULL, 0 } };
15381 
15382   struct buffer_and_length *statement_cursor;
15383   FILE *log_file;
15384   char *master_log_filename;
15385 
15386   myheader("test_bug17667");
15387 
15388   master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1);
15389   strxmov(master_log_filename, opt_vardir, "/log/master.log", NullS);
15390   if (!opt_silent)
15391     printf("Opening '%s'\n", master_log_filename);
15392   log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0));
15393   free(master_log_filename);
15394 
15395   if (log_file == NULL)
15396   {
15397     if (!opt_silent)
15398     {
15399       printf("Could not find the log file, VARDIR/log/master.log, so "
15400              "test_bug17667 is not run.\n"
15401              "Run test from the mysql-test/mysql-test-run* program to set up "
15402              "correct environment for this test.\n\n");
15403     }
15404     return;
15405   }
15406 
15407   enable_query_logs(1);
15408 
15409   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15410        statement_cursor++)
15411   {
15412     if (statement_cursor->qt == QT_NORMAL)
15413     {
15414       /* Run statement as normal query */
15415       rc= mysql_real_query(mysql, statement_cursor->buffer,
15416                            statement_cursor->length);
15417       myquery(rc);
15418     }
15419     else if (statement_cursor->qt == QT_PREPARED)
15420     {
15421       /*
15422         Run as prepared statement
15423 
15424         NOTE! All these queries should be in the log twice,
15425         one time for prepare and one time for execute
15426       */
15427       stmt= mysql_stmt_init(mysql);
15428 
15429       rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
15430                              statement_cursor->length);
15431       check_execute(stmt, rc);
15432 
15433       rc= mysql_stmt_execute(stmt);
15434       check_execute(stmt, rc);
15435 
15436       mysql_stmt_close(stmt);
15437     }
15438     else
15439     {
15440       DIE_UNLESS(0==1);
15441     }
15442   }
15443 
15444   /* Make sure the server has written the logs to disk before reading it */
15445   rc= mysql_query(mysql, "flush logs");
15446   myquery(rc);
15447 
15448   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15449        statement_cursor++)
15450   {
15451     int expected_hits= 1, hits= 0;
15452     char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15453     /* more than enough room for the query and some marginalia. */
15454 
15455     /* Prepared statments always occurs twice in log */
15456     if (statement_cursor->qt == QT_PREPARED)
15457       expected_hits++;
15458 
15459     /* Loop until we found expected number of log entries */
15460     do {
15461       /* Loop until statement is found in log */
15462       do {
15463         memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15464 
15465         if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15466         {
15467           /* If fgets returned NULL, it indicates either error or EOF */
15468           if (feof(log_file))
15469             DIE("Found EOF before all statements where found");
15470 
15471           fprintf(stderr, "Got error %d while reading from file\n",
15472                   ferror(log_file));
15473           DIE("Read error");
15474         }
15475 
15476       } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15477                          statement_cursor->buffer,
15478                          statement_cursor->length) == NULL);
15479       hits++;
15480     } while (hits < expected_hits);
15481 
15482     if (!opt_silent)
15483       printf("Found statement starting with \"%s\"\n",
15484              statement_cursor->buffer);
15485   }
15486 
15487   restore_query_logs();
15488 
15489   if (!opt_silent)
15490     printf("success.  All queries found intact in the log.\n");
15491 
15492   my_fclose(log_file, MYF(0));
15493 }
15494 
15495 
15496 /*
15497   Bug#14169: type of group_concat() result changed to blob if tmp_table was
15498   used
15499 */
test_bug14169()15500 static void test_bug14169()
15501 {
15502   MYSQL_STMT *stmt;
15503   const char *stmt_text;
15504   MYSQL_RES *res;
15505   MYSQL_FIELD *field;
15506   int rc;
15507 
15508   myheader("test_bug14169");
15509 
15510   rc= mysql_query(mysql, "drop table if exists t1");
15511   myquery(rc);
15512   rc= mysql_query(mysql, "set session group_concat_max_len=1024");
15513   myquery(rc);
15514   rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))");
15515   myquery(rc);
15516   rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255)),"
15517                          "(2,repeat('b',255))");
15518   myquery(rc);
15519   stmt= mysql_stmt_init(mysql);
15520   stmt_text= "select f2,group_concat(f1) from t1 group by f2";
15521   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
15522   myquery(rc);
15523   res= mysql_stmt_result_metadata(stmt);
15524   field= mysql_fetch_fields(res);
15525   if (!opt_silent)
15526     printf("GROUP_CONCAT() result type %i", field[1].type);
15527   DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
15528   mysql_free_result(res);
15529   mysql_stmt_free_result(stmt);
15530   mysql_stmt_close(stmt);
15531 
15532   rc= mysql_query(mysql, "drop table t1");
15533   myquery(rc);
15534 }
15535 
15536 /*
15537    Test that mysql_insert_id() behaves as documented in our manual
15538 */
test_mysql_insert_id()15539 static void test_mysql_insert_id()
15540 {
15541   my_ulonglong res;
15542   int rc;
15543 
15544   myheader("test_mysql_insert_id");
15545 
15546   rc= mysql_query(mysql, "drop table if exists t1");
15547   myquery(rc);
15548   /* table without auto_increment column */
15549   rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
15550   myquery(rc);
15551   rc= mysql_query(mysql, "insert into t1 values (1,'a')");
15552   myquery(rc);
15553   res= mysql_insert_id(mysql);
15554   DIE_UNLESS(res == 0);
15555   rc= mysql_query(mysql, "insert into t1 values (null,'b')");
15556   myquery(rc);
15557   res= mysql_insert_id(mysql);
15558   DIE_UNLESS(res == 0);
15559   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15560   myquery(rc);
15561   res= mysql_insert_id(mysql);
15562   DIE_UNLESS(res == 0);
15563 
15564   /*
15565     Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
15566     sporadically
15567   */
15568   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15569   myquery(rc);
15570   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15571   myquery(rc);
15572   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15573   myquery(rc);
15574   res= mysql_insert_id(mysql);
15575   DIE_UNLESS(res == 0);
15576   rc= mysql_query(mysql, "drop table t2");
15577   myquery(rc);
15578 
15579   rc= mysql_query(mysql, "insert into t1 select null,'d'");
15580   myquery(rc);
15581   res= mysql_insert_id(mysql);
15582   DIE_UNLESS(res == 0);
15583   rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
15584   myquery(rc);
15585   res= mysql_insert_id(mysql);
15586   DIE_UNLESS(res == 300);
15587   rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
15588   myquery(rc);
15589   res= mysql_insert_id(mysql);
15590   /*
15591     Behaviour change: old code used to return 0; but 400 is consistent
15592     with INSERT VALUES, and the manual's section of mysql_insert_id() does not
15593     say INSERT SELECT should be different.
15594   */
15595   DIE_UNLESS(res == 400);
15596 
15597   /* table with auto_increment column */
15598   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255)) ENGINE = MyISAM");
15599   myquery(rc);
15600   rc= mysql_query(mysql, "insert into t2 values (1,'a')");
15601   myquery(rc);
15602   res= mysql_insert_id(mysql);
15603   DIE_UNLESS(res == 1);
15604   /* this should not influence next INSERT if it doesn't have auto_inc */
15605   rc= mysql_query(mysql, "insert into t1 values (10,'e')");
15606   myquery(rc);
15607   res= mysql_insert_id(mysql);
15608   DIE_UNLESS(res == 0);
15609 
15610   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15611   myquery(rc);
15612   res= mysql_insert_id(mysql);
15613   DIE_UNLESS(res == 2);
15614   rc= mysql_query(mysql, "insert into t2 select 5,'c'");
15615   myquery(rc);
15616   res= mysql_insert_id(mysql);
15617   /*
15618     Manual says that for multirow insert this should have been 5, but does not
15619     say for INSERT SELECT. This is a behaviour change: old code used to return
15620     0. We try to be consistent with INSERT VALUES.
15621   */
15622   DIE_UNLESS(res == 5);
15623   rc= mysql_query(mysql, "insert into t2 select null,'d'");
15624   myquery(rc);
15625   res= mysql_insert_id(mysql);
15626   DIE_UNLESS(res == 6);
15627   /* with more than one row */
15628   rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
15629   myquery(rc);
15630   res= mysql_insert_id(mysql);
15631   DIE_UNLESS(res == 11);
15632   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15633   myquery(rc);
15634   res= mysql_insert_id(mysql);
15635   /*
15636     Manual says that for multirow insert this should have been 13, but does
15637     not say for INSERT SELECT. This is a behaviour change: old code used to
15638     return 0. We try to be consistent with INSERT VALUES.
15639   */
15640   DIE_UNLESS(res == 13);
15641   rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
15642   myquery(rc);
15643   res= mysql_insert_id(mysql);
15644   DIE_UNLESS(res == 14);
15645   rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
15646   myquery(rc);
15647   res= mysql_insert_id(mysql);
15648   DIE_UNLESS(res == 16);
15649   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15650   myquery_r(rc);
15651   rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
15652   myquery(rc);
15653   res= mysql_insert_id(mysql);
15654   DIE_UNLESS(res == 0);
15655   rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
15656   myquery_r(rc);
15657   res= mysql_insert_id(mysql);
15658   DIE_UNLESS(res == 0);
15659   rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
15660   myquery(rc);
15661   res= mysql_insert_id(mysql);
15662   DIE_UNLESS(res == 0);
15663   /* mixing autogenerated and explicit values */
15664   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
15665   myquery_r(rc);
15666   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
15667   myquery_r(rc);
15668   rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
15669   myquery(rc);
15670   res= mysql_insert_id(mysql);
15671   /*
15672     according to the manual, this might be 20 or 300, but it looks like
15673     auto_increment column takes priority over last_insert_id().
15674   */
15675   DIE_UNLESS(res == 20);
15676   /* If first autogenerated number fails and 2nd works: */
15677   rc= mysql_query(mysql, "drop table t2");
15678   myquery(rc);
15679   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
15680                   "auto_increment, f2 varchar(255), unique (f2)) ENGINE = MyISAM");
15681   myquery(rc);
15682   rc= mysql_query(mysql, "insert into t2 values (null,'e')");
15683   res= mysql_insert_id(mysql);
15684   DIE_UNLESS(res == 1);
15685   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
15686   myquery(rc);
15687   res= mysql_insert_id(mysql);
15688   DIE_UNLESS(res == 2);
15689   /* If autogenerated fails and explicit works: */
15690   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
15691   myquery(rc);
15692   res= mysql_insert_id(mysql);
15693   /*
15694     Behaviour change: old code returned 3 (first autogenerated, even if it
15695     fails); we now return first successful autogenerated.
15696   */
15697   DIE_UNLESS(res == 13);
15698   /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
15699   rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
15700   myquery(rc);
15701   res= mysql_insert_id(mysql);
15702   DIE_UNLESS(res == 0);
15703   rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
15704   myquery(rc);
15705   res= mysql_insert_id(mysql);
15706   DIE_UNLESS(res == 0);
15707   rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
15708   myquery(rc);
15709   res= mysql_insert_id(mysql);
15710   DIE_UNLESS(res == 372);
15711   /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
15712   rc= mysql_query(mysql, "insert into t2 values (null,'g')");
15713   myquery(rc);
15714   res= mysql_insert_id(mysql);
15715   DIE_UNLESS(res == 15);
15716   rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
15717   myquery(rc);
15718   res= mysql_insert_id(mysql);
15719   DIE_UNLESS(res == 0);
15720   /*
15721     Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
15722     mysql_insert_id() returns the id of the row, instead of not being
15723     affected.
15724   */
15725   rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
15726                   "update f2=concat('we updated ',f2)");
15727   myquery(rc);
15728   res= mysql_insert_id(mysql);
15729   DIE_UNLESS(res == 15);
15730 
15731   rc= mysql_query(mysql, "drop table t1,t2");
15732   myquery(rc);
15733 }
15734 
15735 /*
15736   Test for bug#22028117: MYSQLCLIENT DOES NOT RETURN CORRECT
15737   MYSQL_INSERT_ID VIA DATABASE HANDLE
15738 */
15739 
test_bug22028117()15740 static void test_bug22028117()
15741 {
15742   my_ulonglong res;
15743   int rc;
15744   MYSQL_STMT *stmt;
15745 
15746   myheader("test_bug22028117");
15747 
15748   rc = mysql_query(mysql, "USE test");
15749   myquery(rc);
15750   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15751   myquery(rc);
15752   rc= mysql_query(mysql, "CREATE TABLE t1 ("
15753                          "f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT,"
15754                          "f2 VARCHAR(255))");
15755   myquery(rc);
15756   res= mysql_insert_id(mysql);
15757   DIE_UNLESS(res == 0);
15758 
15759   rc= mysql_query(mysql, "INSERT INTO t1 (f2) VALUES ('a')");
15760   myquery(rc);
15761   res= mysql_insert_id(mysql);
15762   DIE_UNLESS(res == 1);
15763 
15764   rc= mysql_query(mysql, "INSERT INTO t1 (f2) VALUES ('b')");
15765   myquery(rc);
15766   res= mysql_insert_id(mysql);
15767   DIE_UNLESS(res == 2);
15768 
15769   /* Make sure that the value of insert_id is not lost after SELECT */
15770   stmt= mysql_simple_prepare(mysql, "SELECT MAX(f1) FROM t1");
15771   check_stmt(stmt);
15772   rc= mysql_stmt_execute(stmt);
15773   check_execute(stmt, rc);
15774   rc= my_process_stmt_result(stmt);
15775   DIE_UNLESS(rc == 1);
15776   mysql_stmt_close(stmt);
15777 
15778   res= mysql_insert_id(mysql);
15779   DIE_UNLESS(res == 2);
15780 
15781   /* insert_id will be reset to 0 after a new table is created */
15782   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
15783   myquery(rc);
15784 
15785   rc= mysql_query(mysql, "CREATE TABLE t2 ("
15786                          "f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT,"
15787                          "f2 VARCHAR(255))");
15788   myquery(rc);
15789   res= mysql_insert_id(mysql);
15790   DIE_UNLESS(res == 0);
15791 
15792   /*
15793     mysql_insert_id() should return expr when the INSERT query contains
15794     last_insert_id(expr)
15795   */
15796   rc= mysql_query(mysql, "INSERT INTO t1 (f1) VALUES (last_insert_id(100))");
15797   myquery(rc);
15798   res= mysql_insert_id(mysql);
15799   DIE_UNLESS(res == 100);
15800 
15801   rc= mysql_query(mysql, "DROP TABLE t1,t2");
15802   myquery(rc);
15803 }
15804 
15805 /*
15806   Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
15807 */
15808 
test_bug20152()15809 static void test_bug20152()
15810 {
15811   MYSQL_BIND my_bind[1];
15812   MYSQL_STMT *stmt;
15813   MYSQL_TIME tm;
15814   int rc;
15815   const char *query= "INSERT INTO t1 (f1) VALUES (?)";
15816 
15817   myheader("test_bug20152");
15818 
15819   memset(my_bind, 0, sizeof(my_bind));
15820   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
15821   my_bind[0].buffer= (void*)&tm;
15822 
15823   tm.year = 2006;
15824   tm.month = 6;
15825   tm.day = 18;
15826   tm.hour = 14;
15827   tm.minute = 9;
15828   tm.second = 42;
15829 
15830   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15831   myquery(rc);
15832   rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)");
15833   myquery(rc);
15834 
15835   stmt= mysql_stmt_init(mysql);
15836   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
15837   check_execute(stmt, rc);
15838   rc= mysql_stmt_bind_param(stmt, my_bind);
15839   check_execute(stmt, rc);
15840   rc= mysql_stmt_execute(stmt);
15841   check_execute(stmt, rc);
15842   rc= mysql_stmt_close(stmt);
15843   check_execute(stmt, rc);
15844   rc= mysql_query(mysql, "DROP TABLE t1");
15845   myquery(rc);
15846 
15847   if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) {
15848     if (!opt_silent)
15849       printf("OK!");
15850   } else {
15851     printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second);
15852     DIE_UNLESS(0==1);
15853   }
15854 }
15855 
15856 /* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
15857 
test_bug15752()15858 static void test_bug15752()
15859 {
15860   MYSQL mysql_local;
15861   int rc, i;
15862   const int ITERATION_COUNT= 100;
15863   const char *query= "CALL p1()";
15864 
15865   myheader("test_bug15752");
15866 
15867   rc= mysql_query(mysql, "drop procedure if exists p1");
15868   myquery(rc);
15869   rc= mysql_query(mysql, "create procedure p1() select 1");
15870   myquery(rc);
15871 
15872   mysql_client_init(&mysql_local);
15873   if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
15874                            opt_password, current_db, opt_port,
15875                            opt_unix_socket,
15876                            CLIENT_MULTI_STATEMENTS))
15877   {
15878     printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
15879     DIE_UNLESS(0);
15880   }
15881   rc= mysql_real_query(&mysql_local, query, (ulong)strlen(query));
15882   myquery(rc);
15883   mysql_free_result(mysql_store_result(&mysql_local));
15884 
15885   rc= mysql_real_query(&mysql_local, query, (ulong)strlen(query));
15886   DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
15887 
15888   if (! opt_silent)
15889     printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
15890 
15891   /* Check some other commands too */
15892 
15893   DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15894   mysql_free_result(mysql_store_result(&mysql_local));
15895   DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15896 
15897   /* The second problem is not reproducible: add the test case */
15898   for (i = 0; i < ITERATION_COUNT; i++)
15899   {
15900     if (mysql_real_query(&mysql_local, query, (ulong)strlen(query)))
15901     {
15902       printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
15903       break;
15904     }
15905     mysql_free_result(mysql_store_result(&mysql_local));
15906     DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15907     mysql_free_result(mysql_store_result(&mysql_local));
15908     DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15909 
15910   }
15911   mysql_close(&mysql_local);
15912   rc= mysql_query(mysql, "drop procedure p1");
15913   myquery(rc);
15914 }
15915 
15916 /*
15917   Bug#21206: memory corruption when too many cursors are opened at once
15918 
15919   Memory corruption happens when more than 1024 cursors are open
15920   simultaneously.
15921 */
test_bug21206()15922 static void test_bug21206()
15923 {
15924   const size_t cursor_count= 1025;
15925 
15926   const char *create_table[]=
15927   {
15928     "DROP TABLE IF EXISTS t1",
15929     "CREATE TABLE t1 (i INT)",
15930     "INSERT INTO t1 VALUES (1), (2), (3)"
15931   };
15932   const char *query= "SELECT * FROM t1";
15933 
15934   Stmt_fetch *fetch_array=
15935     (Stmt_fetch*) calloc(cursor_count, sizeof(Stmt_fetch));
15936 
15937   Stmt_fetch *fetch;
15938 
15939   DBUG_ENTER("test_bug21206");
15940   myheader("test_bug21206");
15941 
15942   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
15943 
15944   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15945   {
15946     /* Init will exit(1) in case of error */
15947     stmt_fetch_init(fetch, fetch - fetch_array, query);
15948   }
15949 
15950   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15951     stmt_fetch_close(fetch);
15952 
15953   free(fetch_array);
15954 
15955   DBUG_VOID_RETURN;
15956 }
15957 
15958 /*
15959   Ensure we execute the status code while testing
15960 */
15961 
test_status()15962 static void test_status()
15963 {
15964   const char *status;
15965   DBUG_ENTER("test_status");
15966   myheader("test_status");
15967 
15968   if (!(status= mysql_stat(mysql)))
15969   {
15970     myerror("mysql_stat failed");                 /* purecov: inspected */
15971     die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
15972   }
15973   DBUG_VOID_RETURN;
15974 }
15975 
15976 /*
15977   Bug#21726: Incorrect result with multiple invocations of
15978   LAST_INSERT_ID
15979 
15980   Test that client gets updated value of insert_id on UPDATE that uses
15981   LAST_INSERT_ID(expr).
15982   select_query added to test for bug
15983     #26921 Problem in mysql_insert_id() Embedded C API function
15984 */
test_bug21726()15985 static void test_bug21726()
15986 {
15987   const char *create_table[]=
15988   {
15989     "DROP TABLE IF EXISTS t1",
15990     "CREATE TABLE t1 (i INT)",
15991     "INSERT INTO t1 VALUES (1)",
15992   };
15993   const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
15994   int rc;
15995   my_ulonglong insert_id;
15996   const char *select_query= "SELECT * FROM t1";
15997   MYSQL_RES  *result;
15998 
15999   DBUG_ENTER("test_bug21726");
16000   myheader("test_bug21726");
16001 
16002   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
16003 
16004   rc= mysql_query(mysql, update_query);
16005   myquery(rc);
16006   insert_id= mysql_insert_id(mysql);
16007   DIE_UNLESS(insert_id == 2);
16008 
16009   rc= mysql_query(mysql, update_query);
16010   myquery(rc);
16011   insert_id= mysql_insert_id(mysql);
16012   DIE_UNLESS(insert_id == 3);
16013 
16014   rc= mysql_query(mysql, select_query);
16015   myquery(rc);
16016   insert_id= mysql_insert_id(mysql);
16017   DIE_UNLESS(insert_id == 3);
16018   result= mysql_store_result(mysql);
16019   mysql_free_result(result);
16020 
16021   DBUG_VOID_RETURN;
16022 }
16023 
16024 
16025 /*
16026   BUG#23383: mysql_affected_rows() returns different values than
16027   mysql_stmt_affected_rows()
16028 
16029   Test that both mysql_affected_rows() and mysql_stmt_affected_rows()
16030   return -1 on error, 0 when no rows were affected, and (positive) row
16031   count when some rows were affected.
16032 */
test_bug23383()16033 static void test_bug23383()
16034 {
16035   const char *insert_query= "INSERT INTO t1 VALUES (1), (2)";
16036   const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3";
16037   MYSQL_STMT *stmt;
16038   my_ulonglong row_count;
16039   int rc;
16040 
16041   DBUG_ENTER("test_bug23383");
16042   myheader("test_bug23383");
16043 
16044   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16045   myquery(rc);
16046 
16047   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)");
16048   myquery(rc);
16049 
16050   rc= mysql_query(mysql, insert_query);
16051   myquery(rc);
16052   row_count= mysql_affected_rows(mysql);
16053   DIE_UNLESS(row_count == 2);
16054 
16055   rc= mysql_query(mysql, insert_query);
16056   DIE_UNLESS(rc != 0);
16057   row_count= mysql_affected_rows(mysql);
16058   DIE_UNLESS(row_count == (my_ulonglong)-1);
16059 
16060   rc= mysql_query(mysql, update_query);
16061   myquery(rc);
16062   row_count= mysql_affected_rows(mysql);
16063   DIE_UNLESS(row_count == 0);
16064 
16065   rc= mysql_query(mysql, "DELETE FROM t1");
16066   myquery(rc);
16067 
16068   stmt= mysql_stmt_init(mysql);
16069   DIE_UNLESS(stmt != 0);
16070 
16071   rc= mysql_stmt_prepare(stmt, insert_query, (ulong)strlen(insert_query));
16072   check_execute(stmt, rc);
16073 
16074   rc= mysql_stmt_execute(stmt);
16075   check_execute(stmt, rc);
16076   row_count= mysql_stmt_affected_rows(stmt);
16077   DIE_UNLESS(row_count == 2);
16078 
16079   rc= mysql_stmt_execute(stmt);
16080   DIE_UNLESS(rc != 0);
16081   row_count= mysql_stmt_affected_rows(stmt);
16082   DIE_UNLESS(row_count == (my_ulonglong)-1);
16083 
16084   rc= mysql_stmt_prepare(stmt, update_query, (ulong)strlen(update_query));
16085   check_execute(stmt, rc);
16086 
16087   rc= mysql_stmt_execute(stmt);
16088   check_execute(stmt, rc);
16089   row_count= mysql_stmt_affected_rows(stmt);
16090   DIE_UNLESS(row_count == 0);
16091 
16092   rc= mysql_stmt_close(stmt);
16093   check_execute(stmt, rc);
16094 
16095   rc= mysql_query(mysql, "DROP TABLE t1");
16096   myquery(rc);
16097 
16098   DBUG_VOID_RETURN;
16099 }
16100 
16101 
16102 /*
16103   BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for
16104   expression cols
16105 
16106   Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set
16107   to either expression or its alias, and db, org_table, table,
16108   org_name fields are empty strings.
16109 */
test_bug21635()16110 static void test_bug21635()
16111 {
16112   const char *expr[]=
16113   {
16114     "MIN(i)", "MIN(i)",
16115     "MIN(i) AS A1", "A1",
16116     "MAX(i)", "MAX(i)",
16117     "MAX(i) AS A2", "A2",
16118     "COUNT(i)", "COUNT(i)",
16119     "COUNT(i) AS A3", "A3",
16120   };
16121   char query[MAX_TEST_QUERY_LENGTH];
16122   char *query_end;
16123   MYSQL_RES *result;
16124   MYSQL_FIELD *field;
16125   unsigned int field_count, i, j;
16126   int rc;
16127 
16128   DBUG_ENTER("test_bug21635");
16129   myheader("test_bug21635");
16130 
16131   query_end= strxmov(query, "SELECT ", NullS);
16132   for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i)
16133     query_end= strxmov(query_end, expr[i * 2], ", ", NullS);
16134   query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS);
16135   DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH);
16136 
16137   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16138   myquery(rc);
16139   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)");
16140   myquery(rc);
16141   /*
16142     We need this loop to ensure correct behavior with both constant and
16143     non-constant tables.
16144   */
16145   for (j= 0; j < 2 ; j++)
16146   {
16147     rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16148     myquery(rc);
16149 
16150     rc= mysql_real_query(mysql, query, (ulong)(query_end - query));
16151     myquery(rc);
16152 
16153     result= mysql_use_result(mysql);
16154     DIE_UNLESS(result);
16155 
16156   field_count= mysql_field_count(mysql);
16157   for (i= 0; i < field_count; ++i)
16158   {
16159     field= mysql_fetch_field_direct(result, i);
16160     if (!opt_silent)
16161       if (!opt_silent)
16162         printf("%s -> %s ... ", expr[i * 2], field->name);
16163     fflush(stdout);
16164     DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
16165                field->table[0] == 0 && field->org_name[0] == 0);
16166     DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
16167     if (!opt_silent)
16168       if (!opt_silent)
16169         puts("OK");
16170   }
16171 
16172     mysql_free_result(result);
16173   }
16174   rc= mysql_query(mysql, "DROP TABLE t1");
16175   myquery(rc);
16176 
16177   DBUG_VOID_RETURN;
16178 }
16179 
16180 /*
16181   Bug#24179 "select b into $var" fails with --cursor_protocol"
16182   The failure is correct, check that the returned message is meaningful.
16183 */
16184 
test_bug24179()16185 static void test_bug24179()
16186 {
16187   int rc;
16188   MYSQL_STMT *stmt;
16189 
16190   DBUG_ENTER("test_bug24179");
16191   myheader("test_bug24179");
16192 
16193   stmt= open_cursor("select 1 into @a");
16194   rc= mysql_stmt_execute(stmt);
16195   DIE_UNLESS(rc);
16196   if (!opt_silent)
16197   {
16198     printf("Got error (as expected): %d %s\n",
16199            mysql_stmt_errno(stmt),
16200            mysql_stmt_error(stmt));
16201   }
16202   DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
16203   mysql_stmt_close(stmt);
16204 
16205   DBUG_VOID_RETURN;
16206 }
16207 
16208 
16209 /**
16210   Bug#32265 Server returns different metadata if prepared statement is used
16211 */
16212 
test_bug32265()16213 static void test_bug32265()
16214 {
16215   int rc;
16216   MYSQL_STMT *stmt;
16217   MYSQL_FIELD *field;
16218   MYSQL_RES *metadata;
16219 
16220   DBUG_ENTER("test_bug32265");
16221   myheader("test_bug32265");
16222 
16223   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16224   myquery(rc);
16225   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
16226   myquery(rc);
16227   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16228   myquery(rc);
16229   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
16230   myquery(rc);
16231 
16232   stmt= open_cursor("SELECT * FROM t1");
16233   rc= mysql_stmt_execute(stmt);
16234   check_execute(stmt, rc);
16235 
16236   metadata= mysql_stmt_result_metadata(stmt);
16237   field= mysql_fetch_field(metadata);
16238   DIE_UNLESS(field);
16239   DIE_UNLESS(strcmp(field->table, "t1") == 0);
16240   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16241   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16242   mysql_free_result(metadata);
16243   mysql_stmt_close(stmt);
16244 
16245   stmt= open_cursor("SELECT a '' FROM t1 ``");
16246   rc= mysql_stmt_execute(stmt);
16247   check_execute(stmt, rc);
16248 
16249   metadata= mysql_stmt_result_metadata(stmt);
16250   field= mysql_fetch_field(metadata);
16251   DIE_UNLESS(strcmp(field->table, "") == 0);
16252   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16253   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16254   mysql_free_result(metadata);
16255   mysql_stmt_close(stmt);
16256 
16257   stmt= open_cursor("SELECT a '' FROM t1 ``");
16258   rc= mysql_stmt_execute(stmt);
16259   check_execute(stmt, rc);
16260 
16261   metadata= mysql_stmt_result_metadata(stmt);
16262   field= mysql_fetch_field(metadata);
16263   DIE_UNLESS(strcmp(field->table, "") == 0);
16264   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16265   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16266   mysql_free_result(metadata);
16267   mysql_stmt_close(stmt);
16268 
16269   stmt= open_cursor("SELECT * FROM v1");
16270   rc= mysql_stmt_execute(stmt);
16271   check_execute(stmt, rc);
16272 
16273   metadata= mysql_stmt_result_metadata(stmt);
16274   field= mysql_fetch_field(metadata);
16275   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16276   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16277   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16278   mysql_free_result(metadata);
16279   mysql_stmt_close(stmt);
16280 
16281   stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
16282   rc= mysql_stmt_execute(stmt);
16283   check_execute(stmt, rc);
16284 
16285   metadata= mysql_stmt_result_metadata(stmt);
16286   field= mysql_fetch_field(metadata);
16287   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16288   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16289   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16290   mysql_free_result(metadata);
16291   mysql_stmt_close(stmt);
16292 
16293   rc= mysql_query(mysql, "DROP VIEW v1");
16294   myquery(rc);
16295   rc= mysql_query(mysql, "DROP TABLE t1");
16296   myquery(rc);
16297 
16298   DBUG_VOID_RETURN;
16299 }
16300 
16301 /*
16302   Bug#28075 "COM_DEBUG crashes mysqld"
16303 */
16304 
test_bug28075()16305 static void test_bug28075()
16306 {
16307   int rc;
16308 
16309   DBUG_ENTER("test_bug28075");
16310   myheader("test_bug28075");
16311 
16312   rc= mysql_dump_debug_info(mysql);
16313   DIE_UNLESS(rc == 0);
16314 
16315   rc= mysql_ping(mysql);
16316   DIE_UNLESS(rc == 0);
16317 
16318   DBUG_VOID_RETURN;
16319 }
16320 
16321 
16322 /*
16323   Bug#27876 (SF with cyrillic variable name fails during execution (regression))
16324 */
16325 
test_bug27876()16326 static void test_bug27876()
16327 {
16328   int rc;
16329   MYSQL_RES *result;
16330 
16331   uchar utf8_func[] =
16332   {
16333     0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
16334     0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
16335     0xd0, 0xb0,
16336     0x00
16337   };
16338 
16339   uchar utf8_param[] =
16340   {
16341     0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
16342     0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
16343     0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
16344     0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
16345     0x00
16346   };
16347 
16348   char query[500];
16349 
16350   DBUG_ENTER("test_bug27876");
16351   myheader("test_bug27876");
16352 
16353   rc= mysql_query(mysql, "set names utf8");
16354   myquery(rc);
16355 
16356   rc= mysql_query(mysql, "select version()");
16357   myquery(rc);
16358   result= mysql_store_result(mysql);
16359   mytest(result);
16360   mysql_free_result(result);
16361 
16362   sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
16363   rc= mysql_query(mysql, query);
16364   myquery(rc);
16365 
16366   sprintf(query,
16367           "CREATE FUNCTION %s( %s VARCHAR(25))"
16368           " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
16369           (char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
16370   rc= mysql_query(mysql, query);
16371   myquery(rc);
16372   sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
16373   rc= mysql_query(mysql, query);
16374   myquery(rc);
16375   result= mysql_store_result(mysql);
16376   mytest(result);
16377   mysql_free_result(result);
16378 
16379   sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
16380   rc= mysql_query(mysql, query);
16381   myquery(rc);
16382 
16383   rc= mysql_query(mysql, "set names default");
16384   myquery(rc);
16385   DBUG_VOID_RETURN;
16386 }
16387 
16388 
16389 /*
16390   Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
16391   flag is set.
16392 */
16393 
test_bug28505()16394 static void test_bug28505()
16395 {
16396   my_ulonglong res;
16397 
16398   myquery(mysql_query(mysql, "drop table if exists t1"));
16399   myquery(mysql_query(mysql, "create table t1(f1 int primary key)"));
16400   myquery(mysql_query(mysql, "insert into t1 values(1)"));
16401   myquery(mysql_query(mysql,
16402                   "insert into t1 values(1) on duplicate key update f1=1"));
16403   res= mysql_affected_rows(mysql);
16404   DIE_UNLESS(!res);
16405   myquery(mysql_query(mysql, "drop table t1"));
16406 }
16407 
16408 
16409 /*
16410   Bug#28934: server crash when receiving malformed com_execute packets
16411 */
16412 
test_bug28934()16413 static void test_bug28934()
16414 {
16415   my_bool error= 0;
16416   MYSQL_BIND bind[5];
16417   MYSQL_STMT *stmt;
16418   int cnt;
16419 
16420   myquery(mysql_query(mysql, "drop table if exists t1"));
16421   myquery(mysql_query(mysql, "create table t1(id int)"));
16422 
16423   myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)"));
16424   stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)");
16425   check_stmt(stmt);
16426 
16427   memset (&bind, 0, sizeof (bind));
16428   for (cnt= 0; cnt < 5; cnt++)
16429   {
16430     bind[cnt].buffer_type= MYSQL_TYPE_LONG;
16431     bind[cnt].buffer= (char*)&cnt;
16432     bind[cnt].buffer_length= 0;
16433   }
16434   myquery(mysql_stmt_bind_param(stmt, bind));
16435 
16436   stmt->param_count=2;
16437   error= mysql_stmt_execute(stmt);
16438   DIE_UNLESS(error != 0);
16439   myerror(NULL);
16440   mysql_stmt_close(stmt);
16441 
16442   myquery(mysql_query(mysql, "drop table t1"));
16443 }
16444 
16445 /*
16446   Test mysql_change_user() C API and COM_CHANGE_USER
16447 */
16448 
reconnect(MYSQL ** mysql)16449 static void reconnect(MYSQL **mysql)
16450 {
16451   mysql_close(*mysql);
16452   *mysql= mysql_client_init(NULL);
16453   DIE_UNLESS(*mysql != 0);
16454   *mysql= mysql_real_connect(*mysql, opt_host, opt_user,
16455                          opt_password, current_db, opt_port,
16456                          opt_unix_socket, 0);
16457   DIE_UNLESS(*mysql != 0);
16458 }
16459 
16460 
test_change_user()16461 static void test_change_user()
16462 {
16463   char buff[256];
16464   const char *user_pw= "mysqltest_pw";
16465   const char *user_no_pw= "mysqltest_no_pw";
16466   const char *pw= "password";
16467   const char *db= "mysqltest_user_test_database";
16468   int rc;
16469   MYSQL *l_mysql;
16470 
16471   DBUG_ENTER("test_change_user");
16472   myheader("test_change_user");
16473 
16474   l_mysql= mysql_client_init(NULL);
16475   DIE_UNLESS(l_mysql != NULL);
16476 
16477   l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
16478                          opt_password, current_db, opt_port,
16479                          opt_unix_socket, 0);
16480   DIE_UNLESS(l_mysql != 0);
16481 
16482   rc = mysql_query(l_mysql, "set sql_mode=(select replace(@@sql_mode,'NO_AUTO_CREATE_USER',''))");
16483   myquery2(l_mysql, rc);
16484 
16485   /* Prepare environment */
16486   sprintf(buff, "drop database if exists %s", db);
16487   rc= mysql_query(l_mysql, buff);
16488   myquery2(l_mysql, rc);
16489 
16490   sprintf(buff, "create database %s", db);
16491   rc= mysql_query(l_mysql, buff);
16492   myquery2(l_mysql, rc);
16493 
16494   sprintf(buff,
16495           "grant select on %s.* to %s@'%%' identified by '%s'",
16496           db,
16497           user_pw,
16498           pw);
16499   rc= mysql_query(l_mysql, buff);
16500   myquery2(l_mysql, rc);
16501 
16502   sprintf(buff,
16503           "grant select on %s.* to %s@'localhost' identified by '%s'",
16504           db,
16505           user_pw,
16506           pw);
16507   rc= mysql_query(l_mysql, buff);
16508   myquery2(l_mysql, rc);
16509 
16510   sprintf(buff,
16511           "grant select on %s.* to %s@'%%'",
16512           db,
16513           user_no_pw);
16514   rc= mysql_query(l_mysql, buff);
16515   myquery2(l_mysql, rc);
16516 
16517   sprintf(buff,
16518           "grant select on %s.* to %s@'localhost'",
16519           db,
16520           user_no_pw);
16521   rc= mysql_query(l_mysql, buff);
16522   myquery2(l_mysql, rc);
16523 
16524   /* Try some combinations */
16525   rc= mysql_change_user(l_mysql, NULL, NULL, NULL);
16526   DIE_UNLESS(rc);
16527   if (! opt_silent)
16528     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16529   reconnect(&l_mysql);
16530 
16531   rc= mysql_change_user(l_mysql, "", NULL, NULL);
16532   DIE_UNLESS(rc);
16533   if (! opt_silent)
16534     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16535   reconnect(&l_mysql);
16536 
16537   rc= mysql_change_user(l_mysql, "", "", NULL);
16538   DIE_UNLESS(rc);
16539   if (! opt_silent)
16540     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16541   reconnect(&l_mysql);
16542 
16543 
16544   rc= mysql_change_user(l_mysql, "", "", "");
16545   DIE_UNLESS(rc);
16546   if (! opt_silent)
16547     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16548   reconnect(&l_mysql);
16549 
16550   rc= mysql_change_user(l_mysql, NULL, "", "");
16551   DIE_UNLESS(rc);
16552   if (! opt_silent)
16553     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16554   reconnect(&l_mysql);
16555 
16556 
16557   rc= mysql_change_user(l_mysql, NULL, NULL, "");
16558   DIE_UNLESS(rc);
16559   if (! opt_silent)
16560     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16561   reconnect(&l_mysql);
16562 
16563   rc= mysql_change_user(l_mysql, "", NULL, "");
16564   DIE_UNLESS(rc);
16565   if (! opt_silent)
16566     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16567   reconnect(&l_mysql);
16568 
16569   rc= mysql_change_user(l_mysql, user_pw, NULL, "");
16570   DIE_UNLESS(rc);
16571   if (! opt_silent)
16572     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16573   reconnect(&l_mysql);
16574 
16575   rc= mysql_change_user(l_mysql, user_pw, "", "");
16576   DIE_UNLESS(rc);
16577   if (! opt_silent)
16578     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16579   reconnect(&l_mysql);
16580 
16581   rc= mysql_change_user(l_mysql, user_pw, "", NULL);
16582   DIE_UNLESS(rc);
16583   if (! opt_silent)
16584     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16585   reconnect(&l_mysql);
16586 
16587   rc= mysql_change_user(l_mysql, user_pw, NULL, NULL);
16588   DIE_UNLESS(rc);
16589   if (! opt_silent)
16590     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16591   reconnect(&l_mysql);
16592 
16593   rc= mysql_change_user(l_mysql, user_pw, "", db);
16594   DIE_UNLESS(rc);
16595   if (! opt_silent)
16596     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16597   reconnect(&l_mysql);
16598 
16599   rc= mysql_change_user(l_mysql, user_pw, NULL, db);
16600   DIE_UNLESS(rc);
16601   if (! opt_silent)
16602     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16603   reconnect(&l_mysql);
16604 
16605   rc= mysql_change_user(l_mysql, user_pw, pw, db);
16606   myquery2(l_mysql, rc);
16607 
16608   rc= mysql_change_user(l_mysql, user_pw, pw, NULL);
16609   myquery2(l_mysql, rc);
16610 
16611   rc= mysql_change_user(l_mysql, user_pw, pw, "");
16612   myquery2(l_mysql, rc);
16613 
16614   rc= mysql_change_user(l_mysql, user_no_pw, pw, db);
16615   DIE_UNLESS(rc);
16616   if (! opt_silent)
16617     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16618 
16619   rc= mysql_change_user(l_mysql, user_no_pw, pw, "");
16620   DIE_UNLESS(rc);
16621   if (! opt_silent)
16622     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16623   reconnect(&l_mysql);
16624 
16625   rc= mysql_change_user(l_mysql, user_no_pw, pw, NULL);
16626   DIE_UNLESS(rc);
16627   if (! opt_silent)
16628     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16629   reconnect(&l_mysql);
16630 
16631   rc= mysql_change_user(l_mysql, user_no_pw, "", NULL);
16632   myquery2(l_mysql, rc);
16633 
16634   rc= mysql_change_user(l_mysql, user_no_pw, "", "");
16635   myquery2(l_mysql, rc);
16636 
16637   rc= mysql_change_user(l_mysql, user_no_pw, "", db);
16638   myquery2(l_mysql, rc);
16639 
16640   rc= mysql_change_user(l_mysql, user_no_pw, NULL, db);
16641   myquery2(l_mysql, rc);
16642 
16643   rc= mysql_change_user(l_mysql, "", pw, db);
16644   DIE_UNLESS(rc);
16645   if (! opt_silent)
16646     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16647   reconnect(&l_mysql);
16648 
16649   rc= mysql_change_user(l_mysql, "", pw, "");
16650   DIE_UNLESS(rc);
16651   if (! opt_silent)
16652     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16653   reconnect(&l_mysql);
16654 
16655   rc= mysql_change_user(l_mysql, "", pw, NULL);
16656   DIE_UNLESS(rc);
16657   if (! opt_silent)
16658     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16659 
16660   rc= mysql_change_user(l_mysql, NULL, pw, NULL);
16661   DIE_UNLESS(rc);
16662   if (! opt_silent)
16663     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16664   reconnect(&l_mysql);
16665 
16666   rc= mysql_change_user(l_mysql, NULL, NULL, db);
16667   DIE_UNLESS(rc);
16668   if (! opt_silent)
16669     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16670   reconnect(&l_mysql);
16671 
16672   rc= mysql_change_user(l_mysql, NULL, "", db);
16673   DIE_UNLESS(rc);
16674   if (! opt_silent)
16675     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16676   reconnect(&l_mysql);
16677 
16678   rc= mysql_change_user(l_mysql, "", "", db);
16679   DIE_UNLESS(rc);
16680   if (! opt_silent)
16681     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16682   reconnect(&l_mysql);
16683 
16684   /* Cleanup the environment */
16685 
16686   mysql_close(l_mysql);
16687 
16688   sprintf(buff, "drop database %s", db);
16689   rc= mysql_query(mysql, buff);
16690   myquery(rc);
16691 
16692   sprintf(buff, "drop user %s@'%%'", user_pw);
16693   rc= mysql_query(mysql, buff);
16694   myquery(rc);
16695 
16696   sprintf(buff, "drop user %s@'%%'", user_no_pw);
16697   rc= mysql_query(mysql, buff);
16698   myquery(rc);
16699 
16700   sprintf(buff, "drop user %s@'localhost'", user_pw);
16701   rc= mysql_query(mysql, buff);
16702   myquery(rc);
16703 
16704   sprintf(buff, "drop user %s@'localhost'", user_no_pw);
16705   rc= mysql_query(mysql, buff);
16706   myquery(rc);
16707 
16708   DBUG_VOID_RETURN;
16709 }
16710 
16711 /*
16712   Bug#27592 (stack overrun when storing datetime value using prepared statements)
16713 */
16714 
test_bug27592()16715 static void test_bug27592()
16716 {
16717   const int NUM_ITERATIONS= 40;
16718   int i;
16719   int rc;
16720   MYSQL_STMT *stmt= NULL;
16721   MYSQL_BIND bind[1];
16722   MYSQL_TIME time_val;
16723 
16724   DBUG_ENTER("test_bug27592");
16725   myheader("test_bug27592");
16726 
16727   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16728   mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
16729 
16730   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
16731   DIE_UNLESS(stmt);
16732 
16733   memset(bind, 0, sizeof(bind));
16734 
16735   bind[0].buffer_type= MYSQL_TYPE_DATETIME;
16736   bind[0].buffer= (char *) &time_val;
16737   bind[0].length= NULL;
16738 
16739   for (i= 0; i < NUM_ITERATIONS; i++)
16740   {
16741     time_val.year= 2007;
16742     time_val.month= 6;
16743     time_val.day= 7;
16744     time_val.hour= 18;
16745     time_val.minute= 41;
16746     time_val.second= 3;
16747 
16748     time_val.second_part=0;
16749     time_val.neg=0;
16750 
16751     rc= mysql_stmt_bind_param(stmt, bind);
16752     check_execute(stmt, rc);
16753 
16754     rc= mysql_stmt_execute(stmt);
16755     check_execute(stmt, rc);
16756   }
16757 
16758   mysql_stmt_close(stmt);
16759 
16760   DBUG_VOID_RETURN;
16761 }
16762 
16763 /*
16764   Bug#29687 mysql_stmt_store_result memory leak in libmysqld
16765 */
16766 
test_bug29687()16767 static void test_bug29687()
16768 {
16769   const int NUM_ITERATIONS= 40;
16770   int i;
16771   int rc;
16772   MYSQL_STMT *stmt= NULL;
16773 
16774   DBUG_ENTER("test_bug29687");
16775   myheader("test_bug29687");
16776 
16777   stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2");
16778   DIE_UNLESS(stmt);
16779 
16780   for (i= 0; i < NUM_ITERATIONS; i++)
16781   {
16782     rc= mysql_stmt_execute(stmt);
16783     check_execute(stmt, rc);
16784     mysql_stmt_store_result(stmt);
16785     while (mysql_stmt_fetch(stmt)==0);
16786     mysql_stmt_free_result(stmt);
16787   }
16788 
16789   mysql_stmt_close(stmt);
16790   DBUG_VOID_RETURN;
16791 }
16792 
16793 
16794 /*
16795   Bug #29692  	Single row inserts can incorrectly report a huge number of
16796   row insertions
16797 */
16798 
test_bug29692()16799 static void test_bug29692()
16800 {
16801   MYSQL* conn;
16802 
16803   if (!(conn= mysql_client_init(NULL)))
16804   {
16805     myerror("test_bug29692 init failed");
16806     exit(1);
16807   }
16808 
16809   if (!(mysql_real_connect(conn, opt_host, opt_user,
16810                            opt_password, opt_db ? opt_db:"test", opt_port,
16811                            opt_unix_socket,  CLIENT_FOUND_ROWS)))
16812   {
16813     myerror("test_bug29692 connection failed");
16814     mysql_close(mysql);
16815     exit(1);
16816   }
16817   myquery(mysql_query(conn, "drop table if exists t1"));
16818   myquery(mysql_query(conn, "create table t1(f1 int)"));
16819   myquery(mysql_query(conn, "insert into t1 values(1)"));
16820   DIE_UNLESS(1 == mysql_affected_rows(conn));
16821   myquery(mysql_query(conn, "drop table t1"));
16822   mysql_close(conn);
16823 }
16824 
16825 /**
16826   Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
16827 */
16828 
test_bug29306()16829 static void test_bug29306()
16830 {
16831   MYSQL_FIELD *field;
16832   int rc;
16833   MYSQL_RES *res;
16834 
16835   DBUG_ENTER("test_bug29306");
16836   myheader("test_bug29306");
16837 
16838   rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
16839   myquery(rc);
16840   rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
16841   myquery(rc);
16842   rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
16843   myquery(rc);
16844   rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
16845   myquery(rc);
16846   rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
16847   myquery(rc);
16848 
16849   /* Checking the view */
16850   res= mysql_list_fields(mysql, "view17557", NULL);
16851   while ((field= mysql_fetch_field(res)))
16852   {
16853     if (! opt_silent)
16854     {
16855       printf("field name %s\n", field->name);
16856       printf("field table %s\n", field->table);
16857       printf("field decimals %d\n", field->decimals);
16858       if (field->decimals < 1)
16859         printf("Error! No decimals! \n");
16860       printf("\n\n");
16861     }
16862     DIE_UNLESS(field->decimals == 1);
16863   }
16864   mysql_free_result(res);
16865 
16866   rc= mysql_query(mysql, "DROP TABLE tab17557");
16867   myquery(rc);
16868   rc= mysql_query(mysql, "DROP VIEW view17557");
16869   myquery(rc);
16870 
16871   DBUG_VOID_RETURN;
16872 }
16873 /*
16874   Bug#30472: libmysql doesn't reset charset, insert_id after succ.
16875   mysql_change_user() call row insertions.
16876 */
16877 
bug30472_retrieve_charset_info(MYSQL * con,char * character_set_name,char * character_set_client,char * character_set_results,char * collation_connection)16878 static void bug30472_retrieve_charset_info(MYSQL *con,
16879                                            char *character_set_name,
16880                                            char *character_set_client,
16881                                            char *character_set_results,
16882                                            char *collation_connection)
16883 {
16884   MYSQL_RES *rs;
16885   MYSQL_ROW row;
16886 
16887   /* Get the cached client character set name. */
16888 
16889   strcpy(character_set_name, mysql_character_set_name(con));
16890 
16891   /* Retrieve server character set information. */
16892 
16893   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
16894   DIE_UNLESS(rs= mysql_store_result(con));
16895   DIE_UNLESS(row= mysql_fetch_row(rs));
16896   strcpy(character_set_client, row[1]);
16897   mysql_free_result(rs);
16898 
16899   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
16900   DIE_UNLESS(rs= mysql_store_result(con));
16901   DIE_UNLESS(row= mysql_fetch_row(rs));
16902   strcpy(character_set_results, row[1]);
16903   mysql_free_result(rs);
16904 
16905   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
16906   DIE_UNLESS(rs= mysql_store_result(con));
16907   DIE_UNLESS(row= mysql_fetch_row(rs));
16908   strcpy(collation_connection, row[1]);
16909   mysql_free_result(rs);
16910 }
16911 
test_bug30472()16912 static void test_bug30472()
16913 {
16914   MYSQL con;
16915 
16916   char character_set_name_1[MY_CS_NAME_SIZE];
16917   char character_set_client_1[MY_CS_NAME_SIZE];
16918   char character_set_results_1[MY_CS_NAME_SIZE];
16919   char collation_connnection_1[MY_CS_NAME_SIZE];
16920 
16921   char character_set_name_2[MY_CS_NAME_SIZE];
16922   char character_set_client_2[MY_CS_NAME_SIZE];
16923   char character_set_results_2[MY_CS_NAME_SIZE];
16924   char collation_connnection_2[MY_CS_NAME_SIZE];
16925 
16926   char character_set_name_3[MY_CS_NAME_SIZE];
16927   char character_set_client_3[MY_CS_NAME_SIZE];
16928   char character_set_results_3[MY_CS_NAME_SIZE];
16929   char collation_connnection_3[MY_CS_NAME_SIZE];
16930 
16931   char character_set_name_4[MY_CS_NAME_SIZE];
16932   char character_set_client_4[MY_CS_NAME_SIZE];
16933   char character_set_results_4[MY_CS_NAME_SIZE];
16934   char collation_connnection_4[MY_CS_NAME_SIZE];
16935 
16936   /* Create a new connection. */
16937 
16938   DIE_UNLESS(mysql_client_init(&con));
16939 
16940   DIE_UNLESS(mysql_real_connect(&con,
16941                                 opt_host,
16942                                 opt_user,
16943                                 opt_password,
16944                                 opt_db ? opt_db : "test",
16945                                 opt_port,
16946                                 opt_unix_socket,
16947                                 CLIENT_FOUND_ROWS));
16948 
16949   /* Retrieve character set information. */
16950 
16951   bug30472_retrieve_charset_info(&con,
16952                                  character_set_name_1,
16953                                  character_set_client_1,
16954                                  character_set_results_1,
16955                                  collation_connnection_1);
16956 
16957   /* Switch client character set. */
16958 
16959   DIE_IF(mysql_set_character_set(&con, "utf8"));
16960 
16961   /* Retrieve character set information. */
16962 
16963   bug30472_retrieve_charset_info(&con,
16964                                  character_set_name_2,
16965                                  character_set_client_2,
16966                                  character_set_results_2,
16967                                  collation_connnection_2);
16968 
16969   /*
16970     Check that
16971       1) character set has been switched and
16972       2) new character set is different from the original one.
16973   */
16974 
16975   DIE_UNLESS(strcmp(character_set_name_2, "utf8") == 0);
16976   DIE_UNLESS(strcmp(character_set_client_2, "utf8") == 0);
16977   DIE_UNLESS(strcmp(character_set_results_2, "utf8") == 0);
16978   DIE_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0);
16979 
16980   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
16981   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
16982   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
16983   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
16984 
16985   /* Call mysql_change_user() with the same username, password, database. */
16986 
16987   DIE_IF(mysql_change_user(&con,
16988                            opt_user,
16989                            opt_password,
16990                            opt_db ? opt_db : "test"));
16991 
16992   /* Retrieve character set information. */
16993 
16994   bug30472_retrieve_charset_info(&con,
16995                                  character_set_name_3,
16996                                  character_set_client_3,
16997                                  character_set_results_3,
16998                                  collation_connnection_3);
16999 
17000   /* Check that character set information has been reset. */
17001 
17002   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
17003   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
17004   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
17005   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
17006 
17007   /* Change connection-default character set in the client. */
17008 
17009   mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8");
17010 
17011   /*
17012     Call mysql_change_user() in order to check that new connection will
17013     have UTF8 character set on the client and on the server.
17014   */
17015 
17016   DIE_IF(mysql_change_user(&con,
17017                            opt_user,
17018                            opt_password,
17019                            opt_db ? opt_db : "test"));
17020 
17021   /* Retrieve character set information. */
17022 
17023   bug30472_retrieve_charset_info(&con,
17024                                  character_set_name_4,
17025                                  character_set_client_4,
17026                                  character_set_results_4,
17027                                  collation_connnection_4);
17028 
17029   /* Check that we have UTF8 on the server and on the client. */
17030 
17031   DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
17032   DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
17033   DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
17034   DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
17035 
17036   /* That's it. Cleanup. */
17037 
17038   mysql_close(&con);
17039 }
17040 
bug20023_change_user(MYSQL * con)17041 static void bug20023_change_user(MYSQL *con)
17042 {
17043   DIE_IF(mysql_change_user(con,
17044                            opt_user,
17045                            opt_password,
17046                            opt_db ? opt_db : "test"));
17047 }
17048 
query_str_variable(MYSQL * con,const char * var_name,char * str,size_t len)17049 static my_bool query_str_variable(MYSQL *con,
17050                                   const char *var_name,
17051                                   char *str,
17052                                   size_t len)
17053 {
17054   MYSQL_RES *rs;
17055   MYSQL_ROW row;
17056 
17057   char query_buffer[MAX_TEST_QUERY_LENGTH];
17058 
17059   my_bool is_null;
17060 
17061   my_snprintf(query_buffer, sizeof (query_buffer),
17062               "SELECT %s", var_name);
17063 
17064   DIE_IF(mysql_query(con, query_buffer));
17065   DIE_UNLESS(rs= mysql_store_result(con));
17066   DIE_UNLESS(row= mysql_fetch_row(rs));
17067 
17068   is_null= row[0] == NULL;
17069 
17070   if (!is_null)
17071     my_snprintf(str, len, "%s", row[0]);
17072 
17073   mysql_free_result(rs);
17074 
17075   return is_null;
17076 }
17077 
query_int_variable(MYSQL * con,const char * var_name,int * var_value)17078 static my_bool query_int_variable(MYSQL *con,
17079                                   const char *var_name,
17080                                   int *var_value)
17081 {
17082   char str[32];
17083   my_bool is_null= query_str_variable(con, var_name, str, sizeof(str));
17084 
17085   if (!is_null)
17086     *var_value= atoi(str);
17087 
17088   return is_null;
17089 }
17090 
test_bug20023()17091 static void test_bug20023()
17092 {
17093   MYSQL con;
17094 
17095   int sql_big_selects_orig= 0;
17096   /*
17097     Type of max_join_size is ha_rows, which might be ulong or off_t
17098     depending on the platform or configure options. Preserve the string
17099     to avoid type overflow pitfalls.
17100   */
17101   char max_join_size_orig[32];
17102 
17103   int sql_big_selects_2= 0;
17104   int sql_big_selects_3= 0;
17105   int sql_big_selects_4= 0;
17106   int sql_big_selects_5= 0;
17107 
17108   char query_buffer[MAX_TEST_QUERY_LENGTH];
17109 
17110   /* Create a new connection. */
17111 
17112   DIE_UNLESS(mysql_client_init(&con));
17113 
17114   DIE_UNLESS(mysql_real_connect(&con,
17115                                 opt_host,
17116                                 opt_user,
17117                                 opt_password,
17118                                 opt_db ? opt_db : "test",
17119                                 opt_port,
17120                                 opt_unix_socket,
17121                                 CLIENT_FOUND_ROWS));
17122 
17123   /***********************************************************************
17124     Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
17125   ***********************************************************************/
17126 
17127   query_int_variable(&con,
17128                      "@@session.sql_big_selects",
17129                      &sql_big_selects_orig);
17130 
17131   query_str_variable(&con,
17132                      "@@global.max_join_size",
17133                      max_join_size_orig,
17134                      sizeof(max_join_size_orig));
17135 
17136   /***********************************************************************
17137     Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
17138   ***********************************************************************/
17139 
17140   /* Issue COM_CHANGE_USER. */
17141 
17142   bug20023_change_user(&con);
17143 
17144   /* Query SQL_BIG_SELECTS. */
17145 
17146   query_int_variable(&con,
17147                      "@@session.sql_big_selects",
17148                      &sql_big_selects_2);
17149 
17150   /* Check that SQL_BIG_SELECTS is reset properly. */
17151 
17152   DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2);
17153 
17154   /***********************************************************************
17155     Test that if MAX_JOIN_SIZE set to non-default value,
17156     SQL_BIG_SELECTS will be 0.
17157   ***********************************************************************/
17158 
17159   /* Set MAX_JOIN_SIZE to some non-default value. */
17160 
17161   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000"));
17162   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17163 
17164   /* Issue COM_CHANGE_USER. */
17165 
17166   bug20023_change_user(&con);
17167 
17168   /* Query SQL_BIG_SELECTS. */
17169 
17170   query_int_variable(&con,
17171                      "@@session.sql_big_selects",
17172                      &sql_big_selects_3);
17173 
17174   /* Check that SQL_BIG_SELECTS is 0. */
17175 
17176   DIE_UNLESS(sql_big_selects_3 == 0);
17177 
17178   /***********************************************************************
17179     Test that if MAX_JOIN_SIZE set to default value,
17180     SQL_BIG_SELECTS will be 1.
17181   ***********************************************************************/
17182 
17183   /* Set MAX_JOIN_SIZE to the default value (2^64-1). */
17184 
17185   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17186   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17187 
17188   /* Issue COM_CHANGE_USER. */
17189 
17190   bug20023_change_user(&con);
17191 
17192   /* Query SQL_BIG_SELECTS. */
17193 
17194   query_int_variable(&con,
17195                      "@@session.sql_big_selects",
17196                      &sql_big_selects_4);
17197 
17198   /* Check that SQL_BIG_SELECTS is 1. */
17199 
17200   DIE_UNLESS(sql_big_selects_4 == 1);
17201 
17202   /***********************************************************************
17203     Restore MAX_JOIN_SIZE.
17204     Check that SQL_BIG_SELECTS will be the original one.
17205   ***********************************************************************/
17206 
17207   /* Restore MAX_JOIN_SIZE. */
17208 
17209   my_snprintf(query_buffer,
17210            sizeof (query_buffer),
17211            "SET @@global.max_join_size = %s",
17212            max_join_size_orig);
17213 
17214   DIE_IF(mysql_query(&con, query_buffer));
17215 
17216   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17217   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17218 
17219   /* Issue COM_CHANGE_USER. */
17220 
17221   bug20023_change_user(&con);
17222 
17223   /* Query SQL_BIG_SELECTS. */
17224 
17225   query_int_variable(&con,
17226                      "@@session.sql_big_selects",
17227                      &sql_big_selects_5);
17228 
17229   /* Check that SQL_BIG_SELECTS is 1. */
17230 
17231   DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig);
17232 
17233   /***********************************************************************
17234     That's it. Cleanup.
17235   ***********************************************************************/
17236 
17237   mysql_close(&con);
17238 }
17239 
bug31418_impl()17240 static void bug31418_impl()
17241 {
17242   MYSQL con;
17243 
17244   my_bool is_null;
17245   int rc= 0;
17246 
17247   /* Create a new connection. */
17248 
17249   DIE_UNLESS(mysql_client_init(&con));
17250 
17251   DIE_UNLESS(mysql_real_connect(&con,
17252                                 opt_host,
17253                                 opt_user,
17254                                 opt_password,
17255                                 opt_db ? opt_db : "test",
17256                                 opt_port,
17257                                 opt_unix_socket,
17258                                 CLIENT_FOUND_ROWS));
17259 
17260   /***********************************************************************
17261     Check that lock is free:
17262       - IS_FREE_LOCK() should return 1;
17263       - IS_USED_LOCK() should return NULL;
17264   ***********************************************************************/
17265 
17266   is_null= query_int_variable(&con,
17267                               "IS_FREE_LOCK('bug31418')",
17268                               &rc);
17269   DIE_UNLESS(!is_null && rc);
17270 
17271   is_null= query_int_variable(&con,
17272                               "IS_USED_LOCK('bug31418')",
17273                               &rc);
17274   DIE_UNLESS(is_null);
17275 
17276   /***********************************************************************
17277     Acquire lock and check the lock status (the lock must be in use):
17278       - IS_FREE_LOCK() should return 0;
17279       - IS_USED_LOCK() should return non-zero thread id;
17280   ***********************************************************************/
17281 
17282   query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
17283   DIE_UNLESS(rc);
17284 
17285   is_null= query_int_variable(&con,
17286                               "IS_FREE_LOCK('bug31418')",
17287                               &rc);
17288   DIE_UNLESS(!is_null && !rc);
17289 
17290   is_null= query_int_variable(&con,
17291                               "IS_USED_LOCK('bug31418')",
17292                               &rc);
17293   DIE_UNLESS(!is_null && rc);
17294 
17295   /***********************************************************************
17296     Issue COM_CHANGE_USER command and check the lock status
17297     (the lock must be free):
17298       - IS_FREE_LOCK() should return 1;
17299       - IS_USED_LOCK() should return NULL;
17300   **********************************************************************/
17301 
17302   bug20023_change_user(&con);
17303 
17304   is_null= query_int_variable(&con,
17305                               "IS_FREE_LOCK('bug31418')",
17306                               &rc);
17307   DIE_UNLESS(!is_null && rc);
17308 
17309   is_null= query_int_variable(&con,
17310                               "IS_USED_LOCK('bug31418')",
17311                               &rc);
17312   DIE_UNLESS(is_null);
17313 
17314   /***********************************************************************
17315    That's it. Cleanup.
17316   ***********************************************************************/
17317 
17318   mysql_close(&con);
17319 }
17320 
test_bug31418()17321 static void test_bug31418()
17322 {
17323   /* Run test case for BUG#31418 for three different connections. */
17324 
17325   bug31418_impl();
17326 
17327   bug31418_impl();
17328 
17329   bug31418_impl();
17330 }
17331 
17332 
17333 
17334 /**
17335   Bug#31669 Buffer overflow in mysql_change_user()
17336 */
17337 
17338 #define LARGE_BUFFER_SIZE 2048
17339 
test_bug31669()17340 static void test_bug31669()
17341 {
17342   int rc;
17343   static char buff[LARGE_BUFFER_SIZE+1];
17344 #ifndef EMBEDDED_LIBRARY
17345   static char user[USERNAME_CHAR_LENGTH+1];
17346   static char db[NAME_CHAR_LEN+1];
17347   static char query[LARGE_BUFFER_SIZE*2];
17348 #endif
17349   MYSQL *l_mysql;
17350 
17351 
17352   DBUG_ENTER("test_bug31669");
17353   myheader("test_bug31669");
17354 
17355   l_mysql= mysql_client_init(NULL);
17356   DIE_UNLESS(l_mysql != NULL);
17357 
17358   l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
17359                          opt_password, current_db, opt_port,
17360                          opt_unix_socket, 0);
17361   DIE_UNLESS(l_mysql != 0);
17362 
17363 
17364   rc= mysql_change_user(l_mysql, NULL, NULL, NULL);
17365   DIE_UNLESS(rc);
17366 
17367   reconnect(&l_mysql);
17368 
17369   rc= mysql_change_user(l_mysql, "", "", "");
17370   DIE_UNLESS(rc);
17371   reconnect(&l_mysql);
17372 
17373   memset(buff, 'a', sizeof(buff));
17374   buff[sizeof(buff) - 1] = '\0';
17375 
17376   rc= mysql_change_user(l_mysql, buff, buff, buff);
17377   DIE_UNLESS(rc);
17378   reconnect(&l_mysql);
17379 
17380   rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
17381   DIE_UNLESS(!rc);
17382 
17383 #ifndef EMBEDDED_LIBRARY
17384   memset(db, 'a', sizeof(db));
17385   db[NAME_CHAR_LEN]= 0;
17386   strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
17387   rc= mysql_query(mysql, query);
17388   myquery(rc);
17389 
17390   memset(user, 'b', sizeof(user));
17391   user[USERNAME_CHAR_LENGTH]= 0;
17392   memset(buff, 'c', sizeof(buff));
17393   buff[LARGE_BUFFER_SIZE]= 0;
17394   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
17395                  "'", buff, "' WITH GRANT OPTION", NullS);
17396   rc= mysql_query(mysql, query);
17397   myquery(rc);
17398 
17399   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY "
17400                  "'", buff, "' WITH GRANT OPTION", NullS);
17401   rc= mysql_query(mysql, query);
17402   myquery(rc);
17403 
17404   rc= mysql_query(mysql, "FLUSH PRIVILEGES");
17405   myquery(rc);
17406 
17407   rc= mysql_change_user(l_mysql, user, buff, db);
17408   DIE_UNLESS(!rc);
17409 
17410   user[USERNAME_CHAR_LENGTH-1]= 'a';
17411   rc= mysql_change_user(l_mysql, user, buff, db);
17412   DIE_UNLESS(rc);
17413   reconnect(&l_mysql);
17414 
17415   user[USERNAME_CHAR_LENGTH-1]= 'b';
17416   buff[LARGE_BUFFER_SIZE-1]= 'd';
17417   rc= mysql_change_user(l_mysql, user, buff, db);
17418   DIE_UNLESS(rc);
17419   reconnect(&l_mysql);
17420 
17421   buff[LARGE_BUFFER_SIZE-1]= 'c';
17422   db[NAME_CHAR_LEN-1]= 'e';
17423   rc= mysql_change_user(l_mysql, user, buff, db);
17424   DIE_UNLESS(rc);
17425   reconnect(&l_mysql);
17426 
17427   db[NAME_CHAR_LEN-1]= 'a';
17428   rc= mysql_change_user(l_mysql, user, buff, db);
17429   DIE_UNLESS(!rc);
17430 
17431   rc= mysql_change_user(l_mysql, user + 1, buff + 1, db + 1);
17432   DIE_UNLESS(rc);
17433   reconnect(&l_mysql);
17434 
17435   rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
17436   DIE_UNLESS(!rc);
17437 
17438   strxmov(query, "DROP DATABASE ", db, NullS);
17439   rc= mysql_query(mysql, query);
17440   myquery(rc);
17441 
17442   strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
17443   rc= mysql_query(mysql, query);
17444   myquery(rc);
17445   DIE_UNLESS(mysql_affected_rows(mysql) == 2);
17446 
17447   mysql_close(l_mysql);
17448 #endif
17449 
17450   DBUG_VOID_RETURN;
17451 }
17452 
17453 
17454 /**
17455   Bug#28386 the general log is incomplete
17456 */
17457 
test_bug28386()17458 static void test_bug28386()
17459 {
17460   int rc;
17461   MYSQL_STMT *stmt;
17462   MYSQL_RES *result;
17463   MYSQL_ROW row;
17464   MYSQL_BIND bind;
17465   const char hello[]= "hello world!";
17466 
17467   DBUG_ENTER("test_bug28386");
17468   myheader("test_bug28386");
17469 
17470   rc= mysql_query(mysql, "select @@global.log_output");
17471   myquery(rc);
17472 
17473   result= mysql_store_result(mysql);
17474   DIE_UNLESS(result);
17475 
17476   row= mysql_fetch_row(result);
17477   if (! strstr(row[0], "TABLE"))
17478   {
17479     mysql_free_result(result);
17480     if (! opt_silent)
17481       printf("Skipping the test since logging to tables is not enabled\n");
17482     /* Log output is not to tables */
17483     return;
17484   }
17485   mysql_free_result(result);
17486 
17487   enable_query_logs(1);
17488 
17489   stmt= mysql_simple_prepare(mysql, "SELECT ?");
17490   check_stmt(stmt);
17491 
17492   memset(&bind, 0, sizeof(bind));
17493 
17494   bind.buffer_type= MYSQL_TYPE_STRING;
17495   bind.buffer= (void *) hello;
17496   bind.buffer_length= (ulong)sizeof(hello);
17497 
17498   mysql_stmt_bind_param(stmt, &bind);
17499   mysql_stmt_send_long_data(stmt, 0, hello, (ulong)sizeof(hello));
17500 
17501   rc= mysql_stmt_execute(stmt);
17502   check_execute(stmt, rc);
17503 
17504   rc= my_process_stmt_result(stmt);
17505   DIE_UNLESS(rc == 1);
17506 
17507   rc= mysql_stmt_reset(stmt);
17508   check_execute(stmt, rc);
17509 
17510   rc= mysql_stmt_close(stmt);
17511   DIE_UNLESS(!rc);
17512 
17513   rc= mysql_query(mysql, "select * from mysql.general_log where "
17514                          "command_type='Close stmt' or "
17515                          "command_type='Reset stmt' or "
17516                          "command_type='Long Data'");
17517   myquery(rc);
17518 
17519   result= mysql_store_result(mysql);
17520   mytest(result);
17521 
17522   DIE_UNLESS(mysql_num_rows(result) == 3);
17523 
17524   mysql_free_result(result);
17525 
17526   restore_query_logs();
17527 
17528   DBUG_VOID_RETURN;
17529 }
17530 
17531 
test_wl4166_1()17532 static void test_wl4166_1()
17533 {
17534   MYSQL_STMT *stmt;
17535   int        int_data;
17536   char       str_data[50];
17537   char       tiny_data;
17538   short      small_data;
17539   longlong   big_data;
17540   float      real_data;
17541   double     double_data;
17542   ulong      length[7];
17543   my_bool    is_null[7];
17544   MYSQL_BIND my_bind[7];
17545   int rc;
17546   int i;
17547 
17548   myheader("test_wl4166_1");
17549 
17550   rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
17551   myquery(rc);
17552 
17553   rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
17554                          "col2 varchar(15), col3 int, "
17555                          "col4 smallint, col5 bigint, "
17556                          "col6 float, col7 double, "
17557                          "colX varchar(10) default NULL)");
17558   myquery(rc);
17559 
17560   stmt= mysql_simple_prepare(mysql,
17561     "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
17562     "VALUES(?, ?, ?, ?, ?, ?, ?)");
17563   check_stmt(stmt);
17564 
17565   verify_param_count(stmt, 7);
17566 
17567   memset(my_bind, 0, sizeof(my_bind));
17568   /* tinyint */
17569   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
17570   my_bind[0].buffer= (void *)&tiny_data;
17571   /* string */
17572   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
17573   my_bind[1].buffer= (void *)str_data;
17574   my_bind[1].buffer_length= 1000;                  /* Max string length */
17575   /* integer */
17576   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
17577   my_bind[2].buffer= (void *)&int_data;
17578   /* short */
17579   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
17580   my_bind[3].buffer= (void *)&small_data;
17581   /* bigint */
17582   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
17583   my_bind[4].buffer= (void *)&big_data;
17584   /* float */
17585   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
17586   my_bind[5].buffer= (void *)&real_data;
17587   /* double */
17588   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
17589   my_bind[6].buffer= (void *)&double_data;
17590 
17591   for (i= 0; i < (int) array_elements(my_bind); i++)
17592   {
17593     my_bind[i].length= &length[i];
17594     my_bind[i].is_null= &is_null[i];
17595     is_null[i]= 0;
17596   }
17597 
17598   rc= mysql_stmt_bind_param(stmt, my_bind);
17599   check_execute(stmt, rc);
17600 
17601   int_data= 320;
17602   small_data= 1867;
17603   big_data= 1000;
17604   real_data= 2;
17605   double_data= 6578.001;
17606 
17607   /* now, execute the prepared statement to insert 10 records.. */
17608   for (tiny_data= 0; tiny_data < 10; tiny_data++)
17609   {
17610     length[1]= sprintf(str_data, "MySQL%d", int_data);
17611     rc= mysql_stmt_execute(stmt);
17612     check_execute(stmt, rc);
17613     int_data += 25;
17614     small_data += 10;
17615     big_data += 100;
17616     real_data += 1;
17617     double_data += 10.09;
17618   }
17619 
17620   /* force a re-prepare with some DDL */
17621 
17622   rc= mysql_query(mysql,
17623     "ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
17624   myquery(rc);
17625 
17626   /*
17627     execute the prepared statement again,
17628     without changing the types of parameters already bound.
17629   */
17630 
17631   for (tiny_data= 50; tiny_data < 60; tiny_data++)
17632   {
17633     length[1]= sprintf(str_data, "MySQL%d", int_data);
17634     rc= mysql_stmt_execute(stmt);
17635     check_execute(stmt, rc);
17636     int_data += 25;
17637     small_data += 10;
17638     big_data += 100;
17639     real_data += 1;
17640     double_data += 10.09;
17641   }
17642 
17643   mysql_stmt_close(stmt);
17644 
17645   rc= mysql_query(mysql, "DROP TABLE table_4166");
17646   myquery(rc);
17647 }
17648 
17649 
test_wl4166_2()17650 static void test_wl4166_2()
17651 {
17652   MYSQL_STMT *stmt;
17653   int        c_int;
17654   MYSQL_TIME d_date;
17655   MYSQL_BIND bind_out[2];
17656   int rc;
17657 
17658   myheader("test_wl4166_2");
17659 
17660   rc= mysql_query(mysql, "SET SQL_MODE=''");
17661   myquery(rc);
17662 
17663   rc= mysql_query(mysql, "drop table if exists t1");
17664   myquery(rc);
17665   rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
17666   myquery(rc);
17667   rc= mysql_query(mysql,
17668                   "insert into t1 (c_int, d_date) values (42, '1948-05-15')");
17669   myquery(rc);
17670 
17671   stmt= mysql_simple_prepare(mysql, "select * from t1");
17672   check_stmt(stmt);
17673 
17674   memset(bind_out, 0, sizeof(bind_out));
17675   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
17676   bind_out[0].buffer= (void*) &c_int;
17677 
17678   bind_out[1].buffer_type= MYSQL_TYPE_DATE;
17679   bind_out[1].buffer= (void*) &d_date;
17680 
17681   rc= mysql_stmt_bind_result(stmt, bind_out);
17682   check_execute(stmt, rc);
17683 
17684   /* int -> varchar transition */
17685 
17686   rc= mysql_query(mysql,
17687                   "alter table t1 change column c_int c_int varchar(11)");
17688   myquery(rc);
17689 
17690   rc= mysql_stmt_execute(stmt);
17691   check_execute(stmt, rc);
17692 
17693   rc= mysql_stmt_fetch(stmt);
17694   check_execute(stmt, rc);
17695 
17696   DIE_UNLESS(c_int == 42);
17697   DIE_UNLESS(d_date.year == 1948);
17698   DIE_UNLESS(d_date.month == 5);
17699   DIE_UNLESS(d_date.day == 15);
17700 
17701   rc= mysql_stmt_fetch(stmt);
17702   DIE_UNLESS(rc == MYSQL_NO_DATA);
17703 
17704   /* varchar to int retrieval with truncation */
17705 
17706   rc= mysql_query(mysql, "update t1 set c_int='abcde'");
17707   myquery(rc);
17708 
17709   rc= mysql_stmt_execute(stmt);
17710   check_execute(stmt, rc);
17711 
17712   rc= mysql_stmt_fetch(stmt);
17713   check_execute_r(stmt, rc);
17714 
17715   DIE_UNLESS(c_int == 0);
17716 
17717   rc= mysql_stmt_fetch(stmt);
17718   DIE_UNLESS(rc == MYSQL_NO_DATA);
17719 
17720   /* alter table and increase the number of columns */
17721   rc= mysql_query(mysql, "alter table t1 add column d_int int");
17722   myquery(rc);
17723 
17724   rc= mysql_stmt_execute(stmt);
17725   check_execute_r(stmt, rc);
17726 
17727   rc= mysql_stmt_reset(stmt);
17728   check_execute(stmt, rc);
17729 
17730   /* decrease the number of columns */
17731   rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
17732   myquery(rc);
17733 
17734   rc= mysql_stmt_execute(stmt);
17735   check_execute_r(stmt, rc);
17736 
17737   mysql_stmt_close(stmt);
17738   rc= mysql_query(mysql, "drop table t1");
17739   myquery(rc);
17740 
17741 }
17742 
17743 
17744 /**
17745   Test how warnings generated during assignment of parameters
17746   are (currently not) preserve in case of reprepare.
17747 */
17748 
test_wl4166_3()17749 static void test_wl4166_3()
17750 {
17751   int rc;
17752   MYSQL_STMT *stmt;
17753   MYSQL_BIND my_bind[1];
17754   MYSQL_TIME tm[1];
17755 
17756   myheader("test_wl4166_3");
17757 
17758   rc= mysql_query(mysql, "drop table if exists t1");
17759   myquery(rc);
17760 
17761   rc= mysql_query(mysql, "create table t1 (year datetime)");
17762   myquery(rc);
17763 
17764   stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)");
17765   check_stmt(stmt);
17766   verify_param_count(stmt, 1);
17767 
17768   memset(my_bind, 0, sizeof(my_bind));
17769   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17770   my_bind[0].buffer= &tm[0];
17771 
17772   rc= mysql_stmt_bind_param(stmt, my_bind);
17773   check_execute(stmt, rc);
17774 
17775   tm[0].year= 10000;
17776   tm[0].month= 1; tm[0].day= 1;
17777   tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
17778   tm[0].second_part= 0; tm[0].neg= 0;
17779 
17780   /* Cause a statement reprepare */
17781   rc= mysql_query(mysql, "alter table t1 add column c int");
17782   myquery(rc);
17783 
17784   rc= mysql_stmt_execute(stmt);
17785   check_execute(stmt, rc);
17786   /*
17787     Sic: only one warning, instead of two. The warning
17788     about data truncation when assigning a parameter is lost.
17789     This is a bug.
17790   */
17791   my_process_warnings(mysql, 1);
17792 
17793   verify_col_data("t1", "year", "0000-00-00 00:00:00");
17794 
17795   mysql_stmt_close(stmt);
17796 
17797   rc= mysql_query(mysql, "drop table t1");
17798   myquery(rc);
17799 }
17800 
17801 
17802 /**
17803   Test that long data parameters, as well as parameters
17804   that were originally in a different character set, are
17805   preserved in case of reprepare.
17806 */
17807 
test_wl4166_4()17808 static void test_wl4166_4()
17809 {
17810   MYSQL_STMT *stmt;
17811   int rc;
17812   const char *stmt_text;
17813   MYSQL_BIND bind_array[2];
17814 
17815   /* Represented as numbers to keep UTF8 tools from clobbering them. */
17816   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
17817   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
17818   char buf1[16], buf2[16];
17819   ulong buf1_len, buf2_len;
17820 
17821   myheader("test_wl4166_4");
17822 
17823   rc= mysql_query(mysql, "drop table if exists t1");
17824   myquery(rc);
17825 
17826   /*
17827     Create table with binary columns, set session character set to cp1251,
17828     client character set to koi8, and make sure that there is conversion
17829     on insert and no conversion on select
17830   */
17831   rc= mysql_query(mysql,
17832                   "create table t1 (c1 varbinary(255), c2 varbinary(255))");
17833   myquery(rc);
17834   rc= mysql_query(mysql, "set character_set_client=koi8r, "
17835                          "character_set_connection=cp1251, "
17836                          "character_set_results=koi8r");
17837   myquery(rc);
17838 
17839   memset(bind_array, 0, sizeof(bind_array));
17840 
17841   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
17842 
17843   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
17844   bind_array[1].buffer= (void *) koi8;
17845   bind_array[1].buffer_length= (ulong)strlen(koi8);
17846 
17847   stmt= mysql_stmt_init(mysql);
17848   check_stmt(stmt);
17849 
17850   stmt_text= "insert into t1 (c1, c2) values (?, ?)";
17851 
17852   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
17853   check_execute(stmt, rc);
17854 
17855   mysql_stmt_bind_param(stmt, bind_array);
17856 
17857   mysql_stmt_send_long_data(stmt, 0, koi8, (ulong)strlen(koi8));
17858 
17859   /* Cause a reprepare at statement execute */
17860   rc= mysql_query(mysql, "alter table t1 add column d int");
17861   myquery(rc);
17862 
17863   rc= mysql_stmt_execute(stmt);
17864   check_execute(stmt, rc);
17865 
17866   stmt_text= "select c1, c2 from t1";
17867 
17868   /* c1 and c2 are binary so no conversion will be done on select */
17869   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
17870   check_execute(stmt, rc);
17871 
17872   rc= mysql_stmt_execute(stmt);
17873   check_execute(stmt, rc);
17874 
17875   bind_array[0].buffer= buf1;
17876   bind_array[0].buffer_length= (ulong)sizeof(buf1);
17877   bind_array[0].length= &buf1_len;
17878 
17879   bind_array[1].buffer= buf2;
17880   bind_array[1].buffer_length= (ulong)sizeof(buf2);
17881   bind_array[1].length= &buf2_len;
17882 
17883   mysql_stmt_bind_result(stmt, bind_array);
17884 
17885   rc= mysql_stmt_fetch(stmt);
17886   check_execute(stmt, rc);
17887 
17888   DIE_UNLESS(buf1_len == strlen(cp1251));
17889   DIE_UNLESS(buf2_len == strlen(cp1251));
17890   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
17891   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
17892 
17893   rc= mysql_stmt_fetch(stmt);
17894   DIE_UNLESS(rc == MYSQL_NO_DATA);
17895 
17896   mysql_stmt_close(stmt);
17897 
17898   rc= mysql_query(mysql, "drop table t1");
17899   myquery(rc);
17900   rc= mysql_query(mysql, "set names default");
17901   myquery(rc);
17902 }
17903 
17904 /**
17905   Bug#36004 mysql_stmt_prepare resets the list of warnings
17906 */
17907 
test_bug36004()17908 static void test_bug36004()
17909 {
17910   int rc, warning_count= 0;
17911   MYSQL_STMT *stmt;
17912 
17913   DBUG_ENTER("test_bug36004");
17914   myheader("test_bug36004");
17915 
17916   rc= mysql_query(mysql, "drop table if exists inexistant");
17917   myquery(rc);
17918 
17919   DIE_UNLESS(mysql_warning_count(mysql) == 1);
17920   query_int_variable(mysql, "@@warning_count", &warning_count);
17921   DIE_UNLESS(warning_count);
17922 
17923   stmt= mysql_simple_prepare(mysql, "select 1");
17924   check_stmt(stmt);
17925 
17926   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17927   query_int_variable(mysql, "@@warning_count", &warning_count);
17928   /* behaviour changed by WL#5928 */
17929   if (mysql_get_server_version(mysql) < 50702)
17930     DIE_UNLESS(warning_count);
17931   else
17932     DIE_UNLESS(!warning_count);
17933 
17934   rc= mysql_stmt_execute(stmt);
17935   check_execute(stmt, rc);
17936 
17937   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17938   mysql_stmt_close(stmt);
17939 
17940   query_int_variable(mysql, "@@warning_count", &warning_count);
17941   /* behaviour changed by WL#5928 */
17942   if (mysql_get_server_version(mysql) < 50702)
17943     DIE_UNLESS(warning_count);
17944   else
17945     DIE_UNLESS(!warning_count);
17946 
17947   stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
17948   check_stmt(stmt);
17949 
17950   query_int_variable(mysql, "@@warning_count", &warning_count);
17951   DIE_UNLESS(warning_count == 0);
17952   mysql_stmt_close(stmt);
17953 
17954   DBUG_VOID_RETURN;
17955 }
17956 
17957 /**
17958   Test that COM_REFRESH issues a implicit commit.
17959 */
17960 
test_wl4284_1()17961 static void test_wl4284_1()
17962 {
17963   int rc;
17964   MYSQL_ROW row;
17965   MYSQL_RES *result;
17966 
17967   DBUG_ENTER("test_wl4284_1");
17968   myheader("test_wl4284_1");
17969 
17970   /* set AUTOCOMMIT to OFF */
17971   rc= mysql_autocommit(mysql, FALSE);
17972   myquery(rc);
17973 
17974   rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
17975   myquery(rc);
17976 
17977   rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
17978   myquery(rc);
17979 
17980   rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
17981   myquery(rc);
17982 
17983   rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
17984   myquery(rc);
17985 
17986   rc= mysql_rollback(mysql);
17987   myquery(rc);
17988 
17989   rc= mysql_query(mysql, "SELECT * FROM trans");
17990   myquery(rc);
17991 
17992   result= mysql_use_result(mysql);
17993   mytest(result);
17994 
17995   row= mysql_fetch_row(result);
17996   mytest(row);
17997 
17998   mysql_free_result(result);
17999 
18000   /* set AUTOCOMMIT to ON */
18001   rc= mysql_autocommit(mysql, TRUE);
18002   myquery(rc);
18003 
18004   rc= mysql_query(mysql, "DROP TABLE trans");
18005   myquery(rc);
18006 
18007   DBUG_VOID_RETURN;
18008 }
18009 
18010 
test_bug38486(void)18011 static void test_bug38486(void)
18012 {
18013   MYSQL_STMT *stmt;
18014   const char *stmt_text;
18015   unsigned long type= CURSOR_TYPE_READ_ONLY;
18016 
18017   DBUG_ENTER("test_bug38486");
18018   myheader("test_bug38486");
18019 
18020   stmt= mysql_stmt_init(mysql);
18021   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18022   stmt_text= "CREATE TABLE t1 (a INT)";
18023   mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
18024   mysql_stmt_execute(stmt);
18025   mysql_stmt_close(stmt);
18026 
18027   stmt= mysql_stmt_init(mysql);
18028   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18029   stmt_text= "INSERT INTO t1 VALUES (1)";
18030   mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
18031   mysql_stmt_execute(stmt);
18032   mysql_stmt_close(stmt);
18033 
18034   DBUG_VOID_RETURN;
18035 }
18036 
18037 
18038 /**
18039      Bug# 33831 mysql_real_connect() should fail if
18040      given an already connected MYSQL handle.
18041 */
18042 
test_bug33831(void)18043 static void test_bug33831(void)
18044 {
18045   MYSQL *l_mysql;
18046 
18047   DBUG_ENTER("test_bug33831");
18048 
18049   if (!(l_mysql= mysql_client_init(NULL)))
18050   {
18051     myerror("mysql_client_init() failed");
18052     DIE_UNLESS(0);
18053   }
18054   if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
18055                            opt_password, current_db, opt_port,
18056                            opt_unix_socket, 0)))
18057   {
18058     myerror("connection failed");
18059     DIE_UNLESS(0);
18060   }
18061 
18062   if (mysql_real_connect(l_mysql, opt_host, opt_user,
18063                          opt_password, current_db, opt_port,
18064                          opt_unix_socket, 0))
18065   {
18066     myerror("connection should have failed");
18067     DIE_UNLESS(0);
18068   }
18069 
18070   mysql_close(l_mysql);
18071 
18072   DBUG_VOID_RETURN;
18073 }
18074 
18075 
test_bug40365(void)18076 static void test_bug40365(void)
18077 {
18078   uint         rc, i;
18079   MYSQL_STMT   *stmt= 0;
18080   MYSQL_BIND   my_bind[2];
18081   my_bool      is_null[2]= {0};
18082   MYSQL_TIME   tm[2];
18083 
18084   DBUG_ENTER("test_bug40365");
18085 
18086   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18087   myquery(rc);
18088   rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \
18089                                           c2 DATE)");
18090   myquery(rc);
18091 
18092   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)");
18093   check_stmt(stmt);
18094   verify_param_count(stmt, 2);
18095 
18096   memset(my_bind, 0, sizeof(my_bind));
18097   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
18098   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
18099   for (i= 0; i < (int) array_elements(my_bind); i++)
18100   {
18101     my_bind[i].buffer= (void *) &tm[i];
18102     my_bind[i].is_null= &is_null[i];
18103   }
18104 
18105   rc= mysql_stmt_bind_param(stmt, my_bind);
18106   check_execute(stmt, rc);
18107 
18108   for (i= 0; i < (int) array_elements(my_bind); i++)
18109   {
18110     tm[i].neg= 0;
18111     tm[i].second_part= 0;
18112     tm[i].year= 2009;
18113     tm[i].month= 2;
18114     tm[i].day= 29;
18115     tm[i].hour= 0;
18116     tm[i].minute= 0;
18117     tm[i].second= 0;
18118   }
18119   rc= mysql_stmt_execute(stmt);
18120   check_execute(stmt, rc);
18121 
18122   rc= mysql_commit(mysql);
18123   myquery(rc);
18124   mysql_stmt_close(stmt);
18125 
18126   stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1");
18127   check_stmt(stmt);
18128 
18129   rc= mysql_stmt_bind_result(stmt, my_bind);
18130   check_execute(stmt, rc);
18131 
18132   rc= mysql_stmt_execute(stmt);
18133   check_execute(stmt, rc);
18134 
18135   rc= mysql_stmt_store_result(stmt);
18136   check_execute(stmt, rc);
18137 
18138   rc= mysql_stmt_fetch(stmt);
18139   check_execute(stmt, rc);
18140 
18141   if (!opt_silent)
18142     fprintf(stdout, "\n");
18143 
18144   for (i= 0; i < array_elements(my_bind); i++)
18145   {
18146     if (!opt_silent)
18147       fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d ",
18148               i, tm[i].year, tm[i].month, tm[i].day);
18149     DIE_UNLESS(tm[i].year == 0);
18150     DIE_UNLESS(tm[i].month == 0);
18151     DIE_UNLESS(tm[i].day == 0);
18152   }
18153   mysql_stmt_close(stmt);
18154   rc= mysql_commit(mysql);
18155   myquery(rc);
18156 
18157   DBUG_VOID_RETURN;
18158 }
18159 
18160 
18161 /**
18162   Subtest for Bug#43560. Verifies that a loss of connection on the server side
18163   is handled well by the mysql_stmt_execute() call, i.e., no SIGSEGV due to
18164   a vio socket that is cleared upon closed connection.
18165 
18166   Assumes the presence of the close_conn_after_stmt_execute debug feature in
18167   the server. Verifies that it is connected to a debug server before proceeding
18168   with the test.
18169  */
test_bug43560(void)18170 static void test_bug43560(void)
18171 {
18172   MYSQL*       conn;
18173   uint         rc;
18174   MYSQL_STMT   *stmt= 0;
18175   MYSQL_BIND   bind;
18176   my_bool      is_null= 0;
18177   char         buffer[256];
18178   const uint   BUFSIZE= sizeof(buffer);
18179   const char*  values[] = {"eins", "zwei", "drei", "viele", NULL};
18180   const char   insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
18181   ulong        length;
18182   const unsigned int drop_db= opt_drop_db;
18183 
18184   DBUG_ENTER("test_bug43560");
18185   myheader("test_bug43560");
18186 
18187   /* Make sure we only run against a debug server. */
18188   if (!strstr(mysql->server_version, "debug"))
18189   {
18190     fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
18191     DBUG_VOID_RETURN;
18192   }
18193 
18194   /*
18195     Set up a separate connection for this test to avoid messing up the
18196     general MYSQL object used in other subtests. Use TCP protocol to avoid
18197     problems with the buffer semantics of AF_UNIX, and turn off auto reconnect.
18198   */
18199   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
18200 
18201   rc= mysql_query(conn, "DROP TABLE IF EXISTS t1");
18202   myquery(rc);
18203   rc= mysql_query(conn,
18204     "CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))");
18205   myquery(rc);
18206 
18207   stmt= mysql_stmt_init(conn);
18208   check_stmt(stmt);
18209   rc= mysql_stmt_prepare(stmt, insert_str, (ulong)strlen(insert_str));
18210   check_execute(stmt, rc);
18211 
18212   memset(&bind, 0, sizeof(bind));
18213   bind.buffer_type= MYSQL_TYPE_STRING;
18214   bind.buffer_length= BUFSIZE;
18215   bind.buffer= buffer;
18216   bind.is_null= &is_null;
18217   bind.length= &length;
18218   rc= mysql_stmt_bind_param(stmt, &bind);
18219   check_execute(stmt, rc);
18220 
18221   /* First execute; should succeed. */
18222   strncpy(buffer, values[0], BUFSIZE);
18223   length= (ulong)strlen(buffer);
18224   rc= mysql_stmt_execute(stmt);
18225   check_execute(stmt, rc);
18226 
18227   /*
18228     Set up the server to close this session's server-side socket after
18229     next execution of prep statement.
18230   */
18231   rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'");
18232   myquery(rc);
18233 
18234   /* Second execute; should fail due to socket closed during execution. */
18235   strncpy(buffer, values[1], BUFSIZE);
18236   length= (ulong)strlen(buffer);
18237   rc= mysql_stmt_execute(stmt);
18238   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18239 
18240   /*
18241     Third execute; should fail (connection already closed), or SIGSEGV in
18242     case of a Bug#43560 type regression in which case the whole test fails.
18243   */
18244   strncpy(buffer, values[2], BUFSIZE);
18245   length= (ulong)strlen(buffer);
18246   rc= mysql_stmt_execute(stmt);
18247   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18248 
18249   mysql_stmt_close(stmt);
18250 
18251   opt_drop_db= 0;
18252   client_disconnect(conn);
18253   rc= mysql_query(mysql, "DROP TABLE t1");
18254   myquery(rc);
18255   opt_drop_db= drop_db;
18256 
18257   DBUG_VOID_RETURN;
18258 }
18259 
18260 
18261 /**
18262   Bug#36326: nested transaction and select
18263 */
18264 
test_bug36326()18265 static void test_bug36326()
18266 {
18267   int rc;
18268 
18269   DBUG_ENTER("test_bug36326");
18270   myheader("test_bug36326");
18271 
18272   rc= mysql_autocommit(mysql, TRUE);
18273   myquery(rc);
18274   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18275   myquery(rc);
18276   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
18277   myquery(rc);
18278   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
18279   myquery(rc);
18280   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
18281   myquery(rc);
18282   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576");
18283   myquery(rc);
18284   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18285   DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
18286   rc= mysql_query(mysql, "BEGIN");
18287   myquery(rc);
18288   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
18289   rc= mysql_query(mysql, "SELECT * FROM t1");
18290   myquery(rc);
18291   rc= my_process_result(mysql);
18292   DIE_UNLESS(rc == 1);
18293   rc= mysql_rollback(mysql);
18294   myquery(rc);
18295   rc= mysql_query(mysql, "ROLLBACK");
18296   myquery(rc);
18297   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18298   rc= mysql_query(mysql, "SELECT * FROM t1");
18299   myquery(rc);
18300   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18301   rc= my_process_result(mysql);
18302   DIE_UNLESS(rc == 1);
18303   rc= mysql_query(mysql, "DROP TABLE t1");
18304   myquery(rc);
18305   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = DEFAULT");
18306   myquery(rc);
18307 
18308   DBUG_VOID_RETURN;
18309 }
18310 
18311 /**
18312   Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
18313              string value.
18314 */
18315 
test_bug41078(void)18316 static void test_bug41078(void)
18317 {
18318   uint         rc;
18319   MYSQL_STMT   *stmt= 0;
18320   MYSQL_BIND   param, result;
18321   ulong        cursor_type= CURSOR_TYPE_READ_ONLY;
18322   ulong        len;
18323   char         str[64];
18324   const char   param_str[]= "abcdefghijklmn";
18325   my_bool      is_null, error;
18326 
18327   DBUG_ENTER("test_bug41078");
18328 
18329   rc= mysql_query(mysql, "SET NAMES UTF8");
18330   myquery(rc);
18331 
18332   stmt= mysql_simple_prepare(mysql, "SELECT ?");
18333   check_stmt(stmt);
18334   verify_param_count(stmt, 1);
18335 
18336   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type);
18337   check_execute(stmt, rc);
18338 
18339   memset(&param, 0, sizeof(param));
18340   param.buffer_type= MYSQL_TYPE_STRING;
18341   param.buffer= (void *) param_str;
18342   len= sizeof(param_str) - 1;
18343   param.length= &len;
18344 
18345   rc= mysql_stmt_bind_param(stmt, &param);
18346   check_execute(stmt, rc);
18347 
18348   rc= mysql_stmt_execute(stmt);
18349   check_execute(stmt, rc);
18350 
18351   memset(&result, 0, sizeof(result));
18352   result.buffer_type= MYSQL_TYPE_STRING;
18353   result.buffer= str;
18354   result.buffer_length= (ulong)sizeof(str);
18355   result.is_null= &is_null;
18356   result.length= &len;
18357   result.error=  &error;
18358 
18359   rc= mysql_stmt_bind_result(stmt, &result);
18360   check_execute(stmt, rc);
18361 
18362   rc= mysql_stmt_store_result(stmt);
18363   check_execute(stmt, rc);
18364 
18365   rc= mysql_stmt_fetch(stmt);
18366   check_execute(stmt, rc);
18367 
18368   DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str));
18369 
18370   mysql_stmt_close(stmt);
18371 
18372   DBUG_VOID_RETURN;
18373 }
18374 
18375 /**
18376   Bug#45010: invalid memory reads during parsing some strange statements
18377 */
test_bug45010()18378 static void test_bug45010()
18379 {
18380   int rc;
18381   const char query1[]= "select a.\x80",
18382              query2[]= "describe `table\xef";
18383 
18384   DBUG_ENTER("test_bug45010");
18385   myheader("test_bug45010");
18386 
18387   rc= mysql_query(mysql, "set names utf8");
18388   myquery(rc);
18389 
18390   /* \x80 (-128) could be used as a index of ident_map. */
18391   rc= mysql_real_query(mysql, query1, (ulong)(sizeof(query1) - 1));
18392   DIE_UNLESS(rc);
18393 
18394   /* \xef (-17) could be used to skip 3 bytes past the buffer end. */
18395   rc= mysql_real_query(mysql, query2, (ulong)(sizeof(query2) - 1));
18396   DIE_UNLESS(rc);
18397 
18398   rc= mysql_query(mysql, "set names default");
18399   myquery(rc);
18400 
18401   DBUG_VOID_RETURN;
18402 }
18403 
18404 /**
18405   Bug#44495: Prepared Statement:
18406              CALL p(<x>) - `thd->get_protocol() == &thd->protocol_text' failed
18407 */
18408 
test_bug44495()18409 static void test_bug44495()
18410 {
18411   int rc;
18412   MYSQL con;
18413   MYSQL_STMT *stmt;
18414 
18415   DBUG_ENTER("test_bug44495");
18416   myheader("test_44495");
18417 
18418   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18419   myquery(rc);
18420 
18421   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN arg VARCHAR(25))"
18422                          "  BEGIN SET @stmt = CONCAT('SELECT \"', arg, '\"');"
18423                          "  PREPARE ps1 FROM @stmt;"
18424                          "  EXECUTE ps1;"
18425                          "  DROP PREPARE ps1;"
18426                          "END;");
18427   myquery(rc);
18428 
18429   DIE_UNLESS(mysql_client_init(&con));
18430 
18431   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18432                                 current_db, opt_port, opt_unix_socket,
18433                                 CLIENT_MULTI_RESULTS));
18434 
18435   stmt= mysql_simple_prepare(&con, "CALL p1('abc')");
18436   check_stmt(stmt);
18437 
18438   rc= mysql_stmt_execute(stmt);
18439   check_execute(stmt, rc);
18440 
18441   rc= my_process_stmt_result(stmt);
18442   DIE_UNLESS(rc == 1);
18443 
18444   mysql_stmt_close(stmt);
18445 
18446   mysql_close(&con);
18447 
18448   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18449   myquery(rc);
18450 
18451   DBUG_VOID_RETURN;
18452 }
18453 
test_bug53371()18454 static void test_bug53371()
18455 {
18456   int rc;
18457   MYSQL_RES *result;
18458 
18459   myheader("test_bug53371");
18460 
18461   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18462   myquery(rc);
18463   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
18464   myquery(rc);
18465   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18466 
18467   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18468   myquery(rc);
18469   rc= mysql_query(mysql, "CREATE DATABASE bug53371");
18470   myquery(rc);
18471   rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
18472   myquery(rc);
18473 
18474   rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
18475   myquery(rc);
18476 
18477   rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
18478   DIE_UNLESS(rc);
18479   DIE_UNLESS(mysql_errno(mysql) == 1142);
18480 
18481   result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
18482   DIE_IF(result);
18483 
18484   result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
18485   DIE_IF(result);
18486 
18487   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
18488   myquery(rc);
18489   rc= mysql_query(mysql, "DROP TABLE t1");
18490   myquery(rc);
18491   rc= mysql_query(mysql, "DROP DATABASE bug53371");
18492   myquery(rc);
18493   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18494   myquery(rc);
18495 }
18496 
18497 
18498 
18499 /**
18500   Bug#42373: libmysql can mess a connection at connect
18501 */
test_bug42373()18502 static void test_bug42373()
18503 {
18504   int rc;
18505   MYSQL con;
18506   MYSQL_STMT *stmt;
18507 
18508   DBUG_ENTER("test_bug42373");
18509   myheader("test_42373");
18510 
18511   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18512   myquery(rc);
18513 
18514   rc= mysql_query(mysql, "CREATE PROCEDURE p1()"
18515                          "  BEGIN"
18516                          "  SELECT 1;"
18517                          "  INSERT INTO t1 VALUES (2);"
18518                          "END;");
18519   myquery(rc);
18520 
18521   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18522   myquery(rc);
18523 
18524   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18525   myquery(rc);
18526 
18527   /* Try with a stored procedure. */
18528   DIE_UNLESS(mysql_client_init(&con));
18529 
18530   mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()");
18531 
18532   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18533                                 current_db, opt_port, opt_unix_socket,
18534                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18535 
18536   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18537   check_stmt(stmt);
18538 
18539   rc= mysql_stmt_execute(stmt);
18540   check_execute(stmt, rc);
18541 
18542   rc= my_process_stmt_result(stmt);
18543   DIE_UNLESS(rc == 1);
18544 
18545   mysql_stmt_close(stmt);
18546   mysql_close(&con);
18547 
18548   /* Now try with a multi-statement. */
18549   DIE_UNLESS(mysql_client_init(&con));
18550 
18551   mysql_options(&con, MYSQL_INIT_COMMAND,
18552                 "SELECT 3; INSERT INTO t1 VALUES (4)");
18553 
18554   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18555                                 current_db, opt_port, opt_unix_socket,
18556                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18557 
18558   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18559   check_stmt(stmt);
18560 
18561   rc= mysql_stmt_execute(stmt);
18562   check_execute(stmt, rc);
18563 
18564   rc= my_process_stmt_result(stmt);
18565   DIE_UNLESS(rc == 2);
18566 
18567   mysql_stmt_close(stmt);
18568   mysql_close(&con);
18569 
18570   rc= mysql_query(mysql, "DROP TABLE t1");
18571   myquery(rc);
18572 
18573   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18574   myquery(rc);
18575 
18576   DBUG_VOID_RETURN;
18577 }
18578 
18579 
18580 /**
18581   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18582 */
18583 
test_bug54041_impl()18584 static void test_bug54041_impl()
18585 {
18586   int rc;
18587   MYSQL_STMT *stmt;
18588   MYSQL_BIND bind;
18589 
18590   DBUG_ENTER("test_bug54041");
18591   myheader("test_bug54041");
18592 
18593   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18594   myquery(rc);
18595 
18596   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18597   myquery(rc);
18598 
18599   stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?");
18600   check_stmt(stmt);
18601   verify_param_count(stmt, 1);
18602 
18603   memset(&bind, 0, sizeof(bind));
18604 
18605   /* Any type that does not support long data handling. */
18606   bind.buffer_type= MYSQL_TYPE_LONG;
18607 
18608   rc= mysql_stmt_bind_param(stmt, &bind);
18609   check_execute(stmt, rc);
18610 
18611   /*
18612     Trick the client API into sending a long data packet for
18613     the parameter. Long data is only supported for string and
18614     binary types.
18615   */
18616   stmt->params[0].buffer_type= MYSQL_TYPE_STRING;
18617 
18618   rc= mysql_stmt_send_long_data(stmt, 0, "data", 5);
18619   check_execute(stmt, rc);
18620 
18621   /* Undo API violation. */
18622   stmt->params[0].buffer_type= MYSQL_TYPE_LONG;
18623 
18624   rc= mysql_stmt_execute(stmt);
18625   /* Incorrect arguments. */
18626   check_execute_r(stmt, rc);
18627 
18628   mysql_stmt_close(stmt);
18629 
18630   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18631   myquery(rc);
18632 
18633   DBUG_VOID_RETURN;
18634 }
18635 
18636 
18637 /**
18638   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18639 */
18640 
test_bug54041()18641 static void test_bug54041()
18642 {
18643   enable_query_logs(0);
18644   test_bug54041_impl();
18645   disable_query_logs();
18646   test_bug54041_impl();
18647   restore_query_logs();
18648 }
18649 
18650 
18651 /**
18652   Bug#47485: mysql_store_result returns a result set for a prepared statement
18653 */
test_bug47485()18654 static void test_bug47485()
18655 {
18656   MYSQL_STMT   *stmt;
18657   MYSQL_RES    *res;
18658   MYSQL_BIND    bind[2];
18659   int           rc;
18660   const char*   sql_select = "SELECT 1, 'a'";
18661   int           int_data;
18662   char          str_data[16];
18663   my_bool       is_null[2];
18664   my_bool       error[2];
18665   ulong         length[2];
18666 
18667   DBUG_ENTER("test_bug47485");
18668   myheader("test_bug47485");
18669 
18670   stmt= mysql_stmt_init(mysql);
18671   check_stmt(stmt);
18672   rc= mysql_stmt_prepare(stmt, sql_select, (ulong)strlen(sql_select));
18673   check_execute(stmt, rc);
18674 
18675   rc= mysql_stmt_execute(stmt);
18676   check_execute(stmt, rc);
18677 
18678   res = mysql_store_result(mysql);
18679   DIE_UNLESS(res == NULL);
18680 
18681   mysql_stmt_reset(stmt);
18682 
18683   rc= mysql_stmt_execute(stmt);
18684   check_execute(stmt, rc);
18685 
18686   res = mysql_use_result(mysql);
18687   DIE_UNLESS(res == NULL);
18688 
18689   mysql_stmt_reset(stmt);
18690 
18691   memset(bind, 0, sizeof(bind));
18692   bind[0].buffer_type= MYSQL_TYPE_LONG;
18693   bind[0].buffer= (char *)&int_data;
18694   bind[0].is_null= &is_null[0];
18695   bind[0].length= &length[0];
18696   bind[0].error= &error[0];
18697 
18698   bind[1].buffer_type= MYSQL_TYPE_STRING;
18699   bind[1].buffer= (char *)str_data;
18700   bind[1].buffer_length= (ulong)sizeof(str_data);
18701   bind[1].is_null= &is_null[1];
18702   bind[1].length= &length[1];
18703   bind[1].error= &error[1];
18704 
18705   rc= mysql_stmt_bind_result(stmt, bind);
18706   check_execute(stmt, rc);
18707 
18708   rc= mysql_stmt_execute(stmt);
18709   check_execute(stmt, rc);
18710 
18711   rc= mysql_stmt_store_result(stmt);
18712   check_execute(stmt, rc);
18713 
18714   while (!(rc= mysql_stmt_fetch(stmt)))
18715     ;
18716 
18717   DIE_UNLESS(rc == MYSQL_NO_DATA);
18718 
18719   mysql_stmt_reset(stmt);
18720 
18721   memset(bind, 0, sizeof(bind));
18722   bind[0].buffer_type= MYSQL_TYPE_LONG;
18723   bind[0].buffer= (char *)&int_data;
18724   bind[0].is_null= &is_null[0];
18725   bind[0].length= &length[0];
18726   bind[0].error= &error[0];
18727 
18728   bind[1].buffer_type= MYSQL_TYPE_STRING;
18729   bind[1].buffer= (char *)str_data;
18730   bind[1].buffer_length= (ulong)sizeof(str_data);
18731   bind[1].is_null= &is_null[1];
18732   bind[1].length= &length[1];
18733   bind[1].error= &error[1];
18734 
18735   rc= mysql_stmt_bind_result(stmt, bind);
18736   check_execute(stmt, rc);
18737 
18738   rc= mysql_stmt_execute(stmt);
18739   check_execute(stmt, rc);
18740 
18741   while (!(rc= mysql_stmt_fetch(stmt)))
18742     ;
18743 
18744   DIE_UNLESS(rc == MYSQL_NO_DATA);
18745 
18746   mysql_stmt_close(stmt);
18747 
18748   DBUG_VOID_RETURN;
18749 }
18750 
18751 
18752 /*
18753   Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server
18754 */
test_bug58036()18755 static void test_bug58036()
18756 {
18757   MYSQL *conn;
18758   enum mysql_ssl_mode ssl_mode= SSL_MODE_DISABLED;
18759   DBUG_ENTER("test_bug47485");
18760   myheader("test_bug58036");
18761 
18762   /* Part1: try to connect with ucs2 client character set */
18763   conn= mysql_client_init(NULL);
18764   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18765   mysql_options(conn, MYSQL_OPT_SSL_MODE, &ssl_mode);
18766   if (mysql_real_connect(conn, opt_host, opt_user,
18767                          opt_password,  opt_db ? opt_db : "test",
18768                          opt_port, opt_unix_socket, 0))
18769   {
18770     if (!opt_silent)
18771       printf("mysql_real_connect() succeeded (failure expected)\n");
18772     mysql_close(conn);
18773     DIE("");
18774   }
18775 
18776   if (!opt_silent)
18777     printf("Got mysql_real_connect() error (expected): %s (%d)\n",
18778            mysql_error(conn), mysql_errno(conn));
18779   DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR);
18780   mysql_close(conn);
18781 
18782 
18783   /*
18784     Part2:
18785     - connect with latin1
18786     - then change client character set to ucs2
18787     - then try mysql_change_user()
18788   */
18789   conn= mysql_client_init(NULL);
18790   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1");
18791   if (!mysql_real_connect(conn, opt_host, opt_user,
18792                          opt_password, opt_db ? opt_db : "test",
18793                          opt_port, opt_unix_socket, 0))
18794   {
18795     if (!opt_silent)
18796       printf("mysql_real_connect() failed: %s (%d)\n",
18797              mysql_error(conn), mysql_errno(conn));
18798     mysql_close(conn);
18799     DIE("");
18800   }
18801 
18802   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18803   if (!mysql_change_user(conn, opt_user, opt_password, NULL))
18804   {
18805     if (!opt_silent)
18806       printf("mysql_change_user() succedded, error expected!");
18807     mysql_close(conn);
18808     DIE("");
18809   }
18810 
18811   if (!opt_silent)
18812     printf("Got mysql_change_user() error (expected): %s (%d)\n",
18813            mysql_error(conn), mysql_errno(conn));
18814   mysql_close(conn);
18815 
18816   DBUG_VOID_RETURN;
18817 }
18818 
18819 
18820 /*
18821   Bug#49972: Crash in prepared statements.
18822 
18823   The following case lead to a server crash:
18824     - Use binary protocol;
18825     - Prepare a statement with OUT-parameter;
18826     - Execute the statement;
18827     - Cause re-prepare of the statement (change dependencies);
18828     - Execute the statement again -- crash here.
18829 */
18830 
test_bug49972()18831 static void test_bug49972()
18832 {
18833   int rc;
18834   MYSQL_STMT *stmt;
18835 
18836   MYSQL_BIND in_param_bind;
18837   MYSQL_BIND out_param_bind;
18838   int int_data= 0;
18839   my_bool is_null= FALSE;
18840 
18841   DBUG_ENTER("test_bug49972");
18842   myheader("test_bug49972");
18843 
18844   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
18845   myquery(rc);
18846 
18847   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18848   myquery(rc);
18849 
18850   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18851   myquery(rc);
18852 
18853   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a");
18854   myquery(rc);
18855 
18856   stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)");
18857   check_stmt(stmt);
18858 
18859   memset(&in_param_bind, 0, sizeof (in_param_bind));
18860 
18861   in_param_bind.buffer_type= MYSQL_TYPE_LONG;
18862   in_param_bind.buffer= (char *) &int_data;
18863   in_param_bind.length= 0;
18864   in_param_bind.is_null= 0;
18865 
18866   rc= mysql_stmt_bind_param(stmt, &in_param_bind);
18867 
18868   rc= mysql_stmt_execute(stmt);
18869   check_execute(stmt, rc);
18870 
18871   {
18872     memset(&out_param_bind, 0, sizeof (out_param_bind));
18873 
18874     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18875     out_param_bind.is_null= &is_null;
18876     out_param_bind.buffer= &int_data;
18877     out_param_bind.buffer_length= (ulong)sizeof (int_data);
18878 
18879     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18880     check_execute(stmt, rc);
18881 
18882     rc= mysql_stmt_fetch(stmt);
18883     rc= mysql_stmt_fetch(stmt);
18884     assert(rc == MYSQL_NO_DATA);
18885 
18886     mysql_stmt_next_result(stmt);
18887     mysql_stmt_fetch(stmt);
18888   }
18889 
18890   rc= mysql_query(mysql, "DROP FUNCTION f1");
18891   myquery(rc);
18892 
18893   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18894   myquery(rc);
18895 
18896   rc= mysql_stmt_execute(stmt);
18897   check_execute(stmt, rc);
18898 
18899   {
18900     memset(&out_param_bind, 0, sizeof (out_param_bind));
18901 
18902     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18903     out_param_bind.is_null= &is_null;
18904     out_param_bind.buffer= &int_data;
18905     out_param_bind.buffer_length= (ulong)sizeof (int_data);
18906 
18907     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18908     check_execute(stmt, rc);
18909 
18910     rc= mysql_stmt_fetch(stmt);
18911     rc= mysql_stmt_fetch(stmt);
18912     assert(rc == MYSQL_NO_DATA);
18913 
18914     mysql_stmt_next_result(stmt);
18915     mysql_stmt_fetch(stmt);
18916   }
18917 
18918   mysql_stmt_close(stmt);
18919 
18920   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18921   myquery(rc);
18922 
18923   rc= mysql_query(mysql, "DROP FUNCTION f1");
18924   myquery(rc);
18925 
18926   DBUG_VOID_RETURN;
18927 }
18928 
18929 
18930 /*
18931   Bug #56976:   Severe Denial Of Service in prepared statements
18932 */
test_bug56976()18933 static void test_bug56976()
18934 {
18935   MYSQL_STMT   *stmt;
18936   MYSQL_BIND    bind[1];
18937   int           rc;
18938   const char*   query = "SELECT LENGTH(?)";
18939   char *long_buffer;
18940   unsigned long i, packet_len = 256 * 1024L;
18941   unsigned long dos_len    = 8 * 1024 * 1024L;
18942 
18943   DBUG_ENTER("test_bug56976");
18944   myheader("test_bug56976");
18945 
18946   stmt= mysql_stmt_init(mysql);
18947   check_stmt(stmt);
18948 
18949   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
18950   check_execute(stmt, rc);
18951 
18952   memset(bind, 0, sizeof(bind));
18953   bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;
18954 
18955   rc= mysql_stmt_bind_param(stmt, bind);
18956   check_execute(stmt, rc);
18957 
18958   long_buffer= (char*) my_malloc(PSI_NOT_INSTRUMENTED,
18959                                  packet_len, MYF(0));
18960   DIE_UNLESS(long_buffer);
18961 
18962   memset(long_buffer, 'a', packet_len);
18963 
18964   for (i= 0; i < dos_len / packet_len; i++)
18965   {
18966     rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len);
18967     check_execute(stmt, rc);
18968   }
18969 
18970   my_free(long_buffer);
18971   rc= mysql_stmt_execute(stmt);
18972 
18973   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);
18974 
18975   mysql_stmt_close(stmt);
18976 
18977   DBUG_VOID_RETURN;
18978 }
18979 
18980 
18981 /**
18982   Bug#57058 SERVER_QUERY_WAS_SLOW not wired up.
18983 */
18984 
test_bug57058()18985 static void test_bug57058()
18986 {
18987   MYSQL_RES *res;
18988   int rc;
18989 
18990   DBUG_ENTER("test_bug57058");
18991   myheader("test_bug57058");
18992 
18993   rc= mysql_query(mysql, "set @@session.long_query_time=0.1");
18994   myquery(rc);
18995 
18996   DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW));
18997 
18998   rc= mysql_query(mysql, "select sleep(1)");
18999   myquery(rc);
19000 
19001   /*
19002     Important: the flag is sent in the last EOF packet of
19003     the query, the one which ends the result. Read the
19004     result to see the "slow" status.
19005   */
19006   res= mysql_store_result(mysql);
19007 
19008   DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW);
19009 
19010   mysql_free_result(res);
19011 
19012   rc= mysql_query(mysql, "set @@session.long_query_time=default");
19013   myquery(rc);
19014 
19015   DBUG_VOID_RETURN;
19016 }
19017 
19018 
19019 /**
19020   Bug#11766854: 60075: MYSQL_LOAD_CLIENT_PLUGIN DOESN'T CLEAR ERROR
19021 */
19022 
test_bug11766854()19023 static void test_bug11766854()
19024 {
19025   struct st_mysql_client_plugin *plugin;
19026 
19027   DBUG_ENTER("test_bug11766854");
19028   myheader("test_bug11766854");
19029 
19030   plugin= mysql_load_plugin(mysql, "foo", -1, 0);
19031   DIE_UNLESS(plugin == 0);
19032 
19033   plugin= mysql_load_plugin(mysql, "qa_auth_client", -1, 0);
19034   DIE_UNLESS(plugin != 0);
19035   DIE_IF(mysql_errno(mysql));
19036 
19037   DBUG_VOID_RETURN;
19038 }
19039 
19040 /**
19041   Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR
19042                        CHAR/VARCHAR/TEXT COLUMNS IN VIEWS
19043 */
test_bug12337762()19044 static void test_bug12337762()
19045 {
19046   int rc,i=0;
19047   MYSQL_RES *result;
19048   MYSQL_FIELD *field;
19049   unsigned int tab_charsetnr[3]= {0};
19050 
19051   DBUG_ENTER("test_bug12337762");
19052   myheader("test_bug12337762");
19053 
19054   /*
19055     Creating table with specific charset.
19056   */
19057   rc= mysql_query(mysql, "drop table if exists charset_tab");
19058   rc= mysql_query(mysql, "create table charset_tab("\
19059                          "txt1 varchar(32) character set Latin1,"\
19060                          "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
19061                          "txt3 varchar(32) character set utf8 collate utf8_bin"\
19062 						 ")");
19063 
19064   DIE_UNLESS(rc == 0);
19065   DIE_IF(mysql_errno(mysql));
19066 
19067   /*
19068     Creating view from table created earlier.
19069   */
19070   rc= mysql_query(mysql, "drop view if exists charset_view");
19071   rc= mysql_query(mysql, "create view charset_view as "\
19072                          "select * from charset_tab;");
19073   DIE_UNLESS(rc == 0);
19074   DIE_IF(mysql_errno(mysql));
19075 
19076   /*
19077     Checking field information for table.
19078   */
19079   result= mysql_list_fields(mysql, "charset_tab", NULL);
19080   DIE_IF(mysql_errno(mysql));
19081   i=0;
19082   while((field= mysql_fetch_field(result)))
19083   {
19084     printf("field name %s\n", field->name);
19085     printf("field table %s\n", field->table);
19086     printf("field type %d\n", field->type);
19087     printf("field charset %d\n", field->charsetnr);
19088     tab_charsetnr[i++]= field->charsetnr;
19089     printf("\n");
19090   }
19091   mysql_free_result(result);
19092 
19093   /*
19094     Checking field information for view.
19095   */
19096   result= mysql_list_fields(mysql, "charset_view", NULL);
19097   DIE_IF(mysql_errno(mysql));
19098   i=0;
19099   while((field= mysql_fetch_field(result)))
19100   {
19101     printf("field name %s\n", field->name);
19102     printf("field table %s\n", field->table);
19103     printf("field type %d\n", field->type);
19104     printf("field charset %d\n", field->charsetnr);
19105     printf("\n");
19106     /*
19107       charset value for field must be same for both, view and table.
19108     */
19109     DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
19110   }
19111   mysql_free_result(result);
19112 
19113   DBUG_VOID_RETURN;
19114 }
19115 
19116 /**
19117   Bug#54790: Use of non-blocking mode for sockets limits performance
19118 */
19119 
test_bug54790()19120 static void test_bug54790()
19121 {
19122   int rc;
19123   MYSQL *lmysql;
19124   uint timeout= 2;
19125   enum mysql_ssl_mode ssl_mode= SSL_MODE_DISABLED;
19126 
19127   DBUG_ENTER("test_bug54790");
19128   myheader("test_bug54790");
19129 
19130   lmysql= mysql_client_init(NULL);
19131   DIE_UNLESS(lmysql);
19132 
19133   rc= mysql_options(lmysql, MYSQL_OPT_READ_TIMEOUT, &timeout);
19134   DIE_UNLESS(!rc);
19135 
19136   mysql_options(lmysql, MYSQL_OPT_SSL_MODE, &ssl_mode);
19137   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
19138                           opt_db ? opt_db : "test", opt_port,
19139                           opt_unix_socket, 0))
19140   {
19141     mysql= lmysql;
19142     myerror("mysql_real_connect failed");
19143     mysql_close(lmysql);
19144     exit(1);
19145   }
19146 
19147   rc= mysql_query(lmysql, "SELECT SLEEP(100);");
19148   myquery_r(rc);
19149 
19150   /* A timeout error (ER_NET_READ_INTERRUPTED) would be more appropriate. */
19151   DIE_UNLESS(mysql_errno(lmysql) == CR_SERVER_LOST);
19152 
19153   mysql_close(lmysql);
19154 
19155   DBUG_VOID_RETURN;
19156 }
19157 
19158 
19159 /*
19160   BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
19161 */
19162 
test_bug11754979()19163 static void test_bug11754979()
19164 {
19165   MYSQL* conn;
19166   DBUG_ENTER("test_bug11754979");
19167 
19168   myheader("test_bug11754979");
19169   DIE_UNLESS((conn= mysql_client_init(NULL)));
19170   DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
19171              opt_password, opt_db ? opt_db:"test", opt_port,
19172              opt_unix_socket,  CLIENT_FOUND_ROWS));
19173   myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
19174   myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
19175   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
19176   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
19177                             "ON DUPLICATE KEY UPDATE id = 4"));
19178   DIE_UNLESS(mysql_affected_rows(conn) == 2);
19179   myquery(mysql_query(conn, "DROP TABLE t1"));
19180   mysql_close(conn);
19181 
19182   DBUG_VOID_RETURN;
19183 }
19184 
19185 
19186 /*
19187   Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
19188 */
test_bug13001491()19189 static void test_bug13001491()
19190 {
19191   int rc;
19192   char query[MAX_TEST_QUERY_LENGTH];
19193   MYSQL *c;
19194 
19195   myheader("test_bug13001491");
19196 
19197   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19198            "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
19199            opt_host ? opt_host : "'localhost'");
19200 
19201   rc= mysql_query(mysql, query);
19202   myquery(rc);
19203 
19204   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19205            "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
19206            opt_host ? opt_host : "'localhost'");
19207 
19208   rc= mysql_query(mysql, query);
19209   myquery(rc);
19210 
19211   c= mysql_client_init(NULL);
19212 
19213   DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
19214                                 current_db, opt_port, opt_unix_socket,
19215                                 CLIENT_MULTI_STATEMENTS |
19216                                 CLIENT_MULTI_RESULTS));
19217 
19218   rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
19219   myquery(rc);
19220 
19221   rc= mysql_query(c,
19222     "CREATE PROCEDURE p1() "
19223     "BEGIN "
19224     " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
19225     " SELECT COUNT(*) "
19226     " FROM INFORMATION_SCHEMA.PROCESSLIST "
19227     " GROUP BY user "
19228     " ORDER BY NULL "
19229     " INTO @a; "
19230     "END");
19231   myquery(rc);
19232 
19233   rc= mysql_query(c, "CALL p1()");
19234   myquery(rc);
19235 
19236   mysql_free_result(mysql_store_result(c));
19237 
19238   /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
19239   rc= mysql_refresh(c, REFRESH_GRANT |
19240                        REFRESH_TABLES | REFRESH_HOSTS |
19241                        REFRESH_STATUS | REFRESH_THREADS);
19242   myquery(rc);
19243 
19244   /*
19245     Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
19246     fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
19247     location.
19248   */
19249   mysql_refresh(c, REFRESH_LOG);
19250 
19251   rc= mysql_query(c, "DROP PROCEDURE p1");
19252   myquery(rc);
19253 
19254   mysql_close(c);
19255   c= NULL;
19256 
19257   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19258            "DROP USER mysqltest_u1@%s",
19259            opt_host ? opt_host : "'localhost'");
19260 
19261   rc= mysql_query(mysql, query);
19262   myquery(rc);
19263 }
19264 
19265 
19266 /*
19267   WL#5968: Implement START TRANSACTION READ (WRITE|ONLY);
19268   Check that the SERVER_STATUS_IN_TRANS_READONLY flag is set properly.
19269 */
test_wl5968()19270 static void test_wl5968()
19271 {
19272   int rc;
19273 
19274   myheader("test_wl5968");
19275 
19276   if (mysql_get_server_version(mysql) < 50600)
19277   {
19278     if (!opt_silent)
19279       fprintf(stdout, "Skipping test_wl5968: "
19280               "tested feature does not exist in versions before MySQL 5.6\n");
19281     return;
19282   }
19283 
19284   rc= mysql_query(mysql, "START TRANSACTION");
19285   myquery(rc);
19286   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19287   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19288   rc= mysql_query(mysql, "COMMIT");
19289   myquery(rc);
19290   rc= mysql_query(mysql, "START TRANSACTION READ ONLY");
19291   myquery(rc);
19292   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19293   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY);
19294   rc= mysql_query(mysql, "COMMIT");
19295   myquery(rc);
19296   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
19297   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19298   rc= mysql_query(mysql, "START TRANSACTION");
19299   myquery(rc);
19300   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19301   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19302   rc= mysql_query(mysql, "COMMIT");
19303   myquery(rc);
19304 }
19305 
19306 
19307 /*
19308   WL#5924: Add connect string processing to mysql
19309 */
test_wl5924()19310 static void test_wl5924()
19311 {
19312   int rc;
19313   MYSQL *l_mysql;
19314   MYSQL_RES *res;
19315   MYSQL_ROW row;
19316 
19317   myheader("test_wl5924");
19318 
19319   if (mysql_get_server_version(mysql) < 50600)
19320   {
19321     if (!opt_silent)
19322       fprintf(stdout, "Skipping test_wl5924: "
19323               "tested feature does not exist in versions before MySQL 5.6\n");
19324     return;
19325   }
19326 
19327   l_mysql= mysql_client_init(NULL);
19328   DIE_UNLESS(l_mysql != NULL);
19329 
19330   /* we want a non-default character set */
19331   rc= mysql_set_character_set(l_mysql, "cp1251");
19332   DIE_UNLESS(rc == 0);
19333 
19334   /* put in an attr */
19335   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19336                      "key1", "value1");
19337   DIE_UNLESS(rc == 0);
19338 
19339   /* put a second attr */
19340   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19341                      "key2", "value2");
19342   DIE_UNLESS(rc == 0);
19343 
19344   /* put the second attr again : should fail */
19345   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19346                      "key2", "value2");
19347   DIE_UNLESS(rc != 0);
19348 
19349   /* delete the second attr */
19350   rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
19351                     "key2");
19352   DIE_UNLESS(rc == 0);
19353 
19354   /* put the second attr again : should pass */
19355   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19356                      "key2", "value2");
19357   DIE_UNLESS(rc == 0);
19358 
19359   /* full reset */
19360   rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_RESET, NULL);
19361   DIE_UNLESS(rc == 0);
19362 
19363   /* put the second attr again : should pass */
19364   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19365                      "key2", "value2");
19366   DIE_UNLESS(rc == 0);
19367 
19368   /* full reset */
19369   rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_RESET, NULL);
19370   DIE_UNLESS(rc == 0);
19371 
19372   /* add a third attr */
19373   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19374                      "key3", "value3");
19375   DIE_UNLESS(rc == 0);
19376 
19377   /* add a fourth attr */
19378   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19379                      "key4", "value4");
19380   DIE_UNLESS(rc == 0);
19381 
19382   /* add a non-ascii attr */
19383   /* note : this is Георги, Кодинов in windows-1251 */
19384   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19385                      "\xc3\xe5\xee\xf0\xe3\xe8",
19386                      "\xca\xee\xe4\xe8\xed\xee\xe2");
19387   DIE_UNLESS(rc == 0);
19388 
19389   l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
19390                          opt_password, current_db, opt_port,
19391                          opt_unix_socket, 0);
19392   DIE_UNLESS(l_mysql != 0);
19393 
19394   rc= mysql_query(l_mysql,
19395                   "SELECT ATTR_NAME, ATTR_VALUE "
19396                   " FROM performance_schema.session_account_connect_attrs"
19397                   " WHERE ATTR_NAME IN ('key1','key2','key3','key4',"
19398                   "  '\xc3\xe5\xee\xf0\xe3\xe8') AND"
19399                   "  PROCESSLIST_ID = CONNECTION_ID() ORDER BY ATTR_NAME");
19400   myquery2(l_mysql,rc);
19401   res= mysql_use_result(l_mysql);
19402   DIE_UNLESS(res);
19403 
19404   row= mysql_fetch_row(res);
19405   DIE_UNLESS(row);
19406   DIE_UNLESS(0 == strcmp(row[0], "key3"));
19407   DIE_UNLESS(0 == strcmp(row[1], "value3"));
19408 
19409   row= mysql_fetch_row(res);
19410   DIE_UNLESS(row);
19411   DIE_UNLESS(0 == strcmp(row[0], "key4"));
19412   DIE_UNLESS(0 == strcmp(row[1], "value4"));
19413 
19414   row= mysql_fetch_row(res);
19415   DIE_UNLESS(row);
19416   DIE_UNLESS(0 == strcmp(row[0], "\xc3\xe5\xee\xf0\xe3\xe8"));
19417   DIE_UNLESS(0 == strcmp(row[1], "\xca\xee\xe4\xe8\xed\xee\xe2"));
19418 
19419   mysql_free_result(res);
19420 
19421   l_mysql->reconnect= 1;
19422   rc= mysql_reconnect(l_mysql);
19423   myquery2(l_mysql,rc);
19424 
19425   mysql_close(l_mysql);
19426 }
19427 
19428 
19429 /*
19430   WL#56587: Protocol support for password expiration
19431 */
test_wl6587()19432 static void test_wl6587()
19433 {
19434   int rc;
19435   MYSQL *l_mysql, *r_mysql;
19436   my_bool can;
19437 
19438   myheader("test_wl6587");
19439 
19440   if (mysql_get_server_version(mysql) < 50600)
19441   {
19442     if (!opt_silent)
19443       fprintf(stdout, "Skipping test_wl6587: "
19444               "tested feature does not exist in versions before MySQL 5.6\n");
19445     return;
19446   }
19447 
19448   /* initialize the server user */
19449   rc= mysql_query(mysql,
19450                   "CREATE USER wl6587_cli@localhost IDENTIFIED BY 'wl6587'");
19451   myquery(rc);
19452   rc= mysql_query(mysql, "ALTER USER wl6587_cli@localhost PASSWORD EXPIRE");
19453   myquery(rc);
19454 
19455   /* prepare the connection */
19456   l_mysql= mysql_client_init(NULL);
19457   DIE_UNLESS(l_mysql != NULL);
19458 
19459   /* connect must fail : the flag is off by default */
19460   r_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19461                               "wl6587", "test", opt_port,
19462                               opt_unix_socket, 0);
19463   DIE_UNLESS(r_mysql == 0);
19464   mysql_close(l_mysql);
19465 
19466   l_mysql= mysql_client_init(NULL);
19467   DIE_UNLESS(l_mysql != NULL);
19468 
19469   /* try the last argument. should work */
19470   l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19471                          "wl6587", "test", opt_port,
19472                          opt_unix_socket,
19473                          CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS);
19474   DIE_UNLESS(l_mysql != 0);
19475 
19476   /* must fail : sandbox mode */
19477   rc= mysql_query(l_mysql, "SELECT USER()");
19478   myerror2(l_mysql,NULL);
19479   DIE_UNLESS(rc != 0);
19480 
19481   mysql_close(l_mysql);
19482 
19483   /* try setting the option */
19484 
19485   l_mysql= mysql_client_init(NULL);
19486   DIE_UNLESS(l_mysql != NULL);
19487 
19488   can= TRUE;
19489   rc= mysql_options(l_mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &can);
19490   DIE_UNLESS(rc == 0);
19491 
19492   l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19493                          "wl6587", "test", opt_port,
19494                          opt_unix_socket, 0);
19495   DIE_UNLESS(l_mysql != 0);
19496 
19497   /* must fail : sandbox mode */
19498   rc= mysql_query(l_mysql, "SELECT USER()");
19499   myerror2(l_mysql,NULL);
19500   DIE_UNLESS(rc != 0);
19501 
19502   mysql_close(l_mysql);
19503 
19504   /* try change user against an expired account */
19505 
19506   l_mysql= mysql_client_init(NULL);
19507   DIE_UNLESS(l_mysql != NULL);
19508 
19509   can= FALSE;
19510   rc= mysql_options(l_mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &can);
19511   DIE_UNLESS(rc == 0);
19512 
19513 
19514   l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
19515                          opt_password, current_db, opt_port,
19516                          opt_unix_socket, 0);
19517   DIE_UNLESS(l_mysql != 0);
19518 
19519   rc= mysql_change_user(l_mysql, "wl6587_cli", "wl6587", "test");
19520   DIE_UNLESS(rc == TRUE);
19521 
19522   mysql_close(l_mysql);
19523 
19524   /* cleanup */
19525   rc= mysql_query(mysql, "DROP USER wl6587_cli@localhost");
19526   myquery(rc);
19527 }
19528 
19529 #ifndef EMBEDDED_LIBRARY
19530 /*
19531   Bug #17309863 AUTO RECONNECT DOES NOT WORK WITH 5.6 LIBMYSQLCLIENT
19532 */
test_bug17309863()19533 static void test_bug17309863()
19534 {
19535   MYSQL *lmysql;
19536   unsigned long thread_id;
19537   char query[MAX_TEST_QUERY_LENGTH];
19538   int rc;
19539 
19540   myheader("test_bug17309863");
19541 
19542   if (!opt_silent)
19543     fprintf(stdout, "\n Establishing a test connection ...");
19544   if (!(lmysql= mysql_client_init(NULL)))
19545   {
19546     myerror("mysql_client_init() failed");
19547     exit(1);
19548   }
19549   lmysql->reconnect= 1;
19550   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
19551                            opt_password, current_db, opt_port,
19552                            opt_unix_socket, 0)))
19553   {
19554     myerror("connection failed");
19555     exit(1);
19556   }
19557   if (!opt_silent)
19558     fprintf(stdout, "OK");
19559 
19560   thread_id= mysql_thread_id(lmysql);
19561   sprintf(query, "KILL %lu", thread_id);
19562 
19563   /*
19564     Running the "KILL <thread_id>" query in a separate connection.
19565   */
19566   if (thread_query(query))
19567     exit(1);
19568 
19569   /*
19570     The above KILL statement should have closed our connection. But reconnect
19571     flag allows to detect this before sending query and re-establish it without
19572     returning an error.
19573   */
19574   rc= mysql_query(lmysql, "SELECT 'bug17309863'");
19575   myquery(rc);
19576 
19577   mysql_close(lmysql);
19578 }
19579 #endif
19580 
test_wl5928()19581 static void test_wl5928()
19582 {
19583   MYSQL_STMT *stmt;
19584   int         rc;
19585   MYSQL_RES  *result;
19586 
19587   myheader("test_wl5928");
19588 
19589   if (mysql_get_server_version(mysql) < 50702)
19590   {
19591     if (!opt_silent)
19592       fprintf(stdout, "Skipping test_wl5928: "
19593               "tested feature does not exist in versions before MySQL 5.7.2\n");
19594     return;
19595   }
19596 
19597   stmt= mysql_simple_prepare(mysql, "SHOW WARNINGS");
19598   DIE_UNLESS(stmt == NULL);
19599   stmt= mysql_simple_prepare(mysql, "SHOW ERRORS");
19600   DIE_UNLESS(stmt == NULL);
19601   stmt= mysql_simple_prepare(mysql, "SHOW COUNT(*) WARNINGS");
19602   DIE_UNLESS(stmt == NULL);
19603   stmt= mysql_simple_prepare(mysql, "SHOW COUNT(*) ERRORS");
19604   DIE_UNLESS(stmt == NULL);
19605   stmt= mysql_simple_prepare(mysql, "SELECT @@warning_count");
19606   DIE_UNLESS(stmt == NULL);
19607   stmt= mysql_simple_prepare(mysql, "SELECT @@error_count");
19608   DIE_UNLESS(stmt == NULL);
19609   stmt= mysql_simple_prepare(mysql, "GET DIAGNOSTICS");
19610   DIE_UNLESS(stmt == NULL);
19611 
19612   rc= mysql_query(mysql, "SET SQL_MODE=''");
19613   myquery(rc);
19614 
19615   /* PREPARE */
19616 
19617   stmt= mysql_simple_prepare(mysql, "CREATE TABLE t1 (f1 INT) ENGINE=UNKNOWN");
19618   DIE_UNLESS(mysql_warning_count(mysql) == 2);
19619   check_stmt(stmt);
19620 
19621   /* SHOW WARNINGS.  (Will keep diagnostics) */
19622   rc= mysql_query(mysql, "SHOW WARNINGS");
19623   myquery(rc);
19624   result= mysql_store_result(mysql);
19625   mytest(result);
19626   rc= my_process_result_set(result);
19627   DIE_UNLESS(rc == 2);
19628   mysql_free_result(result);
19629 
19630   /* EXEC */
19631   rc= mysql_stmt_execute(stmt);
19632   check_execute(stmt, rc);
19633   DIE_UNLESS(mysql_warning_count(mysql) == 0);
19634 
19635   /* SHOW WARNINGS.  (Will keep diagnostics) */
19636   rc= mysql_query(mysql, "SHOW WARNINGS");
19637   myquery(rc);
19638   result= mysql_store_result(mysql);
19639   mytest(result);
19640   rc= my_process_result_set(result);
19641   DIE_UNLESS(rc == 0);
19642   mysql_free_result(result);
19643 
19644   /* clean up */
19645   mysql_stmt_close(stmt);
19646 
19647   stmt= mysql_simple_prepare(mysql, "SELECT 1");
19648   check_stmt(stmt);
19649   rc= mysql_stmt_execute(stmt);
19650   check_execute(stmt, rc);
19651   mysql_stmt_close(stmt);
19652 
19653   myquery(rc);
19654 }
19655 
test_wl6797()19656 static void test_wl6797()
19657 {
19658   MYSQL_STMT *stmt;
19659   int        rc;
19660   const char *stmt_text;
19661   my_ulonglong res;
19662 
19663   myheader("test_wl6797");
19664 
19665   if (mysql_get_server_version(mysql) < 50703)
19666   {
19667     if (!opt_silent)
19668       fprintf(stdout, "Skipping test_wl6797: "
19669              "tested feature does not exist in versions before MySQL 5.7.3\n");
19670     return;
19671   }
19672   /* clean up the session */
19673   rc= mysql_reset_connection(mysql);
19674   DIE_UNLESS(rc == 0);
19675 
19676   /* do prepare of a query */
19677   mysql_query(mysql, "use test");
19678   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
19679   mysql_query(mysql, "CREATE TABLE t1 (a int)");
19680 
19681   stmt= mysql_stmt_init(mysql);
19682   stmt_text= "INSERT INTO t1 VALUES (1), (2)";
19683 
19684   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
19685   check_execute(stmt, rc);
19686 
19687   /* Execute the insert statement */
19688   rc= mysql_stmt_execute(stmt);
19689   check_execute(stmt, rc);
19690 
19691   /*
19692    clean the session this should remove the prepare statement
19693    from the cache.
19694   */
19695   rc= mysql_reset_connection(mysql);
19696   DIE_UNLESS(rc == 0);
19697 
19698   /* this below stmt should report error */
19699   rc= mysql_stmt_execute(stmt);
19700   DIE_IF(rc == 0);
19701 
19702   /*
19703    bug#17653288: MYSQL_RESET_CONNECTION DOES NOT RESET LAST_INSERT_ID
19704   */
19705 
19706   rc= mysql_query(mysql, "CREATE TABLE t2 (a int NOT NULL PRIMARY KEY"\
19707                          " auto_increment)");
19708   myquery(rc);
19709   rc= mysql_query(mysql, "INSERT INTO t2 VALUES (null)");
19710   myquery(rc);
19711   res= mysql_insert_id(mysql);
19712   DIE_UNLESS(res == 1);
19713   rc= mysql_reset_connection(mysql);
19714   DIE_UNLESS(rc == 0);
19715   res= mysql_insert_id(mysql);
19716   DIE_UNLESS(res == 0);
19717 
19718   rc= mysql_query(mysql, "INSERT INTO t2 VALUES (last_insert_id(100))");
19719   myquery(rc);
19720   res= mysql_insert_id(mysql);
19721   DIE_UNLESS(res == 100);
19722   rc= mysql_reset_connection(mysql);
19723   DIE_UNLESS(rc == 0);
19724   res= mysql_insert_id(mysql);
19725   DIE_UNLESS(res == 0);
19726 
19727   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
19728   mysql_query(mysql, "DROP TABLE IF EXISTS t2");
19729   mysql_stmt_close(stmt);
19730 }
19731 
19732 
test_wl6791()19733 static void test_wl6791()
19734 {
19735   int        rc;
19736   uint       idx;
19737   MYSQL      *l_mysql;
19738   enum mysql_option
19739   uint_opts[] = {
19740     MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT,
19741     MYSQL_OPT_PROTOCOL, MYSQL_OPT_LOCAL_INFILE, MYSQL_OPT_SSL_MODE
19742   },
19743   my_bool_opts[] = {
19744     MYSQL_OPT_COMPRESS, MYSQL_OPT_USE_REMOTE_CONNECTION,
19745     MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION,
19746     MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
19747     MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_OPT_SSL_ENFORCE,
19748     MYSQL_ENABLE_CLEARTEXT_PLUGIN, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
19749   },
19750   const_char_opts[] = {
19751     MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
19752     MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME,
19753 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
19754     /* mysql_options() is a no-op on non-supporting platforms. */
19755     MYSQL_SHARED_MEMORY_BASE_NAME,
19756 #endif
19757     MYSQL_SET_CLIENT_IP, MYSQL_OPT_BIND, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
19758     MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT, MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH,
19759     MYSQL_OPT_SSL_CIPHER, MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
19760     MYSQL_SERVER_PUBLIC_KEY
19761   },
19762   err_opts[] = {
19763     MYSQL_OPT_NAMED_PIPE, MYSQL_OPT_CONNECT_ATTR_RESET,
19764     MYSQL_OPT_CONNECT_ATTR_DELETE, MYSQL_INIT_COMMAND
19765   };
19766 
19767   myheader("test_wl6791");
19768 
19769   /* prepare the connection */
19770   l_mysql = mysql_client_init(NULL);
19771   DIE_UNLESS(l_mysql != NULL);
19772 
19773   for (idx= 0; idx < sizeof(uint_opts) / sizeof(enum mysql_option); idx++)
19774   {
19775     uint opt_before= 1, opt_after= 0;
19776 
19777     if (!opt_silent)
19778       fprintf(stdout, "testing uint option #%d (%d)\n", idx,
19779               (int) uint_opts[idx]);
19780     rc= mysql_options(l_mysql, uint_opts[idx], &opt_before);
19781     DIE_UNLESS(rc == 0);
19782 
19783     rc = mysql_get_option(l_mysql, uint_opts[idx], &opt_after);
19784     DIE_UNLESS(rc == 0);
19785 
19786     DIE_UNLESS(opt_before == opt_after);
19787   }
19788 
19789   for (idx= 0; idx < sizeof(my_bool_opts) / sizeof(enum mysql_option); idx++)
19790   {
19791     my_bool opt_before = TRUE, opt_after = FALSE;
19792 
19793     if (!opt_silent)
19794       fprintf(stdout, "testing my_bool option #%d (%d)\n", idx,
19795       (int)my_bool_opts[idx]);
19796 
19797     rc = mysql_options(l_mysql, my_bool_opts[idx], &opt_before);
19798     DIE_UNLESS(rc == 0);
19799 
19800     rc = mysql_get_option(l_mysql, my_bool_opts[idx], &opt_after);
19801     DIE_UNLESS(rc == 0);
19802 
19803     DIE_UNLESS(opt_before == opt_after);
19804   }
19805 
19806   for (idx= 0; idx < sizeof(const_char_opts) / sizeof(enum mysql_option); idx++)
19807   {
19808     const char *opt_before = "TEST", *opt_after = NULL;
19809 
19810     if (!opt_silent)
19811       fprintf(stdout, "testing const char * option #%d (%d)\n", idx,
19812       (int)const_char_opts[idx]);
19813 
19814     rc = mysql_options(l_mysql, const_char_opts[idx], opt_before);
19815     DIE_UNLESS(rc == 0);
19816 
19817     rc = mysql_get_option(l_mysql, const_char_opts[idx], &opt_after);
19818     DIE_UNLESS(rc == 0);
19819 
19820     DIE_UNLESS(opt_before && opt_after &&
19821                0 == strcmp(opt_before, opt_after));
19822   }
19823 
19824   for (idx= 0; idx < sizeof(err_opts) / sizeof(enum mysql_option); idx++)
19825   {
19826     void *dummy_arg;
19827     if (!opt_silent)
19828       fprintf(stdout, "testing invalid option #%d (%d)\n", idx,
19829       (int)err_opts[idx]);
19830 
19831     rc = mysql_get_option(l_mysql, err_opts[idx], &dummy_arg);
19832     DIE_UNLESS(rc != 0);
19833   }
19834 
19835   /* clean up */
19836   mysql_close(l_mysql);
19837 }
19838 
19839 #define QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE \
19840   rc= mysql_query(mysql, "SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE," \
19841   " COUNT_EXECUTE, OWNER_OBJECT_TYPE, OWNER_OBJECT_SCHEMA, OWNER_OBJECT_NAME" \
19842   " from performance_schema.prepared_statements_instances where" \
19843   " sql_text like \"%ps_t1%\""); \
19844   myquery(rc); \
19845   result= mysql_store_result(mysql); \
19846   mytest(result); \
19847   (void) my_process_result_set(result); \
19848   mysql_free_result(result);
19849 
test_wl5768()19850 static void test_wl5768()
19851 {
19852   MYSQL_RES  *result;
19853   MYSQL_STMT *stmt, *sp_stmt;
19854   MYSQL_BIND bind[1];
19855   long       int_data;
19856   int        rc;
19857 
19858   myheader("test_wl5768");
19859 
19860   if (mysql_get_server_version(mysql) < 50704)
19861   {
19862     if (!opt_silent)
19863       fprintf(stdout, "Skipping test_wl5768: "
19864               "tested feature does not exist in versions before MySQL 5.7.4\n");
19865     return;
19866   }
19867 
19868   rc= mysql_query(mysql, "DROP TABLE IF EXISTS ps_t1");
19869   myquery(rc);
19870 
19871   rc= mysql_query(mysql, "CREATE TABLE ps_t1(Id INT)");
19872   myquery(rc);
19873 
19874   // Prepare an insert statement.
19875   stmt= mysql_simple_prepare(mysql, "INSERT INTO ps_t1 VALUES(?)");
19876   check_stmt(stmt);
19877   verify_param_count(stmt, 1);
19878 
19879   // Query P_S table.
19880   QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE;
19881 
19882   memset(bind, 0, sizeof (bind));
19883   bind[0].buffer_type= MYSQL_TYPE_LONG;
19884   bind[0].buffer= (long *) &int_data;
19885   bind[0].length= 0;
19886   bind[0].is_null= 0;
19887   rc= mysql_stmt_bind_param(stmt, bind);
19888   check_execute(stmt, rc);
19889 
19890   // Set the data to be inserted.
19891   int_data= 25;
19892 
19893   // Execute the prepared statement.
19894   rc= mysql_stmt_execute(stmt);
19895   check_execute(stmt, rc);
19896 
19897   // Query P_S table.
19898   QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE;
19899 
19900   // execute the prepared statement for 3 more times to check COUNT_EXECUTE
19901   rc= mysql_stmt_execute(stmt);
19902   check_execute(stmt, rc);
19903 
19904   int_data= 74;
19905 
19906   rc= mysql_stmt_execute(stmt);
19907   check_execute(stmt, rc);
19908 
19909   int_data= 123;
19910 
19911   rc= mysql_stmt_execute(stmt);
19912   check_execute(stmt, rc);
19913 
19914   // Query P_S table.
19915   QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE;
19916 
19917   // Deallocate/Close the prepared statement.
19918   mysql_stmt_close(stmt);
19919 
19920   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS proc");
19921   myquery(rc);
19922 
19923   // Check the instrumentation of the statement prepared in a stored procedure
19924   rc= mysql_query(mysql, "CREATE PROCEDURE proc(IN a INT)"
19925                          "BEGIN"
19926                          "  SET @stmt = CONCAT('UPDATE ps_t1 SET Id = ? WHERE Id > 100');"
19927                          "  PREPARE st FROM @stmt;"
19928                          "  EXECUTE st USING @a;"
19929                          "  DEALLOCATE PREPARE st;"
19930                          "END;");
19931   myquery(rc);
19932 
19933   sp_stmt= mysql_simple_prepare(mysql, "CALL proc(?)");
19934   check_stmt(sp_stmt);
19935   verify_param_count(sp_stmt, 1);
19936 
19937   memset(bind, 0, sizeof (bind));
19938   bind[0].buffer_type= MYSQL_TYPE_LONG;
19939   bind[0].buffer= (long *) &int_data;
19940   bind[0].length= 0;
19941   bind[0].is_null= 0;
19942   rc= mysql_stmt_bind_param(sp_stmt, bind);
19943   check_execute(sp_stmt, rc);
19944 
19945   int_data= 100;
19946 
19947   // Execute the prepared statement.
19948   rc= mysql_stmt_execute(sp_stmt);
19949   check_execute(sp_stmt, rc);
19950 
19951   // Query P_S table.
19952   QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE;
19953 
19954   // Deallocate/Close the prepared statement.
19955   mysql_stmt_close(sp_stmt);
19956 
19957   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS proc");
19958   myquery(rc);
19959 
19960   rc= mysql_query(mysql, "DROP TABLE IF EXISTS ps_t1");
19961   myquery(rc);
19962 }
19963 
19964 
19965 /**
19966    BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST()
19967 */
test_bug17512527()19968 static void test_bug17512527()
19969 {
19970   MYSQL *conn1, *conn2;
19971   MYSQL_STMT *stmt1, *stmt2;
19972   const char *stmt1_txt= "SELECT NOW();";
19973   const char *stmt2_txt= "SELECT 1;";
19974   unsigned long thread_id;
19975   char query[MAX_TEST_QUERY_LENGTH];
19976   int rc;
19977 
19978   conn1= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
19979   conn2= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 0);
19980 
19981   stmt1 = mysql_stmt_init(conn1);
19982   check_stmt(stmt1);
19983   rc= mysql_stmt_prepare(stmt1, stmt1_txt, strlen(stmt1_txt));
19984   check_execute(stmt1, rc);
19985 
19986   thread_id= mysql_thread_id(conn1);
19987   sprintf(query, "KILL %lu", thread_id);
19988   if (thread_query(query))
19989     exit(1);
19990 
19991   /*
19992     After the connection is killed, the connection is
19993     re-established due to the reconnect flag.
19994   */
19995   stmt2 = mysql_stmt_init(conn1);
19996   check_stmt(stmt2);
19997 
19998   rc= mysql_stmt_prepare(stmt2, stmt2_txt, strlen(stmt2_txt));
19999   check_execute(stmt1, rc);
20000 
20001   mysql_stmt_close(stmt2);
20002   mysql_stmt_close(stmt1);
20003 
20004   mysql_close(conn1);
20005   mysql_close(conn2);
20006 }
20007 
20008 
20009 /**
20010    BUG#20810928: CANNOT SHUTDOWN MYSQL USING JDBC DRIVER
20011 */
test_bug20810928()20012 static void test_bug20810928()
20013 {
20014   MYSQL *l_mysql;
20015   int rc;
20016   uint error_code;
20017 
20018   myheader("test_bug20810928");
20019 
20020   /* initialize the server user */
20021   rc= mysql_query(mysql,
20022                   "CREATE USER bug20810928@localhost IDENTIFIED BY 'bug20810928'");
20023   myquery(rc);
20024 
20025   /* prepare the connection */
20026   l_mysql= mysql_client_init(NULL);
20027   DIE_UNLESS(l_mysql != NULL);
20028 
20029   l_mysql= mysql_real_connect(l_mysql, opt_host, "bug20810928",
20030                               "bug20810928", "test", opt_port,
20031                               opt_unix_socket, 0);
20032 
20033   /*
20034     Try the 0 length shutdown command.
20035     Should fail with the right error code to avoid server restart.
20036   */
20037   rc= simple_command(l_mysql, COM_SHUTDOWN, NULL, 0, 0);
20038   DIE_UNLESS(rc != 0);
20039 
20040   /* check if it's the right error */
20041   error_code= mysql_errno(l_mysql);
20042   DIE_UNLESS(error_code == ER_SPECIFIC_ACCESS_DENIED_ERROR);
20043 
20044   mysql_close(l_mysql);
20045 
20046   /* clean up the server user */
20047   rc= mysql_query(mysql, "DROP USER bug20810928@localhost");
20048   myquery(rc);
20049 }
20050 
20051 
20052 /**
20053    WL#8016: Parser for optimizer hints
20054 */
test_wl8016()20055 static void test_wl8016()
20056 {
20057   MYSQL_RES *result;
20058   int        rc;
20059 
20060   myheader("test_wl8016");
20061 
20062   rc= mysql_query(mysql, "SELECT /*+ ");
20063   DIE_UNLESS(rc);
20064 
20065   rc= mysql_query(mysql, "SELECT /*+ ICP(`test");
20066   DIE_UNLESS(rc);
20067 
20068   rc= mysql_query(mysql, "SELECT /*+ ICP(`test*/ 1");
20069   myquery(rc);
20070 
20071   rc= mysql_query(mysql, "SELECT /*+ ICP(`test*/`*/ 1");
20072   DIE_UNLESS(rc);
20073 
20074   /* get the result */
20075   result= mysql_store_result(mysql);
20076   mytest(result);
20077 
20078   (void) my_process_result_set(result);
20079   mysql_free_result(result);
20080 }
20081 
20082 struct execute_test_query
20083 {
20084   const char *create;
20085   const char *select;
20086   const char *drop;
20087 };
20088 
20089 /**
20090   test_bug20645725 helper function
20091 */
execute_and_test(struct execute_test_query * query,char quote,int result,const char * string,const char * expected,my_bool recursive)20092 static void execute_and_test(struct execute_test_query *query, char quote,
20093                              int result, const char* string,
20094                              const char* expected, my_bool recursive)
20095 {
20096   MYSQL_STMT *stmt;
20097   const char *stmt_text;
20098   int rc;
20099   MYSQL_BIND my_bind[1];
20100   char query_buffer[100];
20101   char param_buffer[50];
20102   char buff[50];
20103   ulong length;
20104 
20105   sprintf(param_buffer, "%c%s%c", quote, string, quote);
20106   sprintf(query_buffer, query->create, param_buffer);
20107 
20108   rc = mysql_real_query(mysql, query_buffer, (ulong)strlen(query_buffer));
20109   DIE_UNLESS(rc == result);
20110   if (result != 0) return;
20111   myquery(rc);
20112 
20113   stmt = mysql_stmt_init(mysql);
20114 
20115   memset(my_bind, 0, sizeof(my_bind));
20116   my_bind[0].buffer = buff;
20117   my_bind[0].length = &length;
20118   my_bind[0].buffer_length = (ulong)sizeof(buff);
20119   my_bind[0].buffer_type = MYSQL_TYPE_STRING;
20120 
20121   mysql_stmt_bind_param(stmt, my_bind);
20122 
20123   stmt_text = query->select;
20124   rc = mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
20125   check_execute(stmt, rc);
20126   rc = mysql_stmt_execute(stmt);
20127   check_execute(stmt, rc);
20128 
20129   mysql_stmt_bind_result(stmt, my_bind);
20130 
20131   rc = mysql_stmt_fetch(stmt);
20132   DIE_UNLESS(rc == 0);
20133   DIE_UNLESS(length == (ulong)strlen(expected));
20134   DIE_UNLESS(strcmp(buff, expected) == 0);
20135   rc = mysql_stmt_fetch(stmt);
20136   DIE_UNLESS(rc == MYSQL_NO_DATA);
20137 
20138   mysql_stmt_close(stmt);
20139 
20140   sprintf(query_buffer, query->drop, param_buffer);
20141 
20142   rc = mysql_real_query(mysql, query_buffer, (ulong)strlen(query_buffer));
20143   myquery(rc);
20144 
20145   if (recursive != 0)
20146   {
20147     length = mysql_real_escape_string_quote(mysql, param_buffer, expected,
20148                                             (ulong)strlen(expected), quote);
20149     DIE_UNLESS(length != (ulong)-1);
20150 
20151     execute_and_test(query, quote, result, param_buffer, expected, 0);
20152   }
20153 }
20154 
20155 /**
20156   BUG#20645725 GRAVE ACCENT CHARACTER (`) IS NOT FOLLOWED WITH BACKSLASH
20157                WHEN ESCAPING IT
20158 */
test_bug20645725()20159 static void test_bug20645725()
20160 {
20161   const char *stmt_text;
20162   const char *modes[2];
20163   struct execute_test_query query;
20164   int rc;
20165   int i;
20166 
20167   myheader("test_bug20645725");
20168 
20169   stmt_text = "DROP DATABASE IF EXISTS supertest";
20170   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20171   myquery(rc);
20172 
20173   stmt_text = "CREATE DATABASE supertest";
20174   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20175   myquery(rc);
20176 
20177   stmt_text = "USE supertest";
20178   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20179   myquery(rc);
20180 
20181   stmt_text = "DROP TABLE IF EXISTS t1";
20182   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20183   myquery(rc);
20184   stmt_text = "CREATE TABLE t1 (a TEXT)";
20185   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20186   myquery(rc);
20187 
20188   modes[0]= "SET sql_mode=''";
20189   modes[1]= "SET sql_mode='ANSI_QUOTES'";
20190 
20191   query.create= "INSERT INTO t1 VALUES(%s)";
20192   query.drop= "DELETE FROM t1; -- %s";
20193   query.select= "SELECT a FROM t1";
20194 
20195   for (i = 0; i < (int)(sizeof(modes)/sizeof(modes[0])); i++)
20196   {
20197     rc = mysql_real_query(mysql, modes[i], (ulong)strlen(modes[i]));
20198     myquery(rc);
20199 
20200     execute_and_test(&query, '\'', 0, "aaa",       "aaa",   1);
20201     execute_and_test(&query, '\'', 0, "a\\'",      "a'",    1);
20202     execute_and_test(&query, '\'', 0, "''",        "'",     1);
20203     execute_and_test(&query, '\'', 0, "a''",       "a'",    1);
20204     execute_and_test(&query, '\'', 0, "a''b",      "a'b",   1);
20205     execute_and_test(&query, '\'', 0, "a\\'''\\'", "a'''",  1);
20206     execute_and_test(&query, '\'', 0, "a\\`",      "a`",    1);
20207     execute_and_test(&query, '\'', 0, "a\\n",      "a\n",   1);
20208     execute_and_test(&query, '\'', 0, "a``",       "a``",   1);
20209     execute_and_test(&query, '\'', 0, "a\\``\\`",  "a```",  1);
20210     execute_and_test(&query, '\'', 0, "b\"",       "b\"",   1);
20211     execute_and_test(&query, '\'', 0, "b\"\"",     "b\"\"", 1);
20212     execute_and_test(&query, '\'', 0, "b\"\"",     "b\"\"", 1);
20213     execute_and_test(&query, '\'', 0, "b\\$",      "b$",    1);
20214     execute_and_test(&query, '\'', 0, "b\\\\\"",   "b\\\"", 1);
20215     execute_and_test(&query, '\'', 0, "b\\\"\"",   "b\"\"", 1);
20216     execute_and_test(&query, '"',  i, "b\\\"\"\"", "b\"\"", 1);
20217     execute_and_test(&query, '"',  i, "d\\'e",     "d'e",   1);
20218     execute_and_test(&query, '`',  1, "",          "",      0);
20219   }
20220 
20221   modes[0]= "SET sql_mode='NO_BACKSLASH_ESCAPES'";
20222   modes[1]= "SET sql_mode='NO_BACKSLASH_ESCAPES,ANSI_QUOTES'";
20223 
20224   for (i = 0; i < (int)(sizeof(modes)/sizeof(modes[0])); i++)
20225   {
20226     rc = mysql_real_query(mysql, modes[i], (ulong)strlen(modes[i]));
20227     myquery(rc);
20228 
20229     execute_and_test(&query, '\'', 0, "aaa",       "aaa",      1);
20230     execute_and_test(&query, '\'', 1, "a\\'",      "",         0);
20231     execute_and_test(&query, '\'', 0, "''",        "'",        1);
20232     execute_and_test(&query, '\'', 0, "a''",       "a'",       1);
20233     execute_and_test(&query, '\'', 0, "a''b",      "a'b",      1);
20234     execute_and_test(&query, '\'', 1, "a\\'''\\'", "",         0);
20235     execute_and_test(&query, '\'', 0, "a\\`",      "a\\`",     1);
20236     execute_and_test(&query, '\'', 0, "a\\n",      "a\\n",     1);
20237     execute_and_test(&query, '\'', 0, "a``",       "a``",      1);
20238     execute_and_test(&query, '\'', 0, "a\\``\\`",  "a\\``\\`", 1);
20239     execute_and_test(&query, '\'', 0, "b\"",       "b\"",      1);
20240     execute_and_test(&query, '\'', 0, "b\"\"",     "b\"\"",    1);
20241     execute_and_test(&query, '\'', 0, "b\\$",      "b\\$",     1);
20242     execute_and_test(&query, '\'', 0, "b\\\\\"",   "b\\\\\"",  1);
20243     execute_and_test(&query, '\'', 0, "b\\\"\"",   "b\\\"\"",  1);
20244     execute_and_test(&query, '"',  1, "b\\\"\"\"", "",         0);
20245     execute_and_test(&query, '"',  i, "d\\'e",     "d\\'e",    1);
20246     execute_and_test(&query, '`',  1, "",          "",         1);
20247   }
20248 
20249   stmt_text = "DROP TABLE t1";
20250   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20251   myquery(rc);
20252 
20253   stmt_text = "SET sql_mode=''";
20254   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20255   myquery(rc);
20256 
20257   query.create= "CREATE TABLE %s (a INT)";
20258   query.drop= "DROP TABLE %s";
20259   query.select= "SHOW TABLES";
20260 
20261   execute_and_test(&query, '`', 0, "ccc",     "ccc",     1);
20262   execute_and_test(&query, '`', 0, "c``cc",   "c`cc",    1);
20263   execute_and_test(&query, '`', 0, "c'cc",    "c'cc",    1);
20264   execute_and_test(&query, '`', 0, "c''cc",   "c''cc",   1);
20265   execute_and_test(&query, '`', 1, "c\\`cc",  "",        0);
20266   execute_and_test(&query, '`', 0, "c\"cc",   "c\"cc",   1);
20267   execute_and_test(&query, '`', 0, "c\\\"cc", "c\\\"cc", 1);
20268   execute_and_test(&query, '`', 0, "c\"\"cc", "c\"\"cc", 1);
20269 
20270   stmt_text = "SET sql_mode='ANSI_QUOTES'";
20271   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20272   myquery(rc);
20273 
20274   execute_and_test(&query, '"', 0, "a\"\"a", "a\"a",   0);
20275   execute_and_test(&query, '"', 1, "a\\\"b", "",       0);
20276   execute_and_test(&query, '"', 0, "c\\'cc", "c\\'cc", 0);
20277 
20278   modes[0]= "SET sql_mode='NO_BACKSLASH_ESCAPES'";
20279   modes[1]= "SET sql_mode='NO_BACKSLASH_ESCAPES,ANSI_QUOTES'";
20280 
20281   for (i = 0; i < (int)(sizeof(modes)/sizeof(modes[0])); i++)
20282   {
20283     rc = mysql_real_query(mysql, modes[i], (ulong)strlen(modes[i]));
20284     myquery(rc);
20285 
20286     execute_and_test(&query, '`', 0, "ccc",     "ccc",     1);
20287     execute_and_test(&query, '`', 0, "c``cc",   "c`cc",    1);
20288     execute_and_test(&query, '`', 0, "c'cc",    "c'cc",    1);
20289     execute_and_test(&query, '`', 0, "c''cc",   "c''cc",   1);
20290     execute_and_test(&query, '`', 1, "c\\`cc",  "",        0);
20291     execute_and_test(&query, '`', 0, "c\"cc",   "c\"cc",   1);
20292     execute_and_test(&query, '`', 0, "c\\\"cc", "c\\\"cc", 1);
20293     execute_and_test(&query, '`', 0, "c\"\"cc", "c\"\"cc", 1);
20294   }
20295 
20296   stmt_text = "DROP DATABASE supertest";
20297   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20298   myquery(rc);
20299 }
20300 
20301 
20302 /**
20303   Bug#20444737  STRING::CHOP ASSERTS ON NAUGHTY TABLE NAMES
20304 */
test_bug20444737()20305 static void test_bug20444737()
20306 {
20307   char query[MAX_TEST_QUERY_LENGTH];
20308   FILE       *test_file;
20309   char       *master_test_filename;
20310   ulong length;
20311   int rc;
20312   const char *test_dir= getenv("MYSQL_TEST_DIR");
20313   const char db_query[]="USE client_test_db";
20314 
20315   myheader("Test_bug20444737");
20316   master_test_filename = (char *) malloc(strlen(test_dir) +
20317                          strlen("/std_data/bug20444737.sql") + 1);
20318   strxmov(master_test_filename, test_dir, "/std_data/bug20444737.sql", NullS);
20319   if (!opt_silent)
20320     fprintf(stdout, "Opening '%s'\n", master_test_filename);
20321   test_file= my_fopen(master_test_filename, (int)(O_RDONLY | O_BINARY), MYF(0));
20322   if (test_file == NULL)
20323   {
20324     fprintf(stderr, "Error in opening file");
20325     free(master_test_filename);
20326     DIE("File open error");
20327   }
20328   else if(fgets(query, MAX_TEST_QUERY_LENGTH, test_file) == NULL)
20329   {
20330     free(master_test_filename);
20331     /* If fgets returned NULL, it indicates either error or EOF */
20332     if (feof(test_file))
20333       DIE("Found EOF before all statements were found");
20334 
20335     fprintf(stderr, "Got error %d while reading from file\n",
20336             ferror(test_file));
20337     DIE("Read error");
20338   }
20339 
20340   rc= mysql_real_query(mysql, db_query, (ulong)strlen(db_query));
20341   myquery(rc);
20342   length= (ulong)strlen(query);
20343   fprintf(stdout, "Query is %s\n", query);
20344   rc= mysql_real_query(mysql, query, (ulong)length);
20345   myquery(rc);
20346 
20347   free(master_test_filename);
20348   my_fclose(test_file, MYF(0));
20349 }
20350 
20351 
20352 /**
20353   Bug#21104470 WL8132:ASSERTION `! IS_SET()' FAILED.
20354 */
test_bug21104470()20355 static void test_bug21104470()
20356 {
20357   MYSQL_RES *result;
20358   int rc;
20359 
20360   myheader("test_bug21104470");
20361 
20362   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20363   myquery(rc);
20364 
20365   rc= mysql_query(mysql, "CREATE TABLE t1(j1 JSON, j2 JSON NOT NULL)");
20366   myquery(rc);
20367 
20368   /* This call used to crash the server. */
20369   result= mysql_list_fields(mysql, "t1", NULL);
20370   mytest(result);
20371 
20372   rc= my_process_result_set(result);
20373   DIE_UNLESS(rc == 0);
20374 
20375   verify_prepare_field(result, 0, "j1", "j1", MYSQL_TYPE_JSON,
20376                        "t1", "t1", current_db, UINT_MAX32, 0);
20377 
20378   verify_prepare_field(result, 1, "j2", "j2", MYSQL_TYPE_JSON,
20379                        "t1", "t1", current_db, UINT_MAX32, 0);
20380 
20381   mysql_free_result(result);
20382   myquery(mysql_query(mysql, "DROP TABLE t1"));
20383 }
20384 
20385 
20386 /**
20387   Bug#21293012 ASSERT `!IS_NULL()' FAILED AT FIELD_JSON::VAL_JSON
20388   ON NEW CONN TO DB WITH VIEW
20389 */
test_bug21293012()20390 static void test_bug21293012()
20391 {
20392   MYSQL_RES *result;
20393   int rc;
20394 
20395   myheader("test_bug21293012");
20396 
20397   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20398   myquery(rc);
20399 
20400   rc= mysql_query(mysql, "CREATE TABLE t1(j1 JSON, j2 JSON NOT NULL)");
20401   myquery(rc);
20402 
20403   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
20404   myquery(rc);
20405 
20406   /* This call used to crash the server. */
20407   result= mysql_list_fields(mysql, "v1", NULL);
20408   mytest(result);
20409 
20410   rc= my_process_result_set(result);
20411   DIE_UNLESS(rc == 0);
20412 
20413   verify_prepare_field(result, 0, "j1", "j1", MYSQL_TYPE_JSON,
20414                        "v1", "v1", current_db, UINT_MAX32, 0);
20415 
20416   verify_prepare_field(result, 1, "j2", "j2", MYSQL_TYPE_JSON,
20417                        "v1", "v1", current_db, UINT_MAX32, 0);
20418 
20419   mysql_free_result(result);
20420   myquery(mysql_query(mysql, "DROP VIEW v1"));
20421   myquery(mysql_query(mysql, "DROP TABLE t1"));
20422 }
20423 
test_bug21199582()20424 static void test_bug21199582()
20425 {
20426   int rc= 0;
20427   int recCnt[]={3,4,1};
20428   int i= 0;
20429 	char query[512]={0};
20430 	MYSQL_BIND in_param_bind;
20431   MYSQL_BIND out_param_bind2;
20432   int in_data= 0;
20433   char cout_data[100]={0};
20434   int rows_number= 0;
20435   int num_fields= 0;
20436   MYSQL_RES *result = NULL;
20437   MYSQL_STMT *stmt;
20438   unsigned long cur_type= CURSOR_TYPE_READ_ONLY;
20439   int iLoop= 0;
20440 
20441   myheader("test_bug21199582");
20442 
20443   for (; i < 2; ++i)
20444   {
20445     iLoop= 0;
20446 
20447     myquery(mysql_query(mysql, "drop procedure if exists p3"));
20448     myquery(mysql_query(mysql, "drop table if exists abcd"));
20449     myquery(mysql_query(mysql, "create table abcd(id int,c char(4))"));
20450     myquery(mysql_query(mysql, "insert into abcd values(1,'a'),(2,'b'),(3,'c')"));
20451 
20452     if(i)
20453     {
20454       sprintf(query,"create procedure p3(INOUT p1 Integer) BEGIN select c from abcd;insert into abcd values(4,'d');"
20455       "select id from abcd;SET NAMES 'utf8';set autocommit = ON;SET p1 = 9999;END");
20456     }
20457     else
20458     {
20459       sprintf(query,"create procedure p3(INOUT p1 Integer) BEGIN select id from abcd;insert into abcd values(4,'d');"
20460       "select id from abcd;SET NAMES 'utf8';set autocommit = ON;SET p1 = 9999;END");
20461     }
20462 
20463     rc = mysql_query(mysql, query);
20464     DIE_UNLESS(rc == 0);
20465 
20466     stmt= mysql_stmt_init(mysql);
20467     DIE_UNLESS(stmt);
20468 
20469     rc = mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &cur_type);
20470     DIE_UNLESS(rc == 0);
20471 
20472     sprintf(query,"call p3(?)");
20473     rc = mysql_stmt_prepare(stmt, query, strlen(query));
20474     DIE_UNLESS(rc == 0);
20475 
20476     memset(&in_param_bind,0,sizeof(in_param_bind));
20477     memset(&out_param_bind2,0,sizeof(out_param_bind2));
20478     in_data= 0;
20479     in_param_bind.buffer_type= MYSQL_TYPE_LONG;
20480     in_param_bind.buffer= (char *) &in_data;
20481     in_param_bind.length= 0;
20482     in_param_bind.is_null= 0;
20483 
20484     out_param_bind2.buffer_type= MYSQL_TYPE_STRING;
20485     out_param_bind2.buffer= (char *) cout_data;
20486     out_param_bind2.length= 0;
20487     out_param_bind2.is_null= 0;
20488     out_param_bind2.buffer_length= (ulong)sizeof(cout_data);
20489 
20490     rc= mysql_stmt_bind_param(stmt, &in_param_bind);
20491     check_execute(stmt, rc);
20492 
20493     rc= mysql_stmt_execute(stmt);
20494     check_execute(stmt, rc);
20495 
20496     rows_number= 0;
20497 
20498     do
20499     {
20500       num_fields = mysql_stmt_field_count(stmt);
20501 
20502       if(num_fields > 0)
20503       {
20504         memset(cout_data,0,sizeof(cout_data));
20505         result = mysql_stmt_result_metadata(stmt);
20506         if(result)
20507         {
20508           rows_number= mysql_stmt_num_rows(stmt);
20509           DIE_UNLESS(rows_number == recCnt[iLoop]);
20510 
20511           rc= mysql_stmt_bind_result(stmt, &out_param_bind2);
20512           check_execute(stmt, rc);
20513 
20514           while (!mysql_stmt_fetch(stmt));
20515 
20516           mysql_free_result(result);
20517         }
20518       }
20519       rc= mysql_stmt_next_result(stmt);
20520       ++iLoop;
20521     }
20522     while(rc==0);
20523 
20524     rc= mysql_stmt_free_result(stmt);
20525     DIE_UNLESS(rc == 0);
20526 
20527     mysql_stmt_close(stmt);
20528   }
20529 }
20530 
20531 
20532 /**
20533   Bug#20821550 ADD MYSQL_GET_PARAMETERS FUNCTIONALITY TO MYSQL_GET_OPTION()
20534 */
test_bug20821550()20535 static void test_bug20821550()
20536 {
20537   MYSQL *mysql_ptr= NULL;
20538   int ret_val;
20539   ulong max_allowed_packet_value= 8192*2;
20540   ulong net_buffer_length_value= 8192*4;
20541   ulong save_max_allowed_packet_value= 0;
20542   ulong save_net_buffer_length_value= 0;
20543   ulong ret_max_allowed_packet_value= 0;
20544   ulong ret_net_buffer_length_value= 0;
20545 
20546   myheader("test_bug20821550");
20547 
20548   /* Try setting/getting values without MYSQL object */
20549 
20550   /* Fetch default values and validate */
20551   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20552                             &save_max_allowed_packet_value);
20553   DIE_UNLESS(ret_val == 0);
20554   DIE_UNLESS(save_max_allowed_packet_value == 1024L*1024L*1024L);
20555 
20556   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20557                             &save_net_buffer_length_value);
20558   DIE_UNLESS(ret_val == 0);
20559   DIE_UNLESS(save_net_buffer_length_value == 8192);
20560 
20561   /* Now set global values */
20562   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20563                          &max_allowed_packet_value);
20564   DIE_UNLESS(ret_val == 0);
20565 
20566   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20567                          &net_buffer_length_value);
20568   DIE_UNLESS(ret_val == 0);
20569 
20570   /* Check that global values are set */
20571   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20572                             &ret_max_allowed_packet_value);
20573   DIE_UNLESS(ret_val == 0);
20574   DIE_UNLESS(ret_max_allowed_packet_value == max_allowed_packet_value);
20575 
20576   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20577                             &ret_net_buffer_length_value);
20578   DIE_UNLESS(ret_val == 0);
20579   DIE_UNLESS(ret_net_buffer_length_value == net_buffer_length_value);
20580 
20581   /* Restore default values */
20582   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20583                          &save_max_allowed_packet_value);
20584   DIE_UNLESS(ret_val == 0);
20585 
20586   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20587                          &save_net_buffer_length_value);
20588   DIE_UNLESS(ret_val == 0);
20589 
20590   /* Create MYSQL object */
20591 
20592   if (!(mysql_ptr= mysql_client_init(NULL)))
20593   {
20594     myerror("mysql_client_init() failed");
20595     exit(1);
20596   }
20597 
20598   /* Now try setting/getting values with MYSQL object */
20599 
20600   mysql_ptr= mysql_real_connect(mysql_ptr, opt_host, opt_user, opt_password,
20601                                 "test", opt_port, opt_unix_socket, 0);
20602 
20603   /* By default, session values of max_allowed_packet is 0 */
20604   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20605                             &ret_max_allowed_packet_value);
20606   DIE_UNLESS(ret_val == 0);
20607   DIE_UNLESS(ret_max_allowed_packet_value == 0);
20608 
20609   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20610                             &ret_net_buffer_length_value);
20611   DIE_UNLESS(ret_val == 0);
20612   DIE_UNLESS(ret_net_buffer_length_value == save_net_buffer_length_value);
20613 
20614   DIE_UNLESS(mysql_ptr->net.max_packet_size == save_max_allowed_packet_value);
20615 
20616   mysql_close(mysql_ptr);
20617 
20618   if (!(mysql_ptr= mysql_client_init(NULL)))
20619   {
20620     myerror("mysql_client_init() failed");
20621     exit(1);
20622   }
20623 
20624   /* Set session value for max_allowed_packet */
20625   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20626                          &max_allowed_packet_value);
20627   DIE_UNLESS(ret_val == 0);
20628 
20629   /* net_buffer_length only has global value */
20630   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20631                          &net_buffer_length_value);
20632   DIE_UNLESS(ret_val == 0);
20633 
20634   /* Get session value of max_allowed_packet */
20635   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20636                             &ret_max_allowed_packet_value);
20637   DIE_UNLESS(ret_val == 0);
20638   DIE_UNLESS(ret_max_allowed_packet_value == max_allowed_packet_value);
20639 
20640   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20641                             &ret_net_buffer_length_value);
20642   DIE_UNLESS(ret_val == 0);
20643   DIE_UNLESS(ret_net_buffer_length_value == net_buffer_length_value);
20644 
20645   /* mysql_real_connect() prefers session value of max_allowed_packet */
20646   mysql_ptr= mysql_real_connect(mysql_ptr, opt_host, opt_user, opt_password,
20647                                 "test", opt_port, opt_unix_socket, 0);
20648 
20649   /* Session value is used for net.max_allowed_size */
20650   DIE_UNLESS(mysql_ptr->net.max_packet_size == max_allowed_packet_value);
20651 
20652   /* Get global value of max_allowed_packet */
20653   ret_val= mysql_get_option(NULL, MYSQL_OPT_MAX_ALLOWED_PACKET,
20654                             &ret_max_allowed_packet_value);
20655   DIE_UNLESS(ret_val == 0);
20656   DIE_UNLESS(ret_max_allowed_packet_value == save_max_allowed_packet_value);
20657 
20658   mysql_close(mysql_ptr);
20659 
20660 }
20661 
check_warning(MYSQL * conn)20662 static void check_warning(MYSQL *conn)
20663 {
20664   MYSQL_RES *result;
20665   int        rc;
20666 
20667   rc= mysql_query(conn, "SHOW WARNINGS");
20668   myquery(rc);
20669   result= mysql_store_result(conn);
20670   mytest(result);
20671   rc= my_process_result_set(result);
20672   DIE_UNLESS(rc == 1);
20673   mysql_free_result(result);
20674 }
20675 
test_wl8754()20676 static void test_wl8754()
20677 {
20678   MYSQL_RES     *res;
20679   MYSQL         *conn;
20680   int           rc;
20681   unsigned long thread_id;
20682   const char    *stmt_text;
20683 
20684   myheader("test_wl8754");
20685 
20686   /* Check that mysql_list_fields reports deprecated warning. */
20687   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20688   myquery(rc);
20689   stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
20690   rc= mysql_real_query(mysql, stmt_text, (ulong) strlen(stmt_text));
20691   myquery(rc);
20692 
20693   res= mysql_list_fields(mysql, "t1", "%");
20694   mysql_free_result(res);
20695 
20696   check_warning(mysql);
20697 
20698   stmt_text= "DROP TABLE t1";
20699   rc= mysql_real_query(mysql, stmt_text, (ulong) strlen(stmt_text));
20700   myquery(rc);
20701 
20702   /* Check that mysql_refresh() reports deprecated warning. */
20703   rc= mysql_refresh(mysql, REFRESH_TABLES);
20704   myquery(rc);
20705 
20706   check_warning(mysql);
20707 
20708   /* Run a dummy query to clear diagnostics. */
20709   rc= mysql_query(mysql, "SELECT 1");
20710   myquery(rc);
20711   /* Get the result. */
20712   res= mysql_store_result(mysql);
20713   mytest(res);
20714   (void) my_process_result_set(res);
20715   mysql_free_result(res);
20716 
20717   /* Check that mysql_list_processes() reports deprecated warning. */
20718   res= mysql_list_processes(mysql);
20719   mysql_free_result(res);
20720 
20721   check_warning(mysql);
20722 
20723   /* Check that mysql_kill() reports deprecated warning. */
20724   if (!(conn= mysql_client_init(NULL)))
20725   {
20726     myerror("mysql_client_init() failed");
20727     exit(1);
20728   }
20729   conn->reconnect= 1;
20730   if (!(mysql_real_connect(conn, opt_host, opt_user,
20731                            opt_password, current_db, opt_port,
20732                            opt_unix_socket, 0)))
20733   {
20734     myerror("connection failed");
20735     exit(1);
20736   }
20737   thread_id= mysql_thread_id(conn);
20738   /*
20739     Kill connection would have killed the existing connection which clears
20740     the THD state and reconnects with a new THD thus there will be no
20741     warnings.
20742   */
20743   mysql_kill(conn, (unsigned long) thread_id);
20744   mysql_close(conn);
20745  }
20746 
20747 /*
20748   BUG#17883203: MYSQL EMBEDDED MYSQL_STMT_EXECUTE RETURN
20749                 "MALFORMED COMMUNICATION PACKET" ERROR
20750 */
20751 #define BUG17883203_STRING_SIZE 100
20752 
test_bug17883203()20753 static void test_bug17883203()
20754 {
20755   MYSQL_STMT *stmt;
20756   MYSQL_BIND bind;
20757   char str_data[BUG17883203_STRING_SIZE];
20758   my_bool is_null;
20759   my_bool error;
20760   unsigned long length;
20761   const char stmt_text[] ="SELECT VERSION()";
20762   int rc;
20763 
20764   myheader("test_bug17883203");
20765 
20766   stmt = mysql_stmt_init(mysql);
20767   check_stmt(stmt);
20768   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
20769   check_execute(stmt, rc);
20770   rc= mysql_stmt_execute(stmt);
20771   check_execute(stmt, rc);
20772   memset(&bind, 0, sizeof(bind));
20773 
20774   bind.buffer_type= MYSQL_TYPE_STRING;
20775   bind.buffer= (char *)str_data;
20776   bind.buffer_length= BUG17883203_STRING_SIZE;
20777   bind.is_null= &is_null;
20778   bind.length= &length;
20779   bind.error= &error;
20780 
20781   rc= mysql_stmt_bind_result(stmt, &bind);
20782   check_execute(stmt, rc);
20783   rc= mysql_stmt_fetch(stmt);
20784   check_execute(stmt, rc);
20785 
20786   if (!opt_silent)
20787   {
20788     fprintf(stdout, "\n Version: %s", str_data);
20789   }
20790   mysql_stmt_close(stmt);
20791 }
20792 
20793 /*
20794   Bug#22559575: "the statement (1) has no open cursor" pops
20795                 sometimes with prepared+query_cache
20796 */
bug22559575_base(unsigned long type)20797 static void bug22559575_base(unsigned long type)
20798 {
20799   MYSQL_STMT *stmt;
20800   int rc;
20801   const char stmt_text[] ="SELECT a FROM t22559575";
20802   MYSQL_RES *prepare_meta = NULL;
20803   MYSQL_BIND bind[1];
20804   short data;
20805   unsigned long length;
20806 
20807   stmt = mysql_stmt_init(mysql);
20808   check_stmt(stmt);
20809   if (type == CURSOR_TYPE_READ_ONLY)
20810   {
20811     rc = mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*)&type);
20812     check_execute(stmt, rc);
20813   }
20814   rc = mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
20815   check_execute(stmt, rc);
20816   prepare_meta = mysql_stmt_result_metadata(stmt);
20817   DIE_UNLESS(prepare_meta != NULL);
20818   rc= mysql_stmt_execute(stmt);
20819   check_execute(stmt, rc);
20820 
20821   memset(bind, 0, sizeof(bind));
20822   bind[0].buffer_type= MYSQL_TYPE_SHORT;
20823   bind[0].buffer= (void *)&data;
20824   bind[0].length= &length;
20825   rc= mysql_stmt_bind_result(stmt, bind);
20826   check_execute(stmt, rc);
20827 
20828   rc= mysql_stmt_store_result(stmt);
20829   check_execute(stmt, rc);
20830 
20831   rc= mysql_stmt_fetch(stmt);
20832   check_execute(stmt, rc);
20833   DIE_UNLESS(data == 1);
20834 
20835   mysql_free_result(prepare_meta);
20836   rc= mysql_stmt_close(stmt);
20837   check_execute(stmt, rc);
20838 }
20839 
test_bug22559575()20840 static void test_bug22559575()
20841 {
20842   int rc;
20843 
20844   rc= mysql_query(mysql, "CREATE TABLE t22559575(a SMALLINT)");
20845   myquery(rc);
20846   rc= mysql_query(mysql, "INSERT INTO t22559575 VALUES (1)");
20847   myquery(rc);
20848 
20849   /* Should not cache */
20850   bug22559575_base(CURSOR_TYPE_READ_ONLY);
20851   bug22559575_base(CURSOR_TYPE_READ_ONLY);
20852   /* Should save to cache */
20853   bug22559575_base(CURSOR_TYPE_NO_CURSOR);
20854   /* Should use cache */
20855   bug22559575_base(CURSOR_TYPE_NO_CURSOR);
20856   /* should not use cache */
20857   bug22559575_base(CURSOR_TYPE_READ_ONLY);
20858 
20859   rc= mysql_query(mysql, "DROP TABLE t22559575");
20860   myquery(rc);
20861 }
20862 
20863 
20864 /**
20865    BUG#19894382 - SERVER SIDE PREPARED STATEMENTS LEADS TO POTENTIAL OFF-BY-SECOND
20866                   TIMESTAMP ON SLAVE
20867 */
test_bug19894382()20868 static void test_bug19894382()
20869 {
20870   MYSQL_STMT *stmt1;
20871   const char *stmt1_txt= "INSERT INTO client_test_db.bug19894382 VALUES"
20872                          " ('master', ?, ?, ?, ?, ?, ?);";
20873   my_bool    is_null= 0;
20874   MYSQL_BIND bind_val[6];
20875   MYSQL_TIME tm[6];
20876   MYSQL_TIME tm_common;
20877   ulong      length= sizeof(MYSQL_TIME);
20878   int ind;
20879   int rc;
20880 
20881   myheader("test_bug19894382");
20882 
20883   rc= mysql_query(mysql, "DROP TABLE IF EXISTS client_test_db.bug19894382;");
20884   myquery(rc);
20885   rc= mysql_query(mysql, "CREATE TABLE client_test_db.bug19894382(f1 CHAR(64),"
20886                          " f2 TIME, f3 TIMESTAMP NULL, f4 DATETIME,"
20887                          " f5 TIME(3), f6 TIMESTAMP(3) NULL,"
20888                          " f7 DATETIME(3));");
20889   myquery(rc);
20890 
20891   stmt1 = mysql_stmt_init(mysql);
20892   check_stmt(stmt1);
20893 
20894   // Prepare statement
20895   rc= mysql_stmt_prepare(stmt1, stmt1_txt, strlen(stmt1_txt));
20896   check_execute(stmt1, rc);
20897 
20898   // Prepare and bind values.
20899   tm_common.year= 2015;
20900   tm_common.month= 4;
20901   tm_common.day= 24;
20902   tm_common.hour= 7;
20903   tm_common.minute= 30;
20904   tm_common.second= 30;
20905   tm_common.second_part= 5010;
20906   tm_common.neg= 0;
20907   tm_common.time_type= MYSQL_TIMESTAMP_NONE;
20908 
20909   memset(bind_val, 0, sizeof(MYSQL_BIND) * 6);
20910   for (ind= 0; ind < 6; ind++)
20911   {
20912     tm[ind]= tm_common;
20913     bind_val[ind].buffer= (void *) &tm[ind];
20914     bind_val[ind].is_null= &is_null;
20915     bind_val[ind].length= &length;
20916     bind_val[ind].buffer_length= sizeof(MYSQL_TIME);
20917     switch(ind%3)
20918     {
20919     case 0:
20920       tm[ind].year= tm[ind].month= tm[ind].day= 0;
20921       bind_val[ind].buffer_type= MYSQL_TYPE_TIME;
20922       tm[ind].time_type= MYSQL_TIMESTAMP_TIME;
20923       break;
20924     case 1:
20925       bind_val[ind].buffer_type= MYSQL_TYPE_TIMESTAMP;
20926       tm[ind].time_type= MYSQL_TIMESTAMP_DATETIME;
20927       break;
20928     case 2:
20929       bind_val[ind].buffer_type= MYSQL_TYPE_DATETIME;
20930       tm[ind].time_type= MYSQL_TIMESTAMP_DATETIME;
20931       break;
20932     }
20933   }
20934   rc= mysql_stmt_bind_param(stmt1, bind_val);
20935   check_execute(stmt1, rc);
20936 
20937   /* Execute the insert statement */
20938   rc= mysql_stmt_execute(stmt1);
20939   check_execute(stmt1, rc);
20940   for (ind= 0; ind < 6; ind++)
20941   {
20942     tm[ind].second_part= 501900;
20943   }
20944   /* Execute the insert statement */
20945   rc= mysql_stmt_execute(stmt1);
20946   check_execute(stmt1, rc);
20947 
20948   rc= mysql_commit(mysql);
20949   myquery(rc);
20950 
20951   mysql_stmt_close(stmt1);
20952 }
20953 
test_bug25701141()20954 static void test_bug25701141()
20955 {
20956   MYSQL_STMT *stmt;
20957   int rc;
20958   MYSQL_BIND my_bind[2];
20959   char query[MAX_TEST_QUERY_LENGTH];
20960   const char* input1= "abcdefgh";
20961   const char* input2=  "mnopqrst";
20962   const ulong type = CURSOR_TYPE_READ_ONLY;
20963 
20964   myheader("test_bug25701141");
20965 
20966   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20967   myquery(rc);
20968 
20969   rc= mysql_query(mysql, "CREATE TABLE t1( "
20970       "id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,"
20971       "serial CHAR(10) NOT NULL,"
20972       "pretty CHAR(20) DEFAULT NULL,"
20973       "CONSTRAINT UNIQUE KEY unique_serial (serial) USING HASH,"
20974       "INDEX pretty_index USING HASH (pretty)"
20975       ") ENGINE = InnoDB CHARSET = utf8 COLLATE = utf8_bin");
20976   myquery(rc);
20977 
20978   my_stpcpy(query, "INSERT IGNORE INTO t1 SET `serial`=?, `pretty`=?");
20979   stmt= mysql_simple_prepare(mysql, query);
20980   check_stmt(stmt);
20981 
20982   memset(my_bind, 0, sizeof(my_bind));
20983   my_bind[0].buffer_type = MYSQL_TYPE_STRING;
20984   my_bind[0].buffer = (char*)input1;
20985   my_bind[0].buffer_length = (ulong)strlen(input1);
20986 
20987   my_bind[1].buffer_type = MYSQL_TYPE_STRING;
20988   my_bind[1].buffer = (char*)input2;
20989   my_bind[1].buffer_length = (ulong)strlen(input2);
20990 
20991   rc= mysql_stmt_bind_param(stmt, my_bind);
20992   check_execute(stmt, rc);
20993   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &type);
20994 
20995   /* Execute */
20996   rc= mysql_stmt_execute(stmt);
20997   check_execute(stmt, rc);
20998   mysql_stmt_close(stmt);
20999 
21000   myquery(mysql_query(mysql, "DROP TABLE t1"));
21001 }
21002 
test_bug27443252()21003 static void test_bug27443252()
21004 {
21005   MYSQL_STMT *stmt;
21006   MYSQL_BIND my_bind[1];
21007   int rc;
21008   int32 a;
21009   int row_count=0;
21010   int column_count=0;
21011   MYSQL_RES *metadata = NULL;
21012 
21013   myheader("test_bug27443252");
21014 
21015   rc= mysql_query(mysql, "drop procedure if exists p1");
21016   myquery(rc);
21017   rc= mysql_query(mysql, "drop table if exists p1");
21018   myquery(rc);
21019   rc= mysql_query(mysql, "create table t1 (id int)");
21020   myquery(rc);
21021   rc= mysql_query(mysql, "create procedure p1() begin select * from t1; end");
21022   myquery(rc);
21023 
21024   /* Case 1 - Procedure call with empty result set */
21025   stmt= open_cursor("call p1");
21026   /* This should not result in hang */
21027   rc= mysql_stmt_execute(stmt);
21028   check_execute(stmt, rc);
21029 
21030   metadata = mysql_stmt_result_metadata(stmt);
21031   if (metadata)
21032   {
21033     column_count = mysql_num_fields(metadata);
21034     DIE_UNLESS(column_count == 1);
21035   }
21036 
21037   memset(my_bind, 0, sizeof(my_bind));
21038   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
21039   my_bind[0].buffer= (void*)&a;
21040   my_bind[0].buffer_length= (ulong)sizeof(a);
21041   rc= mysql_stmt_bind_result(stmt, my_bind);
21042   check_execute(stmt, rc);
21043 
21044   while (!mysql_stmt_fetch(stmt))
21045     row_count++;
21046   DIE_UNLESS(row_count == 0);
21047 
21048   rc = mysql_stmt_next_result(stmt);
21049   check_execute(stmt, rc);
21050   rc= mysql_stmt_free_result(stmt);
21051   check_execute(stmt, rc);
21052   mysql_free_result(metadata);
21053   mysql_stmt_close(stmt);
21054 
21055   /* Case 2 - SELECT with empty result set */
21056   row_count= 0;
21057   stmt= open_cursor("select * from t1");
21058   rc= mysql_stmt_execute(stmt);
21059   check_execute(stmt, rc);
21060 
21061   memset(my_bind, 0, sizeof(my_bind));
21062   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
21063   my_bind[0].buffer= (void*)&a;
21064   my_bind[0].buffer_length= (ulong)sizeof(a);
21065 
21066   rc= mysql_stmt_bind_result(stmt, my_bind);
21067   check_execute(stmt, rc);
21068 
21069   while (!mysql_stmt_fetch(stmt))
21070     row_count++;
21071   DIE_UNLESS(row_count == 0);
21072   mysql_stmt_close(stmt);
21073 
21074   /* Case 3 - Procedure call with non-empty result set */
21075   rc= mysql_query(mysql, "insert into t1 (id) values "
21076                           " (1), (2), (3)");
21077   myquery(rc);
21078   row_count= 0;
21079   stmt= open_cursor("call p1");
21080   rc= mysql_stmt_execute(stmt);
21081   check_execute(stmt, rc);
21082 
21083   memset(my_bind, 0, sizeof(my_bind));
21084   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
21085   my_bind[0].buffer= (void*)&a;
21086   my_bind[0].buffer_length= (ulong)sizeof(a);
21087   rc= mysql_stmt_bind_result(stmt, my_bind);
21088   check_execute(stmt, rc);
21089 
21090   while (!mysql_stmt_fetch(stmt))
21091     row_count++;
21092   DIE_UNLESS(row_count == 3);
21093 
21094   rc = mysql_stmt_next_result(stmt);
21095   check_execute(stmt, rc);
21096   rc= mysql_stmt_free_result(stmt);
21097   check_execute(stmt, rc);
21098   mysql_stmt_close(stmt);
21099 
21100   /* Case 4 - SELECT with Non-empty result set */
21101   row_count= 0;
21102   stmt= open_cursor("select * from t1");
21103   rc= mysql_stmt_execute(stmt);
21104   check_execute(stmt, rc);
21105 
21106   memset(my_bind, 0, sizeof(my_bind));
21107   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
21108   my_bind[0].buffer= (void*)&a;
21109   my_bind[0].buffer_length= (ulong)sizeof(a);
21110   rc= mysql_stmt_bind_result(stmt, my_bind);
21111   check_execute(stmt, rc);
21112 
21113   while (!mysql_stmt_fetch(stmt))
21114     row_count++;
21115   DIE_UNLESS(row_count == 3);
21116 
21117   rc= mysql_stmt_free_result(stmt);
21118   check_execute(stmt, rc);
21119   mysql_stmt_close(stmt);
21120 
21121   /* Cleanup */
21122   rc= mysql_query(mysql, "drop table t1");
21123   myquery(rc);
21124   rc= mysql_query(mysql, "drop procedure p1");
21125   myquery(rc);
21126 }
21127 
21128 
test_bug32391415()21129 static void test_bug32391415()
21130 {
21131   MYSQL *lmysql;
21132   MYSQL_ROW row;
21133   MYSQL_RES *res;
21134   int rc;
21135 
21136   myheader("test_bug32391415");
21137 
21138   lmysql= mysql_client_init(NULL);
21139   DIE_UNLESS(lmysql != NULL);
21140 
21141   lmysql= mysql_real_connect(lmysql, opt_host, opt_user,
21142                          opt_password, current_db, opt_port,
21143                          opt_unix_socket, 0);
21144   DIE_UNLESS(lmysql != 0);
21145   if (!opt_silent)
21146     fprintf(stdout, "Established a test connection\n");
21147 
21148   rc= mysql_query(lmysql, "CREATE USER b32391415@localhost");
21149   myquery2(lmysql, rc);
21150   rc= mysql_query(lmysql, "GRANT ALL PRIVILEGES ON *.* TO b32391415@localhost");
21151   myquery2(lmysql, rc);
21152 
21153   if (!opt_silent)
21154     fprintf(stdout, "Created the user\n");
21155 
21156   /* put in an attr */
21157   rc= mysql_options4(lmysql, MYSQL_OPT_CONNECT_ATTR_ADD,
21158                      "key1", "value1");
21159   DIE_UNLESS(rc == 0);
21160 
21161   rc= mysql_change_user(lmysql, "b32391415", NULL, NULL);
21162   myquery2(lmysql, rc);
21163 
21164   /* success: the query attribute should be present */
21165   rc= mysql_query(lmysql,
21166                   "SELECT ATTR_NAME, ATTR_VALUE "
21167                   " FROM performance_schema.session_account_connect_attrs"
21168                   " WHERE ATTR_NAME IN ('key1') AND"
21169                   "  PROCESSLIST_ID = CONNECTION_ID() ORDER BY ATTR_NAME");
21170   myquery2(lmysql,rc);
21171   res = mysql_use_result(lmysql);
21172   DIE_UNLESS(res);
21173 
21174   row= mysql_fetch_row(res);
21175   DIE_UNLESS(row);
21176   DIE_UNLESS(0 == strcmp(row[0], "key1"));
21177   DIE_UNLESS(0 == strcmp(row[1], "value1"));
21178   if (!opt_silent)
21179     fprintf(stdout, "Checked the query attribute\n");
21180 
21181   mysql_free_result(res);
21182 
21183   mysql_close(lmysql);
21184 
21185   rc= mysql_query(mysql, "DROP USER b32391415@localhost");
21186   myquery2(mysql, rc);
21187 }
21188 
21189 static struct my_tests_st my_tests[]= {
21190   { "disable_query_logs", disable_query_logs },
21191   { "test_view_sp_list_fields", test_view_sp_list_fields },
21192   { "client_query", client_query },
21193   { "test_prepare_insert_update", test_prepare_insert_update},
21194 #if NOT_YET_WORKING
21195   { "test_drop_temp", test_drop_temp },
21196 #endif
21197   { "test_fetch_seek", test_fetch_seek },
21198   { "test_fetch_nobuffs", test_fetch_nobuffs },
21199   { "test_open_direct", test_open_direct },
21200   { "test_fetch_null", test_fetch_null },
21201   { "test_ps_null_param", test_ps_null_param },
21202   { "test_fetch_date", test_fetch_date },
21203   { "test_fetch_str", test_fetch_str },
21204   { "test_fetch_long", test_fetch_long },
21205   { "test_fetch_short", test_fetch_short },
21206   { "test_fetch_tiny", test_fetch_tiny },
21207   { "test_fetch_bigint", test_fetch_bigint },
21208   { "test_fetch_float", test_fetch_float },
21209   { "test_fetch_double", test_fetch_double },
21210   { "test_bind_result_ext", test_bind_result_ext },
21211   { "test_bind_result_ext1", test_bind_result_ext1 },
21212   { "test_select_direct", test_select_direct },
21213   { "test_select_prepare", test_select_prepare },
21214   { "test_select", test_select },
21215   { "test_select_version", test_select_version },
21216   { "test_ps_conj_select", test_ps_conj_select },
21217   { "test_select_show_table", test_select_show_table },
21218   { "test_func_fields", test_func_fields },
21219   { "test_long_data", test_long_data },
21220   { "test_insert", test_insert },
21221   { "test_set_variable", test_set_variable },
21222   { "test_select_show", test_select_show },
21223   { "test_prepare_noparam", test_prepare_noparam },
21224   { "test_bind_result", test_bind_result },
21225   { "test_prepare_simple", test_prepare_simple },
21226   { "test_prepare", test_prepare },
21227   { "test_null", test_null },
21228   { "test_debug_example", test_debug_example },
21229   { "test_update", test_update },
21230   { "test_simple_update", test_simple_update },
21231   { "test_simple_delete", test_simple_delete },
21232   { "test_double_compare", test_double_compare },
21233   { "client_store_result", client_store_result },
21234   { "client_use_result", client_use_result },
21235   { "test_tran_bdb", test_tran_bdb },
21236   { "test_tran_innodb", test_tran_innodb },
21237   { "test_prepare_ext", test_prepare_ext },
21238   { "test_prepare_syntax", test_prepare_syntax },
21239   { "test_field_names", test_field_names },
21240   { "test_field_flags", test_field_flags },
21241   { "test_long_data_str", test_long_data_str },
21242   { "test_long_data_str1", test_long_data_str1 },
21243   { "test_long_data_bin", test_long_data_bin },
21244   { "test_warnings", test_warnings },
21245   { "test_errors", test_errors },
21246   { "test_prepare_resultset", test_prepare_resultset },
21247   { "test_stmt_close", test_stmt_close },
21248   { "test_prepare_field_result", test_prepare_field_result },
21249   { "test_multi_stmt", test_multi_stmt },
21250   { "test_multi_statements", test_multi_statements },
21251   { "test_prepare_multi_statements", test_prepare_multi_statements },
21252   { "test_store_result", test_store_result },
21253   { "test_store_result1", test_store_result1 },
21254   { "test_store_result2", test_store_result2 },
21255   { "test_subselect", test_subselect },
21256   { "test_date", test_date },
21257   { "test_date_frac", test_date_frac },
21258   { "test_temporal_param", test_temporal_param },
21259   { "test_date_date", test_date_date },
21260   { "test_date_time", test_date_time },
21261   { "test_date_ts", test_date_ts },
21262   { "test_date_dt", test_date_dt },
21263   { "test_prepare_alter", test_prepare_alter },
21264   { "test_manual_sample", test_manual_sample },
21265   { "test_pure_coverage", test_pure_coverage },
21266   { "test_buffers", test_buffers },
21267   { "test_ushort_bug", test_ushort_bug },
21268   { "test_sshort_bug", test_sshort_bug },
21269   { "test_stiny_bug", test_stiny_bug },
21270   { "test_field_misc", test_field_misc },
21271   { "test_set_option", test_set_option },
21272 #ifdef EMBEDDED_LIBRARY
21273   { "test_embedded_start_stop", test_embedded_start_stop },
21274 #endif
21275 #ifndef EMBEDDED_LIBRARY
21276   { "test_prepare_grant", test_prepare_grant },
21277 #endif
21278   { "test_frm_bug", test_frm_bug },
21279   { "test_explain_bug", test_explain_bug },
21280   { "test_decimal_bug", test_decimal_bug },
21281   { "test_nstmts", test_nstmts },
21282   { "test_logs;", test_logs },
21283   { "test_cuted_rows", test_cuted_rows },
21284   { "test_fetch_offset", test_fetch_offset },
21285   { "test_fetch_column", test_fetch_column },
21286   { "test_mem_overun", test_mem_overun },
21287   { "test_list_fields", test_list_fields },
21288   { "test_free_result", test_free_result },
21289   { "test_free_store_result", test_free_store_result },
21290   { "test_sqlmode", test_sqlmode },
21291   { "test_ts", test_ts },
21292   { "test_bug1115", test_bug1115 },
21293   { "test_bug1180", test_bug1180 },
21294   { "test_bug1500", test_bug1500 },
21295   { "test_bug1644", test_bug1644 },
21296   { "test_bug1946", test_bug1946 },
21297   { "test_bug2248", test_bug2248 },
21298   { "test_parse_error_and_bad_length", test_parse_error_and_bad_length },
21299   { "test_bug2247", test_bug2247 },
21300   { "test_subqueries", test_subqueries },
21301   { "test_bad_union", test_bad_union },
21302   { "test_distinct", test_distinct },
21303   { "test_subqueries_ref", test_subqueries_ref },
21304   { "test_union", test_union },
21305   { "test_bug3117", test_bug3117 },
21306   { "test_join", test_join },
21307   { "test_selecttmp", test_selecttmp },
21308   { "test_create_drop", test_create_drop },
21309   { "test_rename", test_rename },
21310   { "test_do_set", test_do_set },
21311   { "test_multi", test_multi },
21312   { "test_insert_select", test_insert_select },
21313   { "test_bind_nagative", test_bind_nagative },
21314   { "test_derived", test_derived },
21315   { "test_xjoin", test_xjoin },
21316   { "test_bug3035", test_bug3035 },
21317   { "test_union2", test_union2 },
21318   { "test_bug1664", test_bug1664 },
21319   { "test_union_param", test_union_param },
21320   { "test_order_param", test_order_param },
21321   { "test_ps_i18n", test_ps_i18n },
21322   { "test_bug3796", test_bug3796 },
21323   { "test_bug4026", test_bug4026 },
21324   { "test_bug4079", test_bug4079 },
21325   { "test_bug4236", test_bug4236 },
21326   { "test_bug4030", test_bug4030 },
21327   { "test_bug5126", test_bug5126 },
21328   { "test_bug4231", test_bug4231 },
21329   { "test_bug5399", test_bug5399 },
21330   { "test_bug5194", test_bug5194 },
21331   { "test_bug5315", test_bug5315 },
21332   { "test_bug6049", test_bug6049 },
21333   { "test_bug6058", test_bug6058 },
21334   { "test_bug6059", test_bug6059 },
21335   { "test_bug6046", test_bug6046 },
21336   { "test_bug6081", test_bug6081 },
21337   { "test_bug6096", test_bug6096 },
21338   { "test_datetime_ranges", test_datetime_ranges },
21339   { "test_bug4172", test_bug4172 },
21340   { "test_conversion", test_conversion },
21341   { "test_rewind", test_rewind },
21342   { "test_bug6761", test_bug6761 },
21343   { "test_view", test_view },
21344   { "test_view_where", test_view_where },
21345   { "test_view_2where", test_view_2where },
21346   { "test_view_star", test_view_star },
21347   { "test_view_insert", test_view_insert },
21348   { "test_left_join_view", test_left_join_view },
21349   { "test_view_insert_fields", test_view_insert_fields },
21350   { "test_basic_cursors", test_basic_cursors },
21351   { "test_cursors_with_union", test_cursors_with_union },
21352   { "test_cursors_with_procedure", test_cursors_with_procedure },
21353   { "test_truncation", test_truncation },
21354   { "test_truncation_option", test_truncation_option },
21355   { "test_client_character_set", test_client_character_set },
21356   { "test_bug8330", test_bug8330 },
21357   { "test_bug7990", test_bug7990 },
21358   { "test_bug8378", test_bug8378 },
21359   { "test_bug8722", test_bug8722 },
21360   { "test_bug8880", test_bug8880 },
21361   { "test_bug9159", test_bug9159 },
21362   { "test_bug9520", test_bug9520 },
21363   { "test_bug9478", test_bug9478 },
21364   { "test_bug9643", test_bug9643 },
21365   { "test_bug10729", test_bug10729 },
21366   { "test_bug11111", test_bug11111 },
21367   { "test_bug9992", test_bug9992 },
21368   { "test_bug10736", test_bug10736 },
21369   { "test_bug10794", test_bug10794 },
21370   { "test_bug11172", test_bug11172 },
21371   { "test_bug11656", test_bug11656 },
21372   { "test_bug10214", test_bug10214 },
21373   { "test_bug21246", test_bug21246 },
21374   { "test_bug9735", test_bug9735 },
21375   { "test_bug11183", test_bug11183 },
21376   { "test_bug11037", test_bug11037 },
21377   { "test_bug10760", test_bug10760 },
21378   { "test_bug12001", test_bug12001 },
21379   { "test_bug11718", test_bug11718 },
21380   { "test_bug12925", test_bug12925 },
21381   { "test_bug11909", test_bug11909 },
21382   { "test_bug11901", test_bug11901 },
21383   { "test_bug11904", test_bug11904 },
21384   { "test_bug12243", test_bug12243 },
21385   { "test_bug14210", test_bug14210 },
21386   { "test_bug13488", test_bug13488 },
21387   { "test_bug13524", test_bug13524 },
21388   { "test_bug14845", test_bug14845 },
21389   { "test_opt_reconnect", test_opt_reconnect },
21390   { "test_bug15510", test_bug15510},
21391 #ifndef EMBEDDED_LIBRARY
21392   { "test_bug12744", test_bug12744 },
21393 #endif
21394   { "test_bug16143", test_bug16143 },
21395   { "test_bug16144", test_bug16144 },
21396   { "test_bug15613", test_bug15613 },
21397   { "test_bug20152", test_bug20152 },
21398   { "test_bug14169", test_bug14169 },
21399   { "test_bug17667", test_bug17667 },
21400   { "test_bug15752", test_bug15752 },
21401   { "test_mysql_insert_id", test_mysql_insert_id },
21402   { "test_bug19671", test_bug19671 },
21403   { "test_bug21206", test_bug21206 },
21404   { "test_bug21726", test_bug21726 },
21405   { "test_bug15518", test_bug15518 },
21406   { "test_bug23383", test_bug23383 },
21407   { "test_bug32265", test_bug32265 },
21408   { "test_bug21635", test_bug21635 },
21409   { "test_status",   test_status   },
21410   { "test_bug24179", test_bug24179 },
21411   { "test_ps_query_cache", test_ps_query_cache },
21412   { "test_bug28075", test_bug28075 },
21413   { "test_bug27876", test_bug27876 },
21414   { "test_bug28505", test_bug28505 },
21415   { "test_bug28934", test_bug28934 },
21416   { "test_bug27592", test_bug27592 },
21417   { "test_bug29687", test_bug29687 },
21418   { "test_bug29692", test_bug29692 },
21419   { "test_bug29306", test_bug29306 },
21420   { "test_change_user", test_change_user },
21421   { "test_bug30472", test_bug30472 },
21422   { "test_bug20023", test_bug20023 },
21423   { "test_bug45010", test_bug45010 },
21424   { "test_bug53371", test_bug53371 },
21425   { "test_bug31418", test_bug31418 },
21426   { "test_bug31669", test_bug31669 },
21427   { "test_bug28386", test_bug28386 },
21428   { "test_wl4166_1", test_wl4166_1 },
21429   { "test_wl4166_2", test_wl4166_2 },
21430   { "test_wl4166_3", test_wl4166_3 },
21431   { "test_wl4166_4", test_wl4166_4 },
21432   { "test_bug36004", test_bug36004 },
21433   { "test_wl4284_1", test_wl4284_1 },
21434   { "test_wl4435",   test_wl4435 },
21435   { "test_wl4435_2", test_wl4435_2 },
21436   { "test_wl4435_3", test_wl4435_3 },
21437   { "test_bug38486", test_bug38486 },
21438   { "test_bug33831", test_bug33831 },
21439   { "test_bug40365", test_bug40365 },
21440   { "test_bug43560", test_bug43560 },
21441   { "test_bug36326", test_bug36326 },
21442   { "test_bug41078", test_bug41078 },
21443   { "test_bug44495", test_bug44495 },
21444   { "test_bug49972", test_bug49972 },
21445   { "test_bug42373", test_bug42373 },
21446   { "test_bug54041", test_bug54041 },
21447   { "test_bug47485", test_bug47485 },
21448   { "test_bug58036", test_bug58036 },
21449   { "test_bug57058", test_bug57058 },
21450   { "test_bug56976", test_bug56976 },
21451   { "test_bug11766854", test_bug11766854 },
21452   { "test_bug54790", test_bug54790 },
21453   { "test_bug12337762", test_bug12337762 },
21454   { "test_bug11754979", test_bug11754979 },
21455   { "test_bug13001491", test_bug13001491 },
21456   { "test_wl5968", test_wl5968 },
21457   { "test_wl5924", test_wl5924 },
21458   { "test_wl6587", test_wl6587 },
21459   { "test_wl5928", test_wl5928 },
21460   { "test_wl6797", test_wl6797 },
21461   { "test_wl6791", test_wl6791 },
21462   { "test_wl5768", test_wl5768 },
21463 #ifndef EMBEDDED_LIBRARY
21464   { "test_bug17309863", test_bug17309863},
21465 #endif
21466   { "test_bug17512527", test_bug17512527},
21467   { "test_bug20810928", test_bug20810928 },
21468   { "test_wl8016", test_wl8016},
21469   { "test_bug20645725", test_bug20645725 },
21470   { "test_bug20444737", test_bug20444737},
21471   { "test_bug21104470", test_bug21104470 },
21472   { "test_bug21293012", test_bug21293012 },
21473   { "test_bug21199582", test_bug21199582 },
21474   { "test_bug20821550", test_bug20821550 },
21475   { "test_wl8754", test_wl8754 },
21476   { "test_bug17883203", test_bug17883203 },
21477   { "test_bug22559575", test_bug22559575 },
21478   { "test_bug19894382", test_bug19894382 },
21479   { "test_bug22028117", test_bug22028117 },
21480   { "test_bug25701141", test_bug25701141 },
21481   { "test_bug27443252", test_bug27443252 },
21482   { "test_bug32391415", test_bug32391415 },
21483   { 0, 0 }
21484 };
21485 
21486 
get_my_tests()21487 static struct my_tests_st *get_my_tests() { return my_tests; }
21488