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 
4694     }
4695   }
4696   mysql_free_result(result);
4697 }
4698 
4699 
4700 /* Test mysql_stmt_close for open stmts */
4701 
test_stmt_close()4702 static void test_stmt_close()
4703 {
4704   MYSQL *lmysql;
4705   MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x;
4706   MYSQL_BIND  my_bind[1];
4707   MYSQL_RES   *result;
4708   unsigned int  count;
4709   int   rc;
4710   char query[MAX_TEST_QUERY_LENGTH];
4711 
4712   myheader("test_stmt_close");
4713 
4714   if (!opt_silent)
4715     fprintf(stdout, "\n Establishing a test connection ...");
4716   if (!(lmysql= mysql_client_init(NULL)))
4717   {
4718     myerror("mysql_client_init() failed");
4719     exit(1);
4720   }
4721   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
4722                            opt_password, current_db, opt_port,
4723                            opt_unix_socket, 0)))
4724   {
4725     myerror("connection failed");
4726     exit(1);
4727   }
4728   lmysql->reconnect= 1;
4729   if (!opt_silent)
4730     fprintf(stdout, "OK");
4731 
4732 
4733   /* set AUTOCOMMIT to ON*/
4734   mysql_autocommit(lmysql, TRUE);
4735 
4736   rc= mysql_query(lmysql, "SET SQL_MODE = ''");
4737   myquery(rc);
4738 
4739   rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close");
4740   myquery(rc);
4741 
4742   rc= mysql_query(lmysql, "CREATE TABLE test_stmt_close(id int)");
4743   myquery(rc);
4744 
4745   my_stpcpy(query, "DO \"nothing\"");
4746   stmt1= mysql_simple_prepare(lmysql, query);
4747   check_stmt(stmt1);
4748 
4749   verify_param_count(stmt1, 0);
4750 
4751   my_stpcpy(query, "INSERT INTO test_stmt_close(id) VALUES(?)");
4752   stmt_x= mysql_simple_prepare(mysql, query);
4753   check_stmt(stmt_x);
4754 
4755   verify_param_count(stmt_x, 1);
4756 
4757   my_stpcpy(query, "UPDATE test_stmt_close SET id= ? WHERE id= ?");
4758   stmt3= mysql_simple_prepare(lmysql, query);
4759   check_stmt(stmt3);
4760 
4761   verify_param_count(stmt3, 2);
4762 
4763   my_stpcpy(query, "SELECT * FROM test_stmt_close WHERE id= ?");
4764   stmt2= mysql_simple_prepare(lmysql, query);
4765   check_stmt(stmt2);
4766 
4767   verify_param_count(stmt2, 1);
4768 
4769   rc= mysql_stmt_close(stmt1);
4770   if (!opt_silent)
4771     fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
4772   DIE_UNLESS(rc == 0);
4773 
4774   /*
4775     Originally we were going to close all statements automatically in
4776     mysql_close(). This proved to not work well - users weren't able to
4777     close statements by hand once mysql_close() had been called.
4778     Now mysql_close() doesn't free any statements, so this test doesn't
4779     serve its original designation any more.
4780     Here we free stmt2 and stmt3 by hand to avoid memory leaks.
4781   */
4782   mysql_stmt_close(stmt2);
4783   mysql_stmt_close(stmt3);
4784   mysql_close(lmysql);
4785 
4786   /*
4787     We need to memset bind structure because mysql_stmt_bind_param checks all
4788     its members.
4789   */
4790   memset(my_bind, 0, sizeof(my_bind));
4791 
4792   my_bind[0].buffer= (void *)&count;
4793   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
4794   count= 100;
4795 
4796   rc= mysql_stmt_bind_param(stmt_x, my_bind);
4797   check_execute(stmt_x, rc);
4798 
4799   rc= mysql_stmt_execute(stmt_x);
4800   check_execute(stmt_x, rc);
4801 
4802   verify_st_affected_rows(stmt_x, 1);
4803 
4804   rc= mysql_stmt_close(stmt_x);
4805   if (!opt_silent)
4806     fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
4807   DIE_UNLESS( rc == 0);
4808 
4809   rc= mysql_query(mysql, "SELECT id FROM test_stmt_close");
4810   myquery(rc);
4811 
4812   result= mysql_store_result(mysql);
4813   mytest(result);
4814 
4815   rc= my_process_result_set(result);
4816   DIE_UNLESS(rc == 1);
4817   mysql_free_result(result);
4818 }
4819 
4820 
4821 /* Test simple set variable prepare */
4822 
test_set_variable()4823 static void test_set_variable()
4824 {
4825   MYSQL_STMT *stmt, *stmt1;
4826   int        rc;
4827   int        set_count, def_count, get_count;
4828   ulong      length;
4829   char       var[NAME_LEN+1];
4830   MYSQL_BIND set_bind[1], get_bind[2];
4831 
4832   myheader("test_set_variable");
4833 
4834   mysql_autocommit(mysql, TRUE);
4835 
4836   stmt1= mysql_simple_prepare(mysql, "show variables like 'max_error_count'");
4837   check_stmt(stmt1);
4838 
4839   /*
4840     We need to memset bind structure because mysql_stmt_bind_param checks all
4841     its members.
4842   */
4843   memset(get_bind, 0, sizeof(get_bind));
4844 
4845   get_bind[0].buffer_type= MYSQL_TYPE_STRING;
4846   get_bind[0].buffer= (void *)var;
4847   get_bind[0].length= &length;
4848   get_bind[0].buffer_length= (ulong)NAME_LEN;
4849   length= NAME_LEN;
4850 
4851   get_bind[1].buffer_type= MYSQL_TYPE_LONG;
4852   get_bind[1].buffer= (void *)&get_count;
4853 
4854   rc= mysql_stmt_execute(stmt1);
4855   check_execute(stmt1, rc);
4856 
4857   rc= mysql_stmt_bind_result(stmt1, get_bind);
4858   check_execute(stmt1, rc);
4859 
4860   rc= mysql_stmt_fetch(stmt1);
4861   check_execute(stmt1, rc);
4862 
4863   if (!opt_silent)
4864     fprintf(stdout, "\n max_error_count(default): %d", get_count);
4865   def_count= get_count;
4866 
4867   DIE_UNLESS(strcmp(var, "max_error_count") == 0);
4868   rc= mysql_stmt_fetch(stmt1);
4869   DIE_UNLESS(rc == MYSQL_NO_DATA);
4870 
4871   stmt= mysql_simple_prepare(mysql, "set max_error_count= ?");
4872   check_stmt(stmt);
4873 
4874   memset(set_bind, 0, sizeof(set_bind));
4875 
4876   set_bind[0].buffer_type= MYSQL_TYPE_LONG;
4877   set_bind[0].buffer= (void *)&set_count;
4878 
4879   rc= mysql_stmt_bind_param(stmt, set_bind);
4880   check_execute(stmt, rc);
4881 
4882   set_count= 31;
4883   rc= mysql_stmt_execute(stmt);
4884   check_execute(stmt, rc);
4885 
4886   mysql_commit(mysql);
4887 
4888   rc= mysql_stmt_execute(stmt1);
4889   check_execute(stmt1, rc);
4890 
4891   rc= mysql_stmt_fetch(stmt1);
4892   check_execute(stmt1, rc);
4893 
4894   if (!opt_silent)
4895     fprintf(stdout, "\n max_error_count         : %d", get_count);
4896   DIE_UNLESS(get_count == set_count);
4897 
4898   rc= mysql_stmt_fetch(stmt1);
4899   DIE_UNLESS(rc == MYSQL_NO_DATA);
4900 
4901   /* restore back to default */
4902   set_count= def_count;
4903   rc= mysql_stmt_execute(stmt);
4904   check_execute(stmt, rc);
4905 
4906   rc= mysql_stmt_execute(stmt1);
4907   check_execute(stmt1, rc);
4908 
4909   rc= mysql_stmt_fetch(stmt1);
4910   check_execute(stmt1, rc);
4911 
4912   if (!opt_silent)
4913     fprintf(stdout, "\n max_error_count(default): %d", get_count);
4914   DIE_UNLESS(get_count == set_count);
4915 
4916   rc= mysql_stmt_fetch(stmt1);
4917   DIE_UNLESS(rc == MYSQL_NO_DATA);
4918 
4919   mysql_stmt_close(stmt);
4920   mysql_stmt_close(stmt1);
4921 }
4922 
4923 /* Test FUNCTION field info / DATE_FORMAT() table_name . */
4924 
test_func_fields()4925 static void test_func_fields()
4926 {
4927   int        rc;
4928   MYSQL_RES  *result;
4929   MYSQL_FIELD *field;
4930 
4931   myheader("test_func_fields");
4932 
4933   rc= mysql_autocommit(mysql, TRUE);
4934   myquery(rc);
4935 
4936   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_dateformat");
4937   myquery(rc);
4938 
4939   rc= mysql_query(mysql, "CREATE TABLE test_dateformat(id int, \
4940                                                        ts timestamp)");
4941   myquery(rc);
4942 
4943   rc= mysql_query(mysql, "INSERT INTO test_dateformat(id) values(10)");
4944   myquery(rc);
4945 
4946   rc= mysql_query(mysql, "SELECT ts FROM test_dateformat");
4947   myquery(rc);
4948 
4949   result= mysql_store_result(mysql);
4950   mytest(result);
4951 
4952   field= mysql_fetch_field(result);
4953   mytest(field);
4954   if (!opt_silent)
4955     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table,
4956             "test_dateformat");
4957   DIE_UNLESS(strcmp(field->table, "test_dateformat") == 0);
4958 
4959   field= mysql_fetch_field(result);
4960   mytest_r(field); /* no more fields */
4961 
4962   mysql_free_result(result);
4963 
4964   /* DATE_FORMAT */
4965   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'venu' FROM test_dateformat");
4966   myquery(rc);
4967 
4968   result= mysql_store_result(mysql);
4969   mytest(result);
4970 
4971   field= mysql_fetch_field(result);
4972   mytest(field);
4973   if (!opt_silent)
4974     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table, "");
4975   DIE_UNLESS(field->table[0] == '\0');
4976 
4977   field= mysql_fetch_field(result);
4978   mytest_r(field); /* no more fields */
4979 
4980   mysql_free_result(result);
4981 
4982   /* FIELD ALIAS TEST */
4983   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y')  AS 'YEAR' FROM test_dateformat");
4984   myquery(rc);
4985 
4986   result= mysql_store_result(mysql);
4987   mytest(result);
4988 
4989   field= mysql_fetch_field(result);
4990   mytest(field);
4991   if (!opt_silent)
4992   {
4993     printf("\n field name: `%s` (expected: `%s`)", field->name, "YEAR");
4994     printf("\n field org name: `%s` (expected: `%s`)", field->org_name, "");
4995   }
4996   DIE_UNLESS(strcmp(field->name, "YEAR") == 0);
4997   DIE_UNLESS(field->org_name[0] == '\0');
4998 
4999   field= mysql_fetch_field(result);
5000   mytest_r(field); /* no more fields */
5001 
5002   mysql_free_result(result);
5003 }
5004 
5005 
5006 /* Multiple stmts .. */
5007 
test_multi_stmt()5008 static void test_multi_stmt()
5009 {
5010 
5011   MYSQL_STMT  *stmt, *stmt1, *stmt2;
5012   int         rc;
5013   uint32      id;
5014   char        name[50];
5015   MYSQL_BIND  my_bind[2];
5016   ulong       length[2];
5017   my_bool     is_null[2];
5018   myheader("test_multi_stmt");
5019 
5020   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_multi_table");
5021   myquery(rc);
5022 
5023   rc= mysql_query(mysql, "CREATE TABLE test_multi_table(id int, name char(20))");
5024   myquery(rc);
5025 
5026   rc= mysql_query(mysql, "INSERT INTO test_multi_table values(10, 'mysql')");
5027   myquery(rc);
5028 
5029   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_multi_table "
5030                                     "WHERE id= ?");
5031   check_stmt(stmt);
5032 
5033   stmt2= mysql_simple_prepare(mysql, "UPDATE test_multi_table "
5034                                      "SET name='updated' WHERE id=10");
5035   check_stmt(stmt2);
5036 
5037   verify_param_count(stmt, 1);
5038 
5039   /*
5040     We need to memset bind structure because mysql_stmt_bind_param checks all
5041     its members.
5042   */
5043   memset(my_bind, 0, sizeof(my_bind));
5044 
5045   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5046   my_bind[0].buffer= (void *)&id;
5047   my_bind[0].is_null= &is_null[0];
5048   my_bind[0].length= &length[0];
5049   is_null[0]= 0;
5050   length[0]= 0;
5051 
5052   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5053   my_bind[1].buffer= (void *)name;
5054   my_bind[1].buffer_length= (ulong)sizeof(name);
5055   my_bind[1].length= &length[1];
5056   my_bind[1].is_null= &is_null[1];
5057 
5058   rc= mysql_stmt_bind_param(stmt, my_bind);
5059   check_execute(stmt, rc);
5060 
5061   rc= mysql_stmt_bind_result(stmt, my_bind);
5062   check_execute(stmt, rc);
5063 
5064   id= 10;
5065   rc= mysql_stmt_execute(stmt);
5066   check_execute(stmt, rc);
5067 
5068   id= 999;
5069   rc= mysql_stmt_fetch(stmt);
5070   check_execute(stmt, rc);
5071 
5072   if (!opt_silent)
5073   {
5074     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5075     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5076   }
5077   DIE_UNLESS(id == 10);
5078   DIE_UNLESS(strcmp(name, "mysql") == 0);
5079 
5080   rc= mysql_stmt_fetch(stmt);
5081   DIE_UNLESS(rc == MYSQL_NO_DATA);
5082 
5083   /* alter the table schema now */
5084   stmt1= mysql_simple_prepare(mysql, "DELETE FROM test_multi_table "
5085                                      "WHERE id= ? AND "
5086                                      "CONVERT(name USING utf8)=?");
5087   check_stmt(stmt1);
5088 
5089   verify_param_count(stmt1, 2);
5090 
5091   rc= mysql_stmt_bind_param(stmt1, my_bind);
5092   check_execute(stmt1, rc);
5093 
5094   rc= mysql_stmt_execute(stmt2);
5095   check_execute(stmt2, rc);
5096 
5097   verify_st_affected_rows(stmt2, 1);
5098 
5099   rc= mysql_stmt_execute(stmt);
5100   check_execute(stmt, rc);
5101 
5102   rc= mysql_stmt_fetch(stmt);
5103   check_execute(stmt, rc);
5104 
5105   if (!opt_silent)
5106   {
5107     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5108     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5109   }
5110   DIE_UNLESS(id == 10);
5111   DIE_UNLESS(strcmp(name, "updated") == 0);
5112 
5113   rc= mysql_stmt_fetch(stmt);
5114   DIE_UNLESS(rc == MYSQL_NO_DATA);
5115 
5116   rc= mysql_stmt_execute(stmt1);
5117   check_execute(stmt1, rc);
5118 
5119   verify_st_affected_rows(stmt1, 1);
5120 
5121   mysql_stmt_close(stmt1);
5122 
5123   rc= mysql_stmt_execute(stmt);
5124   check_execute(stmt, rc);
5125 
5126   rc= mysql_stmt_fetch(stmt);
5127   DIE_UNLESS(rc == MYSQL_NO_DATA);
5128 
5129   rc= my_stmt_result("SELECT * FROM test_multi_table");
5130   DIE_UNLESS(rc == 0);
5131 
5132   mysql_stmt_close(stmt);
5133   mysql_stmt_close(stmt2);
5134 
5135 }
5136 
5137 
5138 /* Test simple sample - manual */
5139 
test_manual_sample()5140 static void test_manual_sample()
5141 {
5142   unsigned int param_count;
5143   MYSQL_STMT   *stmt;
5144   short        small_data;
5145   int          int_data;
5146   int          rc;
5147   char         str_data[50];
5148   ulonglong    affected_rows;
5149   MYSQL_BIND   my_bind[3];
5150   my_bool      is_null;
5151   char query[MAX_TEST_QUERY_LENGTH];
5152 
5153   myheader("test_manual_sample");
5154 
5155   /*
5156     Sample which is incorporated directly in the manual under Prepared
5157     statements section (Example from mysql_stmt_execute()
5158   */
5159 
5160   mysql_autocommit(mysql, 1);
5161   if (mysql_query(mysql, "DROP TABLE IF EXISTS test_table"))
5162   {
5163     fprintf(stderr, "\n drop table failed");
5164     fprintf(stderr, "\n %s", mysql_error(mysql));
5165     exit(1);
5166   }
5167   if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \
5168                                                  col3 smallint, \
5169                                                  col4 timestamp)"))
5170   {
5171     fprintf(stderr, "\n create table failed");
5172     fprintf(stderr, "\n %s", mysql_error(mysql));
5173     exit(1);
5174   }
5175 
5176   /* Prepare a insert query with 3 parameters */
5177   my_stpcpy(query, "INSERT INTO test_table(col1, col2, col3) values(?, ?, ?)");
5178   if (!(stmt= mysql_simple_prepare(mysql, query)))
5179   {
5180     fprintf(stderr, "\n prepare, insert failed");
5181     fprintf(stderr, "\n %s", mysql_error(mysql));
5182     exit(1);
5183   }
5184   if (!opt_silent)
5185     fprintf(stdout, "\n prepare, insert successful");
5186 
5187   /* Get the parameter count from the statement */
5188   param_count= mysql_stmt_param_count(stmt);
5189 
5190   if (!opt_silent)
5191     fprintf(stdout, "\n total parameters in insert: %d", param_count);
5192   if (param_count != 3) /* validate parameter count */
5193   {
5194     fprintf(stderr, "\n invalid parameter count returned by MySQL");
5195     exit(1);
5196   }
5197 
5198   /* Bind the data for the parameters */
5199 
5200   /*
5201     We need to memset bind structure because mysql_stmt_bind_param checks all
5202     its members.
5203   */
5204   memset(my_bind, 0, sizeof(my_bind));
5205   memset(str_data, 0, sizeof(str_data));
5206 
5207   /* INTEGER PART */
5208   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5209   my_bind[0].buffer= (void *)&int_data;
5210 
5211   /* STRING PART */
5212   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
5213   my_bind[1].buffer= (void *)str_data;
5214   my_bind[1].buffer_length= (ulong)sizeof(str_data);
5215 
5216   /* SMALLINT PART */
5217   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
5218   my_bind[2].buffer= (void *)&small_data;
5219   my_bind[2].is_null= &is_null;
5220   is_null= 0;
5221 
5222   /* Bind the buffers */
5223   if (mysql_stmt_bind_param(stmt, my_bind))
5224   {
5225     fprintf(stderr, "\n param bind failed");
5226     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5227     exit(1);
5228   }
5229 
5230   /* Specify the data */
5231   int_data= 10;             /* integer */
5232   my_stpcpy(str_data, "MySQL"); /* string  */
5233 
5234   /* INSERT SMALLINT data as NULL */
5235   is_null= 1;
5236 
5237   /* Execute the insert statement - 1*/
5238   if (mysql_stmt_execute(stmt))
5239   {
5240     fprintf(stderr, "\n execute 1 failed");
5241     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5242     exit(1);
5243   }
5244 
5245   /* Get the total rows affected */
5246   affected_rows= mysql_stmt_affected_rows(stmt);
5247 
5248   if (!opt_silent)
5249     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5250   if (affected_rows != 1) /* validate affected rows */
5251   {
5252     fprintf(stderr, "\n invalid affected rows by MySQL");
5253     exit(1);
5254   }
5255 
5256   /* Re-execute the insert, by changing the values */
5257   int_data= 1000;
5258   my_stpcpy(str_data, "The most popular open source database");
5259   small_data= 1000;         /* smallint */
5260   is_null= 0;               /* reset */
5261 
5262   /* Execute the insert statement - 2*/
5263   if (mysql_stmt_execute(stmt))
5264   {
5265     fprintf(stderr, "\n execute 2 failed");
5266     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5267     exit(1);
5268   }
5269 
5270   /* Get the total rows affected */
5271   affected_rows= mysql_stmt_affected_rows(stmt);
5272 
5273   if (!opt_silent)
5274     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5275   if (affected_rows != 1) /* validate affected rows */
5276   {
5277     fprintf(stderr, "\n invalid affected rows by MySQL");
5278     exit(1);
5279   }
5280 
5281   /* Close the statement */
5282   if (mysql_stmt_close(stmt))
5283   {
5284     fprintf(stderr, "\n failed while closing the statement");
5285     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5286     exit(1);
5287   }
5288   rc= my_stmt_result("SELECT * FROM test_table");
5289   DIE_UNLESS(rc == 2);
5290 
5291   /* DROP THE TABLE */
5292   if (mysql_query(mysql, "DROP TABLE test_table"))
5293   {
5294     fprintf(stderr, "\n drop table failed");
5295     fprintf(stderr, "\n %s", mysql_error(mysql));
5296     exit(1);
5297   }
5298   if (!opt_silent)
5299     fprintf(stdout, "Success !!!");
5300 }
5301 
5302 
5303 /* Test alter table scenario in the middle of prepare */
5304 
test_prepare_alter()5305 static void test_prepare_alter()
5306 {
5307   MYSQL_STMT  *stmt;
5308   int         rc, id;
5309   MYSQL_BIND  my_bind[1];
5310   my_bool     is_null;
5311 
5312   myheader("test_prepare_alter");
5313 
5314   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_alter");
5315   myquery(rc);
5316 
5317   rc= mysql_query(mysql, "CREATE TABLE test_prep_alter(id int, name char(20))");
5318   myquery(rc);
5319 
5320   rc= mysql_query(mysql, "INSERT INTO test_prep_alter values(10, 'venu'), (20, 'mysql')");
5321   myquery(rc);
5322 
5323   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?, 'monty')");
5324   check_stmt(stmt);
5325 
5326   verify_param_count(stmt, 1);
5327 
5328   /*
5329     We need to memset bind structure because mysql_stmt_bind_param checks all
5330     its members.
5331   */
5332   memset(my_bind, 0, sizeof(my_bind));
5333 
5334   is_null= 0;
5335   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
5336   my_bind[0].buffer= (void *)&id;
5337   my_bind[0].is_null= &is_null;
5338 
5339   rc= mysql_stmt_bind_param(stmt, my_bind);
5340   check_execute(stmt, rc);
5341 
5342   id= 30;
5343   rc= mysql_stmt_execute(stmt);
5344   check_execute(stmt, rc);
5345 
5346   if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)"))
5347     exit(1);
5348 
5349   is_null= 1;
5350   rc= mysql_stmt_execute(stmt);
5351   check_execute(stmt, rc);
5352 
5353   rc= my_stmt_result("SELECT * FROM test_prep_alter");
5354   DIE_UNLESS(rc == 4);
5355 
5356   mysql_stmt_close(stmt);
5357 }
5358 
5359 
5360 /* Test the support of multi-statement executions */
5361 
test_multi_statements()5362 static void test_multi_statements()
5363 {
5364   MYSQL *mysql_local;
5365   MYSQL_RES *result;
5366   int    rc;
5367 
5368   const char *query= "\
5369 DROP TABLE IF EXISTS test_multi_tab;\
5370 CREATE TABLE test_multi_tab(id int, name char(20));\
5371 INSERT INTO test_multi_tab(id) VALUES(10), (20);\
5372 INSERT INTO test_multi_tab VALUES(20, 'insert;comma');\
5373 SELECT * FROM test_multi_tab;\
5374 UPDATE test_multi_tab SET name='new;name' WHERE id=20;\
5375 DELETE FROM test_multi_tab WHERE name='new;name';\
5376 SELECT * FROM test_multi_tab;\
5377 DELETE FROM test_multi_tab WHERE id=10;\
5378 SELECT * FROM test_multi_tab;\
5379 DROP TABLE test_multi_tab;\
5380 select 1;\
5381 DROP TABLE IF EXISTS test_multi_tab";
5382   uint count, exp_value;
5383   uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0};
5384 
5385   myheader("test_multi_statements");
5386 
5387   /*
5388     First test that we get an error for multi statements
5389     (Because default connection is not opened with CLIENT_MULTI_STATEMENTS)
5390   */
5391   rc= mysql_query(mysql, query); /* syntax error */
5392   myquery_r(rc);
5393 
5394   rc= mysql_next_result(mysql);
5395   DIE_UNLESS(rc == -1);
5396   rc= mysql_more_results(mysql);
5397   DIE_UNLESS(rc == 0);
5398 
5399   if (!(mysql_local= mysql_client_init(NULL)))
5400   {
5401     fprintf(stdout, "\n mysql_client_init() failed");
5402     exit(1);
5403   }
5404 
5405   /* Create connection that supports multi statements */
5406   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5407                            opt_password, current_db, opt_port,
5408                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5409   {
5410     fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local));
5411     exit(1);
5412   }
5413   mysql_local->reconnect= 1;
5414 
5415   rc= mysql_query(mysql_local, query);
5416   myquery(rc);
5417 
5418   for (count= 0 ; count < array_elements(rows) ; count++)
5419   {
5420     if (!opt_silent)
5421       fprintf(stdout, "\n Query %d: ", count);
5422     if ((result= mysql_store_result(mysql_local)))
5423     {
5424       (void) my_process_result_set(result);
5425       mysql_free_result(result);
5426     }
5427     else if (!opt_silent)
5428       fprintf(stdout, "OK, %ld row(s) affected, %ld warning(s)\n",
5429               (ulong) mysql_affected_rows(mysql_local),
5430               (ulong) mysql_warning_count(mysql_local));
5431 
5432     exp_value= (uint) mysql_affected_rows(mysql_local);
5433     if (rows[count] !=  exp_value)
5434     {
5435       fprintf(stderr, "row %d  had affected rows: %d, should be %d\n",
5436               count, exp_value, rows[count]);
5437       exit(1);
5438     }
5439     if (count != array_elements(rows) -1)
5440     {
5441       if (!(rc= mysql_more_results(mysql_local)))
5442       {
5443         fprintf(stdout,
5444                 "mysql_more_result returned wrong value: %d for row %d\n",
5445                 rc, count);
5446         exit(1);
5447       }
5448       if ((rc= mysql_next_result(mysql_local)))
5449       {
5450         exp_value= mysql_errno(mysql_local);
5451 
5452         exit(1);
5453       }
5454     }
5455     else
5456     {
5457       rc= mysql_more_results(mysql_local);
5458       DIE_UNLESS(rc == 0);
5459       rc= mysql_next_result(mysql_local);
5460       DIE_UNLESS(rc == -1);
5461     }
5462   }
5463 
5464   /* check that errors abort multi statements */
5465 
5466   rc= mysql_query(mysql_local, "select 1+1+a;select 1+1");
5467   myquery_r(rc);
5468   rc= mysql_more_results(mysql_local);
5469   DIE_UNLESS(rc == 0);
5470   rc= mysql_next_result(mysql_local);
5471   DIE_UNLESS(rc == -1);
5472 
5473   rc= mysql_query(mysql_local, "select 1+1;select 1+1+a;select 1");
5474   myquery(rc);
5475   result= mysql_store_result(mysql_local);
5476   mytest(result);
5477   mysql_free_result(result);
5478   rc= mysql_more_results(mysql_local);
5479   DIE_UNLESS(rc == 1);
5480   rc= mysql_next_result(mysql_local);
5481   DIE_UNLESS(rc > 0);
5482 
5483   /*
5484     Ensure that we can now do a simple query (this checks that the server is
5485     not trying to send us the results for the last 'select 1'
5486   */
5487   rc= mysql_query(mysql_local, "select 1+1+1");
5488   myquery(rc);
5489   result= mysql_store_result(mysql_local);
5490   mytest(result);
5491   (void) my_process_result_set(result);
5492   mysql_free_result(result);
5493 
5494   /*
5495     Check if errors in one of the queries handled properly.
5496   */
5497   rc= mysql_query(mysql_local, "select 1; select * from not_existing_table");
5498   myquery(rc);
5499   result= mysql_store_result(mysql_local);
5500   mysql_free_result(result);
5501 
5502   rc= mysql_next_result(mysql_local);
5503   DIE_UNLESS(rc > 0);
5504 
5505   rc= mysql_next_result(mysql_local);
5506   DIE_UNLESS(rc < 0);
5507 
5508   mysql_close(mysql_local);
5509 }
5510 
5511 
5512 /*
5513   Check that Prepared statement cannot contain several
5514   SQL statements
5515 */
5516 
test_prepare_multi_statements()5517 static void test_prepare_multi_statements()
5518 {
5519   MYSQL *mysql_local;
5520   MYSQL_STMT *stmt;
5521   char query[MAX_TEST_QUERY_LENGTH];
5522   myheader("test_prepare_multi_statements");
5523 
5524   if (!(mysql_local= mysql_client_init(NULL)))
5525   {
5526     fprintf(stderr, "\n mysql_client_init() failed");
5527     exit(1);
5528   }
5529 
5530   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5531                            opt_password, current_db, opt_port,
5532                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5533   {
5534     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
5535     exit(1);
5536   }
5537   mysql_local->reconnect= 1;
5538   my_stpcpy(query, "select 1; select 'another value'");
5539   stmt= mysql_simple_prepare(mysql_local, query);
5540   check_stmt_r(stmt);
5541   mysql_close(mysql_local);
5542 }
5543 
5544 
5545 /* Test simple bind store result */
5546 
test_store_result()5547 static void test_store_result()
5548 {
5549   MYSQL_STMT *stmt;
5550   int        rc;
5551   int32      nData;
5552   char       szData[100];
5553   MYSQL_BIND my_bind[2];
5554   ulong      length, length1;
5555   my_bool    is_null[2];
5556 
5557   myheader("test_store_result");
5558 
5559   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5560   myquery(rc);
5561 
5562   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5563   myquery(rc);
5564 
5565   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5566   myquery(rc);
5567 
5568   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5569   myquery(rc);
5570 
5571   rc= mysql_commit(mysql);
5572   myquery(rc);
5573 
5574   /* fetch */
5575   memset(my_bind, 0, sizeof(my_bind));
5576   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5577   my_bind[0].buffer= (void *) &nData;       /* integer data */
5578   my_bind[0].length= &length;
5579   my_bind[0].is_null= &is_null[0];
5580 
5581   length= 0;
5582   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5583   my_bind[1].buffer= szData;                /* string data */
5584   my_bind[1].buffer_length= (ulong)sizeof(szData);
5585   my_bind[1].length= &length1;
5586   my_bind[1].is_null= &is_null[1];
5587   length1= 0;
5588 
5589   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5590   check_stmt(stmt);
5591 
5592   rc= mysql_stmt_bind_result(stmt, my_bind);
5593   check_execute(stmt, rc);
5594 
5595   rc= mysql_stmt_execute(stmt);
5596   check_execute(stmt, rc);
5597 
5598   rc= mysql_stmt_store_result(stmt);
5599   check_execute(stmt, rc);
5600 
5601   rc= mysql_stmt_fetch(stmt);
5602   check_execute(stmt, rc);
5603 
5604   if (!opt_silent)
5605     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5606   DIE_UNLESS(nData == 10);
5607   DIE_UNLESS(strcmp(szData, "venu") == 0);
5608   DIE_UNLESS(length1 == 4);
5609 
5610   rc= mysql_stmt_fetch(stmt);
5611   check_execute(stmt, rc);
5612 
5613   if (!opt_silent)
5614     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5615   DIE_UNLESS(nData == 20);
5616   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5617   DIE_UNLESS(length1 == 5);
5618 
5619   length= 99;
5620   rc= mysql_stmt_fetch(stmt);
5621   check_execute(stmt, rc);
5622 
5623   if (!opt_silent && is_null[0])
5624     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5625   DIE_UNLESS(is_null[0]);
5626   DIE_UNLESS(strcmp(szData, "monty") == 0);
5627   DIE_UNLESS(length1 == 5);
5628 
5629   rc= mysql_stmt_fetch(stmt);
5630   DIE_UNLESS(rc == MYSQL_NO_DATA);
5631 
5632   rc= mysql_stmt_execute(stmt);
5633   check_execute(stmt, rc);
5634 
5635   rc= mysql_stmt_store_result(stmt);
5636   check_execute(stmt, rc);
5637 
5638   rc= mysql_stmt_fetch(stmt);
5639   check_execute(stmt, rc);
5640 
5641   if (!opt_silent)
5642     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5643   DIE_UNLESS(nData == 10);
5644   DIE_UNLESS(strcmp(szData, "venu") == 0);
5645   DIE_UNLESS(length1 == 4);
5646 
5647   rc= mysql_stmt_fetch(stmt);
5648   check_execute(stmt, rc);
5649 
5650   if (!opt_silent)
5651     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5652   DIE_UNLESS(nData == 20);
5653   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5654   DIE_UNLESS(length1 == 5);
5655 
5656   length= 99;
5657   rc= mysql_stmt_fetch(stmt);
5658   check_execute(stmt, rc);
5659 
5660   if (!opt_silent && is_null[0])
5661     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5662   DIE_UNLESS(is_null[0]);
5663   DIE_UNLESS(strcmp(szData, "monty") == 0);
5664   DIE_UNLESS(length1 == 5);
5665 
5666   rc= mysql_stmt_fetch(stmt);
5667   DIE_UNLESS(rc == MYSQL_NO_DATA);
5668 
5669   mysql_stmt_close(stmt);
5670 }
5671 
5672 
5673 /* Test simple bind store result */
5674 
test_store_result1()5675 static void test_store_result1()
5676 {
5677   MYSQL_STMT *stmt;
5678   int        rc;
5679 
5680   myheader("test_store_result1");
5681 
5682   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5683   myquery(rc);
5684 
5685   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5686   myquery(rc);
5687 
5688   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5689   myquery(rc);
5690 
5691   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5692   myquery(rc);
5693 
5694   rc= mysql_commit(mysql);
5695   myquery(rc);
5696 
5697   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5698   check_stmt(stmt);
5699 
5700   rc= mysql_stmt_execute(stmt);
5701   check_execute(stmt, rc);
5702 
5703   rc= mysql_stmt_store_result(stmt);
5704   check_execute(stmt, rc);
5705 
5706   rc= 0;
5707   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5708     rc++;
5709   if (!opt_silent)
5710     fprintf(stdout, "\n total rows: %d", rc);
5711   DIE_UNLESS(rc == 3);
5712 
5713   rc= mysql_stmt_execute(stmt);
5714   check_execute(stmt, rc);
5715 
5716   rc= mysql_stmt_store_result(stmt);
5717   check_execute(stmt, rc);
5718 
5719   rc= 0;
5720   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5721     rc++;
5722   if (!opt_silent)
5723     fprintf(stdout, "\n total rows: %d", rc);
5724   DIE_UNLESS(rc == 3);
5725 
5726   mysql_stmt_close(stmt);
5727 }
5728 
5729 
5730 /* Another test for bind and store result */
5731 
test_store_result2()5732 static void test_store_result2()
5733 {
5734   MYSQL_STMT *stmt;
5735   int        rc;
5736   int        nData;
5737   ulong      length;
5738   MYSQL_BIND my_bind[1];
5739   char query[MAX_TEST_QUERY_LENGTH];
5740 
5741   myheader("test_store_result2");
5742 
5743   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5744   myquery(rc);
5745 
5746   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5747   myquery(rc);
5748 
5749   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5750   myquery(rc);
5751 
5752   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5753   myquery(rc);
5754 
5755   rc= mysql_commit(mysql);
5756   myquery(rc);
5757 
5758   /*
5759     We need to memset bind structure because mysql_stmt_bind_param checks all
5760     its members.
5761   */
5762   memset(my_bind, 0, sizeof(my_bind));
5763 
5764   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5765   my_bind[0].buffer= (void *) &nData;      /* integer data */
5766   my_bind[0].length= &length;
5767   my_bind[0].is_null= 0;
5768 
5769   my_stpcpy((char *)query , "SELECT col1 FROM test_store_result where col1= ?");
5770   stmt= mysql_simple_prepare(mysql, query);
5771   check_stmt(stmt);
5772 
5773   rc= mysql_stmt_bind_param(stmt, my_bind);
5774   check_execute(stmt, rc);
5775 
5776   rc= mysql_stmt_bind_result(stmt, my_bind);
5777   check_execute(stmt, rc);
5778 
5779   nData= 10; length= 0;
5780   rc= mysql_stmt_execute(stmt);
5781   check_execute(stmt, rc);
5782 
5783   nData= 0;
5784   rc= mysql_stmt_store_result(stmt);
5785   check_execute(stmt, rc);
5786 
5787   rc= mysql_stmt_fetch(stmt);
5788   check_execute(stmt, rc);
5789 
5790   if (!opt_silent)
5791     fprintf(stdout, "\n row 1: %d", nData);
5792   DIE_UNLESS(nData == 10);
5793 
5794   rc= mysql_stmt_fetch(stmt);
5795   DIE_UNLESS(rc == MYSQL_NO_DATA);
5796 
5797   nData= 20;
5798   rc= mysql_stmt_execute(stmt);
5799   check_execute(stmt, rc);
5800 
5801   nData= 0;
5802   rc= mysql_stmt_store_result(stmt);
5803   check_execute(stmt, rc);
5804 
5805   rc= mysql_stmt_fetch(stmt);
5806   check_execute(stmt, rc);
5807 
5808   if (!opt_silent)
5809     fprintf(stdout, "\n row 1: %d", nData);
5810   DIE_UNLESS(nData == 20);
5811 
5812   rc= mysql_stmt_fetch(stmt);
5813   DIE_UNLESS(rc == MYSQL_NO_DATA);
5814   mysql_stmt_close(stmt);
5815 }
5816 
5817 
5818 /* Test simple subselect prepare */
5819 
test_subselect()5820 static void test_subselect()
5821 {
5822 
5823   MYSQL_STMT *stmt;
5824   int        rc, id;
5825   MYSQL_BIND my_bind[1];
5826   DBUG_ENTER("test_subselect");
5827 
5828   myheader("test_subselect");
5829 
5830   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub1");
5831   myquery(rc);
5832 
5833   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub2");
5834   myquery(rc);
5835 
5836   rc= mysql_query(mysql, "CREATE TABLE test_sub1(id int)");
5837   myquery(rc);
5838 
5839   rc= mysql_query(mysql, "CREATE TABLE test_sub2(id int, id1 int)");
5840   myquery(rc);
5841 
5842   rc= mysql_query(mysql, "INSERT INTO test_sub1 values(2)");
5843   myquery(rc);
5844 
5845   rc= mysql_query(mysql, "INSERT INTO test_sub2 VALUES(1, 7), (2, 7)");
5846   myquery(rc);
5847 
5848   rc= mysql_commit(mysql);
5849   myquery(rc);
5850 
5851   /* fetch */
5852   /*
5853     We need to memset bind structure because mysql_stmt_bind_param checks all
5854     its members.
5855   */
5856   memset(my_bind, 0, sizeof(my_bind));
5857 
5858   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5859   my_bind[0].buffer= (void *) &id;
5860   my_bind[0].length= 0;
5861   my_bind[0].is_null= 0;
5862 
5863   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id= ?");
5864   check_stmt(stmt);
5865 
5866   rc= mysql_stmt_bind_param(stmt, my_bind);
5867   check_execute(stmt, rc);
5868 
5869   id= 2;
5870   rc= mysql_stmt_execute(stmt);
5871   check_execute(stmt, rc);
5872 
5873   verify_st_affected_rows(stmt, 1);
5874 
5875   id= 9;
5876   rc= mysql_stmt_execute(stmt);
5877   check_execute(stmt, rc);
5878 
5879   verify_st_affected_rows(stmt, 0);
5880 
5881   mysql_stmt_close(stmt);
5882 
5883   rc= my_stmt_result("SELECT * FROM test_sub2");
5884   DIE_UNLESS(rc == 3);
5885 
5886   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
5887                      "from test_sub2 WHERE id1= 8)");
5888   DIE_UNLESS(rc == 1);
5889   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
5890                      "from test_sub2 WHERE id1= 7)");
5891   DIE_UNLESS(rc == 1);
5892 
5893   stmt= mysql_simple_prepare(mysql, ("SELECT ROW(1, 7) IN (select id, id1 "
5894                                      "from test_sub2 WHERE id1= ?)"));
5895   check_stmt(stmt);
5896 
5897   rc= mysql_stmt_bind_param(stmt, my_bind);
5898   check_execute(stmt, rc);
5899 
5900   rc= mysql_stmt_bind_result(stmt, my_bind);
5901   check_execute(stmt, rc);
5902 
5903   id= 7;
5904   rc= mysql_stmt_execute(stmt);
5905   check_execute(stmt, rc);
5906 
5907   rc= mysql_stmt_fetch(stmt);
5908   check_execute(stmt, rc);
5909 
5910   if (!opt_silent)
5911     fprintf(stdout, "\n row 1: %d", id);
5912   DIE_UNLESS(id == 1);
5913 
5914   rc= mysql_stmt_fetch(stmt);
5915   DIE_UNLESS(rc == MYSQL_NO_DATA);
5916 
5917   id= 8;
5918   rc= mysql_stmt_execute(stmt);
5919   check_execute(stmt, rc);
5920 
5921   rc= mysql_stmt_fetch(stmt);
5922   check_execute(stmt, rc);
5923 
5924   if (!opt_silent)
5925     fprintf(stdout, "\n row 1: %d", id);
5926   DIE_UNLESS(id == 0);
5927 
5928   rc= mysql_stmt_fetch(stmt);
5929   DIE_UNLESS(rc == MYSQL_NO_DATA);
5930 
5931   mysql_stmt_close(stmt);
5932   DBUG_VOID_RETURN;
5933 }
5934 
5935 
5936 /*
5937   Generalized conversion routine to handle DATE, TIME and DATETIME
5938   conversion using MYSQL_TIME structure
5939 */
5940 
bind_date_conv(uint row_count,my_bool preserveFractions)5941 static void bind_date_conv(uint row_count, my_bool preserveFractions)
5942 {
5943   MYSQL_STMT   *stmt= 0;
5944   uint         rc, i, count= row_count;
5945   ulong        length[4];
5946   MYSQL_BIND   my_bind[4];
5947   my_bool      is_null[4]= {0};
5948   MYSQL_TIME   tm[4];
5949   ulong        second_part;
5950   uint         year, month, day, hour, minute, sec;
5951   uint         now_year= 1990, now_month= 3, now_day= 13;
5952 
5953   rc= mysql_query(mysql, "SET timestamp=UNIX_TIMESTAMP('1990-03-13')");
5954   myquery(rc);
5955 
5956   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_date VALUES(?, ?, ?, ?)");
5957   check_stmt(stmt);
5958 
5959   verify_param_count(stmt, 4);
5960 
5961   /*
5962     We need to memset bind structure because mysql_stmt_bind_param checks all
5963     its members.
5964   */
5965   memset(my_bind, 0, sizeof(my_bind));
5966 
5967   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
5968   my_bind[1].buffer_type= MYSQL_TYPE_TIME;
5969   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
5970   my_bind[3].buffer_type= MYSQL_TYPE_DATE;
5971 
5972   for (i= 0; i < (int) array_elements(my_bind); i++)
5973   {
5974     my_bind[i].buffer= (void *) &tm[i];
5975     my_bind[i].is_null= &is_null[i];
5976     my_bind[i].length= &length[i];
5977     my_bind[i].buffer_length= 30;
5978     length[i]= 20;
5979   }
5980 
5981   second_part= 0;
5982 
5983   year= 2000;
5984   month= 01;
5985   day= 10;
5986 
5987   hour= 11;
5988   minute= 16;
5989   sec= 20;
5990 
5991   rc= mysql_stmt_bind_param(stmt, my_bind);
5992   check_execute(stmt, rc);
5993 
5994   for (count= 0; count < row_count; count++)
5995   {
5996     for (i= 0; i < (int) array_elements(my_bind); i++)
5997     {
5998       tm[i].neg= 0;
5999       tm[i].second_part= second_part+count;
6000       if (my_bind[i].buffer_type != MYSQL_TYPE_TIME)
6001       {
6002         tm[i].year= year+count;
6003         tm[i].month= month+count;
6004         tm[i].day= day+count;
6005       }
6006       else
6007         tm[i].year= tm[i].month= tm[i].day= 0;
6008       if (my_bind[i].buffer_type != MYSQL_TYPE_DATE)
6009       {
6010         tm[i].hour= hour+count;
6011         tm[i].minute= minute+count;
6012         tm[i].second= sec+count;
6013       }
6014       else
6015         tm[i].hour= tm[i].minute= tm[i].second= 0;
6016     }
6017     rc= mysql_stmt_execute(stmt);
6018     check_execute(stmt, rc);
6019   }
6020 
6021   rc= mysql_commit(mysql);
6022   myquery(rc);
6023 
6024   mysql_stmt_close(stmt);
6025 
6026   rc= my_stmt_result("SELECT * FROM test_date");
6027   DIE_UNLESS(row_count == rc);
6028 
6029   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_date");
6030   check_stmt(stmt);
6031 
6032   rc= mysql_stmt_bind_result(stmt, my_bind);
6033   check_execute(stmt, rc);
6034 
6035   rc= mysql_stmt_execute(stmt);
6036   check_execute(stmt, rc);
6037 
6038   rc= mysql_stmt_store_result(stmt);
6039   check_execute(stmt, rc);
6040 
6041   for (count= 0; count < row_count; count++)
6042   {
6043     rc= mysql_stmt_fetch(stmt);
6044     DIE_UNLESS(rc == 0 || rc == MYSQL_DATA_TRUNCATED);
6045 
6046     if (!opt_silent)
6047       fprintf(stdout, "\n");
6048     for (i= 0; i < array_elements(my_bind); i++)
6049     {
6050       if (!opt_silent)
6051         fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d %02d:%02d:%02d.%06lu",
6052                 i, tm[i].year, tm[i].month, tm[i].day,
6053                 tm[i].hour, tm[i].minute, tm[i].second,
6054                 tm[i].second_part);
6055       DIE_UNLESS(tm[i].year == 0 || tm[i].year == year + count ||
6056                  (tm[i].year == now_year &&
6057                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6058       DIE_UNLESS(tm[i].month == 0 || tm[i].month == month + count ||
6059                  (tm[i].month == now_month &&
6060                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6061       DIE_UNLESS(tm[i].day == 0 || tm[i].day == day + count ||
6062                  (tm[i].day == now_day &&
6063                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6064 
6065       DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count);
6066       DIE_UNLESS(tm[i].minute == 0 || tm[i].minute == minute+count);
6067       DIE_UNLESS(tm[i].second == 0 || tm[i].second == sec+count);
6068       if (preserveFractions) {
6069         if (i == 3) { /* Dates dont have fractions */
6070           DIE_UNLESS(tm[i].second_part == 0);
6071         } else {
6072           DIE_UNLESS(tm[i].second_part == second_part+count);
6073         }
6074       } else {
6075         DIE_UNLESS((tm[i].second_part == 0)||
6076                    tm[i].second_part == second_part+count);
6077       }
6078     }
6079   }
6080   rc= mysql_stmt_fetch(stmt);
6081   DIE_UNLESS(rc == MYSQL_NO_DATA);
6082 
6083   mysql_stmt_close(stmt);
6084 
6085   /* set the timestamp back to default */
6086   rc= mysql_query(mysql, "SET timestamp=DEFAULT");
6087   myquery(rc);
6088 }
6089 
6090 
6091 /* Test DATE, TIME, DATETIME and TS with MYSQL_TIME conversion */
6092 
test_date()6093 static void test_date()
6094 {
6095   int        rc;
6096 
6097   myheader("test_date");
6098 
6099   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6100   myquery(rc);
6101 
6102   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6103                                                  c2 TIME, \
6104                                                  c3 DATETIME, \
6105                                                  c4 DATE)");
6106 
6107   myquery(rc);
6108 
6109   bind_date_conv(5,FALSE);
6110 }
6111 
6112 
6113 /* Test DATE, TIME(6), DATETIME(6) and TS(6) with MYSQL_TIME conversion */
6114 
test_date_frac()6115 static void test_date_frac()
6116 {
6117   int        rc;
6118 
6119   myheader("test_date");
6120 
6121   if (mysql_get_server_version(mysql) < 50604)
6122   {
6123     if (!opt_silent)
6124       fprintf(stdout, "Skipping test_date_frac: fractinal seconds implemented "
6125               "in MySQL 5.6.4\n");
6126     return;
6127   }
6128 
6129   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6130   myquery(rc);
6131 
6132   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP(6), \
6133                                                  c2 TIME(6), \
6134                                                  c3 DATETIME(6), \
6135                                                  c4 DATE)");
6136 
6137   myquery(rc);
6138 
6139   bind_date_conv(5,TRUE);
6140 }
6141 
6142 
6143 /* Test all time types to DATE and DATE to all types */
6144 
test_date_date()6145 static void test_date_date()
6146 {
6147   int        rc;
6148 
6149   myheader("test_date_date");
6150 
6151   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6152   myquery(rc);
6153 
6154   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 DATE, \
6155                                                  c2 DATE, \
6156                                                  c3 DATE, \
6157                                                  c4 DATE)");
6158 
6159   myquery(rc);
6160 
6161   bind_date_conv(3,FALSE);
6162 }
6163 
6164 
6165 /* Test all time types to TIME and TIME to all types */
6166 
test_date_time()6167 static void test_date_time()
6168 {
6169   int        rc;
6170 
6171   myheader("test_date_time");
6172 
6173   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6174   myquery(rc);
6175 
6176   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIME, \
6177                                                  c2 TIME, \
6178                                                  c3 TIME, \
6179                                                  c4 TIME)");
6180 
6181   myquery(rc);
6182 
6183   bind_date_conv(3, FALSE);
6184 }
6185 
6186 
6187 /* Test all time types to TIMESTAMP and TIMESTAMP to all types */
6188 
test_date_ts()6189 static void test_date_ts()
6190 {
6191   int        rc;
6192 
6193   myheader("test_date_ts");
6194 
6195   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6196   myquery(rc);
6197 
6198   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6199                                                  c2 TIMESTAMP, \
6200                                                  c3 TIMESTAMP, \
6201                                                  c4 TIMESTAMP)");
6202 
6203   myquery(rc);
6204 
6205   bind_date_conv(2, FALSE);
6206 }
6207 
6208 
6209 /* Test all time types to DATETIME and DATETIME to all types */
6210 
test_date_dt()6211 static void test_date_dt()
6212 {
6213   int rc;
6214 
6215   myheader("test_date_dt");
6216 
6217   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6218   myquery(rc);
6219 
6220   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 datetime, "
6221                          " c2 datetime, c3 datetime, c4 date)");
6222   myquery(rc);
6223 
6224   bind_date_conv(2, FALSE);
6225 }
6226 
6227 
6228 /*
6229   Test TIME/DATETIME parameters to cover the following methods:
6230     Item_param::val_int()
6231     Item_param::val_real()
6232     Item_param::val_decimal()
6233 */
test_temporal_param()6234 static void test_temporal_param()
6235 {
6236 #define N_PARAMS 3
6237   MYSQL_STMT   *stmt= 0;
6238   uint         rc;
6239   ulong        length[N_PARAMS],  length2[N_PARAMS];
6240   MYSQL_BIND   my_bind[N_PARAMS], my_bind2[N_PARAMS];
6241   my_bool      is_null[N_PARAMS], is_null2[N_PARAMS];
6242   MYSQL_TIME   tm;
6243   longlong     bigint= 123;
6244   double       real= 123;
6245   char         dec[40];
6246 
6247   if (mysql_get_server_version(mysql) < 50600)
6248   {
6249     if (!opt_silent)
6250       fprintf(stdout, "Skipping test_temporal_param: this test cannot be "
6251               "executed on servers prior to 5.6 until bug#16328037 is fixed\n");
6252     return;
6253   }
6254 
6255   /* Initialize param/fetch buffers for data, null flags, lengths */
6256   memset(&my_bind, 0, sizeof(my_bind));
6257   memset(&my_bind2, 0, sizeof(my_bind2));
6258   memset(&length, 0, sizeof(length));
6259   memset(&length2, 0, sizeof(length2));
6260   memset(&is_null, 0, sizeof(is_null));
6261   memset(&is_null2, 0, sizeof(is_null2));
6262 
6263   /* Initialize the first input parameter */
6264   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
6265   my_bind[0].buffer= (void *) &tm;
6266   my_bind[0].is_null= &is_null[0];
6267   my_bind[0].length= &length[0];
6268   my_bind[0].buffer_length= (ulong)sizeof(tm);
6269 
6270   /* Clone the second and the third input parameter */
6271   my_bind[2]= my_bind[1]= my_bind[0];
6272 
6273   /* Initialize fetch parameters */
6274   my_bind2[0].buffer_type= MYSQL_TYPE_LONGLONG;
6275   my_bind2[0].length= &length2[0];
6276   my_bind2[0].is_null= &is_null2[0];
6277   my_bind2[0].buffer_length= (ulong)sizeof(bigint);
6278   my_bind2[0].buffer= (void *) &bigint;
6279 
6280   my_bind2[1].buffer_type= MYSQL_TYPE_DOUBLE;
6281   my_bind2[1].length= &length2[1];
6282   my_bind2[1].is_null= &is_null2[1];
6283   my_bind2[1].buffer_length= (ulong)sizeof(real);
6284   my_bind2[1].buffer= (void *) &real;
6285 
6286   my_bind2[2].buffer_type= MYSQL_TYPE_STRING;
6287   my_bind2[2].length= &length2[2];
6288   my_bind2[2].is_null= &is_null2[2];
6289   my_bind2[2].buffer_length= (ulong)sizeof(dec);
6290   my_bind2[2].buffer= (void *) &dec;
6291 
6292 
6293   /* Prepare and bind input and output parameters */
6294   stmt= mysql_simple_prepare(mysql, "SELECT CAST(? AS SIGNED), ?+0e0, ?+0.0");
6295   check_stmt(stmt);
6296   verify_param_count(stmt, N_PARAMS);
6297 
6298   rc= mysql_stmt_bind_param(stmt, my_bind);
6299   check_execute(stmt, rc);
6300 
6301   rc= mysql_stmt_bind_result(stmt, my_bind2);
6302   check_execute(stmt, rc);
6303 
6304   /* Initialize DATETIME value */
6305   tm.neg= 0;
6306   tm.time_type= MYSQL_TIMESTAMP_DATETIME;
6307   tm.year= 2001;
6308   tm.month= 10;
6309   tm.day= 20;
6310   tm.hour= 10;
6311   tm.minute= 10;
6312   tm.second= 59;
6313   tm.second_part= 500000;
6314 
6315   /* Execute and fetch */
6316   rc= mysql_stmt_execute(stmt);
6317   check_execute(stmt, rc);
6318 
6319   rc= mysql_stmt_store_result(stmt);
6320   check_execute(stmt, rc);
6321 
6322   rc= mysql_stmt_fetch(stmt);
6323   check_execute(stmt, rc);
6324 
6325   if (!opt_silent)
6326     printf("\n%lld %f '%s'\n", bigint, real, dec);
6327 
6328   /* Check values.  */
6329   DIE_UNLESS(bigint ==  20011020101100LL);
6330   DIE_UNLESS(real == 20011020101059.5);
6331   DIE_UNLESS(!strcmp(dec, "20011020101059.500000"));
6332 
6333   mysql_stmt_close(stmt);
6334 
6335   /* Re-initialize input parameters to TIME data type */
6336   my_bind[0].buffer_type= my_bind[1].buffer_type=
6337                           my_bind[2].buffer_type= MYSQL_TYPE_TIME;
6338 
6339   /* Prepare and bind intput and output parameters */
6340   stmt= mysql_simple_prepare(mysql, "SELECT CAST(? AS SIGNED), ?+0e0, ?+0.0");
6341   check_stmt(stmt);
6342   verify_param_count(stmt, N_PARAMS);
6343 
6344   rc= mysql_stmt_bind_param(stmt, my_bind);
6345   check_execute(stmt, rc);
6346 
6347   rc= mysql_stmt_bind_result(stmt, my_bind2);
6348   check_execute(stmt, rc);
6349 
6350   /* Initialize TIME value */
6351   tm.neg= 0;
6352   tm.time_type= MYSQL_TIMESTAMP_TIME;
6353   tm.year= tm.month= tm.day= 0;
6354   tm.hour= 10;
6355   tm.minute= 10;
6356   tm.second= 59;
6357   tm.second_part= 500000;
6358 
6359   /* Execute and fetch */
6360   rc= mysql_stmt_execute(stmt);
6361   check_execute(stmt, rc);
6362 
6363   rc= mysql_stmt_store_result(stmt);
6364   check_execute(stmt, rc);
6365 
6366   rc= mysql_stmt_fetch(stmt);
6367   check_execute(stmt, rc);
6368 
6369   if (!opt_silent)
6370     printf("\n%lld %f '%s'\n", bigint, real, dec);
6371 
6372   /* Check returned values */
6373   DIE_UNLESS(bigint ==  101100);
6374   DIE_UNLESS(real ==  101059.5);
6375   DIE_UNLESS(!strcmp(dec, "101059.500000"));
6376 
6377   mysql_stmt_close(stmt);
6378 }
6379 
6380 
6381 
6382 
6383 /* Misc tests to keep pure coverage happy */
6384 
test_pure_coverage()6385 static void test_pure_coverage()
6386 {
6387   MYSQL_STMT *stmt;
6388   MYSQL_BIND my_bind[2];
6389   int        rc;
6390   ulong      length;
6391 
6392   myheader("test_pure_coverage");
6393 
6394   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_pure");
6395   myquery(rc);
6396 
6397   rc= mysql_query(mysql, "CREATE TABLE test_pure(c1 int, c2 varchar(20))");
6398   myquery(rc);
6399 
6400   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c67788) values(10)");
6401   check_stmt_r(stmt);
6402 
6403   /* Query without params and result should allow to bind 0 arrays */
6404   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(10)");
6405   check_stmt(stmt);
6406 
6407   rc= mysql_stmt_bind_param(stmt, (MYSQL_BIND*)0);
6408   check_execute(stmt, rc);
6409 
6410   rc= mysql_stmt_execute(stmt);
6411   check_execute(stmt, rc);
6412 
6413   rc= mysql_stmt_bind_result(stmt, (MYSQL_BIND*)0);
6414   DIE_UNLESS(rc == 1);
6415 
6416   mysql_stmt_close(stmt);
6417 
6418   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(?)");
6419   check_stmt(stmt);
6420 
6421   /*
6422     We need to memset bind structure because mysql_stmt_bind_param checks all
6423     its members.
6424   */
6425   memset(my_bind, 0, sizeof(my_bind));
6426 
6427   my_bind[0].length= &length;
6428   my_bind[0].is_null= 0;
6429   my_bind[0].buffer_length= 0;
6430 
6431   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6432   rc= mysql_stmt_bind_param(stmt, my_bind);
6433   check_execute_r(stmt, rc); /* unsupported buffer type */
6434 
6435   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6436   rc= mysql_stmt_bind_param(stmt, my_bind);
6437   check_execute(stmt, rc);
6438 
6439   rc= mysql_stmt_store_result(stmt);
6440   check_execute(stmt, rc);
6441 
6442   mysql_stmt_close(stmt);
6443 
6444   stmt= mysql_simple_prepare(mysql, "select * from test_pure");
6445   check_execute(stmt, rc);
6446 
6447   rc= mysql_stmt_execute(stmt);
6448   check_execute(stmt, rc);
6449 
6450   // NOTE: stmt now has two columns, but only my_bind[0] is initialized.
6451   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6452   rc= mysql_stmt_bind_result(stmt, my_bind);
6453   check_execute_r(stmt, rc); /* unsupported buffer type */
6454 
6455   rc= mysql_stmt_store_result(stmt);
6456   DIE_UNLESS(rc);
6457 
6458   rc= mysql_stmt_store_result(stmt);
6459   DIE_UNLESS(rc); /* Old error must be reset first */
6460 
6461   mysql_stmt_close(stmt);
6462 
6463   mysql_query(mysql, "DROP TABLE test_pure");
6464 }
6465 
6466 
6467 /* Test for string buffer fetch */
6468 
test_buffers()6469 static void test_buffers()
6470 {
6471   MYSQL_STMT *stmt;
6472   // The test_pure table has two columns.
6473   MYSQL_BIND my_bind[2];
6474   int        rc;
6475   ulong      length;
6476   my_bool    is_null;
6477   char       buffer[20];
6478 
6479   myheader("test_buffers");
6480 
6481   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_buffer");
6482   myquery(rc);
6483 
6484   rc= mysql_query(mysql, "CREATE TABLE test_buffer(str varchar(20))");
6485   myquery(rc);
6486 
6487   rc= mysql_query(mysql, "insert into test_buffer values('MySQL')\
6488                           , ('Database'), ('Open-Source'), ('Popular')");
6489   myquery(rc);
6490 
6491   stmt= mysql_simple_prepare(mysql, "select str from test_buffer");
6492   check_stmt(stmt);
6493 
6494   rc= mysql_stmt_execute(stmt);
6495   check_execute(stmt, rc);
6496 
6497   memset(buffer, 0, sizeof(buffer));  /* Avoid overruns in printf() */
6498 
6499   memset(my_bind, 0, sizeof(my_bind));
6500   my_bind[0].length= &length;
6501   my_bind[0].is_null= &is_null;
6502   my_bind[0].buffer_length= 1;
6503   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6504   my_bind[0].buffer= (void *)buffer;
6505   my_bind[0].error= &my_bind[0].error_value;
6506 
6507   rc= mysql_stmt_bind_result(stmt, my_bind);
6508   check_execute(stmt, rc);
6509 
6510   rc= mysql_stmt_store_result(stmt);
6511   check_execute(stmt, rc);
6512 
6513   buffer[1]= 'X';
6514   rc= mysql_stmt_fetch(stmt);
6515   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6516   DIE_UNLESS(my_bind[0].error_value);
6517   if (!opt_silent)
6518     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6519   DIE_UNLESS(buffer[0] == 'M');
6520   DIE_UNLESS(buffer[1] == 'X');
6521   DIE_UNLESS(length == 5);
6522 
6523   my_bind[0].buffer_length= 8;
6524   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6525   check_execute(stmt, rc);
6526 
6527   rc= mysql_stmt_fetch(stmt);
6528   check_execute(stmt, rc);
6529   if (!opt_silent)
6530     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6531   DIE_UNLESS(strncmp(buffer, "Database", 8) == 0);
6532   DIE_UNLESS(length == 8);
6533 
6534   my_bind[0].buffer_length= 12;
6535   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6536   check_execute(stmt, rc);
6537 
6538   rc= mysql_stmt_fetch(stmt);
6539   check_execute(stmt, rc);
6540   if (!opt_silent)
6541     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6542   DIE_UNLESS(strcmp(buffer, "Open-Source") == 0);
6543   DIE_UNLESS(length == 11);
6544 
6545   my_bind[0].buffer_length= 6;
6546   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6547   check_execute(stmt, rc);
6548 
6549   rc= mysql_stmt_fetch(stmt);
6550   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6551   DIE_UNLESS(my_bind[0].error_value);
6552   if (!opt_silent)
6553     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6554   DIE_UNLESS(strncmp(buffer, "Popula", 6) == 0);
6555   DIE_UNLESS(length == 7);
6556 
6557   mysql_stmt_close(stmt);
6558 }
6559 
6560 
6561 /* Test the direct query execution in the middle of open stmts */
6562 
test_open_direct()6563 static void test_open_direct()
6564 {
6565   MYSQL_STMT  *stmt;
6566   MYSQL_RES   *result;
6567   int         rc;
6568 
6569   myheader("test_open_direct");
6570 
6571   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_open_direct");
6572   myquery(rc);
6573 
6574   rc= mysql_query(mysql, "CREATE TABLE test_open_direct(id int, name char(6))");
6575   myquery(rc);
6576 
6577   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_open_direct values(10, 'mysql')");
6578   check_stmt(stmt);
6579 
6580   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6581   myquery(rc);
6582 
6583   result= mysql_store_result(mysql);
6584   mytest(result);
6585 
6586   rc= my_process_result_set(result);
6587   DIE_UNLESS(rc == 0);
6588   mysql_free_result(result);
6589 
6590   rc= mysql_stmt_execute(stmt);
6591   check_execute(stmt, rc);
6592 
6593   verify_st_affected_rows(stmt, 1);
6594 
6595   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6596   myquery(rc);
6597 
6598   result= mysql_store_result(mysql);
6599   mytest(result);
6600 
6601   rc= my_process_result_set(result);
6602   DIE_UNLESS(rc == 1);
6603   mysql_free_result(result);
6604 
6605   rc= mysql_stmt_execute(stmt);
6606   check_execute(stmt, rc);
6607 
6608   verify_st_affected_rows(stmt, 1);
6609 
6610   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6611   myquery(rc);
6612 
6613   result= mysql_store_result(mysql);
6614   mytest(result);
6615 
6616   rc= my_process_result_set(result);
6617   DIE_UNLESS(rc == 2);
6618   mysql_free_result(result);
6619 
6620   mysql_stmt_close(stmt);
6621 
6622   /* run a direct query in the middle of a fetch */
6623   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6624   check_stmt(stmt);
6625 
6626   rc= mysql_stmt_execute(stmt);
6627   check_execute(stmt, rc);
6628 
6629   rc= mysql_stmt_fetch(stmt);
6630   check_execute(stmt, rc);
6631 
6632   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6633   myquery_r(rc);
6634 
6635   rc= mysql_stmt_close(stmt);
6636   check_execute(stmt, rc);
6637 
6638   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6639   myquery(rc);
6640 
6641   /* run a direct query with store result */
6642   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6643   check_stmt(stmt);
6644 
6645   rc= mysql_stmt_execute(stmt);
6646   check_execute(stmt, rc);
6647 
6648   rc= mysql_stmt_store_result(stmt);
6649   check_execute(stmt, rc);
6650 
6651   rc= mysql_stmt_fetch(stmt);
6652   check_execute(stmt, rc);
6653 
6654   rc= mysql_query(mysql, "drop table test_open_direct");
6655   myquery(rc);
6656 
6657   rc= mysql_stmt_close(stmt);
6658   check_execute(stmt, rc);
6659 }
6660 
6661 
6662 /* Test fetch without prior bound buffers */
6663 
test_fetch_nobuffs()6664 static void test_fetch_nobuffs()
6665 {
6666   MYSQL_STMT *stmt;
6667   MYSQL_BIND my_bind[4];
6668   char       str[4][50];
6669   int        rc;
6670 
6671   myheader("test_fetch_nobuffs");
6672 
6673   stmt= mysql_simple_prepare(mysql, "SELECT DATABASE(), CURRENT_USER(), \
6674                               CURRENT_DATE(), CURRENT_TIME()");
6675   check_stmt(stmt);
6676 
6677   rc= mysql_stmt_execute(stmt);
6678   check_execute(stmt, rc);
6679 
6680   rc= 0;
6681   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6682     rc++;
6683 
6684   if (!opt_silent)
6685     fprintf(stdout, "\n total rows        : %d", rc);
6686   DIE_UNLESS(rc == 1);
6687 
6688   memset(my_bind, 0, sizeof(MYSQL_BIND));
6689   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6690   my_bind[0].buffer= (void *)str[0];
6691   my_bind[0].buffer_length= (ulong)sizeof(str[0]);
6692   my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0];
6693   my_bind[1].buffer= (void *)str[1];
6694   my_bind[2].buffer= (void *)str[2];
6695   my_bind[3].buffer= (void *)str[3];
6696 
6697   rc= mysql_stmt_bind_result(stmt, my_bind);
6698   check_execute(stmt, rc);
6699 
6700   rc= mysql_stmt_execute(stmt);
6701   check_execute(stmt, rc);
6702 
6703   rc= 0;
6704   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6705   {
6706     rc++;
6707     if (!opt_silent)
6708     {
6709       fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
6710       fprintf(stdout, "\n CURRENT_USER()    : %s", str[1]);
6711       fprintf(stdout, "\n CURRENT_DATE()    : %s", str[2]);
6712       fprintf(stdout, "\n CURRENT_TIME()    : %s", str[3]);
6713     }
6714   }
6715   if (!opt_silent)
6716     fprintf(stdout, "\n total rows        : %d", rc);
6717   DIE_UNLESS(rc == 1);
6718 
6719   mysql_stmt_close(stmt);
6720 }
6721 
6722 
6723 /* Test a misc bug */
6724 
test_ushort_bug()6725 static void test_ushort_bug()
6726 {
6727   MYSQL_STMT *stmt;
6728   MYSQL_BIND my_bind[4];
6729   ushort     short_value;
6730   uint32     long_value;
6731   ulong      s_length, l_length, ll_length, t_length;
6732   ulonglong  longlong_value;
6733   int        rc;
6734   uchar      tiny_value;
6735   char       llbuf[22];
6736   myheader("test_ushort_bug");
6737 
6738   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ushort");
6739   myquery(rc);
6740 
6741   rc= mysql_query(mysql, "CREATE TABLE test_ushort(a smallint unsigned, \
6742                                                   b smallint unsigned, \
6743                                                   c smallint unsigned, \
6744                                                   d smallint unsigned)");
6745   myquery(rc);
6746 
6747   rc= mysql_query(mysql,
6748                   "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)");
6749   myquery(rc);
6750 
6751 
6752   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ushort");
6753   check_stmt(stmt);
6754 
6755   rc= mysql_stmt_execute(stmt);
6756   check_execute(stmt, rc);
6757 
6758   memset(my_bind, 0, sizeof(my_bind));
6759   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6760   my_bind[0].buffer= (void *)&short_value;
6761   my_bind[0].is_unsigned= TRUE;
6762   my_bind[0].length= &s_length;
6763 
6764   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6765   my_bind[1].buffer= (void *)&long_value;
6766   my_bind[1].length= &l_length;
6767 
6768   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6769   my_bind[2].buffer= (void *)&longlong_value;
6770   my_bind[2].length= &ll_length;
6771 
6772   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6773   my_bind[3].buffer= (void *)&tiny_value;
6774   my_bind[3].is_unsigned= TRUE;
6775   my_bind[3].length= &t_length;
6776 
6777   rc= mysql_stmt_bind_result(stmt, my_bind);
6778   check_execute(stmt, rc);
6779 
6780   rc= mysql_stmt_fetch(stmt);
6781   check_execute(stmt, rc);
6782 
6783   if (!opt_silent)
6784   {
6785     fprintf(stdout, "\n ushort   : %d (%ld)", short_value, (long)s_length);
6786     fprintf(stdout, "\n ulong    : %lu (%ld)", (ulong) long_value, (long)l_length);
6787     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6788             (long)ll_length);
6789     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, (long)t_length);
6790   }
6791 
6792   DIE_UNLESS(short_value == 35999);
6793   DIE_UNLESS(s_length == 2);
6794 
6795   DIE_UNLESS(long_value == 35999);
6796   DIE_UNLESS(l_length == 4);
6797 
6798   DIE_UNLESS(longlong_value == 35999);
6799   DIE_UNLESS(ll_length == 8);
6800 
6801   DIE_UNLESS(tiny_value == 200);
6802   DIE_UNLESS(t_length == 1);
6803 
6804   rc= mysql_stmt_fetch(stmt);
6805   DIE_UNLESS(rc == MYSQL_NO_DATA);
6806 
6807   mysql_stmt_close(stmt);
6808 }
6809 
6810 
6811 /* Test a misc smallint-signed conversion bug */
6812 
test_sshort_bug()6813 static void test_sshort_bug()
6814 {
6815   MYSQL_STMT *stmt;
6816   MYSQL_BIND my_bind[4];
6817   short      short_value;
6818   int32      long_value;
6819   ulong      s_length, l_length, ll_length, t_length;
6820   ulonglong  longlong_value;
6821   int        rc;
6822   uchar      tiny_value;
6823   char       llbuf[22];
6824 
6825   myheader("test_sshort_bug");
6826 
6827   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sshort");
6828   myquery(rc);
6829 
6830   rc= mysql_query(mysql, "CREATE TABLE test_sshort(a smallint signed, \
6831                                                   b smallint signed, \
6832                                                   c smallint unsigned, \
6833                                                   d smallint unsigned)");
6834   myquery(rc);
6835 
6836   rc= mysql_query(mysql, "INSERT INTO test_sshort VALUES(-5999, -5999, 35999, 200)");
6837   myquery(rc);
6838 
6839 
6840   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_sshort");
6841   check_stmt(stmt);
6842 
6843   rc= mysql_stmt_execute(stmt);
6844   check_execute(stmt, rc);
6845 
6846   memset(my_bind, 0, sizeof(my_bind));
6847   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6848   my_bind[0].buffer= (void *)&short_value;
6849   my_bind[0].length= &s_length;
6850 
6851   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6852   my_bind[1].buffer= (void *)&long_value;
6853   my_bind[1].length= &l_length;
6854 
6855   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6856   my_bind[2].buffer= (void *)&longlong_value;
6857   my_bind[2].length= &ll_length;
6858 
6859   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6860   my_bind[3].buffer= (void *)&tiny_value;
6861   my_bind[3].is_unsigned= TRUE;
6862   my_bind[3].length= &t_length;
6863 
6864   rc= mysql_stmt_bind_result(stmt, my_bind);
6865   check_execute(stmt, rc);
6866 
6867   rc= mysql_stmt_fetch(stmt);
6868   check_execute(stmt, rc);
6869 
6870   if (!opt_silent)
6871   {
6872     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, (long)s_length);
6873     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, (long)l_length);
6874     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6875             (long)ll_length);
6876     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, (long)t_length);
6877   }
6878 
6879   DIE_UNLESS(short_value == -5999);
6880   DIE_UNLESS(s_length == 2);
6881 
6882   DIE_UNLESS(long_value == -5999);
6883   DIE_UNLESS(l_length == 4);
6884 
6885   DIE_UNLESS(longlong_value == 35999);
6886   DIE_UNLESS(ll_length == 8);
6887 
6888   DIE_UNLESS(tiny_value == 200);
6889   DIE_UNLESS(t_length == 1);
6890 
6891   rc= mysql_stmt_fetch(stmt);
6892   DIE_UNLESS(rc == MYSQL_NO_DATA);
6893 
6894   mysql_stmt_close(stmt);
6895 }
6896 
6897 
6898 /* Test a misc tinyint-signed conversion bug */
6899 
test_stiny_bug()6900 static void test_stiny_bug()
6901 {
6902   MYSQL_STMT *stmt;
6903   MYSQL_BIND my_bind[4];
6904   short      short_value;
6905   int32      long_value;
6906   ulong      s_length, l_length, ll_length, t_length;
6907   ulonglong  longlong_value;
6908   int        rc;
6909   uchar      tiny_value;
6910   char       llbuf[22];
6911 
6912   myheader("test_stiny_bug");
6913 
6914   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_stiny");
6915   myquery(rc);
6916 
6917   rc= mysql_query(mysql, "CREATE TABLE test_stiny(a tinyint signed, \
6918                                                   b tinyint signed, \
6919                                                   c tinyint unsigned, \
6920                                                   d tinyint unsigned)");
6921   myquery(rc);
6922 
6923   rc= mysql_query(mysql, "INSERT INTO test_stiny VALUES(-128, -127, 255, 0)");
6924   myquery(rc);
6925 
6926 
6927   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_stiny");
6928   check_stmt(stmt);
6929 
6930   rc= mysql_stmt_execute(stmt);
6931   check_execute(stmt, rc);
6932 
6933   memset(my_bind, 0, sizeof(my_bind));
6934   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6935   my_bind[0].buffer= (void *)&short_value;
6936   my_bind[0].length= &s_length;
6937 
6938   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6939   my_bind[1].buffer= (void *)&long_value;
6940   my_bind[1].length= &l_length;
6941 
6942   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6943   my_bind[2].buffer= (void *)&longlong_value;
6944   my_bind[2].length= &ll_length;
6945 
6946   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6947   my_bind[3].buffer= (void *)&tiny_value;
6948   my_bind[3].length= &t_length;
6949 
6950   rc= mysql_stmt_bind_result(stmt, my_bind);
6951   check_execute(stmt, rc);
6952 
6953   rc= mysql_stmt_fetch(stmt);
6954   check_execute(stmt, rc);
6955 
6956   if (!opt_silent)
6957   {
6958     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, (long)s_length);
6959     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, (long)l_length);
6960     fprintf(stdout, "\n longlong : %s  (%ld)", llstr(longlong_value, llbuf),
6961             (long)ll_length);
6962     fprintf(stdout, "\n tinyint  : %d    (%ld)", tiny_value, (long)t_length);
6963   }
6964 
6965   DIE_UNLESS(short_value == -128);
6966   DIE_UNLESS(s_length == 2);
6967 
6968   DIE_UNLESS(long_value == -127);
6969   DIE_UNLESS(l_length == 4);
6970 
6971   DIE_UNLESS(longlong_value == 255);
6972   DIE_UNLESS(ll_length == 8);
6973 
6974   DIE_UNLESS(tiny_value == 0);
6975   DIE_UNLESS(t_length == 1);
6976 
6977   rc= mysql_stmt_fetch(stmt);
6978   DIE_UNLESS(rc == MYSQL_NO_DATA);
6979 
6980   mysql_stmt_close(stmt);
6981 }
6982 
6983 
6984 /* Test misc field information, bug: #74 */
6985 
test_field_misc()6986 static void test_field_misc()
6987 {
6988   MYSQL_STMT  *stmt;
6989   MYSQL_RES   *result;
6990   int         rc;
6991 
6992   myheader("test_field_misc");
6993 
6994   rc= mysql_query(mysql, "SELECT @@autocommit");
6995   myquery(rc);
6996 
6997   result= mysql_store_result(mysql);
6998   mytest(result);
6999 
7000   rc= my_process_result_set(result);
7001   DIE_UNLESS(rc == 1);
7002 
7003   verify_prepare_field(result, 0,
7004                        "@@autocommit", "",  /* field and its org name */
7005                        MYSQL_TYPE_LONGLONG, /* field type */
7006                        "", "",              /* table and its org name */
7007                        "", 1, 0);           /* db name, length(its bool flag)*/
7008 
7009   mysql_free_result(result);
7010 
7011   stmt= mysql_simple_prepare(mysql, "SELECT @@autocommit");
7012   check_stmt(stmt);
7013 
7014   rc= mysql_stmt_execute(stmt);
7015   check_execute(stmt, rc);
7016 
7017   result= mysql_stmt_result_metadata(stmt);
7018   mytest(result);
7019 
7020   rc= my_process_stmt_result(stmt);
7021   DIE_UNLESS(rc == 1);
7022 
7023   verify_prepare_field(result, 0,
7024                        "@@autocommit", "",  /* field and its org name */
7025                        MYSQL_TYPE_LONGLONG, /* field type */
7026                        "", "",              /* table and its org name */
7027                        "", 1, 0);           /* db name, length(its bool flag)*/
7028 
7029   mysql_free_result(result);
7030   mysql_stmt_close(stmt);
7031 
7032   stmt= mysql_simple_prepare(mysql, "SELECT @@max_error_count");
7033   check_stmt(stmt);
7034 
7035   result= mysql_stmt_result_metadata(stmt);
7036   mytest(result);
7037 
7038   rc= mysql_stmt_execute(stmt);
7039   check_execute(stmt, rc);
7040 
7041   rc= my_process_stmt_result(stmt);
7042   DIE_UNLESS(rc == 1);
7043 
7044   verify_prepare_field(result, 0,
7045                        "@@max_error_count", "",   /* field and its org name */
7046                        MYSQL_TYPE_LONGLONG, /* field type */
7047                        "", "",              /* table and its org name */
7048                        /* db name, length */
7049                        "", MY_INT64_NUM_DECIMAL_DIGITS , 0);
7050 
7051   mysql_free_result(result);
7052   mysql_stmt_close(stmt);
7053 
7054   stmt= mysql_simple_prepare(mysql, "SELECT @@max_allowed_packet");
7055   check_stmt(stmt);
7056 
7057   result= mysql_stmt_result_metadata(stmt);
7058   mytest(result);
7059 
7060   rc= mysql_stmt_execute(stmt);
7061   check_execute(stmt, rc);
7062 
7063   DIE_UNLESS(1 == my_process_stmt_result(stmt));
7064 
7065   verify_prepare_field(result, 0,
7066                        "@@max_allowed_packet", "", /* field and its org name */
7067                        MYSQL_TYPE_LONGLONG, /* field type */
7068                        "", "",              /* table and its org name */
7069                        /* db name, length */
7070                        "", MY_INT64_NUM_DECIMAL_DIGITS, 0);
7071 
7072   mysql_free_result(result);
7073   mysql_stmt_close(stmt);
7074 
7075   stmt= mysql_simple_prepare(mysql, "SELECT @@sql_warnings");
7076   check_stmt(stmt);
7077 
7078   result= mysql_stmt_result_metadata(stmt);
7079   mytest(result);
7080 
7081   rc= mysql_stmt_execute(stmt);
7082   check_execute(stmt, rc);
7083 
7084   rc= my_process_stmt_result(stmt);
7085   DIE_UNLESS(rc == 1);
7086 
7087   verify_prepare_field(result, 0,
7088                        "@@sql_warnings", "",  /* field and its org name */
7089                        MYSQL_TYPE_LONGLONG,   /* field type */
7090                        "", "",                /* table and its org name */
7091                        "", 1, 0);             /* db name, length */
7092 
7093   mysql_free_result(result);
7094   mysql_stmt_close(stmt);
7095 }
7096 
7097 
7098 /*
7099   Test SET feature with prepare stmts
7100   bug #85 (reported by mark@mysql.com)
7101 */
7102 
test_set_option()7103 static void test_set_option()
7104 {
7105   MYSQL_STMT *stmt;
7106   MYSQL_RES  *result;
7107   int        rc;
7108 
7109   myheader("test_set_option");
7110 
7111   mysql_autocommit(mysql, TRUE);
7112 
7113   /* LIMIT the rows count to 2 */
7114   rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT= 2");
7115   myquery(rc);
7116 
7117   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_limit");
7118   myquery(rc);
7119 
7120   rc= mysql_query(mysql, "CREATE TABLE test_limit(a tinyint)");
7121   myquery(rc);
7122 
7123   rc= mysql_query(mysql, "INSERT INTO test_limit VALUES(10), (20), (30), (40)");
7124   myquery(rc);
7125 
7126   if (!opt_silent)
7127     fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)");
7128   rc= mysql_query(mysql, "SELECT * FROM test_limit");
7129   myquery(rc);
7130 
7131   result= mysql_store_result(mysql);
7132   mytest(result);
7133 
7134   rc= my_process_result_set(result);
7135   DIE_UNLESS(rc == 2);
7136 
7137   mysql_free_result(result);
7138 
7139   if (!opt_silent)
7140     fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)");
7141   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7142   check_stmt(stmt);
7143 
7144   rc= mysql_stmt_execute(stmt);
7145   check_execute(stmt, rc);
7146 
7147   rc= my_process_stmt_result(stmt);
7148   DIE_UNLESS(rc == 2);
7149 
7150   mysql_stmt_close(stmt);
7151 
7152   /* RESET the LIMIT the rows count to 0 */
7153   if (!opt_silent)
7154     fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)");
7155   rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT=DEFAULT");
7156   myquery(rc);
7157 
7158   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7159   check_stmt(stmt);
7160 
7161   rc= mysql_stmt_execute(stmt);
7162   check_execute(stmt, rc);
7163 
7164   rc= my_process_stmt_result(stmt);
7165   DIE_UNLESS(rc == 4);
7166 
7167   mysql_stmt_close(stmt);
7168 }
7169 
7170 
7171 #ifdef EMBEDDED_LIBRARY
test_embedded_start_stop()7172 static void test_embedded_start_stop()
7173 {
7174   MYSQL *mysql_emb=NULL;
7175   int i, j;
7176   int argc= original_argc;                    // Start with the original args
7177   char **argv, **my_argv;
7178   char test_name[]= "test_embedded_start_stop";
7179   const unsigned int drop_db= opt_drop_db;
7180 #define EMBEDDED_RESTARTS 64
7181 
7182   myheader("test_embedded_start_stop");
7183 
7184   /* Must stop the main embedded server, since we use the same config. */
7185   opt_drop_db= 0;
7186   client_disconnect(mysql);    /* disconnect from server */
7187   free_defaults(defaults_argv);
7188   mysql_server_end();
7189   /* Free everything allocated by my_once_alloc */
7190   my_end(0);
7191   opt_drop_db= drop_db;
7192 
7193   /*
7194     Use a copy of the original arguments.
7195     The arguments will be altered when reading the configs and parsing
7196     options.
7197   */
7198   my_argv= malloc((argc + 1) * sizeof(char*));
7199   if (!my_argv)
7200     exit(1);
7201 
7202   /* Test restarting the embedded library many times. */
7203   for (i= 1; i <= EMBEDDED_RESTARTS; i++)
7204   {
7205     argv= my_argv;
7206     argv[0]= test_name;
7207     for (j= 1; j < argc; j++)
7208       argv[j]= original_argv[j];
7209 
7210     /* Initialize everything again. */
7211     MY_INIT(argv[0]);
7212 
7213     /* Load the client defaults from the .cnf file[s]. */
7214     if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
7215     {
7216       myerror("load_defaults failed");
7217       exit(1);
7218     }
7219 
7220     /* Parse the options (including the ones given from defaults files). */
7221     get_options(&argc, &argv);
7222 
7223     /* mysql_library_init is the same as mysql_server_init. */
7224     if (mysql_library_init(embedded_server_arg_count,
7225                            embedded_server_args,
7226                            (char**) embedded_server_groups))
7227     {
7228       myerror("mysql_library_init failed");
7229       exit(1);
7230     }
7231 
7232     /* Create a client connection. */
7233     if (!(mysql_emb= mysql_client_init(NULL)))
7234     {
7235       myerror("mysql_client_init failed");
7236       exit(1);
7237     }
7238 
7239     /* Connect it and see if we can use the database. */
7240     if (!(mysql_real_connect(mysql_emb, opt_host, opt_user,
7241                              opt_password, current_db, 0,
7242                              NULL, 0)))
7243     {
7244       myerror("mysql_real_connect failed");
7245     }
7246 
7247     /* Close the client connection */
7248     mysql_close(mysql_emb);
7249     mysql_emb = NULL;
7250     /* Free arguments allocated for defaults files. */
7251     free_defaults(defaults_argv);
7252     /* mysql_library_end is a define for mysql_server_end. */
7253     mysql_library_end();
7254     /* Free everything allocated by my_once_alloc */
7255     my_end(0);
7256   }
7257 
7258   argc= original_argc;
7259   argv= my_argv;
7260   argv[0]= test_name;
7261   for (j= 1; j < argc; j++)
7262     argv[j]= original_argv[j];
7263 
7264   MY_INIT(argv[0]);
7265 
7266   if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
7267   {
7268     myerror("load_defaults failed \n ");
7269     exit(1);
7270   }
7271 
7272   get_options(&argc, &argv);
7273 
7274   /* Must start the main embedded server again after the test. */
7275   if (mysql_server_init(embedded_server_arg_count,
7276                         embedded_server_args,
7277                         (char**) embedded_server_groups))
7278     DIE("Can't initialize MySQL server");
7279 
7280   /* connect to server with no flags, default protocol, auto reconnect true */
7281   mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
7282   free(my_argv);
7283 }
7284 #endif /* EMBEDDED_LIBRARY */
7285 
7286 
7287 /*
7288   Test a misc GRANT option
7289   bug #89 (reported by mark@mysql.com)
7290 */
7291 
7292 #ifndef EMBEDDED_LIBRARY
test_prepare_grant()7293 static void test_prepare_grant()
7294 {
7295   int rc;
7296   char query[MAX_TEST_QUERY_LENGTH];
7297 
7298   myheader("test_prepare_grant");
7299 
7300   mysql_autocommit(mysql, TRUE);
7301 
7302   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_grant");
7303   myquery(rc);
7304 
7305   rc= mysql_query(mysql, "CREATE TABLE test_grant(a tinyint primary key auto_increment)");
7306   myquery(rc);
7307 
7308   strxmov(query, "GRANT INSERT, UPDATE, SELECT ON ", current_db,
7309                 ".test_grant TO 'test_grant'@",
7310                 opt_host ? opt_host : "'localhost'", NullS);
7311 
7312   if (mysql_query(mysql, query))
7313   {
7314     myerror("GRANT failed");
7315 
7316     /*
7317        If server started with --skip-grant-tables, skip this test, else
7318        exit to indicate an error
7319 
7320        ER_UNKNOWN_COM_ERROR= 1047
7321      */
7322     if (mysql_errno(mysql) != 1047)
7323       exit(1);
7324   }
7325   else
7326   {
7327     MYSQL *org_mysql= mysql, *lmysql;
7328     MYSQL_STMT *stmt;
7329 
7330     if (!opt_silent)
7331       fprintf(stdout, "\n Establishing a test connection ...");
7332     if (!(lmysql= mysql_client_init(NULL)))
7333     {
7334       myerror("mysql_client_init() failed");
7335       exit(1);
7336     }
7337     if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
7338                              "", current_db, opt_port,
7339                              opt_unix_socket, 0)))
7340     {
7341       myerror("connection failed");
7342       mysql_close(lmysql);
7343       exit(1);
7344     }
7345     lmysql->reconnect= 1;
7346     if (!opt_silent)
7347       fprintf(stdout, "OK");
7348 
7349     mysql= lmysql;
7350     rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)");
7351     myquery(rc);
7352 
7353     rc= mysql_query(mysql, "INSERT INTO test_grant(a) VALUES(NULL)");
7354     myquery(rc);
7355 
7356     execute_prepare_query("INSERT INTO test_grant(a) VALUES(NULL)", 1);
7357     execute_prepare_query("INSERT INTO test_grant VALUES(NULL)", 1);
7358     execute_prepare_query("UPDATE test_grant SET a=9 WHERE a=1", 1);
7359     rc= my_stmt_result("SELECT a FROM test_grant");
7360     DIE_UNLESS(rc == 4);
7361 
7362     /* Both DELETE expected to fail as user does not have DELETE privs */
7363 
7364     rc= mysql_query(mysql, "DELETE FROM test_grant");
7365     myquery_r(rc);
7366 
7367     stmt= mysql_simple_prepare(mysql, "DELETE FROM test_grant");
7368     check_stmt_r(stmt);
7369 
7370     rc= my_stmt_result("SELECT * FROM test_grant");
7371     DIE_UNLESS(rc == 4);
7372 
7373     mysql_close(lmysql);
7374     mysql= org_mysql;
7375 
7376     rc= mysql_query(mysql, "delete from mysql.user where User='test_grant'");
7377     myquery(rc);
7378     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7379 
7380     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_grant'");
7381     myquery(rc);
7382     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7383 
7384   }
7385 }
7386 #endif /* EMBEDDED_LIBRARY */
7387 
7388 /*
7389   Test a crash when invalid/corrupted .frm is used in the
7390   SHOW TABLE STATUS
7391   bug #93 (reported by serg@mysql.com).
7392 */
7393 
test_frm_bug()7394 static void test_frm_bug()
7395 {
7396   MYSQL_STMT *stmt;
7397   MYSQL_BIND my_bind[2];
7398   MYSQL_RES  *result;
7399   MYSQL_ROW  row;
7400   FILE       *test_file;
7401   char       data_dir[FN_REFLEN];
7402   char       test_frm[FN_REFLEN];
7403   int        rc;
7404 
7405   myheader("test_frm_bug");
7406 
7407   mysql_autocommit(mysql, TRUE);
7408 
7409   rc= mysql_query(mysql, "drop table if exists test_frm_bug");
7410   myquery(rc);
7411 
7412   rc= mysql_query(mysql, "flush tables");
7413   myquery(rc);
7414 
7415   stmt= mysql_simple_prepare(mysql, "show variables like 'datadir'");
7416   check_stmt(stmt);
7417 
7418   rc= mysql_stmt_execute(stmt);
7419   check_execute(stmt, rc);
7420 
7421   memset(my_bind, 0, sizeof(my_bind));
7422   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
7423   my_bind[0].buffer= data_dir;
7424   my_bind[0].buffer_length= FN_REFLEN;
7425   my_bind[1]= my_bind[0];
7426 
7427   rc= mysql_stmt_bind_result(stmt, my_bind);
7428   check_execute(stmt, rc);
7429 
7430   rc= mysql_stmt_fetch(stmt);
7431   check_execute(stmt, rc);
7432 
7433   if (!opt_silent)
7434     fprintf(stdout, "\n data directory: %s", data_dir);
7435 
7436   rc= mysql_stmt_fetch(stmt);
7437   DIE_UNLESS(rc == MYSQL_NO_DATA);
7438 
7439   strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS);
7440 
7441   if (!opt_silent)
7442     fprintf(stdout, "\n test_frm: %s", test_frm);
7443 
7444   if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
7445   {
7446     fprintf(stdout, "\n ERROR: my_fopen failed for '%s'", test_frm);
7447     fprintf(stdout, "\n test cancelled");
7448     exit(1);
7449   }
7450   if (!opt_silent)
7451     fprintf(test_file, "this is a junk file for test");
7452 
7453   rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'");
7454   myquery(rc);
7455 
7456   result= mysql_store_result(mysql);
7457   mytest(result);/* It can't be NULL */
7458 
7459   rc= my_process_result_set(result);
7460   DIE_UNLESS(rc == 1);
7461 
7462   mysql_data_seek(result, 0);
7463 
7464   row= mysql_fetch_row(result);
7465   mytest(row);
7466 
7467   if (!opt_silent)
7468     fprintf(stdout, "\n Comment: %s", row[17]);
7469   DIE_UNLESS(row[17] != 0);
7470 
7471   mysql_free_result(result);
7472   mysql_stmt_close(stmt);
7473 
7474   my_fclose(test_file, MYF(0));
7475   mysql_query(mysql, "drop table if exists test_frm_bug");
7476 }
7477 
7478 
7479 /* Test DECIMAL conversion */
7480 
test_decimal_bug()7481 static void test_decimal_bug()
7482 {
7483   MYSQL_STMT *stmt;
7484   MYSQL_BIND my_bind[1];
7485   char       data[30];
7486   int        rc;
7487   my_bool    is_null;
7488 
7489   myheader("test_decimal_bug");
7490 
7491   mysql_autocommit(mysql, TRUE);
7492 
7493   rc= mysql_query(mysql, "drop table if exists test_decimal_bug");
7494   myquery(rc);
7495 
7496   rc= mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10, 2))");
7497   myquery(rc);
7498 
7499   rc= mysql_query(mysql, "insert into test_decimal_bug value(8), (10.22), (5.61)");
7500   myquery(rc);
7501 
7502   stmt= mysql_simple_prepare(mysql, "select c1 from test_decimal_bug where c1= ?");
7503   check_stmt(stmt);
7504 
7505   /*
7506     We need to memset bind structure because mysql_stmt_bind_param checks all
7507     its members.
7508   */
7509   memset(my_bind, 0, sizeof(my_bind));
7510   memset(data, 0, sizeof(data));
7511 
7512   my_bind[0].buffer_type= MYSQL_TYPE_NEWDECIMAL;
7513   my_bind[0].buffer= (void *)data;
7514   my_bind[0].buffer_length= 25;
7515   my_bind[0].is_null= &is_null;
7516 
7517   is_null= 0;
7518   rc= mysql_stmt_bind_param(stmt, my_bind);
7519   check_execute(stmt, rc);
7520 
7521   my_stpcpy(data, "8.0");
7522   rc= mysql_stmt_execute(stmt);
7523   check_execute(stmt, rc);
7524 
7525   data[0]= 0;
7526   rc= mysql_stmt_bind_result(stmt, my_bind);
7527   check_execute(stmt, rc);
7528 
7529   rc= mysql_stmt_fetch(stmt);
7530   check_execute(stmt, rc);
7531 
7532   if (!opt_silent)
7533     fprintf(stdout, "\n data: %s", data);
7534   DIE_UNLESS(strcmp(data, "8.00") == 0);
7535 
7536   rc= mysql_stmt_fetch(stmt);
7537   DIE_UNLESS(rc == MYSQL_NO_DATA);
7538 
7539   my_stpcpy(data, "5.61");
7540   rc= mysql_stmt_execute(stmt);
7541   check_execute(stmt, rc);
7542 
7543   data[0]= 0;
7544   rc= mysql_stmt_bind_result(stmt, my_bind);
7545   check_execute(stmt, rc);
7546 
7547   rc= mysql_stmt_fetch(stmt);
7548   check_execute(stmt, rc);
7549 
7550   if (!opt_silent)
7551     fprintf(stdout, "\n data: %s", data);
7552   DIE_UNLESS(strcmp(data, "5.61") == 0);
7553 
7554   rc= mysql_stmt_fetch(stmt);
7555   DIE_UNLESS(rc == MYSQL_NO_DATA);
7556 
7557   is_null= 1;
7558   rc= mysql_stmt_execute(stmt);
7559   check_execute(stmt, rc);
7560 
7561   rc= mysql_stmt_fetch(stmt);
7562   DIE_UNLESS(rc == MYSQL_NO_DATA);
7563 
7564   my_stpcpy(data, "10.22"); is_null= 0;
7565   rc= mysql_stmt_execute(stmt);
7566   check_execute(stmt, rc);
7567 
7568   data[0]= 0;
7569   rc= mysql_stmt_bind_result(stmt, my_bind);
7570   check_execute(stmt, rc);
7571 
7572   rc= mysql_stmt_fetch(stmt);
7573   check_execute(stmt, rc);
7574 
7575   if (!opt_silent)
7576     fprintf(stdout, "\n data: %s", data);
7577   DIE_UNLESS(strcmp(data, "10.22") == 0);
7578 
7579   rc= mysql_stmt_fetch(stmt);
7580   DIE_UNLESS(rc == MYSQL_NO_DATA);
7581 
7582   mysql_stmt_close(stmt);
7583 }
7584 
7585 
7586 /* Test EXPLAIN bug (#115, reported by mark@mysql.com & georg@php.net). */
7587 
test_explain_bug()7588 static void test_explain_bug()
7589 {
7590   MYSQL_STMT *stmt;
7591   MYSQL_RES  *result;
7592   int        rc;
7593   int        no;
7594 
7595   myheader("test_explain_bug");
7596 
7597   mysql_autocommit(mysql, TRUE);
7598 
7599   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_explain");
7600   myquery(rc);
7601 
7602   rc= mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))");
7603   myquery(rc);
7604 
7605   stmt= mysql_simple_prepare(mysql, "explain test_explain");
7606   check_stmt(stmt);
7607 
7608   rc= mysql_stmt_execute(stmt);
7609   check_execute(stmt, rc);
7610 
7611   rc= my_process_stmt_result(stmt);
7612   DIE_UNLESS(rc == 2);
7613 
7614   result= mysql_stmt_result_metadata(stmt);
7615   mytest(result);
7616 
7617   if (!opt_silent)
7618     fprintf(stdout, "\n total fields in the result: %d",
7619             mysql_num_fields(result));
7620   DIE_UNLESS(6 == mysql_num_fields(result));
7621 
7622   verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
7623                        mysql_get_server_version(mysql) <= 50000 ?
7624                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7625                        0, 0, "information_schema", 64, 0);
7626 
7627   verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
7628                        0, 0, "information_schema", 0, 0);
7629 
7630   verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
7631                        mysql_get_server_version(mysql) <= 50000 ?
7632                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7633                        0, 0, "information_schema", 3, 0);
7634 
7635   verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
7636                        mysql_get_server_version(mysql) <= 50000 ?
7637                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7638                        0, 0, "information_schema", 3, 0);
7639 
7640   if ( mysql_get_server_version(mysql) >= 50027 )
7641   {
7642     /*  The patch for bug#23037 changes column type of DEAULT to blob */
7643     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7644                          MYSQL_TYPE_BLOB, 0, 0, "information_schema", 0, 0);
7645   }
7646   else
7647   {
7648     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7649                          mysql_get_server_version(mysql) >= 50027 ?
7650                          MYSQL_TYPE_BLOB :
7651                          mysql_get_server_version(mysql) <= 50000 ?
7652                          MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7653                          0, 0, "information_schema",
7654                          mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
7655   }
7656 
7657   verify_prepare_field(result, 5, "Extra", "EXTRA",
7658                        mysql_get_server_version(mysql) <= 50000 ?
7659                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7660                        0, 0, "information_schema",
7661                        mysql_get_server_version(mysql) <= 50602 ? 27 : 30,
7662                        0);
7663 
7664   mysql_free_result(result);
7665   mysql_stmt_close(stmt);
7666 
7667   stmt= mysql_simple_prepare(mysql, "explain select id, name FROM test_explain");
7668   check_stmt(stmt);
7669 
7670   rc= mysql_stmt_execute(stmt);
7671   check_execute(stmt, rc);
7672 
7673   rc= my_process_stmt_result(stmt);
7674   DIE_UNLESS(rc == 1);
7675 
7676   result= mysql_stmt_result_metadata(stmt);
7677   mytest(result);
7678 
7679   if (!opt_silent)
7680     fprintf(stdout, "\n total fields in the result: %d",
7681             mysql_num_fields(result));
7682   if (mysql_get_server_version(mysql) <= 50702)
7683     DIE_UNLESS(10 == mysql_num_fields(result));
7684   else
7685     DIE_UNLESS(12 == mysql_num_fields(result));
7686 
7687   no= 0;
7688 
7689   verify_prepare_field(result, no++, "id", "", MYSQL_TYPE_LONGLONG,
7690                        "", "", "", 3, 0);
7691 
7692   verify_prepare_field(result, no++, "select_type", "", MYSQL_TYPE_VAR_STRING,
7693                        "", "", "", 19, 0);
7694 
7695   verify_prepare_field(result, no++, "table", "", MYSQL_TYPE_VAR_STRING,
7696                        "", "", "", NAME_CHAR_LEN, 0);
7697 
7698   if (mysql_get_server_version(mysql) > 50702)
7699     no++;
7700 
7701   verify_prepare_field(result, no++, "type", "", MYSQL_TYPE_VAR_STRING,
7702                        "", "", "", 10, 0);
7703 
7704   verify_prepare_field(result, no++, "possible_keys", "", MYSQL_TYPE_VAR_STRING,
7705                        "", "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7706 
7707   verify_prepare_field(result, no++, "key", "", MYSQL_TYPE_VAR_STRING,
7708                        "", "", "", NAME_CHAR_LEN, 0);
7709 
7710   if (mysql_get_server_version(mysql) <= 50000)
7711   {
7712     verify_prepare_field(result, no++, "key_len", "", MYSQL_TYPE_LONGLONG, "",
7713                          "", "", 3, 0);
7714   }
7715   else
7716   {
7717     verify_prepare_field(result, no++, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
7718                          "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7719   }
7720 
7721   verify_prepare_field(result, no++, "ref", "", MYSQL_TYPE_VAR_STRING,
7722                        "", "", "", NAME_CHAR_LEN*16, 0);
7723 
7724   verify_prepare_field(result, no++, "rows", "", MYSQL_TYPE_LONGLONG,
7725                        "", "", "", 10, 0);
7726 
7727   if (mysql_get_server_version(mysql) > 50702)
7728     no++;
7729 
7730   verify_prepare_field(result, no++, "Extra", "", MYSQL_TYPE_VAR_STRING,
7731                        "", "", "", 255, 0);
7732 
7733   mysql_free_result(result);
7734   mysql_stmt_close(stmt);
7735 }
7736 
7737 #ifdef NOT_YET_WORKING
7738 
7739 /*
7740   Test math functions.
7741   Bug #148 (reported by salle@mysql.com).
7742 */
7743 
7744 #define myerrno(n) check_errcode(n)
7745 
check_errcode(const unsigned int err)7746 static void check_errcode(const unsigned int err)
7747 {
7748   if (!opt_silent || mysql_errno(mysql) != err)
7749   {
7750     if (mysql->server_version)
7751       fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
7752     else
7753       fprintf(stdout, "\n [MySQL]");
7754     fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
7755   }
7756   DIE_UNLESS(mysql_errno(mysql) == err);
7757 }
7758 
7759 
test_drop_temp()7760 static void test_drop_temp()
7761 {
7762   int rc;
7763 
7764   myheader("test_drop_temp");
7765 
7766   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS test_drop_temp_db");
7767   myquery(rc);
7768 
7769   rc= mysql_query(mysql, "CREATE DATABASE test_drop_temp_db");
7770   myquery(rc);
7771 
7772   rc= mysql_query(mysql, "CREATE TABLE test_drop_temp_db.t1(c1 int, c2 char(1))");
7773   myquery(rc);
7774 
7775   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7776   myquery(rc);
7777 
7778   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7779   myquery(rc);
7780 
7781   strxmov(query, "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@",
7782                 opt_host ? opt_host : "localhost", NullS);
7783 
7784   if (mysql_query(mysql, query))
7785   {
7786     myerror("GRANT failed");
7787 
7788     /*
7789        If server started with --skip-grant-tables, skip this test, else
7790        exit to indicate an error
7791 
7792        ER_UNKNOWN_COM_ERROR= 1047
7793      */
7794     if (mysql_errno(mysql) != 1047)
7795       exit(1);
7796   }
7797   else
7798   {
7799     MYSQL *org_mysql= mysql, *lmysql;
7800 
7801     if (!opt_silent)
7802       fprintf(stdout, "\n Establishing a test connection ...");
7803     if (!(lmysql= mysql_client_init(NULL)))
7804     {
7805       myerror("mysql_client_init() failed");
7806       exit(1);
7807     }
7808 
7809     rc= mysql_query(mysql, "flush privileges");
7810     myquery(rc);
7811 
7812     if (!(mysql_real_connect(lmysql, opt_host ? opt_host : "localhost", "test_temp",
7813                              "", "test_drop_temp_db", opt_port,
7814                              opt_unix_socket, 0)))
7815     {
7816       mysql= lmysql;
7817       myerror("connection failed");
7818       mysql_close(lmysql);
7819       exit(1);
7820     }
7821     lmysql->reconnect= 1;
7822     if (!opt_silent)
7823       fprintf(stdout, "OK");
7824 
7825     mysql= lmysql;
7826     rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')");
7827     myerrno((uint)1142);
7828 
7829     rc= mysql_query(mysql, "DROP TABLE t1");
7830     myerrno((uint)1142);
7831 
7832     mysql= org_mysql;
7833     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t1(c1 int)");
7834     myquery(rc);
7835 
7836     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t2 LIKE test_drop_temp_db.t1");
7837     myquery(rc);
7838 
7839     mysql= lmysql;
7840 
7841     rc= mysql_query(mysql, "DROP TABLE t1, t2");
7842     myquery_r(rc);
7843 
7844     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t1");
7845     myquery_r(rc);
7846 
7847     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t2");
7848     myquery_r(rc);
7849 
7850     mysql_close(lmysql);
7851     mysql= org_mysql;
7852 
7853     rc= mysql_query(mysql, "drop database test_drop_temp_db");
7854     myquery(rc);
7855     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7856 
7857     rc= mysql_query(mysql, "delete from mysql.user where User='test_temp'");
7858     myquery(rc);
7859     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7860 
7861 
7862     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_temp'");
7863     myquery(rc);
7864     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7865   }
7866 }
7867 #endif
7868 
7869 
7870 /* Test warnings for cuted rows */
7871 
test_cuted_rows()7872 static void test_cuted_rows()
7873 {
7874   int        rc, count;
7875   MYSQL_RES  *result;
7876 
7877   myheader("test_cuted_rows");
7878 
7879   mysql_query(mysql, "DROP TABLE if exists t1");
7880   mysql_query(mysql, "DROP TABLE if exists t2");
7881 
7882   rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)");
7883   myquery(rc);
7884 
7885   rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)");
7886   myquery(rc);
7887 
7888   rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)");
7889   myquery(rc);
7890 
7891   count= mysql_warning_count(mysql);
7892   if (!opt_silent)
7893     fprintf(stdout, "\n total warnings: %d", count);
7894   DIE_UNLESS(count == 0);
7895 
7896   rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
7897   myquery(rc);
7898 
7899   count= mysql_warning_count(mysql);
7900   if (!opt_silent)
7901     fprintf(stdout, "\n total warnings: %d", count);
7902   // Number of warnings changed in mysql-5.7
7903   DIE_UNLESS(count == (mysql_get_server_version(mysql) < 50700 ? 2 : 1));
7904 
7905   rc= mysql_query(mysql, "SHOW WARNINGS");
7906   myquery(rc);
7907 
7908   result= mysql_store_result(mysql);
7909   mytest(result);
7910 
7911   rc= my_process_result_set(result);
7912   // Number of warnings changed in mysql-5.7
7913   DIE_UNLESS(rc == (mysql_get_server_version(mysql) < 50700 ? 2 : 1));
7914   mysql_free_result(result);
7915 
7916   rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)");
7917   myquery(rc);
7918 
7919   count= mysql_warning_count(mysql);
7920   if (!opt_silent)
7921     fprintf(stdout, "\n total warnings: %d", count);
7922   DIE_UNLESS(count == 2);
7923 
7924   rc= mysql_query(mysql, "SHOW WARNINGS");
7925   myquery(rc);
7926 
7927   result= mysql_store_result(mysql);
7928   mytest(result);
7929 
7930   rc= my_process_result_set(result);
7931   DIE_UNLESS(rc == 2);
7932   mysql_free_result(result);
7933 }
7934 
7935 
7936 /* Test update/binary logs */
7937 
test_logs()7938 static void test_logs()
7939 {
7940   MYSQL_STMT *stmt;
7941   MYSQL_BIND my_bind[2];
7942   char       data[255];
7943   ulong      length;
7944   int        rc;
7945   short      id;
7946 
7947   myheader("test_logs");
7948 
7949 
7950   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs");
7951   myquery(rc);
7952 
7953   rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))");
7954   myquery(rc);
7955 
7956   my_stpcpy((char *)data, "INSERT INTO test_logs VALUES(?, ?)");
7957   stmt= mysql_simple_prepare(mysql, data);
7958   check_stmt(stmt);
7959 
7960   /*
7961     We need to memset bind structure because mysql_stmt_bind_param checks all
7962     its members.
7963   */
7964   memset(my_bind, 0, sizeof(my_bind));
7965 
7966   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
7967   my_bind[0].buffer= (void *)&id;
7968 
7969   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
7970   my_bind[1].buffer= (void *)&data;
7971   my_bind[1].buffer_length= 255;
7972   my_bind[1].length= &length;
7973 
7974   id= 9876;
7975   length= (ulong)(my_stpcpy((char *)data, "MySQL - Open Source Database")- data);
7976 
7977   rc= mysql_stmt_bind_param(stmt, my_bind);
7978   check_execute(stmt, rc);
7979 
7980   rc= mysql_stmt_execute(stmt);
7981   check_execute(stmt, rc);
7982 
7983   my_stpcpy((char *)data, "'");
7984   length= 1;
7985 
7986   rc= mysql_stmt_execute(stmt);
7987   check_execute(stmt, rc);
7988 
7989   my_stpcpy((char *)data, "\"");
7990   length= 1;
7991 
7992   rc= mysql_stmt_execute(stmt);
7993   check_execute(stmt, rc);
7994 
7995   length= (ulong)(my_stpcpy((char *)data, "my\'sql\'")-data);
7996   rc= mysql_stmt_execute(stmt);
7997   check_execute(stmt, rc);
7998 
7999   length= (ulong)(my_stpcpy((char *)data, "my\"sql\"")-data);
8000   rc= mysql_stmt_execute(stmt);
8001   check_execute(stmt, rc);
8002 
8003   mysql_stmt_close(stmt);
8004 
8005   my_stpcpy((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')");
8006   stmt= mysql_simple_prepare(mysql, data);
8007   check_stmt(stmt);
8008 
8009   rc= mysql_stmt_execute(stmt);
8010   check_execute(stmt, rc);
8011 
8012   rc= mysql_stmt_execute(stmt);
8013   check_execute(stmt, rc);
8014 
8015   mysql_stmt_close(stmt);
8016 
8017   my_stpcpy((char *)data, "SELECT * FROM test_logs WHERE id=?");
8018   stmt= mysql_simple_prepare(mysql, data);
8019   check_stmt(stmt);
8020 
8021   rc= mysql_stmt_bind_param(stmt, my_bind);
8022   check_execute(stmt, rc);
8023 
8024   rc= mysql_stmt_execute(stmt);
8025   check_execute(stmt, rc);
8026 
8027   my_bind[1].buffer_length= 255;
8028   rc= mysql_stmt_bind_result(stmt, my_bind);
8029   check_execute(stmt, rc);
8030 
8031   rc= mysql_stmt_fetch(stmt);
8032   check_execute(stmt, rc);
8033 
8034   if (!opt_silent)
8035   {
8036     fprintf(stdout, "id    : %d\n", id);
8037     fprintf(stdout, "name  : %s(%ld)\n", data, (long)length);
8038   }
8039 
8040   DIE_UNLESS(id == 9876);
8041   DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */
8042   DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1);
8043 
8044   rc= mysql_stmt_fetch(stmt);
8045   check_execute(stmt, rc);
8046 
8047   if (!opt_silent)
8048     fprintf(stdout, "\n name  : %s(%ld)", data, (long)length);
8049 
8050   DIE_UNLESS(length == 1);
8051   DIE_UNLESS(strcmp(data, "'") == 0);
8052 
8053   rc= mysql_stmt_fetch(stmt);
8054   check_execute(stmt, rc);
8055 
8056   if (!opt_silent)
8057     fprintf(stdout, "\n name  : %s(%ld)", data, (long)length);
8058 
8059   DIE_UNLESS(length == 1);
8060   DIE_UNLESS(strcmp(data, "\"") == 0);
8061 
8062   rc= mysql_stmt_fetch(stmt);
8063   check_execute(stmt, rc);
8064 
8065   if (!opt_silent)
8066     fprintf(stdout, "\n name  : %s(%ld)", data, (long)length);
8067 
8068   DIE_UNLESS(length == 7);
8069   DIE_UNLESS(strcmp(data, "my\'sql\'") == 0);
8070 
8071   rc= mysql_stmt_fetch(stmt);
8072   check_execute(stmt, rc);
8073 
8074   if (!opt_silent)
8075     fprintf(stdout, "\n name  : %s(%ld)", data, (long)length);
8076 
8077   DIE_UNLESS(length == 7);
8078   /*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */
8079 
8080   rc= mysql_stmt_fetch(stmt);
8081   DIE_UNLESS(rc == MYSQL_NO_DATA);
8082 
8083   mysql_stmt_close(stmt);
8084 
8085   rc= mysql_query(mysql, "DROP TABLE test_logs");
8086   myquery(rc);
8087 }
8088 
8089 
8090 /* Test 'n' statements create and close */
8091 
test_nstmts()8092 static void test_nstmts()
8093 {
8094   MYSQL_STMT  *stmt;
8095   char        query[255];
8096   int         rc;
8097   static uint i, total_stmts= 2000;
8098   MYSQL_BIND  my_bind[1];
8099 
8100   myheader("test_nstmts");
8101 
8102   mysql_autocommit(mysql, TRUE);
8103 
8104   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_nstmts");
8105   myquery(rc);
8106 
8107   rc= mysql_query(mysql, "CREATE TABLE test_nstmts(id int)");
8108   myquery(rc);
8109 
8110   /*
8111     We need to memset bind structure because mysql_stmt_bind_param checks all
8112     its members.
8113   */
8114   memset(my_bind, 0, sizeof(my_bind));
8115 
8116   my_bind[0].buffer= (void *)&i;
8117   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8118 
8119   for (i= 0; i < total_stmts; i++)
8120   {
8121     if (!opt_silent)
8122       fprintf(stdout, "\r stmt: %d", i);
8123 
8124     my_stpcpy(query, "insert into test_nstmts values(?)");
8125     stmt= mysql_simple_prepare(mysql, query);
8126     check_stmt(stmt);
8127 
8128     rc= mysql_stmt_bind_param(stmt, my_bind);
8129     check_execute(stmt, rc);
8130 
8131     rc= mysql_stmt_execute(stmt);
8132     check_execute(stmt, rc);
8133 
8134     mysql_stmt_close(stmt);
8135   }
8136 
8137   stmt= mysql_simple_prepare(mysql, " select count(*) from test_nstmts");
8138   check_stmt(stmt);
8139 
8140   rc= mysql_stmt_execute(stmt);
8141   check_execute(stmt, rc);
8142 
8143   i= 0;
8144   rc= mysql_stmt_bind_result(stmt, my_bind);
8145   check_execute(stmt, rc);
8146 
8147   rc= mysql_stmt_fetch(stmt);
8148   check_execute(stmt, rc);
8149   if (!opt_silent)
8150     fprintf(stdout, "\n total rows: %d", i);
8151   DIE_UNLESS( i == total_stmts);
8152 
8153   rc= mysql_stmt_fetch(stmt);
8154   DIE_UNLESS(rc == MYSQL_NO_DATA);
8155 
8156   mysql_stmt_close(stmt);
8157 
8158   rc= mysql_query(mysql, "DROP TABLE test_nstmts");
8159   myquery(rc);
8160 }
8161 
8162 
8163 /* Test stmt seek() functions */
8164 
test_fetch_seek()8165 static void test_fetch_seek()
8166 {
8167   MYSQL_STMT *stmt;
8168   MYSQL_BIND my_bind[3];
8169   MYSQL_ROW_OFFSET row;
8170   int        rc;
8171   int32      c1;
8172   char       c2[11], c3[20];
8173 
8174   myheader("test_fetch_seek");
8175   rc= mysql_query(mysql, "drop table if exists t1");
8176 
8177   myquery(rc);
8178 
8179   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
8180   myquery(rc);
8181 
8182   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
8183   myquery(rc);
8184 
8185   stmt= mysql_simple_prepare(mysql, "select * from t1");
8186   check_stmt(stmt);
8187 
8188   memset(my_bind, 0, sizeof(my_bind));
8189   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8190   my_bind[0].buffer= (void *)&c1;
8191 
8192   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8193   my_bind[1].buffer= (void *)c2;
8194   my_bind[1].buffer_length= (ulong)sizeof(c2);
8195 
8196   my_bind[2]= my_bind[1];
8197   my_bind[2].buffer= (void *)c3;
8198   my_bind[2].buffer_length= (ulong)sizeof(c3);
8199 
8200   rc= mysql_stmt_execute(stmt);
8201   check_execute(stmt, rc);
8202 
8203   rc= mysql_stmt_bind_result(stmt, my_bind);
8204   check_execute(stmt, rc);
8205 
8206   rc= mysql_stmt_store_result(stmt);
8207   check_execute(stmt, rc);
8208 
8209   rc= mysql_stmt_fetch(stmt);
8210   check_execute(stmt, rc);
8211 
8212   if (!opt_silent)
8213     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8214 
8215   row= mysql_stmt_row_tell(stmt);
8216 
8217   row= mysql_stmt_row_seek(stmt, row);
8218 
8219   rc= mysql_stmt_fetch(stmt);
8220   check_execute(stmt, rc);
8221 
8222   if (!opt_silent)
8223     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8224 
8225   row= mysql_stmt_row_seek(stmt, row);
8226 
8227   rc= mysql_stmt_fetch(stmt);
8228   check_execute(stmt, rc);
8229 
8230   if (!opt_silent)
8231     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8232 
8233   mysql_stmt_data_seek(stmt, 0);
8234 
8235   rc= mysql_stmt_fetch(stmt);
8236   check_execute(stmt, rc);
8237 
8238   if (!opt_silent)
8239     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8240 
8241   rc= mysql_stmt_fetch(stmt);
8242   check_execute(stmt, rc);
8243 
8244   rc= mysql_stmt_fetch(stmt);
8245   check_execute(stmt, rc);
8246 
8247   rc= mysql_stmt_fetch(stmt);
8248   check_execute(stmt, rc);
8249 
8250   rc= mysql_stmt_fetch(stmt);
8251   DIE_UNLESS(rc == MYSQL_NO_DATA);
8252 
8253   mysql_stmt_close(stmt);
8254   myquery(mysql_query(mysql, "drop table t1"));
8255 }
8256 
8257 
8258 /* Test mysql_stmt_fetch_column() with offset */
8259 
test_fetch_offset()8260 static void test_fetch_offset()
8261 {
8262   MYSQL_STMT *stmt;
8263   MYSQL_BIND my_bind[1];
8264   char       data[11];
8265   ulong      length;
8266   int        rc;
8267   my_bool    is_null;
8268 
8269 
8270   myheader("test_fetch_offset");
8271 
8272   rc= mysql_query(mysql, "drop table if exists t1");
8273   myquery(rc);
8274 
8275   rc= mysql_query(mysql, "create table t1(a char(10))");
8276   myquery(rc);
8277 
8278   rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)");
8279   myquery(rc);
8280 
8281   stmt= mysql_simple_prepare(mysql, "select * from t1");
8282   check_stmt(stmt);
8283 
8284   memset(my_bind, 0, sizeof(my_bind));
8285   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8286   my_bind[0].buffer= (void *)data;
8287   my_bind[0].buffer_length= 11;
8288   my_bind[0].is_null= &is_null;
8289   my_bind[0].length= &length;
8290 
8291   rc= mysql_stmt_execute(stmt);
8292   check_execute(stmt, rc);
8293 
8294   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8295   check_execute_r(stmt, rc);
8296 
8297   rc= mysql_stmt_execute(stmt);
8298   check_execute(stmt, rc);
8299 
8300   rc= mysql_stmt_bind_result(stmt, my_bind);
8301   check_execute(stmt, rc);
8302 
8303   rc= mysql_stmt_store_result(stmt);
8304   check_execute(stmt, rc);
8305 
8306   rc= mysql_stmt_fetch(stmt);
8307   check_execute(stmt, rc);
8308 
8309   data[0]= '\0';
8310   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8311   check_execute(stmt, rc);
8312   if (!opt_silent)
8313     fprintf(stdout, "\n col 1: %s (%ld)", data, (long)length);
8314   DIE_UNLESS(strncmp(data, "abcd", 4) == 0 && length == 10);
8315 
8316   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5);
8317   check_execute(stmt, rc);
8318   if (!opt_silent)
8319     fprintf(stdout, "\n col 1: %s (%ld)", data, (long)length);
8320   DIE_UNLESS(strncmp(data, "fg", 2) == 0 && length == 10);
8321 
8322   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9);
8323   check_execute(stmt, rc);
8324   if (!opt_silent)
8325     fprintf(stdout, "\n col 0: %s (%ld)", data, (long)length);
8326   DIE_UNLESS(strncmp(data, "j", 1) == 0 && length == 10);
8327 
8328   rc= mysql_stmt_fetch(stmt);
8329   check_execute(stmt, rc);
8330 
8331   is_null= 0;
8332 
8333   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8334   check_execute(stmt, rc);
8335 
8336   DIE_UNLESS(is_null == 1);
8337 
8338   rc= mysql_stmt_fetch(stmt);
8339   DIE_UNLESS(rc == MYSQL_NO_DATA);
8340 
8341   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8342   check_execute_r(stmt, rc);
8343 
8344   mysql_stmt_close(stmt);
8345 
8346   myquery(mysql_query(mysql, "drop table t1"));
8347 }
8348 
8349 
8350 /* Test mysql_stmt_fetch_column() */
8351 
test_fetch_column()8352 static void test_fetch_column()
8353 {
8354   MYSQL_STMT *stmt;
8355   MYSQL_BIND my_bind[2];
8356   char       c2[20], bc2[20];
8357   ulong      l1, l2, bl1, bl2;
8358   int        rc, c1, bc1;
8359 
8360   myheader("test_fetch_column");
8361 
8362   rc= mysql_query(mysql, "drop table if exists t1");
8363   myquery(rc);
8364 
8365   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
8366   myquery(rc);
8367 
8368   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
8369   myquery(rc);
8370 
8371   stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc");
8372   check_stmt(stmt);
8373 
8374   memset(my_bind, 0, sizeof(my_bind));
8375   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8376   my_bind[0].buffer= (void *)&bc1;
8377   my_bind[0].buffer_length= 0;
8378   my_bind[0].is_null= 0;
8379   my_bind[0].length= &bl1;
8380   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8381   my_bind[1].buffer= (void *)bc2;
8382   my_bind[1].buffer_length= 7;
8383   my_bind[1].is_null= 0;
8384   my_bind[1].length= &bl2;
8385 
8386   rc= mysql_stmt_execute(stmt);
8387   check_execute(stmt, rc);
8388 
8389   rc= mysql_stmt_bind_result(stmt, my_bind);
8390   check_execute(stmt, rc);
8391 
8392   rc= mysql_stmt_store_result(stmt);
8393   check_execute(stmt, rc);
8394 
8395   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */
8396   check_execute_r(stmt, rc);
8397 
8398   rc= mysql_stmt_fetch(stmt);
8399   check_execute(stmt, rc);
8400 
8401   if (!opt_silent)
8402     fprintf(stdout, "\n row 0: %d, %s", bc1, bc2);
8403 
8404   c2[0]= '\0'; l2= 0;
8405   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8406   my_bind[0].buffer= (void *)c2;
8407   my_bind[0].buffer_length= 7;
8408   my_bind[0].is_null= 0;
8409   my_bind[0].length= &l2;
8410 
8411   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8412   check_execute(stmt, rc);
8413   if (!opt_silent)
8414     fprintf(stdout, "\n col 1: %s(%ld)", c2, (long)l2);
8415   DIE_UNLESS(strncmp(c2, "venu", 4) == 0 && l2 == 4);
8416 
8417   c2[0]= '\0'; l2= 0;
8418   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8419   check_execute(stmt, rc);
8420   if (!opt_silent)
8421     fprintf(stdout, "\n col 1: %s(%ld)", c2, (long)l2);
8422   DIE_UNLESS(strcmp(c2, "venu") == 0 && l2 == 4);
8423 
8424   c1= 0;
8425   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8426   my_bind[0].buffer= (void *)&c1;
8427   my_bind[0].buffer_length= 0;
8428   my_bind[0].is_null= 0;
8429   my_bind[0].length= &l1;
8430 
8431   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8432   check_execute(stmt, rc);
8433   if (!opt_silent)
8434     fprintf(stdout, "\n col 0: %d(%ld)", c1, (long)l1);
8435   DIE_UNLESS(c1 == 1 && l1 == 4);
8436 
8437   rc= mysql_stmt_fetch(stmt);
8438   check_execute(stmt, rc);
8439 
8440   if (!opt_silent)
8441     fprintf(stdout, "\n row 1: %d, %s", bc1, bc2);
8442 
8443   c2[0]= '\0'; l2= 0;
8444   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8445   my_bind[0].buffer= (void *)c2;
8446   my_bind[0].buffer_length= 7;
8447   my_bind[0].is_null= 0;
8448   my_bind[0].length= &l2;
8449 
8450   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8451   check_execute(stmt, rc);
8452   if (!opt_silent)
8453     fprintf(stdout, "\n col 1: %s(%ld)", c2, (long)l2);
8454   DIE_UNLESS(strncmp(c2, "mysq", 4) == 0 && l2 == 5);
8455 
8456   c2[0]= '\0'; l2= 0;
8457   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8458   check_execute(stmt, rc);
8459   if (!opt_silent)
8460     fprintf(stdout, "\n col 1: %si(%ld)", c2, (long)l2);
8461   DIE_UNLESS(strcmp(c2, "mysql") == 0 && l2 == 5);
8462 
8463   c1= 0;
8464   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8465   my_bind[0].buffer= (void *)&c1;
8466   my_bind[0].buffer_length= 0;
8467   my_bind[0].is_null= 0;
8468   my_bind[0].length= &l1;
8469 
8470   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8471   check_execute(stmt, rc);
8472   if (!opt_silent)
8473     fprintf(stdout, "\n col 0: %d(%ld)", c1, (long)l1);
8474   DIE_UNLESS(c1 == 2 && l1 == 4);
8475 
8476   rc= mysql_stmt_fetch(stmt);
8477   DIE_UNLESS(rc == MYSQL_NO_DATA);
8478 
8479   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8480   check_execute_r(stmt, rc);
8481 
8482   mysql_stmt_close(stmt);
8483   myquery(mysql_query(mysql, "drop table t1"));
8484 }
8485 
8486 
8487 /* Test mysql_list_fields() */
8488 
test_list_fields()8489 static void test_list_fields()
8490 {
8491   MYSQL_RES *result;
8492   int rc;
8493   myheader("test_list_fields");
8494 
8495   rc= mysql_query(mysql, "drop table if exists t1");
8496   myquery(rc);
8497 
8498   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10) default 'mysql')");
8499   myquery(rc);
8500 
8501   result= mysql_list_fields(mysql, "t1", NULL);
8502   mytest(result);
8503 
8504   rc= my_process_result_set(result);
8505   DIE_UNLESS(rc == 0);
8506 
8507   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_LONG,
8508                        "t1", "t1",
8509                        current_db, 11, "0");
8510 
8511   verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_STRING,
8512                        "t1", "t1",
8513                        current_db, 10, "mysql");
8514 
8515   mysql_free_result(result);
8516   myquery(mysql_query(mysql, "drop table t1"));
8517 }
8518 
8519 
test_bug19671()8520 static void test_bug19671()
8521 {
8522   MYSQL_RES *result;
8523   int rc;
8524   myheader("test_bug19671");
8525 
8526   mysql_query(mysql, "set sql_mode=''");
8527   rc= mysql_query(mysql, "drop table if exists t1");
8528   myquery(rc);
8529 
8530   rc= mysql_query(mysql, "drop view if exists v1");
8531   myquery(rc);
8532 
8533   rc= mysql_query(mysql, "create table t1(f1 int)");
8534   myquery(rc);
8535 
8536   rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
8537   myquery(rc);
8538 
8539   result= mysql_list_fields(mysql, "v1", NULL);
8540   mytest(result);
8541 
8542   rc= my_process_result_set(result);
8543   DIE_UNLESS(rc == 0);
8544 
8545   verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
8546                        "v1", "v1", current_db, 11, "0");
8547 
8548   mysql_free_result(result);
8549   myquery(mysql_query(mysql, "drop view v1"));
8550   myquery(mysql_query(mysql, "drop table t1"));
8551 }
8552 
8553 
8554 /* Test a memory ovverun bug */
8555 
test_mem_overun()8556 static void test_mem_overun()
8557 {
8558   char       buffer[10000], field[10];
8559   MYSQL_STMT *stmt;
8560   MYSQL_RES  *field_res;
8561   int        rc, i;
8562   ulong      length;
8563 
8564   myheader("test_mem_overun");
8565 
8566   /*
8567     Test a memory ovverun bug when a table had 1000 fields with
8568     a row of data
8569   */
8570   rc= mysql_query(mysql, "drop table if exists t_mem_overun");
8571   myquery(rc);
8572 
8573   strxmov(buffer, "create table t_mem_overun(", NullS);
8574   for (i= 0; i < 1000; i++)
8575   {
8576     sprintf(field, "c%d int", i);
8577     strxmov(buffer, buffer, field, ", ", NullS);
8578   }
8579   length= (ulong)strlen(buffer);
8580   buffer[length-2]= ')';
8581   buffer[--length]= '\0';
8582 
8583   strcat(buffer," ENGINE = MyISAM ");
8584   length= (ulong)strlen(buffer);
8585   rc= mysql_real_query(mysql, buffer, length);
8586   myquery(rc);
8587 
8588   strxmov(buffer, "insert into t_mem_overun values(", NullS);
8589   for (i= 0; i < 1000; i++)
8590   {
8591     strxmov(buffer, buffer, "1, ", NullS);
8592   }
8593   length= (ulong)strlen(buffer);
8594   buffer[length-2]= ')';
8595   buffer[--length]= '\0';
8596 
8597   rc= mysql_real_query(mysql, buffer, length);
8598   myquery(rc);
8599 
8600   rc= mysql_query(mysql, "select * from t_mem_overun");
8601   myquery(rc);
8602 
8603   rc= my_process_result(mysql);
8604   DIE_UNLESS(rc == 1);
8605 
8606   stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun");
8607   check_stmt(stmt);
8608 
8609   rc= mysql_stmt_execute(stmt);
8610   check_execute(stmt, rc);
8611 
8612   field_res= mysql_stmt_result_metadata(stmt);
8613   mytest(field_res);
8614 
8615   if (!opt_silent)
8616     fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
8617   DIE_UNLESS( 1000 == mysql_num_fields(field_res));
8618 
8619   rc= mysql_stmt_store_result(stmt);
8620   check_execute(stmt, rc);
8621 
8622   rc= mysql_stmt_fetch(stmt);
8623   check_execute(stmt, rc);
8624 
8625   rc= mysql_stmt_fetch(stmt);
8626   DIE_UNLESS(rc == MYSQL_NO_DATA);
8627 
8628   mysql_free_result(field_res);
8629 
8630   mysql_stmt_close(stmt);
8631 }
8632 
8633 
8634 /* Test mysql_stmt_free_result() */
8635 
test_free_result()8636 static void test_free_result()
8637 {
8638   MYSQL_STMT *stmt;
8639   MYSQL_BIND my_bind[1];
8640   char       c2[5];
8641   ulong      bl1, l2;
8642   int        rc, c1, bc1;
8643 
8644   myheader("test_free_result");
8645 
8646   rc= mysql_query(mysql, "drop table if exists test_free_result");
8647   myquery(rc);
8648 
8649   rc= mysql_query(mysql, "create table test_free_result("
8650                          "c1 int primary key auto_increment)");
8651   myquery(rc);
8652 
8653   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8654   myquery(rc);
8655 
8656   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8657   check_stmt(stmt);
8658 
8659   memset(my_bind, 0, sizeof(my_bind));
8660   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8661   my_bind[0].buffer= (void *)&bc1;
8662   my_bind[0].length= &bl1;
8663 
8664   rc= mysql_stmt_execute(stmt);
8665   check_execute(stmt, rc);
8666 
8667   rc= mysql_stmt_bind_result(stmt, my_bind);
8668   check_execute(stmt, rc);
8669 
8670   rc= mysql_stmt_fetch(stmt);
8671   check_execute(stmt, rc);
8672 
8673   c2[0]= '\0'; l2= 0;
8674   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8675   my_bind[0].buffer= (void *)c2;
8676   my_bind[0].buffer_length= 7;
8677   my_bind[0].is_null= 0;
8678   my_bind[0].length= &l2;
8679 
8680   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8681   check_execute(stmt, rc);
8682   if (!opt_silent)
8683     fprintf(stdout, "\n col 0: %s(%ld)", c2, (long)l2);
8684   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8685 
8686   rc= mysql_stmt_fetch(stmt);
8687   check_execute(stmt, rc);
8688 
8689   c1= 0, l2= 0;
8690   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8691   my_bind[0].buffer= (void *)&c1;
8692   my_bind[0].buffer_length= 0;
8693   my_bind[0].is_null= 0;
8694   my_bind[0].length= &l2;
8695 
8696   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8697   check_execute(stmt, rc);
8698   if (!opt_silent)
8699     fprintf(stdout, "\n col 0: %d(%ld)", c1, (long)l2);
8700   DIE_UNLESS(c1 == 2 && l2 == 4);
8701 
8702   rc= mysql_query(mysql, "drop table test_free_result");
8703   myquery_r(rc); /* error should be, COMMANDS OUT OF SYNC */
8704 
8705   rc= mysql_stmt_free_result(stmt);
8706   check_execute(stmt, rc);
8707 
8708   rc= mysql_query(mysql, "drop table test_free_result");
8709   myquery(rc);  /* should be successful */
8710 
8711   mysql_stmt_close(stmt);
8712 }
8713 
8714 
8715 /* Test mysql_stmt_store_result() */
8716 
test_free_store_result()8717 static void test_free_store_result()
8718 {
8719   MYSQL_STMT *stmt;
8720   MYSQL_BIND my_bind[1];
8721   char       c2[5];
8722   ulong      bl1, l2;
8723   int        rc, c1, bc1;
8724 
8725   myheader("test_free_store_result");
8726 
8727   rc= mysql_query(mysql, "drop table if exists test_free_result");
8728   myquery(rc);
8729 
8730   rc= mysql_query(mysql, "create table test_free_result(c1 int primary key auto_increment)");
8731   myquery(rc);
8732 
8733   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8734   myquery(rc);
8735 
8736   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8737   check_stmt(stmt);
8738 
8739   memset(my_bind, 0, sizeof(my_bind));
8740   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8741   my_bind[0].buffer= (void *)&bc1;
8742   my_bind[0].buffer_length= 0;
8743   my_bind[0].is_null= 0;
8744   my_bind[0].length= &bl1;
8745 
8746   rc= mysql_stmt_execute(stmt);
8747   check_execute(stmt, rc);
8748 
8749   rc= mysql_stmt_bind_result(stmt, my_bind);
8750   check_execute(stmt, rc);
8751 
8752   rc= mysql_stmt_store_result(stmt);
8753   check_execute(stmt, rc);
8754 
8755   rc= mysql_stmt_fetch(stmt);
8756   check_execute(stmt, rc);
8757 
8758   c2[0]= '\0'; l2= 0;
8759   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8760   my_bind[0].buffer= (void *)c2;
8761   my_bind[0].buffer_length= 7;
8762   my_bind[0].is_null= 0;
8763   my_bind[0].length= &l2;
8764 
8765   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8766   check_execute(stmt, rc);
8767   if (!opt_silent)
8768     fprintf(stdout, "\n col 1: %s(%ld)", c2, (long)l2);
8769   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8770 
8771   rc= mysql_stmt_fetch(stmt);
8772   check_execute(stmt, rc);
8773 
8774   c1= 0, l2= 0;
8775   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8776   my_bind[0].buffer= (void *)&c1;
8777   my_bind[0].buffer_length= 0;
8778   my_bind[0].is_null= 0;
8779   my_bind[0].length= &l2;
8780 
8781   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8782   check_execute(stmt, rc);
8783   if (!opt_silent)
8784     fprintf(stdout, "\n col 0: %d(%ld)", c1, (long)l2);
8785   DIE_UNLESS(c1 == 2 && l2 == 4);
8786 
8787   rc= mysql_stmt_free_result(stmt);
8788   check_execute(stmt, rc);
8789 
8790   rc= mysql_query(mysql, "drop table test_free_result");
8791   myquery(rc);
8792 
8793   mysql_stmt_close(stmt);
8794 }
8795 
8796 
8797 /* Test SQLmode */
8798 
test_sqlmode()8799 static void test_sqlmode()
8800 {
8801   MYSQL_STMT *stmt;
8802   MYSQL_BIND my_bind[2];
8803   char       c1[5], c2[5];
8804   int        rc;
8805   char query[MAX_TEST_QUERY_LENGTH];
8806 
8807   myheader("test_sqlmode");
8808 
8809   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping");
8810   myquery(rc);
8811 
8812   rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))");
8813   myquery(rc);
8814 
8815   /* PIPES_AS_CONCAT */
8816   my_stpcpy(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
8817   if (!opt_silent)
8818     fprintf(stdout, "\n With %s", query);
8819   rc= mysql_query(mysql, query);
8820   myquery(rc);
8821 
8822   my_stpcpy(query, "INSERT INTO test_piping VALUES(?||?)");
8823   if (!opt_silent)
8824     fprintf(stdout, "\n  query: %s", query);
8825   stmt= mysql_simple_prepare(mysql, query);
8826   check_stmt(stmt);
8827 
8828   if (!opt_silent)
8829     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8830 
8831   /*
8832     We need to memset bind structure because mysql_stmt_bind_param checks all
8833     its members.
8834   */
8835   memset(my_bind, 0, sizeof(my_bind));
8836 
8837   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8838   my_bind[0].buffer= (void *)c1;
8839   my_bind[0].buffer_length= 2;
8840 
8841   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8842   my_bind[1].buffer= (void *)c2;
8843   my_bind[1].buffer_length= 3;
8844 
8845   rc= mysql_stmt_bind_param(stmt, my_bind);
8846   check_execute(stmt, rc);
8847 
8848   my_stpcpy(c1, "My"); my_stpcpy(c2, "SQL");
8849   rc= mysql_stmt_execute(stmt);
8850   check_execute(stmt, rc);
8851   mysql_stmt_close(stmt);
8852 
8853   verify_col_data("test_piping", "name", "MySQL");
8854 
8855   rc= mysql_query(mysql, "DELETE FROM test_piping");
8856   myquery(rc);
8857 
8858   my_stpcpy(query, "SELECT connection_id    ()");
8859   if (!opt_silent)
8860     fprintf(stdout, "\n  query: %s", query);
8861   stmt= mysql_simple_prepare(mysql, query);
8862   check_stmt(stmt);
8863   mysql_stmt_close(stmt);
8864 
8865   /* ANSI */
8866   my_stpcpy(query, "SET SQL_MODE= \"ANSI\"");
8867   if (!opt_silent)
8868     fprintf(stdout, "\n With %s", query);
8869   rc= mysql_query(mysql, query);
8870   myquery(rc);
8871 
8872   my_stpcpy(query, "INSERT INTO test_piping VALUES(?||?)");
8873   if (!opt_silent)
8874     fprintf(stdout, "\n  query: %s", query);
8875   stmt= mysql_simple_prepare(mysql, query);
8876   check_stmt(stmt);
8877   if (!opt_silent)
8878     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8879 
8880   rc= mysql_stmt_bind_param(stmt, my_bind);
8881   check_execute(stmt, rc);
8882 
8883   my_stpcpy(c1, "My"); my_stpcpy(c2, "SQL");
8884   rc= mysql_stmt_execute(stmt);
8885   check_execute(stmt, rc);
8886 
8887   mysql_stmt_close(stmt);
8888   verify_col_data("test_piping", "name", "MySQL");
8889 
8890   /* ANSI mode spaces ... */
8891   my_stpcpy(query, "SELECT connection_id    ()");
8892   if (!opt_silent)
8893     fprintf(stdout, "\n  query: %s", query);
8894   stmt= mysql_simple_prepare(mysql, query);
8895   check_stmt(stmt);
8896 
8897   rc= mysql_stmt_execute(stmt);
8898   check_execute(stmt, rc);
8899 
8900   rc= mysql_stmt_fetch(stmt);
8901   check_execute(stmt, rc);
8902 
8903   rc= mysql_stmt_fetch(stmt);
8904   DIE_UNLESS(rc == MYSQL_NO_DATA);
8905   if (!opt_silent)
8906     fprintf(stdout, "\n  returned 1 row\n");
8907 
8908   mysql_stmt_close(stmt);
8909 
8910   /* IGNORE SPACE MODE */
8911   my_stpcpy(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
8912   if (!opt_silent)
8913     fprintf(stdout, "\n With %s", query);
8914   rc= mysql_query(mysql, query);
8915   myquery(rc);
8916 
8917   my_stpcpy(query, "SELECT connection_id    ()");
8918   if (!opt_silent)
8919     fprintf(stdout, "\n  query: %s", query);
8920   stmt= mysql_simple_prepare(mysql, query);
8921   check_stmt(stmt);
8922 
8923   rc= mysql_stmt_execute(stmt);
8924   check_execute(stmt, rc);
8925 
8926   rc= mysql_stmt_fetch(stmt);
8927   check_execute(stmt, rc);
8928 
8929   rc= mysql_stmt_fetch(stmt);
8930   DIE_UNLESS(rc == MYSQL_NO_DATA);
8931   if (!opt_silent)
8932     fprintf(stdout, "\n  returned 1 row");
8933 
8934   mysql_stmt_close(stmt);
8935 }
8936 
8937 
8938 /* Test for timestamp handling */
8939 
test_ts()8940 static void test_ts()
8941 {
8942   MYSQL_STMT *stmt;
8943   MYSQL_BIND my_bind[6];
8944   MYSQL_TIME ts;
8945   MYSQL_RES  *prep_res;
8946   char       strts[30];
8947   ulong      length;
8948   int        rc, field_count;
8949   char       name;
8950   char query[MAX_TEST_QUERY_LENGTH];
8951   const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
8952                             "SELECT a, b, c FROM test_ts WHERE %c=?",
8953                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
8954   myheader("test_ts");
8955 
8956   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts");
8957   myquery(rc);
8958 
8959   rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)");
8960   myquery(rc);
8961 
8962   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)");
8963   check_stmt(stmt);
8964 
8965   ts.year= 2003;
8966   ts.month= 07;
8967   ts.day= 12;
8968   ts.hour= 21;
8969   ts.minute= 07;
8970   ts.second= 46;
8971   ts.second_part= 0;
8972   length= (long)(my_stpcpy(strts, "2003-07-12 21:07:46") - strts);
8973 
8974   /*
8975     We need to memset bind structure because mysql_stmt_bind_param checks all
8976     its members.
8977   */
8978   memset(my_bind, 0, sizeof(my_bind));
8979 
8980   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
8981   my_bind[0].buffer= (void *)&ts;
8982   my_bind[0].buffer_length= (ulong)sizeof(ts);
8983 
8984   my_bind[2]= my_bind[1]= my_bind[0];
8985 
8986   my_bind[3].buffer_type= MYSQL_TYPE_STRING;
8987   my_bind[3].buffer= (void *)strts;
8988   my_bind[3].buffer_length= (ulong)sizeof(strts);
8989   my_bind[3].length= &length;
8990 
8991   my_bind[5]= my_bind[4]= my_bind[3];
8992 
8993   rc= mysql_stmt_bind_param(stmt, my_bind);
8994   check_execute(stmt, rc);
8995 
8996   rc= mysql_stmt_execute(stmt);
8997   check_execute(stmt, rc);
8998 
8999   mysql_stmt_close(stmt);
9000 
9001   verify_col_data("test_ts", "a", "2003-07-12");
9002   verify_col_data("test_ts", "b", "21:07:46");
9003   verify_col_data("test_ts", "c", "2003-07-12 21:07:46");
9004 
9005   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts");
9006   check_stmt(stmt);
9007 
9008   prep_res= mysql_stmt_result_metadata(stmt);
9009   mytest(prep_res);
9010 
9011   rc= mysql_stmt_execute(stmt);
9012   check_execute(stmt, rc);
9013 
9014   rc= my_process_stmt_result(stmt);
9015   DIE_UNLESS(rc == 2);
9016   field_count= mysql_num_fields(prep_res);
9017 
9018   mysql_free_result(prep_res);
9019   mysql_stmt_close(stmt);
9020 
9021   for (name= 'a'; field_count--; name++)
9022   {
9023     int row_count= 0;
9024 
9025     sprintf(query, queries[field_count], name);
9026 
9027     if (!opt_silent)
9028       fprintf(stdout, "\n  %s", query);
9029     stmt= mysql_simple_prepare(mysql, query);
9030     check_stmt(stmt);
9031 
9032     rc= mysql_stmt_bind_param(stmt, my_bind);
9033     check_execute(stmt, rc);
9034 
9035     rc= mysql_stmt_execute(stmt);
9036     check_execute(stmt, rc);
9037 
9038     while (mysql_stmt_fetch(stmt) == 0)
9039       row_count++;
9040 
9041     if (!opt_silent)
9042       fprintf(stdout, "\n   returned '%d' rows", row_count);
9043     DIE_UNLESS(row_count == 2);
9044     mysql_stmt_close(stmt);
9045   }
9046 }
9047 
9048 
9049 /* Test for bug #1500. */
9050 
test_bug1500()9051 static void test_bug1500()
9052 {
9053   MYSQL_STMT *stmt;
9054   MYSQL_BIND my_bind[3];
9055   int        rc;
9056   int32 int_data[3]= {2, 3, 4};
9057   const char *data;
9058 
9059   myheader("test_bug1500");
9060 
9061   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
9062   myquery(rc);
9063 
9064   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (i INT)");
9065   myquery(rc);
9066 
9067   rc= mysql_query(mysql, "INSERT INTO test_bg1500 VALUES (1), (2)");
9068   myquery(rc);
9069 
9070   rc= mysql_commit(mysql);
9071   myquery(rc);
9072 
9073   stmt= mysql_simple_prepare(mysql, "SELECT i FROM test_bg1500 WHERE i IN (?, ?, ?)");
9074   check_stmt(stmt);
9075   verify_param_count(stmt, 3);
9076 
9077   /*
9078     We need to memset bind structure because mysql_stmt_bind_param checks all
9079     its members.
9080   */
9081   memset(my_bind, 0, sizeof(my_bind));
9082 
9083   my_bind[0].buffer= (void *)int_data;
9084   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9085   my_bind[2]= my_bind[1]= my_bind[0];
9086   my_bind[1].buffer= (void *)(int_data + 1);
9087   my_bind[2].buffer= (void *)(int_data + 2);
9088 
9089   rc= mysql_stmt_bind_param(stmt, my_bind);
9090   check_execute(stmt, rc);
9091 
9092   rc= mysql_stmt_execute(stmt);
9093   check_execute(stmt, rc);
9094 
9095   rc= my_process_stmt_result(stmt);
9096   DIE_UNLESS(rc == 1);
9097 
9098   mysql_stmt_close(stmt);
9099 
9100   rc= mysql_query(mysql, "DROP TABLE test_bg1500");
9101   myquery(rc);
9102 
9103   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM");
9104   myquery(rc);
9105 
9106   rc= mysql_query(mysql,
9107         "INSERT INTO test_bg1500 VALUES ('Gravedigger'), ('Greed'), ('Hollow Dogs')");
9108   myquery(rc);
9109 
9110   rc= mysql_commit(mysql);
9111   myquery(rc);
9112 
9113   stmt= mysql_simple_prepare(mysql,
9114           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)");
9115   check_stmt(stmt);
9116 
9117   verify_param_count(stmt, 1);
9118 
9119   data= "Dogs";
9120   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9121   my_bind[0].buffer= (void *) data;
9122   my_bind[0].buffer_length= (ulong)strlen(data);
9123   my_bind[0].is_null= 0;
9124   my_bind[0].length= 0;
9125 
9126   rc= mysql_stmt_bind_param(stmt, my_bind);
9127   check_execute(stmt, rc);
9128 
9129   rc= mysql_stmt_execute(stmt);
9130   check_execute(stmt, rc);
9131 
9132   rc= my_process_stmt_result(stmt);
9133   DIE_UNLESS(rc == 1);
9134 
9135   mysql_stmt_close(stmt);
9136 
9137   /* This should work too */
9138   stmt= mysql_simple_prepare(mysql,
9139           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?, 'digger'))");
9140   check_stmt(stmt);
9141 
9142   verify_param_count(stmt, 1);
9143 
9144   data= "Grave";
9145   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9146   my_bind[0].buffer= (void *) data;
9147   my_bind[0].buffer_length= (ulong)strlen(data);
9148 
9149   rc= mysql_stmt_bind_param(stmt, my_bind);
9150   check_execute(stmt, rc);
9151 
9152   rc= mysql_stmt_execute(stmt);
9153   check_execute(stmt, rc);
9154 
9155   rc= my_process_stmt_result(stmt);
9156   DIE_UNLESS(rc == 1);
9157 
9158   mysql_stmt_close(stmt);
9159 }
9160 
9161 
test_bug1946()9162 static void test_bug1946()
9163 {
9164   MYSQL_STMT *stmt;
9165   int rc;
9166   const char *query= "INSERT INTO prepare_command VALUES (?)";
9167 
9168   myheader("test_bug1946");
9169 
9170   rc= mysql_query(mysql, "DROP TABLE IF EXISTS prepare_command");
9171   myquery(rc);
9172 
9173   rc= mysql_query(mysql, "CREATE TABLE prepare_command(ID INT)");
9174   myquery(rc);
9175 
9176   stmt= mysql_simple_prepare(mysql, query);
9177   check_stmt(stmt);
9178   rc= mysql_real_query(mysql, query, (ulong)strlen(query));
9179   DIE_UNLESS(rc != 0);
9180   if (!opt_silent)
9181     fprintf(stdout, "Got error (as expected):\n");
9182   myerror(NULL);
9183 
9184   mysql_stmt_close(stmt);
9185   rc= mysql_query(mysql, "DROP TABLE prepare_command");
9186 }
9187 
9188 
test_parse_error_and_bad_length()9189 static void test_parse_error_and_bad_length()
9190 {
9191   MYSQL_STMT *stmt;
9192   int rc;
9193 
9194   /* check that we get 4 syntax errors over the 4 calls */
9195   myheader("test_parse_error_and_bad_length");
9196 
9197   rc= mysql_query(mysql, "SHOW DATABAAAA");
9198   DIE_UNLESS(rc);
9199   if (!opt_silent)
9200     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9201   rc= mysql_real_query(mysql, "SHOW DATABASES", 12); // Incorrect length.
9202   DIE_UNLESS(rc);
9203   if (!opt_silent)
9204     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9205 
9206   stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA");
9207   DIE_UNLESS(!stmt);
9208   if (!opt_silent)
9209     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9210   stmt= mysql_stmt_init(mysql);
9211   DIE_UNLESS(stmt);
9212   rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 12); // Incorrect length.
9213   DIE_UNLESS(rc != 0);
9214   if (!opt_silent)
9215     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
9216   mysql_stmt_close(stmt);
9217 }
9218 
9219 
test_bug2247()9220 static void test_bug2247()
9221 {
9222   MYSQL_STMT *stmt;
9223   MYSQL_RES *res;
9224   int rc;
9225   int i;
9226   const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)";
9227   const char *insert= "INSERT INTO bug2247 VALUES (NULL)";
9228   const char *SELECT= "SELECT id FROM bug2247";
9229   const char *update= "UPDATE bug2247 SET id=id+10";
9230   const char *drop= "DROP TABLE IF EXISTS bug2247";
9231   ulonglong exp_count;
9232   enum { NUM_ROWS= 5 };
9233 
9234   myheader("test_bug2247");
9235 
9236   if (!opt_silent)
9237     fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
9238                   "mysql_query ... ");
9239   /* create table and insert few rows */
9240   rc= mysql_query(mysql, drop);
9241   myquery(rc);
9242 
9243   rc= mysql_query(mysql, create);
9244   myquery(rc);
9245 
9246   stmt= mysql_simple_prepare(mysql, insert);
9247   check_stmt(stmt);
9248   for (i= 0; i < NUM_ROWS; ++i)
9249   {
9250     rc= mysql_stmt_execute(stmt);
9251     check_execute(stmt, rc);
9252   }
9253   exp_count= mysql_stmt_affected_rows(stmt);
9254   DIE_UNLESS(exp_count == 1);
9255 
9256   rc= mysql_query(mysql, SELECT);
9257   myquery(rc);
9258   /*
9259     mysql_store_result overwrites mysql->affected_rows. Check that
9260     mysql_stmt_affected_rows() returns the same value, whereas
9261     mysql_affected_rows() value is correct.
9262   */
9263   res= mysql_store_result(mysql);
9264   mytest(res);
9265 
9266   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9267   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9268 
9269   rc= mysql_query(mysql, update);
9270   myquery(rc);
9271   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9272   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9273 
9274   mysql_free_result(res);
9275   mysql_stmt_close(stmt);
9276 
9277   /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */
9278   stmt= mysql_simple_prepare(mysql, SELECT);
9279   check_stmt(stmt);
9280 
9281   rc= mysql_stmt_execute(stmt);
9282   check_execute(stmt, rc);
9283   rc= mysql_stmt_store_result(stmt);
9284   check_execute(stmt, rc);
9285   exp_count= mysql_stmt_affected_rows(stmt);
9286   DIE_UNLESS(exp_count == NUM_ROWS);
9287 
9288   rc= mysql_query(mysql, insert);
9289   myquery(rc);
9290   DIE_UNLESS(mysql_affected_rows(mysql) == 1);
9291   DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count);
9292 
9293   mysql_stmt_close(stmt);
9294   if (!opt_silent)
9295     fprintf(stdout, "OK");
9296 }
9297 
9298 
test_subqueries()9299 static void test_subqueries()
9300 {
9301   MYSQL_STMT *stmt;
9302   int rc, i;
9303   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";
9304 
9305   myheader("test_subqueries");
9306 
9307   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9308   myquery(rc);
9309 
9310   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9311   myquery(rc);
9312 
9313   rc= mysql_query(mysql,
9314                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9315   myquery(rc);
9316 
9317   rc= mysql_query(mysql, "create table t2 select * from t1;");
9318   myquery(rc);
9319 
9320   stmt= mysql_simple_prepare(mysql, query);
9321   check_stmt(stmt);
9322   for (i= 0; i < 3; i++)
9323   {
9324     rc= mysql_stmt_execute(stmt);
9325     check_execute(stmt, rc);
9326     rc= my_process_stmt_result(stmt);
9327     DIE_UNLESS(rc == 5);
9328   }
9329   mysql_stmt_close(stmt);
9330 
9331   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9332   myquery(rc);
9333 }
9334 
9335 
test_bad_union()9336 static void test_bad_union()
9337 {
9338   MYSQL_STMT *stmt;
9339   const char *query= "SELECT 1, 2 union SELECT 1";
9340 
9341   myheader("test_bad_union");
9342 
9343   stmt= mysql_simple_prepare(mysql, query);
9344   DIE_UNLESS(stmt == 0);
9345   myerror(NULL);
9346 }
9347 
9348 
test_distinct()9349 static void test_distinct()
9350 {
9351   MYSQL_STMT *stmt;
9352   int rc, i;
9353   const char *query=
9354     "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a";
9355 
9356   myheader("test_distinct");
9357 
9358   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9359   myquery(rc);
9360 
9361   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9362   myquery(rc);
9363 
9364   rc= mysql_query(mysql,
9365                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), \
9366 (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);");
9367   myquery(rc);
9368 
9369   for (i= 0; i < 3; i++)
9370   {
9371     stmt= mysql_simple_prepare(mysql, query);
9372     check_stmt(stmt);
9373     rc= mysql_stmt_execute(stmt);
9374     check_execute(stmt, rc);
9375     rc= my_process_stmt_result(stmt);
9376     DIE_UNLESS(rc == 5);
9377     mysql_stmt_close(stmt);
9378   }
9379 
9380   rc= mysql_query(mysql, "DROP TABLE t1");
9381   myquery(rc);
9382 }
9383 
9384 
9385 /*
9386   Test for bug#2248 "mysql_fetch without prior mysql_stmt_execute hangs"
9387 */
9388 
test_bug2248()9389 static void test_bug2248()
9390 {
9391   MYSQL_STMT *stmt;
9392   int rc;
9393   const char *query1= "SELECT DATABASE()";
9394   const char *query2= "INSERT INTO test_bug2248 VALUES (10)";
9395 
9396   myheader("test_bug2248");
9397 
9398   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248");
9399   myquery(rc);
9400 
9401   rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)");
9402   myquery(rc);
9403 
9404   stmt= mysql_simple_prepare(mysql, query1);
9405   check_stmt(stmt);
9406 
9407   /* This should not hang */
9408   rc= mysql_stmt_fetch(stmt);
9409   check_execute_r(stmt, rc);
9410 
9411   /* And this too */
9412   rc= mysql_stmt_store_result(stmt);
9413   check_execute_r(stmt, rc);
9414 
9415   mysql_stmt_close(stmt);
9416 
9417   stmt= mysql_simple_prepare(mysql, query2);
9418   check_stmt(stmt);
9419 
9420   rc= mysql_stmt_execute(stmt);
9421   check_execute(stmt, rc);
9422 
9423   /* This too should not hang but should return proper error */
9424   rc= mysql_stmt_fetch(stmt);
9425   DIE_UNLESS(rc == 1);
9426 
9427   /* This too should not hang but should not bark */
9428   rc= mysql_stmt_store_result(stmt);
9429   check_execute(stmt, rc);
9430 
9431   /* This should return proper error */
9432   rc= mysql_stmt_fetch(stmt);
9433   check_execute_r(stmt, rc);
9434   DIE_UNLESS(rc == 1);
9435 
9436   mysql_stmt_close(stmt);
9437 
9438   rc= mysql_query(mysql, "DROP TABLE test_bug2248");
9439   myquery(rc);
9440 }
9441 
9442 
test_subqueries_ref()9443 static void test_subqueries_ref()
9444 {
9445   MYSQL_STMT *stmt;
9446   int rc, i;
9447   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)";
9448 
9449   myheader("test_subqueries_ref");
9450 
9451   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9452   myquery(rc);
9453 
9454   rc= mysql_query(mysql, "CREATE TABLE t1 (a int);");
9455   myquery(rc);
9456 
9457   rc= mysql_query(mysql,
9458                   "insert into t1 values (1), (2), (3), (4), (5);");
9459   myquery(rc);
9460 
9461   stmt= mysql_simple_prepare(mysql, query);
9462   check_stmt(stmt);
9463   for (i= 0; i < 3; i++)
9464   {
9465     rc= mysql_stmt_execute(stmt);
9466     check_execute(stmt, rc);
9467     rc= my_process_stmt_result(stmt);
9468     DIE_UNLESS(rc == 1);
9469   }
9470   mysql_stmt_close(stmt);
9471 
9472   rc= mysql_query(mysql, "DROP TABLE t1");
9473   myquery(rc);
9474 }
9475 
9476 
test_union()9477 static void test_union()
9478 {
9479   MYSQL_STMT *stmt;
9480   int rc;
9481 
9482   myheader("test_union");
9483 
9484   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9485   myquery(rc);
9486 
9487   rc= mysql_query(mysql,
9488                   "CREATE TABLE t1 "
9489                   "(id INTEGER NOT NULL PRIMARY KEY, "
9490                   " name VARCHAR(20) NOT NULL)");
9491   myquery(rc);
9492   rc= mysql_query(mysql,
9493                   "INSERT INTO t1 (id, name) VALUES "
9494                   "(2, 'Ja'), (3, 'Ede'), "
9495                   "(4, 'Haag'), (5, 'Kabul'), "
9496                   "(6, 'Almere'), (7, 'Utrecht'), "
9497                   "(8, 'Qandahar'), (9, 'Amsterdam'), "
9498                   "(10, 'Amersfoort'), (11, 'Constantine')");
9499   myquery(rc);
9500   rc= mysql_query(mysql,
9501                   "CREATE TABLE t2 "
9502                   "(id INTEGER NOT NULL PRIMARY KEY, "
9503                   " name VARCHAR(20) NOT NULL)");
9504   myquery(rc);
9505   rc= mysql_query(mysql,
9506                   "INSERT INTO t2 (id, name) VALUES "
9507                   "(4, 'Guam'), (5, 'Aruba'), "
9508                   "(6, 'Angola'), (7, 'Albania'), "
9509                   "(8, 'Anguilla'), (9, 'Argentina'), "
9510                   "(10, 'Azerbaijan'), (11, 'Afghanistan'), "
9511                   "(12, 'Burkina Faso'), (13, 'Faroe Islands')");
9512   myquery(rc);
9513 
9514   stmt= mysql_simple_prepare(mysql,
9515                              "SELECT t1.name FROM t1 UNION "
9516                              "SELECT t2.name FROM t2");
9517   check_stmt(stmt);
9518 
9519   rc= mysql_stmt_execute(stmt);
9520   check_execute(stmt, rc);
9521   rc= my_process_stmt_result(stmt);
9522   DIE_UNLESS(rc == 20);
9523   mysql_stmt_close(stmt);
9524 
9525   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9526   myquery(rc);
9527 }
9528 
9529 
test_bug3117()9530 static void test_bug3117()
9531 {
9532   MYSQL_STMT *stmt;
9533   MYSQL_BIND buffer;
9534   longlong lii;
9535   ulong length;
9536   my_bool is_null;
9537   int rc;
9538 
9539   myheader("test_bug3117");
9540 
9541   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9542   myquery(rc);
9543 
9544   rc= mysql_query(mysql, "CREATE TABLE t1 (id int auto_increment primary key)");
9545   myquery(rc);
9546 
9547   stmt= mysql_simple_prepare(mysql, "SELECT LAST_INSERT_ID()");
9548   check_stmt(stmt);
9549 
9550   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9551   myquery(rc);
9552 
9553   rc= mysql_stmt_execute(stmt);
9554   check_execute(stmt, rc);
9555 
9556   memset(&buffer, 0, sizeof(buffer));
9557   buffer.buffer_type= MYSQL_TYPE_LONGLONG;
9558   buffer.buffer_length= (ulong)sizeof(lii);
9559   buffer.buffer= (void *)&lii;
9560   buffer.length= &length;
9561   buffer.is_null= &is_null;
9562 
9563   rc= mysql_stmt_bind_result(stmt, &buffer);
9564   check_execute(stmt, rc);
9565 
9566   rc= mysql_stmt_store_result(stmt);
9567   check_execute(stmt, rc);
9568 
9569   rc= mysql_stmt_fetch(stmt);
9570   check_execute(stmt, rc);
9571 
9572   DIE_UNLESS(is_null == 0 && lii == 1);
9573   if (!opt_silent)
9574     fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
9575 
9576   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9577   myquery(rc);
9578 
9579   rc= mysql_stmt_execute(stmt);
9580   check_execute(stmt, rc);
9581 
9582   rc= mysql_stmt_fetch(stmt);
9583   check_execute(stmt, rc);
9584 
9585   DIE_UNLESS(is_null == 0 && lii == 2);
9586   if (!opt_silent)
9587     fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
9588 
9589   mysql_stmt_close(stmt);
9590 
9591   rc= mysql_query(mysql, "DROP TABLE t1");
9592   myquery(rc);
9593 }
9594 
9595 
test_join()9596 static void test_join()
9597 {
9598   MYSQL_STMT *stmt;
9599   int rc, i, j;
9600   const char *query[]= {"SELECT * FROM t2 join t1 on (t1.a=t2.a)",
9601                         "SELECT * FROM t2 natural join t1",
9602                         "SELECT * FROM t2 join t1 using(a)",
9603                         "SELECT * FROM t2 left join t1 on(t1.a=t2.a)",
9604                         "SELECT * FROM t2 natural left join t1",
9605                         "SELECT * FROM t2 left join t1 using(a)",
9606                         "SELECT * FROM t2 right join t1 on(t1.a=t2.a)",
9607                         "SELECT * FROM t2 natural right join t1",
9608                         "SELECT * FROM t2 right join t1 using(a)"};
9609 
9610   myheader("test_join");
9611 
9612   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9613   myquery(rc);
9614 
9615   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9616   myquery(rc);
9617 
9618   rc= mysql_query(mysql,
9619                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9620   myquery(rc);
9621 
9622   rc= mysql_query(mysql, "CREATE TABLE t2 (a int , c int);");
9623   myquery(rc);
9624 
9625   rc= mysql_query(mysql,
9626                   "insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9627   myquery(rc);
9628 
9629   for (j= 0; j < 9; j++)
9630   {
9631     stmt= mysql_simple_prepare(mysql, query[j]);
9632     check_stmt(stmt);
9633     for (i= 0; i < 3; i++)
9634     {
9635       rc= mysql_stmt_execute(stmt);
9636       check_execute(stmt, rc);
9637       rc= my_process_stmt_result(stmt);
9638       DIE_UNLESS(rc == 5);
9639     }
9640     mysql_stmt_close(stmt);
9641   }
9642 
9643   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9644   myquery(rc);
9645 }
9646 
9647 
test_selecttmp()9648 static void test_selecttmp()
9649 {
9650   MYSQL_STMT *stmt;
9651   int rc, i;
9652   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";
9653 
9654   myheader("test_select_tmp");
9655 
9656   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3");
9657   myquery(rc);
9658 
9659   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9660   myquery(rc);
9661 
9662   rc= mysql_query(mysql, "create table t2 (a int, b int);");
9663   myquery(rc);
9664 
9665   rc= mysql_query(mysql, "create table t3 (a int, b int);");
9666   myquery(rc);
9667 
9668   rc= mysql_query(mysql,
9669                   "insert into t1 values (0, 100), (1, 2), (1, 3), (2, 2), (2, 7), \
9670 (2, -1), (3, 10);");
9671   myquery(rc);
9672   rc= mysql_query(mysql,
9673                   "insert into t2 values (0, 0), (1, 1), (2, 1), (3, 1), (4, 1);");
9674   myquery(rc);
9675   rc= mysql_query(mysql,
9676                   "insert into t3 values (3, 3), (2, 2), (1, 1);");
9677   myquery(rc);
9678 
9679   stmt= mysql_simple_prepare(mysql, query);
9680   check_stmt(stmt);
9681   for (i= 0; i < 3; i++)
9682   {
9683     rc= mysql_stmt_execute(stmt);
9684     check_execute(stmt, rc);
9685     rc= my_process_stmt_result(stmt);
9686     DIE_UNLESS(rc == 3);
9687   }
9688   mysql_stmt_close(stmt);
9689 
9690   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3");
9691   myquery(rc);
9692 }
9693 
9694 
test_create_drop()9695 static void test_create_drop()
9696 {
9697   MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select;
9698   char *query;
9699   int rc, i;
9700   myheader("test_table_manipulation");
9701 
9702   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9703   myquery(rc);
9704 
9705   rc= mysql_query(mysql, "create table t2 (a int);");
9706   myquery(rc);
9707 
9708   rc= mysql_query(mysql, "create table t1 (a int);");
9709   myquery(rc);
9710 
9711   rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);");
9712   myquery(rc);
9713 
9714   query= (char*)"create table t1 (a int)";
9715   stmt_create= mysql_simple_prepare(mysql, query);
9716   check_stmt(stmt_create);
9717 
9718   query= (char*)"drop table t1";
9719   stmt_drop= mysql_simple_prepare(mysql, query);
9720   check_stmt(stmt_drop);
9721 
9722   query= (char*)"select a in (select a from t2) from t1";
9723   stmt_select= mysql_simple_prepare(mysql, query);
9724   check_stmt(stmt_select);
9725 
9726   rc= mysql_query(mysql, "DROP TABLE t1");
9727   myquery(rc);
9728 
9729   query= (char*)"create table t1 select a from t2";
9730   stmt_create_select= mysql_simple_prepare(mysql, query);
9731   check_stmt(stmt_create_select);
9732 
9733   for (i= 0; i < 3; i++)
9734   {
9735     rc= mysql_stmt_execute(stmt_create);
9736     check_execute(stmt_create, rc);
9737     if (!opt_silent)
9738       fprintf(stdout, "created %i\n", i);
9739 
9740     rc= mysql_stmt_execute(stmt_select);
9741     check_execute(stmt_select, rc);
9742     rc= my_process_stmt_result(stmt_select);
9743     DIE_UNLESS(rc == 0);
9744 
9745     rc= mysql_stmt_execute(stmt_drop);
9746     check_execute(stmt_drop, rc);
9747     if (!opt_silent)
9748       fprintf(stdout, "dropped %i\n", i);
9749 
9750     rc= mysql_stmt_execute(stmt_create_select);
9751     check_execute(stmt_create, rc);
9752     if (!opt_silent)
9753       fprintf(stdout, "created select %i\n", i);
9754 
9755     rc= mysql_stmt_execute(stmt_select);
9756     check_execute(stmt_select, rc);
9757     rc= my_process_stmt_result(stmt_select);
9758     DIE_UNLESS(rc == 3);
9759 
9760     rc= mysql_stmt_execute(stmt_drop);
9761     check_execute(stmt_drop, rc);
9762     if (!opt_silent)
9763       fprintf(stdout, "dropped %i\n", i);
9764   }
9765 
9766   mysql_stmt_close(stmt_create);
9767   mysql_stmt_close(stmt_drop);
9768   mysql_stmt_close(stmt_select);
9769   mysql_stmt_close(stmt_create_select);
9770 
9771   rc= mysql_query(mysql, "DROP TABLE t2");
9772   myquery(rc);
9773 }
9774 
9775 
test_rename()9776 static void test_rename()
9777 {
9778   MYSQL_STMT *stmt;
9779   const char *query= "rename table t1 to t2, t3 to t4";
9780   int rc;
9781   myheader("test_table_rename");
9782 
9783   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
9784   myquery(rc);
9785 
9786   stmt= mysql_simple_prepare(mysql, query);
9787   check_stmt(stmt);
9788 
9789   rc= mysql_query(mysql, "create table t1 (a int)");
9790   myquery(rc);
9791 
9792   rc= mysql_stmt_execute(stmt);
9793   check_execute_r(stmt, rc);
9794   if (!opt_silent)
9795     fprintf(stdout, "rename without t3\n");
9796 
9797   rc= mysql_query(mysql, "create table t3 (a int)");
9798   myquery(rc);
9799 
9800   rc= mysql_stmt_execute(stmt);
9801   check_execute(stmt, rc);
9802   if (!opt_silent)
9803     fprintf(stdout, "rename with t3\n");
9804 
9805   rc= mysql_stmt_execute(stmt);
9806   check_execute_r(stmt, rc);
9807   if (!opt_silent)
9808     fprintf(stdout, "rename renamed\n");
9809 
9810   rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3");
9811   myquery(rc);
9812 
9813   rc= mysql_stmt_execute(stmt);
9814   check_execute(stmt, rc);
9815   if (!opt_silent)
9816     fprintf(stdout, "rename reverted\n");
9817 
9818   mysql_stmt_close(stmt);
9819 
9820   rc= mysql_query(mysql, "DROP TABLE t2, t4");
9821   myquery(rc);
9822 }
9823 
9824 
test_do_set()9825 static void test_do_set()
9826 {
9827   MYSQL_STMT *stmt_do, *stmt_set;
9828   char *query;
9829   int rc, i;
9830   myheader("test_do_set");
9831 
9832   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9833   myquery(rc);
9834 
9835   rc= mysql_query(mysql, "create table t1 (a int)");
9836   myquery(rc);
9837 
9838   query= (char*)"do @var:=(1 in (select * from t1))";
9839   stmt_do= mysql_simple_prepare(mysql, query);
9840   check_stmt(stmt_do);
9841 
9842   query= (char*)"set @var=(1 in (select * from t1))";
9843   stmt_set= mysql_simple_prepare(mysql, query);
9844   check_stmt(stmt_set);
9845 
9846   for (i= 0; i < 3; i++)
9847   {
9848     rc= mysql_stmt_execute(stmt_do);
9849     check_execute(stmt_do, rc);
9850     if (!opt_silent)
9851       fprintf(stdout, "do %i\n", i);
9852     rc= mysql_stmt_execute(stmt_set);
9853     check_execute(stmt_set, rc);
9854     if (!opt_silent)
9855       fprintf(stdout, "set %i\n", i);
9856   }
9857 
9858   mysql_stmt_close(stmt_do);
9859   mysql_stmt_close(stmt_set);
9860 }
9861 
9862 
test_multi()9863 static void test_multi()
9864 {
9865   MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2;
9866   char *query;
9867   MYSQL_BIND my_bind[1];
9868   int rc, i;
9869   int32 param= 1;
9870   ulong length= 1;
9871   myheader("test_multi");
9872 
9873   /*
9874     We need to memset bind structure because mysql_stmt_bind_param checks all
9875     its members.
9876   */
9877   memset(my_bind, 0, sizeof(my_bind));
9878 
9879   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9880   my_bind[0].buffer= (void *)&param;
9881   my_bind[0].length= &length;
9882 
9883   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9884   myquery(rc);
9885 
9886   rc= mysql_query(mysql, "create table t1 (a int, b int)");
9887   myquery(rc);
9888 
9889   rc= mysql_query(mysql, "create table t2 (a int, b int)");
9890   myquery(rc);
9891 
9892   rc= mysql_query(mysql, "insert into t1 values (3, 3), (2, 2), (1, 1)");
9893   myquery(rc);
9894 
9895   rc= mysql_query(mysql, "insert into t2 values (3, 3), (2, 2), (1, 1)");
9896   myquery(rc);
9897 
9898   query= (char*)"delete t1, t2 from t1, t2 where t1.a=t2.a and t1.b=10";
9899   stmt_delete= mysql_simple_prepare(mysql, query);
9900   check_stmt(stmt_delete);
9901 
9902   query= (char*)"update t1, t2 set t1.b=10, t2.b=10 where t1.a=t2.a and t1.b=?";
9903   stmt_update= mysql_simple_prepare(mysql, query);
9904   check_stmt(stmt_update);
9905 
9906   query= (char*)"select * from t1";
9907   stmt_select1= mysql_simple_prepare(mysql, query);
9908   check_stmt(stmt_select1);
9909 
9910   query= (char*)"select * from t2";
9911   stmt_select2= mysql_simple_prepare(mysql, query);
9912   check_stmt(stmt_select2);
9913 
9914   for(i= 0; i < 3; i++)
9915   {
9916     rc= mysql_stmt_bind_param(stmt_update, my_bind);
9917     check_execute(stmt_update, rc);
9918 
9919     rc= mysql_stmt_execute(stmt_update);
9920     check_execute(stmt_update, rc);
9921     if (!opt_silent)
9922       fprintf(stdout, "update %ld\n", (long) param);
9923 
9924     rc= mysql_stmt_execute(stmt_delete);
9925     check_execute(stmt_delete, rc);
9926     if (!opt_silent)
9927       fprintf(stdout, "delete %ld\n", (long) param);
9928 
9929     rc= mysql_stmt_execute(stmt_select1);
9930     check_execute(stmt_select1, rc);
9931     rc= my_process_stmt_result(stmt_select1);
9932     DIE_UNLESS(rc == 3-param);
9933 
9934     rc= mysql_stmt_execute(stmt_select2);
9935     check_execute(stmt_select2, rc);
9936     rc= my_process_stmt_result(stmt_select2);
9937     DIE_UNLESS(rc == 3-param);
9938 
9939     param++;
9940   }
9941 
9942   mysql_stmt_close(stmt_delete);
9943   mysql_stmt_close(stmt_update);
9944   mysql_stmt_close(stmt_select1);
9945   mysql_stmt_close(stmt_select2);
9946   rc= mysql_query(mysql, "drop table t1, t2");
9947   myquery(rc);
9948 }
9949 
9950 
test_insert_select()9951 static void test_insert_select()
9952 {
9953   MYSQL_STMT *stmt_insert, *stmt_select;
9954   char *query;
9955   int rc;
9956   uint i;
9957   myheader("test_insert_select");
9958 
9959   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9960   myquery(rc);
9961 
9962   rc= mysql_query(mysql, "create table t1 (a int)");
9963   myquery(rc);
9964 
9965   rc= mysql_query(mysql, "create table t2 (a int)");
9966   myquery(rc);
9967 
9968   rc= mysql_query(mysql, "insert into t2 values (1)");
9969   myquery(rc);
9970 
9971   query= (char*)"insert into t1 select a from t2";
9972   stmt_insert= mysql_simple_prepare(mysql, query);
9973   check_stmt(stmt_insert);
9974 
9975   query= (char*)"select * from t1";
9976   stmt_select= mysql_simple_prepare(mysql, query);
9977   check_stmt(stmt_select);
9978 
9979   for(i= 0; i < 3; i++)
9980   {
9981     rc= mysql_stmt_execute(stmt_insert);
9982     check_execute(stmt_insert, rc);
9983     if (!opt_silent)
9984       fprintf(stdout, "insert %u\n", i);
9985 
9986     rc= mysql_stmt_execute(stmt_select);
9987     check_execute(stmt_select, rc);
9988     rc= my_process_stmt_result(stmt_select);
9989     DIE_UNLESS(rc == (int)(i+1));
9990   }
9991 
9992   mysql_stmt_close(stmt_insert);
9993   mysql_stmt_close(stmt_select);
9994   rc= mysql_query(mysql, "drop table t1, t2");
9995   myquery(rc);
9996 }
9997 
9998 
test_bind_nagative()9999 static void test_bind_nagative()
10000 {
10001   MYSQL_STMT *stmt_insert;
10002   char *query;
10003   int rc;
10004   MYSQL_BIND      my_bind[1];
10005   int32           my_val= 0;
10006   ulong           my_length= 0L;
10007   my_bool         my_null= FALSE;
10008   myheader("test_insert_select");
10009 
10010   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10011   myquery(rc);
10012 
10013   rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)");
10014   myquery(rc);
10015 
10016   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)");
10017   myquery(rc);
10018 
10019   query= (char*)"INSERT INTO t1 VALUES (?)";
10020   stmt_insert= mysql_simple_prepare(mysql, query);
10021   check_stmt(stmt_insert);
10022 
10023   /* bind parameters */
10024   memset(my_bind, 0, sizeof(my_bind));
10025 
10026   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10027   my_bind[0].buffer= (void *)&my_val;
10028   my_bind[0].length= &my_length;
10029   my_bind[0].is_null= (char*)&my_null;
10030 
10031   rc= mysql_stmt_bind_param(stmt_insert, my_bind);
10032   check_execute(stmt_insert, rc);
10033 
10034   my_val= -1;
10035   rc= mysql_stmt_execute(stmt_insert);
10036   check_execute(stmt_insert, rc);
10037 
10038   mysql_stmt_close(stmt_insert);
10039   rc= mysql_query(mysql, "drop table t1");
10040   myquery(rc);
10041 }
10042 
10043 
test_derived()10044 static void test_derived()
10045 {
10046   MYSQL_STMT *stmt;
10047   int rc, i;
10048   MYSQL_BIND      my_bind[1];
10049   int32           my_val= 0;
10050   ulong           my_length= 0L;
10051   my_bool         my_null= FALSE;
10052   const char *query=
10053     "select count(1) from (select f.id from t1 f where f.id=?) as x";
10054 
10055   myheader("test_derived");
10056 
10057   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10058   myquery(rc);
10059 
10060   rc= mysql_query(mysql, "create table t1 (id  int(8), primary key (id)) \
10061 ENGINE=InnoDB DEFAULT CHARSET=utf8");
10062   myquery(rc);
10063 
10064   rc= mysql_query(mysql, "insert into t1 values (1)");
10065   myquery(rc);
10066 
10067   stmt= mysql_simple_prepare(mysql, query);
10068   check_stmt(stmt);
10069   /*
10070     We need to memset bind structure because mysql_stmt_bind_param checks all
10071     its members.
10072   */
10073   memset(my_bind, 0, sizeof(my_bind));
10074 
10075   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10076   my_bind[0].buffer= (void *)&my_val;
10077   my_bind[0].length= &my_length;
10078   my_bind[0].is_null= (char*)&my_null;
10079   my_val= 1;
10080   rc= mysql_stmt_bind_param(stmt, my_bind);
10081   check_execute(stmt, rc);
10082 
10083   for (i= 0; i < 3; i++)
10084   {
10085     rc= mysql_stmt_execute(stmt);
10086     check_execute(stmt, rc);
10087     rc= my_process_stmt_result(stmt);
10088     DIE_UNLESS(rc == 1);
10089   }
10090   mysql_stmt_close(stmt);
10091 
10092   rc= mysql_query(mysql, "DROP TABLE t1");
10093   myquery(rc);
10094 }
10095 
10096 
test_xjoin()10097 static void test_xjoin()
10098 {
10099   MYSQL_STMT *stmt;
10100   int rc, i;
10101   const char *query=
10102     "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";
10103 
10104   myheader("test_xjoin");
10105 
10106   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
10107   myquery(rc);
10108 
10109   rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10110   myquery(rc);
10111 
10112   rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10113   myquery(rc);
10114 
10115   rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
10116   myquery(rc);
10117 
10118   rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10119   myquery(rc);
10120 
10121   rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)");
10122   myquery(rc);
10123 
10124   rc= mysql_query(mysql, "insert into t1 values (1, 1, 'aaa'), (2, null, 'bbb')");
10125   myquery(rc);
10126 
10127   rc= mysql_query(mysql, "insert into t2 values (1, 2, 'ccc')");
10128   myquery(rc);
10129 
10130   rc= mysql_query(mysql, "insert into t4 values (1, 'Name1'), (2, null)");
10131   myquery(rc);
10132 
10133   stmt= mysql_simple_prepare(mysql, query);
10134   check_stmt(stmt);
10135 
10136   for (i= 0; i < 3; i++)
10137   {
10138     rc= mysql_stmt_execute(stmt);
10139     check_execute(stmt, rc);
10140     rc= my_process_stmt_result(stmt);
10141     DIE_UNLESS(rc == 1);
10142   }
10143   mysql_stmt_close(stmt);
10144 
10145   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3, t4");
10146   myquery(rc);
10147 }
10148 
10149 
test_bug3035()10150 static void test_bug3035()
10151 {
10152   MYSQL_STMT *stmt;
10153   int rc;
10154   MYSQL_BIND bind_array[12], *my_bind= bind_array, *bind_end= my_bind + 12;
10155   int8 int8_val;
10156   uint8 uint8_val;
10157   int16 int16_val;
10158   uint16 uint16_val;
10159   int32 int32_val;
10160   uint32 uint32_val;
10161   longlong int64_val;
10162   ulonglong uint64_val;
10163   double double_val, udouble_val, double_tmp;
10164   char longlong_as_string[22], ulonglong_as_string[22];
10165 
10166   /* mins and maxes */
10167   const int8 int8_min= -128;
10168   const int8 int8_max= 127;
10169   const uint8 uint8_min= 0;
10170   const uint8 uint8_max= 255;
10171 
10172   const int16 int16_min= -32768;
10173   const int16 int16_max= 32767;
10174   const uint16 uint16_min= 0;
10175   const uint16 uint16_max= 65535;
10176 
10177   const int32 int32_max= 2147483647L;
10178   const int32 int32_min= -int32_max - 1;
10179   const uint32 uint32_min= 0;
10180   const uint32 uint32_max= 4294967295U;
10181 
10182   /* it might not work okay everyplace */
10183   const longlong int64_max= 9223372036854775807LL;
10184   const longlong int64_min= -int64_max - 1;
10185 
10186   const ulonglong uint64_min= 0U;
10187   const ulonglong uint64_max= 18446744073709551615ULL;
10188 
10189   const char *stmt_text;
10190 
10191   myheader("test_bug3035");
10192 
10193   stmt_text= "DROP TABLE IF EXISTS t1";
10194   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10195   myquery(rc);
10196 
10197   stmt_text= "CREATE TABLE t1 (i8 TINYINT, ui8 TINYINT UNSIGNED, "
10198                               "i16 SMALLINT, ui16 SMALLINT UNSIGNED, "
10199                               "i32 INT, ui32 INT UNSIGNED, "
10200                               "i64 BIGINT, ui64 BIGINT UNSIGNED, "
10201                               "id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT)";
10202   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10203   myquery(rc);
10204 
10205   memset(bind_array, 0, sizeof(bind_array));
10206 
10207   for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10208     my_bind->error= &my_bind->error_value;
10209 
10210   bind_array[0].buffer_type= MYSQL_TYPE_TINY;
10211   bind_array[0].buffer= (void *) &int8_val;
10212 
10213   bind_array[1].buffer_type= MYSQL_TYPE_TINY;
10214   bind_array[1].buffer= (void *) &uint8_val;
10215   bind_array[1].is_unsigned= 1;
10216 
10217   bind_array[2].buffer_type= MYSQL_TYPE_SHORT;
10218   bind_array[2].buffer= (void *) &int16_val;
10219 
10220   bind_array[3].buffer_type= MYSQL_TYPE_SHORT;
10221   bind_array[3].buffer= (void *) &uint16_val;
10222   bind_array[3].is_unsigned= 1;
10223 
10224   bind_array[4].buffer_type= MYSQL_TYPE_LONG;
10225   bind_array[4].buffer= (void *) &int32_val;
10226 
10227   bind_array[5].buffer_type= MYSQL_TYPE_LONG;
10228   bind_array[5].buffer= (void *) &uint32_val;
10229   bind_array[5].is_unsigned= 1;
10230 
10231   bind_array[6].buffer_type= MYSQL_TYPE_LONGLONG;
10232   bind_array[6].buffer= (void *) &int64_val;
10233 
10234   bind_array[7].buffer_type= MYSQL_TYPE_LONGLONG;
10235   bind_array[7].buffer= (void *) &uint64_val;
10236   bind_array[7].is_unsigned= 1;
10237 
10238   stmt= mysql_stmt_init(mysql);
10239   check_stmt(stmt);
10240 
10241   stmt_text= "INSERT INTO t1 (i8, ui8, i16, ui16, i32, ui32, i64, ui64) "
10242                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
10243   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10244   check_execute(stmt, rc);
10245 
10246   mysql_stmt_bind_param(stmt, bind_array);
10247 
10248   int8_val= int8_min;
10249   uint8_val= uint8_min;
10250   int16_val= int16_min;
10251   uint16_val= uint16_min;
10252   int32_val= int32_min;
10253   uint32_val= uint32_min;
10254   int64_val= int64_min;
10255   uint64_val= uint64_min;
10256 
10257   rc= mysql_stmt_execute(stmt);
10258   check_execute(stmt, rc);
10259 
10260   int8_val= int8_max;
10261   uint8_val= uint8_max;
10262   int16_val= int16_max;
10263   uint16_val= uint16_max;
10264   int32_val= int32_max;
10265   uint32_val= uint32_max;
10266   int64_val= int64_max;
10267   uint64_val= uint64_max;
10268 
10269   rc= mysql_stmt_execute(stmt);
10270   check_execute(stmt, rc);
10271 
10272   stmt_text= "SELECT i8, ui8, i16, ui16, i32, ui32, i64, ui64, ui64, "
10273              "cast(ui64 as signed), ui64, cast(ui64 as signed)"
10274              "FROM t1 ORDER BY id ASC";
10275 
10276   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10277   check_execute(stmt, rc);
10278 
10279   rc= mysql_stmt_execute(stmt);
10280   check_execute(stmt, rc);
10281 
10282   bind_array[8].buffer_type= MYSQL_TYPE_DOUBLE;
10283   bind_array[8].buffer= (void *) &udouble_val;
10284 
10285   bind_array[9].buffer_type= MYSQL_TYPE_DOUBLE;
10286   bind_array[9].buffer= (void *) &double_val;
10287 
10288   bind_array[10].buffer_type= MYSQL_TYPE_STRING;
10289   bind_array[10].buffer= (void *) &ulonglong_as_string;
10290   bind_array[10].buffer_length= (ulong)sizeof(ulonglong_as_string);
10291 
10292   bind_array[11].buffer_type= MYSQL_TYPE_STRING;
10293   bind_array[11].buffer= (void *) &longlong_as_string;
10294   bind_array[11].buffer_length= (ulong)sizeof(longlong_as_string);
10295 
10296   mysql_stmt_bind_result(stmt, bind_array);
10297 
10298   rc= mysql_stmt_fetch(stmt);
10299   check_execute(stmt, rc);
10300 
10301   DIE_UNLESS(int8_val == int8_min);
10302   DIE_UNLESS(uint8_val == uint8_min);
10303   DIE_UNLESS(int16_val == int16_min);
10304   DIE_UNLESS(uint16_val == uint16_min);
10305   DIE_UNLESS(int32_val == int32_min);
10306   DIE_UNLESS(uint32_val == uint32_min);
10307   DIE_UNLESS(int64_val == int64_min);
10308   DIE_UNLESS(uint64_val == uint64_min);
10309   DIE_UNLESS(double_val == (longlong) uint64_min);
10310   double_tmp= ulonglong2double(uint64_val);
10311   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10312   DIE_UNLESS(!strcmp(longlong_as_string, "0"));
10313   DIE_UNLESS(!strcmp(ulonglong_as_string, "0"));
10314 
10315   rc= mysql_stmt_fetch(stmt);
10316 
10317   if (!opt_silent)
10318   {
10319     printf("Truncation mask: ");
10320     for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10321       printf("%d", (int) my_bind->error_value);
10322     printf("\n");
10323   }
10324   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0);
10325 
10326   DIE_UNLESS(int8_val == int8_max);
10327   DIE_UNLESS(uint8_val == uint8_max);
10328   DIE_UNLESS(int16_val == int16_max);
10329   DIE_UNLESS(uint16_val == uint16_max);
10330   DIE_UNLESS(int32_val == int32_max);
10331   DIE_UNLESS(uint32_val == uint32_max);
10332   DIE_UNLESS(int64_val == int64_max);
10333   DIE_UNLESS(uint64_val == uint64_max);
10334   DIE_UNLESS(double_val == (longlong) uint64_val);
10335   double_tmp= ulonglong2double(uint64_val);
10336   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10337   DIE_UNLESS(!strcmp(longlong_as_string, "-1"));
10338   DIE_UNLESS(!strcmp(ulonglong_as_string, "18446744073709551615"));
10339 
10340   rc= mysql_stmt_fetch(stmt);
10341   DIE_UNLESS(rc == MYSQL_NO_DATA);
10342 
10343   mysql_stmt_close(stmt);
10344 
10345   stmt_text= "DROP TABLE t1";
10346   mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10347 }
10348 
10349 
test_union2()10350 static void test_union2()
10351 {
10352   MYSQL_STMT *stmt;
10353   int rc, i;
10354 
10355   myheader("test_union2");
10356 
10357   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10358   myquery(rc);
10359 
10360   rc= mysql_query(mysql, "CREATE TABLE t1(col1 INT, \
10361                                          col2 VARCHAR(40),      \
10362                                          col3 SMALLINT, \
10363                                          col4 TIMESTAMP)");
10364   myquery(rc);
10365 
10366   stmt= mysql_simple_prepare(mysql,
10367                              "select col1 FROM t1 where col1=1 union distinct "
10368                              "select col1 FROM t1 where col1=2");
10369   check_stmt(stmt);
10370 
10371   for (i= 0; i < 3; i++)
10372   {
10373     rc= mysql_stmt_execute(stmt);
10374     check_execute(stmt, rc);
10375     rc= my_process_stmt_result(stmt);
10376     DIE_UNLESS(rc == 0);
10377   }
10378 
10379   mysql_stmt_close(stmt);
10380 
10381   rc= mysql_query(mysql, "DROP TABLE t1");
10382   myquery(rc);
10383 }
10384 
10385 
10386 /*
10387   This tests for various mysql_stmt_send_long_data bugs described in #1664
10388 */
10389 
test_bug1664()10390 static void test_bug1664()
10391 {
10392     MYSQL_STMT *stmt;
10393     int        rc, int_data;
10394     const char *data;
10395     const char *str_data= "Simple string";
10396     MYSQL_BIND my_bind[2];
10397     const char *query= "INSERT INTO test_long_data(col2, col1) VALUES(?, ?)";
10398 
10399     myheader("test_bug1664");
10400 
10401     rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
10402     myquery(rc);
10403 
10404     rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, col2 long varchar)");
10405     myquery(rc);
10406 
10407     stmt= mysql_stmt_init(mysql);
10408     check_stmt(stmt);
10409     rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
10410     check_execute(stmt, rc);
10411 
10412     verify_param_count(stmt, 2);
10413 
10414     memset(my_bind, 0, sizeof(my_bind));
10415 
10416     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10417     my_bind[0].buffer= (void *)str_data;
10418     my_bind[0].buffer_length= (ulong)strlen(str_data);
10419 
10420     my_bind[1].buffer= (void *)&int_data;
10421     my_bind[1].buffer_type= MYSQL_TYPE_LONG;
10422 
10423     rc= mysql_stmt_bind_param(stmt, my_bind);
10424     check_execute(stmt, rc);
10425 
10426     int_data= 1;
10427 
10428     /*
10429       Let us supply empty long_data. This should work and should
10430       not break following execution.
10431     */
10432     data= "";
10433     rc= mysql_stmt_send_long_data(stmt, 0, data, (ulong)strlen(data));
10434     check_execute(stmt, rc);
10435 
10436     rc= mysql_stmt_execute(stmt);
10437     check_execute(stmt, rc);
10438 
10439     verify_col_data("test_long_data", "col1", "1");
10440     verify_col_data("test_long_data", "col2", "");
10441 
10442     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10443     myquery(rc);
10444 
10445     /* This should pass OK */
10446     data= (char *)"Data";
10447     rc= mysql_stmt_send_long_data(stmt, 0, data, (ulong)strlen(data));
10448     check_execute(stmt, rc);
10449 
10450     rc= mysql_stmt_execute(stmt);
10451     check_execute(stmt, rc);
10452 
10453     verify_col_data("test_long_data", "col1", "1");
10454     verify_col_data("test_long_data", "col2", "Data");
10455 
10456     /* clean up */
10457     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10458     myquery(rc);
10459 
10460     /*
10461       Now we are changing int parameter and don't do anything
10462       with first parameter. Second mysql_stmt_execute() should run
10463       OK treating this first parameter as string parameter.
10464     */
10465 
10466     int_data= 2;
10467     /* execute */
10468     rc= mysql_stmt_execute(stmt);
10469     check_execute(stmt, rc);
10470 
10471     verify_col_data("test_long_data", "col1", "2");
10472     verify_col_data("test_long_data", "col2", str_data);
10473 
10474     /* clean up */
10475     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10476     myquery(rc);
10477 
10478     /*
10479       Now we are sending other long data. It should not be
10480       concatened to previous.
10481     */
10482 
10483     data= (char *)"SomeOtherData";
10484     rc= mysql_stmt_send_long_data(stmt, 0, data, (ulong)strlen(data));
10485     check_execute(stmt, rc);
10486 
10487     rc= mysql_stmt_execute(stmt);
10488     check_execute(stmt, rc);
10489 
10490     verify_col_data("test_long_data", "col1", "2");
10491     verify_col_data("test_long_data", "col2", "SomeOtherData");
10492 
10493     mysql_stmt_close(stmt);
10494 
10495     /* clean up */
10496     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10497     myquery(rc);
10498 
10499     /* Now let us test how mysql_stmt_reset works. */
10500     stmt= mysql_stmt_init(mysql);
10501     check_stmt(stmt);
10502     rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
10503     check_execute(stmt, rc);
10504     rc= mysql_stmt_bind_param(stmt, my_bind);
10505     check_execute(stmt, rc);
10506 
10507     data= (char *)"SomeData";
10508     rc= mysql_stmt_send_long_data(stmt, 0, data, (ulong)strlen(data));
10509     check_execute(stmt, rc);
10510 
10511     rc= mysql_stmt_reset(stmt);
10512     check_execute(stmt, rc);
10513 
10514     rc= mysql_stmt_execute(stmt);
10515     check_execute(stmt, rc);
10516 
10517     verify_col_data("test_long_data", "col1", "2");
10518     verify_col_data("test_long_data", "col2", str_data);
10519 
10520     mysql_stmt_close(stmt);
10521 
10522     /* Final clean up */
10523     rc= mysql_query(mysql, "DROP TABLE test_long_data");
10524     myquery(rc);
10525 }
10526 
10527 
test_order_param()10528 static void test_order_param()
10529 {
10530   MYSQL_STMT *stmt;
10531   int rc;
10532 
10533   myheader("test_order_param");
10534 
10535   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10536   myquery(rc);
10537 
10538   rc= mysql_query(mysql, "CREATE TABLE t1(a INT, b char(10))");
10539   myquery(rc);
10540 
10541   stmt= mysql_simple_prepare(mysql,
10542                              "select sum(a) + 200, 1 from t1 "
10543                              " union distinct "
10544                              "select sum(a) + 200, 1 from t1 group by b ");
10545   check_stmt(stmt);
10546   mysql_stmt_close(stmt);
10547 
10548   stmt= mysql_simple_prepare(mysql,
10549                              "select sum(a) + 200, ? from t1 group by b "
10550                              " union distinct "
10551                              "select sum(a) + 200, 1 from t1 group by b ");
10552   check_stmt(stmt);
10553   mysql_stmt_close(stmt);
10554 
10555   stmt= mysql_simple_prepare(mysql,
10556                              "select sum(a) + 200, ? from t1 "
10557                              " union distinct "
10558                              "select sum(a) + 200, 1 from t1 group by b ");
10559   check_stmt(stmt);
10560   mysql_stmt_close(stmt);
10561 
10562   rc= mysql_query(mysql, "DROP TABLE t1");
10563   myquery(rc);
10564 }
10565 
10566 
test_union_param()10567 static void test_union_param()
10568 {
10569   MYSQL_STMT *stmt;
10570   char *query;
10571   int rc, i;
10572   MYSQL_BIND      my_bind[2];
10573   char            my_val[4];
10574   ulong           my_length= 3L;
10575   my_bool         my_null= FALSE;
10576   myheader("test_union_param");
10577 
10578   my_stpcpy(my_val, "abc");
10579 
10580   query= (char*)"select ? as my_col union distinct select ?";
10581   stmt= mysql_simple_prepare(mysql, query);
10582   check_stmt(stmt);
10583 
10584   /*
10585     We need to memset bind structure because mysql_stmt_bind_param checks all
10586     its members.
10587   */
10588   memset(my_bind, 0, sizeof(my_bind));
10589 
10590   /* bind parameters */
10591   my_bind[0].buffer_type=    MYSQL_TYPE_STRING;
10592   my_bind[0].buffer=         (char*) &my_val;
10593   my_bind[0].buffer_length=  4;
10594   my_bind[0].length=         &my_length;
10595   my_bind[0].is_null=        (char*)&my_null;
10596   my_bind[1].buffer_type=    MYSQL_TYPE_STRING;
10597   my_bind[1].buffer=         (char*) &my_val;
10598   my_bind[1].buffer_length=  4;
10599   my_bind[1].length=         &my_length;
10600   my_bind[1].is_null=        (char*)&my_null;
10601 
10602   rc= mysql_stmt_bind_param(stmt, my_bind);
10603   check_execute(stmt, rc);
10604 
10605   for (i= 0; i < 3; i++)
10606   {
10607     rc= mysql_stmt_execute(stmt);
10608     check_execute(stmt, rc);
10609     rc= my_process_stmt_result(stmt);
10610     DIE_UNLESS(rc == 1);
10611   }
10612 
10613   mysql_stmt_close(stmt);
10614 }
10615 
10616 
test_ps_i18n()10617 static void test_ps_i18n()
10618 {
10619   MYSQL_STMT *stmt;
10620   int rc;
10621   const char *stmt_text;
10622   MYSQL_BIND bind_array[2];
10623 
10624   /* Represented as numbers to keep UTF8 tools from clobbering them. */
10625   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
10626   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
10627   char buf1[16], buf2[16];
10628   ulong buf1_len, buf2_len;
10629 
10630 
10631   myheader("test_ps_i18n");
10632 
10633   stmt_text= "DROP TABLE IF EXISTS t1";
10634   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10635   myquery(rc);
10636 
10637   /*
10638     Create table with binary columns, set session character set to cp1251,
10639     client character set to koi8, and make sure that there is conversion
10640     on insert and no conversion on select
10641   */
10642 
10643   stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
10644 
10645   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10646   myquery(rc);
10647 
10648   stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
10649                  "CHARACTER_SET_CONNECTION=cp1251, "
10650                  "CHARACTER_SET_RESULTS=koi8r";
10651 
10652   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10653   myquery(rc);
10654 
10655   memset(bind_array, 0, sizeof(bind_array));
10656 
10657   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10658   bind_array[0].buffer= (void *) koi8;
10659   bind_array[0].buffer_length= (ulong)strlen(koi8);
10660 
10661   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10662   bind_array[1].buffer= (void *) koi8;
10663   bind_array[1].buffer_length= (ulong)strlen(koi8);
10664 
10665   stmt= mysql_stmt_init(mysql);
10666   check_stmt(stmt);
10667 
10668   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10669 
10670   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10671   check_execute(stmt, rc);
10672 
10673   mysql_stmt_bind_param(stmt, bind_array);
10674 
10675   mysql_stmt_send_long_data(stmt, 0, koi8, (ulong)strlen(koi8));
10676 
10677   rc= mysql_stmt_execute(stmt);
10678   check_execute(stmt, rc);
10679 
10680   stmt_text= "SELECT c1, c2 FROM t1";
10681 
10682   /* c1 and c2 are binary so no conversion will be done on select */
10683   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10684   check_execute(stmt, rc);
10685 
10686   rc= mysql_stmt_execute(stmt);
10687   check_execute(stmt, rc);
10688 
10689   bind_array[0].buffer= buf1;
10690   bind_array[0].buffer_length= (ulong)sizeof(buf1);
10691   bind_array[0].length= &buf1_len;
10692 
10693   bind_array[1].buffer= buf2;
10694   bind_array[1].buffer_length= (ulong)sizeof(buf2);
10695   bind_array[1].length= &buf2_len;
10696 
10697   mysql_stmt_bind_result(stmt, bind_array);
10698 
10699   rc= mysql_stmt_fetch(stmt);
10700   check_execute(stmt, rc);
10701 
10702   DIE_UNLESS(buf1_len == strlen(cp1251));
10703   DIE_UNLESS(buf2_len == strlen(cp1251));
10704   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
10705   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
10706 
10707   rc= mysql_stmt_fetch(stmt);
10708   DIE_UNLESS(rc == MYSQL_NO_DATA);
10709 
10710   stmt_text= "DROP TABLE IF EXISTS t1";
10711   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10712   myquery(rc);
10713 
10714   /*
10715     Now create table with two cp1251 columns, set client character
10716     set to koi8 and supply columns of one row as string and another as
10717     binary data. Binary data must not be converted on insert, and both
10718     columns must be converted to client character set on select.
10719   */
10720 
10721   stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
10722                               "c2 VARCHAR(255) CHARACTER SET cp1251)";
10723 
10724   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10725   myquery(rc);
10726 
10727   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10728 
10729   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10730   check_execute(stmt, rc);
10731 
10732   /* this data must be converted */
10733   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10734   bind_array[0].buffer= (void *) koi8;
10735   bind_array[0].buffer_length= (ulong)strlen(koi8);
10736 
10737   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10738   bind_array[1].buffer= (void *) koi8;
10739   bind_array[1].buffer_length= (ulong)strlen(koi8);
10740 
10741   mysql_stmt_bind_param(stmt, bind_array);
10742 
10743   mysql_stmt_send_long_data(stmt, 0, koi8, (ulong)strlen(koi8));
10744 
10745   rc= mysql_stmt_execute(stmt);
10746   check_execute(stmt, rc);
10747 
10748   /* this data must not be converted */
10749   bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
10750   bind_array[0].buffer= (void *) cp1251;
10751   bind_array[0].buffer_length= (ulong)strlen(cp1251);
10752 
10753   bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
10754   bind_array[1].buffer= (void *) cp1251;
10755   bind_array[1].buffer_length= (ulong)strlen(cp1251);
10756 
10757   mysql_stmt_bind_param(stmt, bind_array);
10758 
10759   mysql_stmt_send_long_data(stmt, 0, cp1251, (ulong)strlen(cp1251));
10760 
10761   rc= mysql_stmt_execute(stmt);
10762   check_execute(stmt, rc);
10763 
10764   /* Fetch data and verify that rows are in koi8 */
10765 
10766   stmt_text= "SELECT c1, c2 FROM t1";
10767 
10768   /* c1 and c2 are binary so no conversion will be done on select */
10769   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10770   check_execute(stmt, rc);
10771 
10772   rc= mysql_stmt_execute(stmt);
10773   check_execute(stmt, rc);
10774 
10775   bind_array[0].buffer= buf1;
10776   bind_array[0].buffer_length= (ulong)sizeof(buf1);
10777   bind_array[0].length= &buf1_len;
10778 
10779   bind_array[1].buffer= buf2;
10780   bind_array[1].buffer_length= (ulong)sizeof(buf2);
10781   bind_array[1].length= &buf2_len;
10782 
10783   mysql_stmt_bind_result(stmt, bind_array);
10784 
10785   while ((rc= mysql_stmt_fetch(stmt)) == 0)
10786   {
10787     DIE_UNLESS(buf1_len == strlen(koi8));
10788     DIE_UNLESS(buf2_len == strlen(koi8));
10789     DIE_UNLESS(!memcmp(buf1, koi8, buf1_len));
10790     DIE_UNLESS(!memcmp(buf2, koi8, buf1_len));
10791   }
10792   DIE_UNLESS(rc == MYSQL_NO_DATA);
10793   mysql_stmt_close(stmt);
10794 
10795   stmt_text= "DROP TABLE t1";
10796   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10797   myquery(rc);
10798   stmt_text= "SET NAMES DEFAULT";
10799   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10800   myquery(rc);
10801 }
10802 
10803 
test_bug3796()10804 static void test_bug3796()
10805 {
10806   MYSQL_STMT *stmt;
10807   MYSQL_BIND my_bind[1];
10808   const char *concat_arg0= "concat_with_";
10809   enum { OUT_BUFF_SIZE= 30 };
10810   char out_buff[OUT_BUFF_SIZE];
10811   char canonical_buff[OUT_BUFF_SIZE];
10812   ulong out_length;
10813   const char *stmt_text;
10814   int rc;
10815 
10816   myheader("test_bug3796");
10817 
10818   /* Create and fill test table */
10819   stmt_text= "DROP TABLE IF EXISTS t1";
10820   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10821   myquery(rc);
10822 
10823   stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))";
10824   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10825   myquery(rc);
10826 
10827   stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')";
10828   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10829   myquery(rc);
10830 
10831   /* Create statement handle and prepare it with select */
10832   stmt= mysql_stmt_init(mysql);
10833   stmt_text= "SELECT concat(?, b) FROM t1";
10834 
10835   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10836   check_execute(stmt, rc);
10837 
10838   /* Bind input buffers */
10839   memset(my_bind, 0, sizeof(my_bind));
10840 
10841   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10842   my_bind[0].buffer= (void *) concat_arg0;
10843   my_bind[0].buffer_length= (ulong)strlen(concat_arg0);
10844 
10845   mysql_stmt_bind_param(stmt, my_bind);
10846 
10847   /* Execute the select statement */
10848   rc= mysql_stmt_execute(stmt);
10849   check_execute(stmt, rc);
10850 
10851   my_bind[0].buffer= (void *) out_buff;
10852   my_bind[0].buffer_length= OUT_BUFF_SIZE;
10853   my_bind[0].length= &out_length;
10854 
10855   mysql_stmt_bind_result(stmt, my_bind);
10856 
10857   rc= mysql_stmt_fetch(stmt);
10858   if (!opt_silent)
10859     printf("Concat result: '%s'\n", out_buff);
10860   check_execute(stmt, rc);
10861   my_stpcpy(canonical_buff, concat_arg0);
10862   strcat(canonical_buff, "ONE");
10863   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10864          strncmp(out_buff, canonical_buff, out_length) == 0);
10865 
10866   rc= mysql_stmt_fetch(stmt);
10867   check_execute(stmt, rc);
10868   my_stpcpy(canonical_buff + strlen(concat_arg0), "TWO");
10869   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10870          strncmp(out_buff, canonical_buff, out_length) == 0);
10871   if (!opt_silent)
10872     printf("Concat result: '%s'\n", out_buff);
10873 
10874   rc= mysql_stmt_fetch(stmt);
10875   DIE_UNLESS(rc == MYSQL_NO_DATA);
10876 
10877   mysql_stmt_close(stmt);
10878 
10879   stmt_text= "DROP TABLE IF EXISTS t1";
10880   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
10881   myquery(rc);
10882 }
10883 
10884 
test_bug4026()10885 static void test_bug4026()
10886 {
10887   MYSQL_STMT *stmt;
10888   MYSQL_BIND my_bind[2];
10889   MYSQL_TIME time_in, time_out;
10890   MYSQL_TIME datetime_in, datetime_out;
10891   const char *stmt_text;
10892   int rc;
10893 
10894   myheader("test_bug4026");
10895 
10896   /* Check that microseconds are inserted and selected successfully */
10897 
10898   /* Create a statement handle and prepare it with select */
10899   stmt= mysql_stmt_init(mysql);
10900   stmt_text= "SELECT ?, ?";
10901 
10902   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10903   check_execute(stmt, rc);
10904 
10905   /* Bind input buffers */
10906   memset(my_bind, 0, sizeof(my_bind));
10907   memset(&time_in, 0, sizeof(time_in));
10908   memset(&time_out, 0, sizeof(time_out));
10909   memset(&datetime_in, 0, sizeof(datetime_in));
10910   memset(&datetime_out, 0, sizeof(datetime_out));
10911 
10912   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
10913   my_bind[0].buffer= (void *) &time_in;
10914   my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
10915   my_bind[1].buffer= (void *) &datetime_in;
10916 
10917   time_in.hour= 23;
10918   time_in.minute= 59;
10919   time_in.second= 59;
10920   time_in.second_part= 123456;
10921   /*
10922     This is not necessary, just to make DIE_UNLESS below work: this field
10923     is filled in when time is received from server
10924   */
10925   time_in.time_type= MYSQL_TIMESTAMP_TIME;
10926 
10927   datetime_in= time_in;
10928   datetime_in.year= 2003;
10929   datetime_in.month= 12;
10930   datetime_in.day= 31;
10931   datetime_in.time_type= MYSQL_TIMESTAMP_DATETIME;
10932 
10933   mysql_stmt_bind_param(stmt, my_bind);
10934 
10935   /* Execute the select statement */
10936   rc= mysql_stmt_execute(stmt);
10937   check_execute(stmt, rc);
10938 
10939   my_bind[0].buffer= (void *) &time_out;
10940   my_bind[1].buffer= (void *) &datetime_out;
10941 
10942   mysql_stmt_bind_result(stmt, my_bind);
10943 
10944   rc= mysql_stmt_fetch(stmt);
10945   DIE_UNLESS(rc == 0);
10946   if (!opt_silent)
10947   {
10948     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
10949            time_out.second_part);
10950     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
10951            datetime_out.day, datetime_out.hour,
10952            datetime_out.minute, datetime_out.second,
10953            datetime_out.second_part);
10954   }
10955   DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0);
10956   DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0);
10957   mysql_stmt_close(stmt);
10958 }
10959 
10960 
test_bug4079()10961 static void test_bug4079()
10962 {
10963   MYSQL_STMT *stmt;
10964   MYSQL_BIND my_bind[1];
10965   const char *stmt_text;
10966   uint32 res;
10967   int rc;
10968 
10969   myheader("test_bug4079");
10970 
10971   /* Create and fill table */
10972   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10973   mysql_query(mysql, "CREATE TABLE t1 (a int)");
10974   mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2)");
10975 
10976   /* Prepare erroneous statement */
10977   stmt= mysql_stmt_init(mysql);
10978   stmt_text= "SELECT 1 < (SELECT a FROM t1)";
10979 
10980   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
10981   check_execute(stmt, rc);
10982 
10983   /* Execute the select statement */
10984   rc= mysql_stmt_execute(stmt);
10985   check_execute(stmt, rc);
10986 
10987   /* Bind input buffers */
10988   memset(my_bind, 0, sizeof(my_bind));
10989 
10990   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10991   my_bind[0].buffer= (void *) &res;
10992 
10993   mysql_stmt_bind_result(stmt, my_bind);
10994 
10995   rc= mysql_stmt_fetch(stmt);
10996   DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA);
10997   if (!opt_silent)
10998     printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
10999            mysql_stmt_error(stmt));
11000   /* buggy version of libmysql hanged up here */
11001   mysql_stmt_close(stmt);
11002 }
11003 
11004 
test_bug4236()11005 static void test_bug4236()
11006 {
11007   MYSQL_STMT *stmt;
11008   const char *stmt_text;
11009   int rc;
11010   MYSQL_STMT backup;
11011 
11012   myheader("test_bug4236");
11013 
11014   stmt= mysql_stmt_init(mysql);
11015 
11016   /* mysql_stmt_execute() of statement with statement id= 0 crashed server */
11017   stmt_text= "SELECT 1";
11018   /* We need to prepare statement to pass by possible check in libmysql */
11019   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11020   check_execute(stmt, rc);
11021   /* Hack to check that server works OK if statement wasn't found */
11022   backup.stmt_id= stmt->stmt_id;
11023   stmt->stmt_id= 0;
11024   rc= mysql_stmt_execute(stmt);
11025   DIE_UNLESS(rc);
11026   /* Restore original statement id to be able to reprepare it */
11027   stmt->stmt_id= backup.stmt_id;
11028 
11029   mysql_stmt_close(stmt);
11030 }
11031 
11032 
test_bug4030()11033 static void test_bug4030()
11034 {
11035   MYSQL_STMT *stmt;
11036   MYSQL_BIND my_bind[3];
11037   MYSQL_TIME time_canonical, time_out;
11038   MYSQL_TIME date_canonical, date_out;
11039   MYSQL_TIME datetime_canonical, datetime_out;
11040   const char *stmt_text;
11041   int rc;
11042 
11043   myheader("test_bug4030");
11044 
11045   /* Check that microseconds are inserted and selected successfully */
11046 
11047   /* Execute a query with time values in prepared mode */
11048   stmt= mysql_stmt_init(mysql);
11049   stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
11050              "'2003-12-31 23:59:59.123456'";
11051   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11052   check_execute(stmt, rc);
11053   rc= mysql_stmt_execute(stmt);
11054   check_execute(stmt, rc);
11055 
11056   /* Bind output buffers */
11057   memset(my_bind, 0, sizeof(my_bind));
11058   memset(&time_canonical, 0, sizeof(time_canonical));
11059   memset(&time_out, 0, sizeof(time_out));
11060   memset(&date_canonical, 0, sizeof(date_canonical));
11061   memset(&date_out, 0, sizeof(date_out));
11062   memset(&datetime_canonical, 0, sizeof(datetime_canonical));
11063   memset(&datetime_out, 0, sizeof(datetime_out));
11064 
11065   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
11066   my_bind[0].buffer= (void *) &time_out;
11067   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11068   my_bind[1].buffer= (void *) &date_out;
11069   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
11070   my_bind[2].buffer= (void *) &datetime_out;
11071 
11072   time_canonical.hour= 23;
11073   time_canonical.minute= 59;
11074   time_canonical.second= 59;
11075   time_canonical.second_part= 123456;
11076   time_canonical.time_type= MYSQL_TIMESTAMP_TIME;
11077 
11078   date_canonical.year= 2003;
11079   date_canonical.month= 12;
11080   date_canonical.day= 31;
11081   date_canonical.time_type= MYSQL_TIMESTAMP_DATE;
11082 
11083   datetime_canonical= time_canonical;
11084   datetime_canonical.year= 2003;
11085   datetime_canonical.month= 12;
11086   datetime_canonical.day= 31;
11087   datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME;
11088 
11089   mysql_stmt_bind_result(stmt, my_bind);
11090 
11091   rc= mysql_stmt_fetch(stmt);
11092   DIE_UNLESS(rc == 0);
11093   if (!opt_silent)
11094   {
11095     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
11096            time_out.second_part);
11097     printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
11098     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
11099            datetime_out.day, datetime_out.hour,
11100            datetime_out.minute, datetime_out.second,
11101            datetime_out.second_part);
11102   }
11103   DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
11104   DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
11105   DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
11106   mysql_stmt_close(stmt);
11107 }
11108 
test_view()11109 static void test_view()
11110 {
11111   MYSQL_STMT *stmt;
11112   int rc, i;
11113   MYSQL_BIND      my_bind[1];
11114   char            str_data[50];
11115   ulong           length = 0L;
11116   long            is_null = 0L;
11117   const char *query=
11118     "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
11119 
11120   myheader("test_view");
11121 
11122   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
11123   myquery(rc);
11124 
11125   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
11126   myquery(rc);
11127   rc= mysql_query(mysql,"CREATE TABLE t1 ("
11128                         " SERVERGRP varchar(20) NOT NULL default '', "
11129                         " DBINSTANCE varchar(20) NOT NULL default '', "
11130                         " PRIMARY KEY  (SERVERGRP)) "
11131                         " CHARSET=latin1 collate=latin1_bin");
11132   myquery(rc);
11133   rc= mysql_query(mysql,"CREATE TABLE t2 ("
11134                         " SERVERNAME varchar(20) NOT NULL, "
11135                         " SERVERGRP varchar(20) NOT NULL, "
11136                         " PRIMARY KEY (SERVERNAME)) "
11137                         " CHARSET=latin1 COLLATE latin1_bin");
11138   myquery(rc);
11139   rc= mysql_query(mysql,
11140                   "CREATE TABLE t3 ("
11141                   " SERVERGRP varchar(20) BINARY NOT NULL, "
11142                   " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
11143                   " ACTSTATE char(1) NOT NULL , "
11144                   " LOCAL_NAME varchar(30) NOT NULL, "
11145                   " CHG_DATE varchar(8) NOT NULL default '00000000', "
11146                   " CHG_TIME varchar(6) NOT NULL default '000000', "
11147                   " MXUSER varchar(12) NOT NULL default '', "
11148                   " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
11149                   " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
11150   myquery(rc);
11151   rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
11152                   " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
11153                   " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
11154                   " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
11155                   " ((T0002.SERVERGRP = T0001.SERVERGRP) and"
11156                   " (T0002.SERVERGRP = T0003.SERVERGRP)"
11157                   " and (T0003.MAPSTATE = _latin1'A') and"
11158                   " (T0003.ACTSTATE = _latin1' '))");
11159   myquery(rc);
11160 
11161   stmt= mysql_stmt_init(mysql);
11162   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11163   check_execute(stmt, rc);
11164 
11165   my_stpcpy(str_data, "TEST");
11166   memset(my_bind, 0, sizeof(my_bind));
11167   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
11168   my_bind[0].buffer= (char *)&str_data;
11169   my_bind[0].buffer_length= 50;
11170   my_bind[0].length= &length;
11171   length= 4;
11172   my_bind[0].is_null= (char*)&is_null;
11173   rc= mysql_stmt_bind_param(stmt, my_bind);
11174   check_execute(stmt,rc);
11175 
11176   for (i= 0; i < 3; i++)
11177   {
11178     rc= mysql_stmt_execute(stmt);
11179     check_execute(stmt, rc);
11180     rc= my_process_stmt_result(stmt);
11181     DIE_UNLESS(1 == rc);
11182   }
11183   mysql_stmt_close(stmt);
11184 
11185   rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
11186   myquery(rc);
11187   rc= mysql_query(mysql, "DROP VIEW v1");
11188   myquery(rc);
11189 }
11190 
11191 
test_view_where()11192 static void test_view_where()
11193 {
11194   MYSQL_STMT *stmt;
11195   int rc, i;
11196   const char *query=
11197     "select v1.c,v2.c from v1, v2";
11198 
11199   myheader("test_view_where");
11200 
11201   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2");
11202   myquery(rc);
11203 
11204   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1");
11205   myquery(rc);
11206   rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)");
11207   myquery(rc);
11208   rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)");
11209   myquery(rc);
11210   rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3");
11211   myquery(rc);
11212   rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3");
11213   myquery(rc);
11214 
11215   stmt= mysql_stmt_init(mysql);
11216   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11217   check_execute(stmt, rc);
11218 
11219   for (i= 0; i < 3; i++)
11220   {
11221     rc= mysql_stmt_execute(stmt);
11222     check_execute(stmt, rc);
11223     rc= my_process_stmt_result(stmt);
11224     DIE_UNLESS(4 == rc);
11225   }
11226   mysql_stmt_close(stmt);
11227 
11228   rc= mysql_query(mysql, "DROP TABLE t1");
11229   myquery(rc);
11230   rc= mysql_query(mysql, "DROP VIEW v1, v2");
11231   myquery(rc);
11232 }
11233 
11234 
test_view_2where()11235 static void test_view_2where()
11236 {
11237   MYSQL_STMT *stmt;
11238   int rc, i;
11239   MYSQL_BIND      my_bind[8];
11240   char            parms[8][100];
11241   ulong           length[8];
11242   const char *query=
11243     "select relid, report, handle, log_group, username, variant, type, "
11244     "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
11245     "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
11246     "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";
11247 
11248   myheader("test_view_2where");
11249 
11250   rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
11251   myquery(rc);
11252   rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
11253   myquery(rc);
11254   rc= mysql_query(mysql,
11255                   "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
11256                   " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
11257                   " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
11258                   " USERNAME varchar(12) NOT NULL,"
11259                   " VARIANT varchar(12) NOT NULL,"
11260                   " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
11261                   " VERSION varchar(6) NOT NULL default '000000',"
11262                   " ERFDAT varchar(8) NOT NULL default '00000000',"
11263                   " ERFTIME varchar(6) NOT NULL default '000000',"
11264                   " ERFNAME varchar(12) NOT NULL,"
11265                   " AEDAT varchar(8) NOT NULL default '00000000',"
11266                   " AETIME varchar(6) NOT NULL default '000000',"
11267                   " AENAME varchar(12) NOT NULL,"
11268                   " DEPENDVARS varchar(10) NOT NULL,"
11269                   " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
11270                   " CLUSTD blob,"
11271                   " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
11272                                 "USERNAME, VARIANT, TYPE, SRTF2))"
11273                  " CHARSET=latin1 COLLATE latin1_bin");
11274   myquery(rc);
11275   rc= mysql_query(mysql,
11276                   "CREATE VIEW V_LTDX AS select T0001.MANDT AS "
11277                   " MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
11278                   " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
11279                   " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
11280                   " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
11281                   " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
11282                   " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
11283                   " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
11284                   " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
11285                   " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
11286   myquery(rc);
11287   memset(my_bind, 0, sizeof(my_bind));
11288   for (i=0; i < 8; i++) {
11289     my_stpcpy(parms[i], "1");
11290     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11291     my_bind[i].buffer = (char *)&parms[i];
11292     my_bind[i].buffer_length = 100;
11293     my_bind[i].is_null = 0;
11294     my_bind[i].length = &length[i];
11295     length[i] = 1;
11296   }
11297   stmt= mysql_stmt_init(mysql);
11298   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11299   check_execute(stmt, rc);
11300 
11301   rc= mysql_stmt_bind_param(stmt, my_bind);
11302   check_execute(stmt,rc);
11303 
11304   rc= mysql_stmt_execute(stmt);
11305   check_execute(stmt, rc);
11306   rc= my_process_stmt_result(stmt);
11307   DIE_UNLESS(0 == rc);
11308 
11309   mysql_stmt_close(stmt);
11310 
11311   rc= mysql_query(mysql, "DROP VIEW V_LTDX");
11312   myquery(rc);
11313   rc= mysql_query(mysql, "DROP TABLE LTDX");
11314   myquery(rc);
11315 }
11316 
11317 
test_view_star()11318 static void test_view_star()
11319 {
11320   MYSQL_STMT *stmt;
11321   int rc, i;
11322   MYSQL_BIND      my_bind[8];
11323   char            parms[8][100];
11324   ulong           length[8];
11325   const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)";
11326 
11327   myheader("test_view_star");
11328 
11329   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1");
11330   myquery(rc);
11331   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1");
11332   myquery(rc);
11333   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
11334   myquery(rc);
11335   rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1");
11336   myquery(rc);
11337   memset(my_bind, 0, sizeof(my_bind));
11338   for (i= 0; i < 2; i++) {
11339     sprintf((char *)&parms[i], "%d", i);
11340     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11341     my_bind[i].buffer = (char *)&parms[i];
11342     my_bind[i].buffer_length = 100;
11343     my_bind[i].is_null = 0;
11344     my_bind[i].length = &length[i];
11345     length[i] = 1;
11346   }
11347 
11348   stmt= mysql_stmt_init(mysql);
11349   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11350   check_execute(stmt, rc);
11351 
11352   rc= mysql_stmt_bind_param(stmt, my_bind);
11353   check_execute(stmt,rc);
11354 
11355   for (i= 0; i < 3; i++)
11356   {
11357     rc= mysql_stmt_execute(stmt);
11358     check_execute(stmt, rc);
11359     rc= my_process_stmt_result(stmt);
11360     DIE_UNLESS(0 == rc);
11361   }
11362 
11363   mysql_stmt_close(stmt);
11364 
11365   rc= mysql_query(mysql, "DROP TABLE t1");
11366   myquery(rc);
11367   rc= mysql_query(mysql, "DROP VIEW vt1");
11368   myquery(rc);
11369 }
11370 
11371 
test_view_insert()11372 static void test_view_insert()
11373 {
11374   MYSQL_STMT *insert_stmt, *select_stmt;
11375   int rc, i;
11376   MYSQL_BIND      my_bind[1];
11377   int             my_val = 0;
11378   ulong           my_length = 0L;
11379   long            my_null = 0L;
11380   const char *query=
11381     "insert into v1 values (?)";
11382 
11383   myheader("test_view_insert");
11384 
11385   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11386   myquery(rc);
11387   rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1");
11388   myquery(rc);
11389 
11390   rc= mysql_query(mysql,"create table t1 (a int, primary key (a))");
11391   myquery(rc);
11392 
11393   rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1");
11394   myquery(rc);
11395 
11396   insert_stmt= mysql_stmt_init(mysql);
11397   rc= mysql_stmt_prepare(insert_stmt, query, (ulong)strlen(query));
11398   check_execute(insert_stmt, rc);
11399   query= "select * from t1";
11400   select_stmt= mysql_stmt_init(mysql);
11401   rc= mysql_stmt_prepare(select_stmt, query, (ulong)strlen(query));
11402   check_execute(select_stmt, rc);
11403 
11404   memset(my_bind, 0, sizeof(my_bind));
11405   my_bind[0].buffer_type = MYSQL_TYPE_LONG;
11406   my_bind[0].buffer = (char *)&my_val;
11407   my_bind[0].length = &my_length;
11408   my_bind[0].is_null = (char*)&my_null;
11409   rc= mysql_stmt_bind_param(insert_stmt, my_bind);
11410   check_execute(insert_stmt, rc);
11411 
11412   for (i= 0; i < 3; i++)
11413   {
11414     int rowcount= 0;
11415     my_val= i;
11416 
11417     rc= mysql_stmt_execute(insert_stmt);
11418     check_execute(insert_stmt, rc);
11419 
11420     rc= mysql_stmt_execute(select_stmt);
11421     check_execute(select_stmt, rc);
11422     rowcount= (int)my_process_stmt_result(select_stmt);
11423     DIE_UNLESS((i+1) == rowcount);
11424   }
11425   mysql_stmt_close(insert_stmt);
11426   mysql_stmt_close(select_stmt);
11427 
11428   rc= mysql_query(mysql, "DROP VIEW v1");
11429   myquery(rc);
11430   rc= mysql_query(mysql, "DROP TABLE t1");
11431   myquery(rc);
11432 }
11433 
11434 
test_left_join_view()11435 static void test_left_join_view()
11436 {
11437   MYSQL_STMT *stmt;
11438   int rc, i;
11439   const char *query=
11440     "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);";
11441 
11442   myheader("test_left_join_view");
11443 
11444   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11445   myquery(rc);
11446 
11447   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1");
11448   myquery(rc);
11449   rc= mysql_query(mysql,"CREATE TABLE t1 (a int)");
11450   myquery(rc);
11451   rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)");
11452   myquery(rc);
11453   rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1");
11454   myquery(rc);
11455   stmt= mysql_stmt_init(mysql);
11456   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11457   check_execute(stmt, rc);
11458 
11459   for (i= 0; i < 3; i++)
11460   {
11461     rc= mysql_stmt_execute(stmt);
11462     check_execute(stmt, rc);
11463     rc= my_process_stmt_result(stmt);
11464     DIE_UNLESS(3 == rc);
11465   }
11466   mysql_stmt_close(stmt);
11467 
11468   rc= mysql_query(mysql, "DROP VIEW v1");
11469   myquery(rc);
11470   rc= mysql_query(mysql, "DROP TABLE t1");
11471   myquery(rc);
11472 }
11473 
11474 
test_view_insert_fields()11475 static void test_view_insert_fields()
11476 {
11477   MYSQL_STMT	*stmt;
11478   char		parm[11][1000];
11479   ulong         l[11];
11480   int		rc, i;
11481   MYSQL_BIND	my_bind[11];
11482   const char    *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";
11483 
11484   myheader("test_view_insert_fields");
11485 
11486   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
11487   myquery(rc);
11488   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
11489   myquery(rc);
11490   rc= mysql_query(mysql,
11491                   "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
11492                   "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
11493                   "K4N4 varchar(4) NOT NULL default '0000',"
11494                   "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
11495                   "F3N5 varchar(5) NOT NULL default '00000',"
11496                   "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
11497                   "F6N4 varchar(4) NOT NULL default '0000',"
11498                   "F7F8 double NOT NULL default '0',"
11499                   "F8F8 double NOT NULL default '0',"
11500                   "F9D8 decimal(8,2) NOT NULL default '0.00',"
11501                   "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
11502                   "CHARSET=latin1 COLLATE latin1_bin");
11503   myquery(rc);
11504   rc= mysql_query(mysql,
11505                   "CREATE VIEW v1 AS select sql_no_cache "
11506                   " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
11507                   " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
11508                   " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
11509                   " from t1 T0001");
11510 
11511   memset(my_bind, 0, sizeof(my_bind));
11512   memset(parm, 0, sizeof(parm));
11513   for (i= 0; i < 11; i++)
11514   {
11515     l[i]= 20;
11516     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
11517     my_bind[i].is_null= 0;
11518     my_bind[i].buffer= (char *)&parm[i];
11519 
11520     my_stpcpy(parm[i], "1");
11521     my_bind[i].buffer_length= 2;
11522     my_bind[i].length= &l[i];
11523   }
11524   stmt= mysql_stmt_init(mysql);
11525   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11526   check_execute(stmt, rc);
11527   rc= mysql_stmt_bind_param(stmt, my_bind);
11528   check_execute(stmt, rc);
11529 
11530   rc= mysql_stmt_execute(stmt);
11531   check_execute(stmt, rc);
11532   mysql_stmt_close(stmt);
11533 
11534   query= "select * from t1";
11535   stmt= mysql_stmt_init(mysql);
11536   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
11537   check_execute(stmt, rc);
11538   rc= mysql_stmt_execute(stmt);
11539   check_execute(stmt, rc);
11540   rc= my_process_stmt_result(stmt);
11541   DIE_UNLESS(1 == rc);
11542 
11543   mysql_stmt_close(stmt);
11544   rc= mysql_query(mysql, "DROP VIEW v1");
11545   myquery(rc);
11546   rc= mysql_query(mysql, "DROP TABLE t1");
11547   myquery(rc);
11548 
11549 }
11550 
test_bug5126()11551 static void test_bug5126()
11552 {
11553   MYSQL_STMT *stmt;
11554   MYSQL_BIND my_bind[2];
11555   int32 c1, c2;
11556   const char *stmt_text;
11557   int rc;
11558 
11559   myheader("test_bug5126");
11560 
11561   stmt_text= "DROP TABLE IF EXISTS t1";
11562   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11563   myquery(rc);
11564 
11565   stmt_text= "CREATE TABLE t1 (a mediumint, b int)";
11566   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11567   myquery(rc);
11568 
11569   stmt_text= "INSERT INTO t1 VALUES (8386608, 1)";
11570   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11571   myquery(rc);
11572 
11573   stmt= mysql_stmt_init(mysql);
11574   stmt_text= "SELECT a, b FROM t1";
11575   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11576   check_execute(stmt, rc);
11577   rc= mysql_stmt_execute(stmt);
11578   check_execute(stmt, rc);
11579 
11580   /* Bind output buffers */
11581   memset(my_bind, 0, sizeof(my_bind));
11582 
11583   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11584   my_bind[0].buffer= &c1;
11585   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
11586   my_bind[1].buffer= &c2;
11587 
11588   mysql_stmt_bind_result(stmt, my_bind);
11589 
11590   rc= mysql_stmt_fetch(stmt);
11591   DIE_UNLESS(rc == 0);
11592   DIE_UNLESS(c1 == 8386608 && c2 == 1);
11593   if (!opt_silent)
11594     printf("%ld, %ld\n", (long) c1, (long) c2);
11595   mysql_stmt_close(stmt);
11596 }
11597 
11598 
test_bug4231()11599 static void test_bug4231()
11600 {
11601   MYSQL_STMT *stmt;
11602   MYSQL_BIND my_bind[2];
11603   MYSQL_TIME tm[2];
11604   const char *stmt_text;
11605   int rc;
11606 
11607   myheader("test_bug4231");
11608 
11609   stmt_text= "DROP TABLE IF EXISTS t1";
11610   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11611   myquery(rc);
11612 
11613   stmt_text= "CREATE TABLE t1 (a int)";
11614   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11615   myquery(rc);
11616 
11617   stmt_text= "INSERT INTO t1 VALUES (1)";
11618   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11619   myquery(rc);
11620 
11621   stmt= mysql_stmt_init(mysql);
11622   stmt_text= "SELECT a FROM t1 WHERE ? = ?";
11623   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11624   check_execute(stmt, rc);
11625 
11626   /* Bind input buffers */
11627   memset(my_bind, 0, sizeof(my_bind));
11628   memset(tm, 0, sizeof(tm));
11629 
11630   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
11631   my_bind[0].buffer= &tm[0];
11632   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11633   my_bind[1].buffer= &tm[1];
11634 
11635   mysql_stmt_bind_param(stmt, my_bind);
11636   check_execute(stmt, rc);
11637 
11638   /*
11639     First set server-side params to some non-zero non-equal values:
11640     then we will check that they are not used when client sends
11641     new (zero) times.
11642   */
11643   tm[0].time_type = MYSQL_TIMESTAMP_DATE;
11644   tm[0].year = 2000;
11645   tm[0].month = 1;
11646   tm[0].day = 1;
11647   tm[1]= tm[0];
11648   --tm[1].year;                                 /* tm[0] != tm[1] */
11649 
11650   rc= mysql_stmt_execute(stmt);
11651   check_execute(stmt, rc);
11652 
11653   rc= mysql_stmt_fetch(stmt);
11654 
11655   /* binds are unequal, no rows should be returned */
11656   DIE_UNLESS(rc == MYSQL_NO_DATA);
11657 
11658   /* Set one of the dates to zero */
11659   tm[0].year= tm[0].month= tm[0].day= 0;
11660   tm[1]= tm[0];
11661   mysql_stmt_execute(stmt);
11662   rc= mysql_stmt_fetch(stmt);
11663   DIE_UNLESS(rc == 0);
11664 
11665   mysql_stmt_close(stmt);
11666   stmt_text= "DROP TABLE t1";
11667   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11668   myquery(rc);
11669 }
11670 
11671 
test_bug5399()11672 static void test_bug5399()
11673 {
11674   /*
11675     Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
11676     statement id hash in the server uses binary collation.
11677   */
11678 #define NUM_OF_USED_STMT 97
11679   MYSQL_STMT *stmt_list[NUM_OF_USED_STMT];
11680   MYSQL_STMT **stmt;
11681   MYSQL_BIND my_bind[1];
11682   char buff[600];
11683   int rc;
11684   int32 no;
11685 
11686   myheader("test_bug5399");
11687 
11688   memset(my_bind, 0, sizeof(my_bind));
11689   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11690   my_bind[0].buffer= &no;
11691 
11692   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11693   {
11694     sprintf(buff, "select %d", (int) (stmt - stmt_list));
11695     *stmt= mysql_stmt_init(mysql);
11696     rc= mysql_stmt_prepare(*stmt, buff, (ulong)strlen(buff));
11697     check_execute(*stmt, rc);
11698     mysql_stmt_bind_result(*stmt, my_bind);
11699   }
11700   if (!opt_silent)
11701     printf("%d statements prepared.\n", NUM_OF_USED_STMT);
11702 
11703   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11704   {
11705     rc= mysql_stmt_execute(*stmt);
11706     check_execute(*stmt, rc);
11707     rc= mysql_stmt_store_result(*stmt);
11708     check_execute(*stmt, rc);
11709     rc= mysql_stmt_fetch(*stmt);
11710     DIE_UNLESS(rc == 0);
11711     DIE_UNLESS((int32) (stmt - stmt_list) == no);
11712   }
11713 
11714   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11715     mysql_stmt_close(*stmt);
11716 #undef NUM_OF_USED_STMT
11717 }
11718 
11719 
test_bug5194()11720 static void test_bug5194()
11721 {
11722   MYSQL_STMT *stmt;
11723   MYSQL_BIND *my_bind;
11724   char *query;
11725   char *param_str;
11726   ulong param_str_length;
11727   const char *stmt_text;
11728   int rc;
11729   float float_array[250] =
11730   {
11731     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
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.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
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   };
11757   float *fa_ptr= float_array;
11758   /* Number of columns per row */
11759   const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array);
11760   /* Number of rows per bulk insert to start with */
11761   const int MIN_ROWS_PER_INSERT= 262;
11762   /* Max number of rows per bulk insert to end with */
11763   const int MAX_ROWS_PER_INSERT= 300;
11764   const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT;
11765   const char *query_template= "insert into t1 values %s";
11766   const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */
11767   const int uint16_max= 65535;
11768   int nrows, i;
11769 
11770   myheader("test_bug5194");
11771 
11772   stmt_text= "drop table if exists t1";
11773   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11774 
11775   stmt_text= "create table if not exists t1"
11776    "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, "
11777    "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, "
11778    "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, "
11779    "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, "
11780    "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, "
11781    "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, "
11782    "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, "
11783    "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, "
11784    "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, "
11785    "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, "
11786    "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, "
11787    "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, "
11788    "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, "
11789    "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, "
11790    "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, "
11791    "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, "
11792    "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, "
11793    "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, "
11794    "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, "
11795    "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, "
11796    "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, "
11797    "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, "
11798    "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, "
11799    "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, "
11800    "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, "
11801    "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, "
11802    "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, "
11803    "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, "
11804    "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, "
11805    "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, "
11806    "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, "
11807    "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, "
11808    "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, "
11809    "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, "
11810    "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, "
11811    "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, "
11812    "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, "
11813    "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, "
11814    "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, "
11815    "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, "
11816    "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, "
11817    "c247 float, c248 float, c249 float, c250 float)";
11818   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11819   myquery(rc);
11820 
11821   my_bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11822   query= (char*) malloc(strlen(query_template) +
11823                         MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
11824   param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
11825 
11826   if (my_bind == 0 || query == 0 || param_str == 0)
11827   {
11828     fprintf(stderr, "Can't allocate enough memory for query structs\n");
11829     if (my_bind)
11830       free(my_bind);
11831     if (query)
11832       free(query);
11833     if (param_str)
11834       free(param_str);
11835     return;
11836   }
11837 
11838   stmt= mysql_stmt_init(mysql);
11839 
11840   /* setup a template for one row of parameters */
11841   sprintf(param_str, "(");
11842   for (i= 1; i < COLUMN_COUNT; ++i)
11843     strcat(param_str, "?, ");
11844   strcat(param_str, "?)");
11845   param_str_length= (ulong)strlen(param_str);
11846 
11847   /* setup bind array */
11848   memset(my_bind, 0, MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11849   for (i= 0; i < MAX_PARAM_COUNT; ++i)
11850   {
11851     my_bind[i].buffer_type= MYSQL_TYPE_FLOAT;
11852     my_bind[i].buffer= fa_ptr;
11853     if (++fa_ptr == float_array + COLUMN_COUNT)
11854       fa_ptr= float_array;
11855   }
11856 
11857   /*
11858     Test each number of rows per bulk insert, so that we can see where
11859     MySQL fails.
11860   */
11861   for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows)
11862   {
11863     char *query_ptr;
11864     /* Create statement text for current number of rows */
11865     sprintf(query, query_template, param_str);
11866     query_ptr= query + strlen(query);
11867     for (i= 1; i < nrows; ++i)
11868     {
11869       memcpy(query_ptr, ", ", 2);
11870       query_ptr+= 2;
11871       memcpy(query_ptr, param_str, param_str_length);
11872       query_ptr+= param_str_length;
11873     }
11874     *query_ptr= '\0';
11875 
11876     rc= mysql_stmt_prepare(stmt, query, (ulong)(query_ptr - query));
11877     if (rc && nrows * COLUMN_COUNT > uint16_max)
11878     {
11879       if (!opt_silent)
11880         printf("Failed to prepare a statement with %d placeholders "
11881                "(as expected).\n", nrows * COLUMN_COUNT);
11882       break;
11883     }
11884     else
11885       check_execute(stmt, rc);
11886 
11887     if (!opt_silent)
11888       printf("Insert: query length= %d, row count= %d, param count= %lu\n",
11889              (int) strlen(query), nrows, mysql_stmt_param_count(stmt));
11890 
11891     /* bind the parameter array and execute the query */
11892     rc= mysql_stmt_bind_param(stmt, my_bind);
11893     check_execute(stmt, rc);
11894 
11895     rc= mysql_stmt_execute(stmt);
11896     check_execute(stmt, rc);
11897     mysql_stmt_reset(stmt);
11898   }
11899 
11900   mysql_stmt_close(stmt);
11901   free(my_bind);
11902   free(query);
11903   free(param_str);
11904   stmt_text= "drop table t1";
11905   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11906   myquery(rc);
11907 }
11908 
11909 
test_bug5315()11910 static void test_bug5315()
11911 {
11912   MYSQL_STMT *stmt;
11913   const char *stmt_text;
11914   int rc;
11915 
11916   myheader("test_bug5315");
11917 
11918   stmt_text= "SELECT 1";
11919   stmt= mysql_stmt_init(mysql);
11920   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11921   DIE_UNLESS(rc == 0);
11922   if (!opt_silent)
11923     printf("Excuting mysql_change_user\n");
11924   mysql_change_user(mysql, opt_user, opt_password, current_db);
11925   if (!opt_silent)
11926     printf("Excuting mysql_stmt_execute\n");
11927   rc= mysql_stmt_execute(stmt);
11928   DIE_UNLESS(rc != 0);
11929   if (rc)
11930   {
11931     if (!opt_silent)
11932       printf("Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
11933   }
11934   /* check that connection is OK */
11935   if (!opt_silent)
11936     printf("Excuting mysql_stmt_close\n");
11937   mysql_stmt_close(stmt);
11938   if (!opt_silent)
11939     printf("Excuting mysql_stmt_init\n");
11940   stmt= mysql_stmt_init(mysql);
11941   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11942   DIE_UNLESS(rc == 0);
11943   rc= mysql_stmt_execute(stmt);
11944   DIE_UNLESS(rc == 0);
11945   mysql_stmt_close(stmt);
11946 }
11947 
11948 
test_bug6049()11949 static void test_bug6049()
11950 {
11951   MYSQL_STMT *stmt;
11952   MYSQL_BIND my_bind[1];
11953   MYSQL_RES *res;
11954   MYSQL_ROW row;
11955   const char *stmt_text;
11956   char buffer[30];
11957   ulong length;
11958   int rc;
11959 
11960   myheader("test_bug6049");
11961 
11962   if (mysql_get_server_version(mysql) < 50600)
11963   {
11964     if (!opt_silent)
11965       fprintf(stdout, "Skipping test_bug6049: this test cannot be executed "
11966               "on servers prior to 5.6 until bug#16433596 is fixed\n");
11967     return;
11968   }
11969 
11970   stmt_text= "SELECT MAKETIME(-25, 12, 12)";
11971 
11972   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
11973   myquery(rc);
11974   res= mysql_store_result(mysql);
11975   row= mysql_fetch_row(res);
11976 
11977   stmt= mysql_stmt_init(mysql);
11978   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
11979   check_execute(stmt, rc);
11980   rc= mysql_stmt_execute(stmt);
11981   check_execute(stmt, rc);
11982 
11983   memset(my_bind, 0, sizeof(my_bind));
11984   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
11985   my_bind[0].buffer         = &buffer;
11986   my_bind[0].buffer_length  = (ulong)sizeof(buffer);
11987   my_bind[0].length         = &length;
11988 
11989   mysql_stmt_bind_result(stmt, my_bind);
11990   rc= mysql_stmt_fetch(stmt);
11991   DIE_UNLESS(rc == 0);
11992 
11993   if (!opt_silent)
11994   {
11995     printf("Result from query: %s\n", row[0]);
11996     printf("Result from prepared statement: %s\n", (char*) buffer);
11997   }
11998 
11999   DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);
12000 
12001   mysql_free_result(res);
12002   mysql_stmt_close(stmt);
12003 }
12004 
12005 
test_bug6058()12006 static void test_bug6058()
12007 {
12008   MYSQL_STMT *stmt;
12009   MYSQL_BIND my_bind[1];
12010   MYSQL_RES *res;
12011   MYSQL_ROW row;
12012   const char *stmt_text;
12013   char buffer[30];
12014   ulong length;
12015   int rc;
12016 
12017   myheader("test_bug6058");
12018 
12019   rc= mysql_query(mysql, "SET SQL_MODE=''");
12020   myquery(rc);
12021 
12022   stmt_text= "SELECT CAST('0000-00-00' AS DATE)";
12023 
12024   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12025   myquery(rc);
12026   res= mysql_store_result(mysql);
12027   row= mysql_fetch_row(res);
12028 
12029   stmt= mysql_stmt_init(mysql);
12030   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12031   check_execute(stmt, rc);
12032   rc= mysql_stmt_execute(stmt);
12033   check_execute(stmt, rc);
12034 
12035   memset(my_bind, 0, sizeof(my_bind));
12036   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
12037   my_bind[0].buffer         = &buffer;
12038   my_bind[0].buffer_length  = (ulong)sizeof(buffer);
12039   my_bind[0].length         = &length;
12040 
12041   mysql_stmt_bind_result(stmt, my_bind);
12042   rc= mysql_stmt_fetch(stmt);
12043   DIE_UNLESS(rc == 0);
12044 
12045   if (!opt_silent)
12046   {
12047     printf("Result from query: %s\n", row[0]);
12048     printf("Result from prepared statement: %s\n", buffer);
12049   }
12050 
12051   DIE_UNLESS(strcmp(row[0], buffer) == 0);
12052 
12053   mysql_free_result(res);
12054   mysql_stmt_close(stmt);
12055 }
12056 
12057 
test_bug6059()12058 static void test_bug6059()
12059 {
12060   MYSQL_STMT *stmt;
12061   const char *stmt_text;
12062 
12063   myheader("test_bug6059");
12064 
12065   stmt_text= "SELECT 'foo' INTO OUTFILE 'x.3'";
12066 
12067   stmt= mysql_stmt_init(mysql);
12068   (void) mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12069   DIE_UNLESS(mysql_stmt_field_count(stmt) == 0);
12070   mysql_stmt_close(stmt);
12071 }
12072 
12073 
test_bug6046()12074 static void test_bug6046()
12075 {
12076   MYSQL_STMT *stmt;
12077   const char *stmt_text;
12078   int rc;
12079   short b= 1;
12080   MYSQL_BIND my_bind[1];
12081 
12082   myheader("test_bug6046");
12083 
12084   stmt_text= "DROP TABLE IF EXISTS t1";
12085   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12086   myquery(rc);
12087   stmt_text= "CREATE TABLE t1 (a int, b int)";
12088   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12089   myquery(rc);
12090   stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)";
12091   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12092   myquery(rc);
12093 
12094   stmt= mysql_stmt_init(mysql);
12095 
12096   stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 "
12097              "WHERE t1.b > ? ORDER BY t1.a";
12098 
12099   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12100   check_execute(stmt, rc);
12101 
12102   b= 1;
12103   memset(my_bind, 0, sizeof(my_bind));
12104   my_bind[0].buffer= &b;
12105   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
12106 
12107   mysql_stmt_bind_param(stmt, my_bind);
12108 
12109   rc= mysql_stmt_execute(stmt);
12110   check_execute(stmt, rc);
12111   mysql_stmt_store_result(stmt);
12112 
12113   rc= mysql_stmt_execute(stmt);
12114   check_execute(stmt, rc);
12115 
12116   mysql_stmt_close(stmt);
12117 }
12118 
12119 
12120 
test_basic_cursors()12121 static void test_basic_cursors()
12122 {
12123   const char *basic_tables[]=
12124   {
12125     "DROP TABLE IF EXISTS t1, t2",
12126 
12127     "CREATE TABLE t1 "
12128     "(id INTEGER NOT NULL PRIMARY KEY, "
12129     " name VARCHAR(20) NOT NULL)",
12130 
12131     "INSERT INTO t1 (id, name) VALUES "
12132     "  (2, 'Ja'), (3, 'Ede'), "
12133     "  (4, 'Haag'), (5, 'Kabul'), "
12134     "  (6, 'Almere'), (7, 'Utrecht'), "
12135     "  (8, 'Qandahar'), (9, 'Amsterdam'), "
12136     "  (10, 'Amersfoort'), (11, 'Constantine')",
12137 
12138     "CREATE TABLE t2 "
12139     "(id INTEGER NOT NULL PRIMARY KEY, "
12140     " name VARCHAR(20) NOT NULL)",
12141 
12142     "INSERT INTO t2 (id, name) VALUES "
12143     "  (4, 'Guam'), (5, 'Aruba'), "
12144     "  (6, 'Angola'), (7, 'Albania'), "
12145     "  (8, 'Anguilla'), (9, 'Argentina'), "
12146     "  (10, 'Azerbaijan'), (11, 'Afghanistan'), "
12147     "  (12, 'Burkina Faso'), (13, 'Faroe Islands')"
12148   };
12149   const char *queries[]=
12150   {
12151     "SELECT * FROM t1",
12152     "SELECT * FROM t2"
12153   };
12154 
12155   DBUG_ENTER("test_basic_cursors");
12156   myheader("test_basic_cursors");
12157 
12158   fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
12159 
12160   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12161   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12162   DBUG_VOID_RETURN;
12163 }
12164 
12165 
test_cursors_with_union()12166 static void test_cursors_with_union()
12167 {
12168   const char *queries[]=
12169   {
12170     "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2",
12171     "SELECT t1.id FROM t1 WHERE t1.id < 5"
12172   };
12173   myheader("test_cursors_with_union");
12174   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12175   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12176 }
12177 
12178 
test_cursors_with_procedure()12179 static void test_cursors_with_procedure()
12180 {
12181   const char *queries[]=
12182   {
12183     "SELECT * FROM t1 procedure analyse()"
12184   };
12185   myheader("test_cursors_with_procedure");
12186   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12187   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12188 }
12189 
12190 
12191 /*
12192   Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
12193   should not crash server and should not hang in case of errors.
12194 
12195   Since those functions can't be seen in modern API we use simple_command() macro.
12196 */
test_bug6081()12197 static void test_bug6081()
12198 {
12199   int rc;
12200   myheader("test_bug6081");
12201 
12202   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12203                      (ulong)strlen(current_db), 0);
12204   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12205   {
12206     myerror(NULL);                                   /* purecov: inspected */
12207     die(__FILE__, __LINE__, "COM_DROP_DB failed");   /* purecov: inspected */
12208   }
12209   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12210                      (ulong)strlen(current_db), 0);
12211   myquery_r(rc);
12212   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12213                      (ulong)strlen(current_db), 0);
12214   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12215   {
12216     myerror(NULL);                                   /* purecov: inspected */
12217     die(__FILE__, __LINE__, "COM_CREATE_DB failed"); /* purecov: inspected */
12218   }
12219   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12220                      (ulong)strlen(current_db), 0);
12221   myquery_r(rc);
12222   rc= mysql_select_db(mysql, current_db);
12223   myquery(rc);
12224 }
12225 
12226 
test_bug6096()12227 static void test_bug6096()
12228 {
12229   MYSQL_STMT *stmt;
12230   MYSQL_RES *query_result, *stmt_metadata;
12231   const char *stmt_text;
12232   MYSQL_BIND my_bind[12];
12233   MYSQL_FIELD *query_field_list, *stmt_field_list;
12234   ulong query_field_count, stmt_field_count;
12235   int rc;
12236   my_bool update_max_length= TRUE;
12237   uint i;
12238 
12239   myheader("test_bug6096");
12240 
12241   stmt_text= "drop table if exists t1";
12242   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12243   myquery(rc);
12244 
12245   mysql_query(mysql, "set sql_mode=''");
12246   stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, "
12247                              " c_mediumint mediumint, c_int int, "
12248                              " c_bigint bigint, c_float float, "
12249                              " c_double double, c_varchar varchar(20), "
12250                              " c_char char(20), c_time time, c_date date, "
12251                              " c_datetime datetime)";
12252   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12253   myquery(rc);
12254   stmt_text= "insert into t1  values (-100, -20000, 30000000, 4, 8, 1.0, "
12255                                      "2.0, 'abc', 'def', now(), now(), now())";
12256   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12257   myquery(rc);
12258 
12259   stmt_text= "select * from t1";
12260 
12261   /* Run select in prepared and non-prepared mode and compare metadata */
12262   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12263   myquery(rc);
12264   query_result= mysql_store_result(mysql);
12265   query_field_list= mysql_fetch_fields(query_result);
12266   query_field_count= mysql_num_fields(query_result);
12267 
12268   stmt= mysql_stmt_init(mysql);
12269   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12270   check_execute(stmt, rc);
12271   rc= mysql_stmt_execute(stmt);
12272   check_execute(stmt, rc);
12273   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
12274                       (void*) &update_max_length);
12275   mysql_stmt_store_result(stmt);
12276   stmt_metadata= mysql_stmt_result_metadata(stmt);
12277   stmt_field_list= mysql_fetch_fields(stmt_metadata);
12278   stmt_field_count= mysql_num_fields(stmt_metadata);
12279   DIE_UNLESS(stmt_field_count == query_field_count);
12280 
12281   /* Print out and check the metadata */
12282 
12283   if (!opt_silent)
12284   {
12285     printf(" ------------------------------------------------------------\n");
12286     printf("             |                     Metadata \n");
12287     printf(" ------------------------------------------------------------\n");
12288     printf("             |         Query          |   Prepared statement \n");
12289     printf(" ------------------------------------------------------------\n");
12290     printf(" field name  |  length   | max_length |  length   |  max_length\n");
12291     printf(" ------------------------------------------------------------\n");
12292 
12293     for (i= 0; i < query_field_count; ++i)
12294     {
12295       MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
12296       printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
12297              f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
12298       DIE_UNLESS(f1->length == f2->length);
12299     }
12300     printf(" ---------------------------------------------------------------\n");
12301   }
12302 
12303   /* Bind and fetch the data */
12304 
12305   memset(my_bind, 0, sizeof(my_bind));
12306   for (i= 0; i < stmt_field_count; ++i)
12307   {
12308     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
12309     my_bind[i].buffer_length= stmt_field_list[i].max_length + 1;
12310     my_bind[i].buffer= malloc(my_bind[i].buffer_length);
12311   }
12312   mysql_stmt_bind_result(stmt, my_bind);
12313   rc= mysql_stmt_fetch(stmt);
12314   check_execute(stmt, rc);
12315   rc= mysql_stmt_fetch(stmt);
12316   DIE_UNLESS(rc == MYSQL_NO_DATA);
12317 
12318   /* Clean up */
12319 
12320   for (i= 0; i < stmt_field_count; ++i)
12321     free(my_bind[i].buffer);
12322   mysql_stmt_close(stmt);
12323   mysql_free_result(query_result);
12324   mysql_free_result(stmt_metadata);
12325   stmt_text= "drop table t1";
12326   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12327   myquery(rc);
12328 }
12329 
12330 
12331 /*
12332   Test of basic checks that are performed in server for components
12333   of MYSQL_TIME parameters.
12334 */
12335 
test_datetime_ranges()12336 static void test_datetime_ranges()
12337 {
12338   const char *stmt_text;
12339   int rc, i;
12340   MYSQL_STMT *stmt;
12341   MYSQL_BIND my_bind[6];
12342   MYSQL_TIME tm[6];
12343 
12344   myheader("test_datetime_ranges");
12345 
12346   stmt_text= "drop table if exists t1";
12347   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12348   myquery(rc);
12349 
12350   stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
12351                               "hour datetime, min datetime, sec datetime)";
12352   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12353   myquery(rc);
12354 
12355   stmt= mysql_simple_prepare(mysql,
12356                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
12357   check_stmt(stmt);
12358   verify_param_count(stmt, 6);
12359 
12360   memset(my_bind, 0, sizeof(my_bind));
12361   for (i= 0; i < 6; i++)
12362   {
12363     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12364     my_bind[i].buffer= &tm[i];
12365   }
12366   rc= mysql_stmt_bind_param(stmt, my_bind);
12367   check_execute(stmt, rc);
12368 
12369   tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
12370   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12371   tm[0].second_part= 0; tm[0].neg= 0;
12372 
12373   tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12374   tm[0].year= 10000;  tm[1].month= 13; tm[2].day= 32;
12375   tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;
12376 
12377   rc= mysql_stmt_execute(stmt);
12378   check_execute(stmt, rc);
12379   /* behaviour changed by WL#5928 */
12380   my_process_warnings(mysql, mysql_get_server_version(mysql) < 50702 ? 12 : 6);
12381 
12382   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12383   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12384   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12385   verify_col_data("t1", "hour", "0000-00-00 00:00:00");
12386   verify_col_data("t1", "min", "0000-00-00 00:00:00");
12387   verify_col_data("t1", "sec", "0000-00-00 00:00:00");
12388 
12389   mysql_stmt_close(stmt);
12390 
12391   stmt_text= "delete from t1";
12392   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12393   myquery(rc);
12394 
12395   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
12396                                     "VALUES (?, ?, ?)");
12397   check_stmt(stmt);
12398   verify_param_count(stmt, 3);
12399 
12400   /*
12401     We reuse contents of bind and tm arrays left from previous part of test.
12402   */
12403   for (i= 0; i < 3; i++)
12404     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12405 
12406   rc= mysql_stmt_bind_param(stmt, my_bind);
12407   check_execute(stmt, rc);
12408 
12409   rc= mysql_stmt_execute(stmt);
12410   check_execute(stmt, rc);
12411   /* behaviour changed by WL#5928 */
12412   my_process_warnings(mysql, mysql_get_server_version(mysql) < 50702 ? 6 : 3);
12413 
12414   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12415   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12416   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12417 
12418   mysql_stmt_close(stmt);
12419 
12420   stmt_text= "drop table t1";
12421   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12422   myquery(rc);
12423 
12424   stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
12425   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12426   myquery(rc);
12427 
12428   stmt= mysql_simple_prepare(mysql,
12429                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
12430   check_stmt(stmt);
12431   verify_param_count(stmt, 5);
12432 
12433   /*
12434     Again we reuse what we can from previous part of test.
12435   */
12436   for (i= 0; i < 5; i++)
12437     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12438 
12439   rc= mysql_stmt_bind_param(stmt, my_bind);
12440   check_execute(stmt, rc);
12441 
12442   tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
12443   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12444   tm[0].second_part= 0; tm[0].neg= 0;
12445 
12446   tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12447   tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;
12448 
12449   rc= mysql_stmt_execute(stmt);
12450   check_execute(stmt, rc);
12451   /* behaviour changed by WL#5928 */
12452   my_process_warnings(mysql, mysql_get_server_version(mysql) < 50702 ? 2 : 0);
12453 
12454   verify_col_data("t1", "day_ovfl", "838:59:59");
12455   verify_col_data("t1", "day", "828:30:30");
12456   verify_col_data("t1", "hour", "270:30:30");
12457   verify_col_data("t1", "min", "00:00:00");
12458   verify_col_data("t1", "sec", "00:00:00");
12459 
12460   mysql_stmt_close(stmt);
12461 
12462   stmt_text= "drop table t1";
12463   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12464   myquery(rc);
12465 }
12466 
12467 
test_bug4172()12468 static void test_bug4172()
12469 {
12470   MYSQL_STMT *stmt;
12471   MYSQL_BIND my_bind[3];
12472   const char *stmt_text;
12473   MYSQL_RES *res;
12474   MYSQL_ROW row;
12475   int rc;
12476   char f[100], d[100], e[100];
12477   ulong f_len, d_len, e_len;
12478 
12479   myheader("test_bug4172");
12480 
12481   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
12482   mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))");
12483   mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, "
12484                                             "123456.1234)");
12485 
12486   stmt= mysql_stmt_init(mysql);
12487   stmt_text= "SELECT f, d, e FROM t1";
12488 
12489   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12490   check_execute(stmt, rc);
12491   rc= mysql_stmt_execute(stmt);
12492   check_execute(stmt, rc);
12493 
12494   memset(my_bind, 0, sizeof(my_bind));
12495   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12496   my_bind[0].buffer= f;
12497   my_bind[0].buffer_length= (ulong)sizeof(f);
12498   my_bind[0].length= &f_len;
12499   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
12500   my_bind[1].buffer= d;
12501   my_bind[1].buffer_length= (ulong)sizeof(d);
12502   my_bind[1].length= &d_len;
12503   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
12504   my_bind[2].buffer= e;
12505   my_bind[2].buffer_length= (ulong)sizeof(e);
12506   my_bind[2].length= &e_len;
12507 
12508   mysql_stmt_bind_result(stmt, my_bind);
12509 
12510   mysql_stmt_store_result(stmt);
12511   rc= mysql_stmt_fetch(stmt);
12512   check_execute(stmt, rc);
12513 
12514   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12515   myquery(rc);
12516   res= mysql_store_result(mysql);
12517   row= mysql_fetch_row(res);
12518 
12519   if (!opt_silent)
12520   {
12521     printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n",
12522            f, d, e);
12523     printf("Text protocol:   float=%s, double=%s, decimal(10,4)=%s\n",
12524            row[0], row[1], row[2]);
12525   }
12526   DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]));
12527 
12528   mysql_free_result(res);
12529   mysql_stmt_close(stmt);
12530 }
12531 
12532 
test_conversion()12533 static void test_conversion()
12534 {
12535   MYSQL_STMT *stmt;
12536   const char *stmt_text;
12537   int rc;
12538   MYSQL_BIND my_bind[1];
12539   char buff[4];
12540   ulong length;
12541 
12542   myheader("test_conversion");
12543 
12544   stmt_text= "DROP TABLE IF EXISTS t1";
12545   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12546   myquery(rc);
12547   stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
12548   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12549   myquery(rc);
12550   stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
12551              " character_set_results=latin1";
12552   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12553   myquery(rc);
12554 
12555   stmt= mysql_stmt_init(mysql);
12556 
12557   stmt_text= "INSERT INTO t1 (a) VALUES (?)";
12558   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12559   check_execute(stmt, rc);
12560 
12561   memset(my_bind, 0, sizeof(my_bind));
12562   my_bind[0].buffer= buff;
12563   my_bind[0].length= &length;
12564   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12565 
12566   mysql_stmt_bind_param(stmt, my_bind);
12567 
12568   buff[0]= (uchar) 0xC3;
12569   buff[1]= (uchar) 0xA0;
12570   length= 2;
12571 
12572   rc= mysql_stmt_execute(stmt);
12573   check_execute(stmt, rc);
12574 
12575   stmt_text= "SELECT a FROM t1";
12576   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12577   check_execute(stmt, rc);
12578   rc= mysql_stmt_execute(stmt);
12579   check_execute(stmt, rc);
12580 
12581   my_bind[0].buffer_length= (ulong)sizeof(buff);
12582   mysql_stmt_bind_result(stmt, my_bind);
12583 
12584   rc= mysql_stmt_fetch(stmt);
12585   DIE_UNLESS(rc == 0);
12586   DIE_UNLESS(length == 1);
12587   DIE_UNLESS((uchar) buff[0] == 0xE0);
12588   rc= mysql_stmt_fetch(stmt);
12589   DIE_UNLESS(rc == MYSQL_NO_DATA);
12590 
12591   mysql_stmt_close(stmt);
12592   stmt_text= "DROP TABLE t1";
12593   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12594   myquery(rc);
12595   stmt_text= "SET NAMES DEFAULT";
12596   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12597   myquery(rc);
12598 }
12599 
test_rewind(void)12600 static void test_rewind(void)
12601 {
12602   MYSQL_STMT *stmt;
12603   MYSQL_BIND my_bind;
12604   int rc = 0;
12605   const char *stmt_text;
12606   ulong length= 4;
12607   long unsigned int Data= 0;
12608   my_bool isnull=0;
12609 
12610   myheader("test_rewind");
12611 
12612   stmt_text= "CREATE TABLE t1 (a int)";
12613   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12614   myquery(rc);
12615   stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)";
12616   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12617   myquery(rc);
12618 
12619   stmt= mysql_stmt_init(mysql);
12620 
12621   stmt_text= "SELECT * FROM t1";
12622   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12623   check_execute(stmt, rc);
12624 
12625   memset(&my_bind, 0, sizeof(MYSQL_BIND));
12626   my_bind.buffer_type= MYSQL_TYPE_LONG;
12627   my_bind.buffer= (void *)&Data; /* this buffer won't be altered */
12628   my_bind.length= &length;
12629   my_bind.is_null= &isnull;
12630 
12631   rc= mysql_stmt_execute(stmt);
12632   check_execute(stmt, rc);
12633 
12634   rc= mysql_stmt_store_result(stmt);
12635   DIE_UNLESS(rc == 0);
12636 
12637   rc= mysql_stmt_bind_result(stmt, &my_bind);
12638   DIE_UNLESS(rc == 0);
12639 
12640   /* retreive all result sets till we are at the end */
12641   while(!mysql_stmt_fetch(stmt))
12642     if (!opt_silent)
12643       printf("fetched result:%ld\n", Data);
12644 
12645   DIE_UNLESS(rc != MYSQL_NO_DATA);
12646 
12647   /* seek to the first row */
12648   mysql_stmt_data_seek(stmt, 0);
12649 
12650   /* now we should be able to fetch the results again */
12651   /* but mysql_stmt_fetch returns MYSQL_NO_DATA */
12652   while(!(rc= mysql_stmt_fetch(stmt)))
12653     if (!opt_silent)
12654       printf("fetched result after seek:%ld\n", Data);
12655 
12656   DIE_UNLESS(rc == MYSQL_NO_DATA);
12657 
12658   stmt_text= "DROP TABLE t1";
12659   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12660   myquery(rc);
12661   rc= mysql_stmt_free_result(stmt);
12662   rc= mysql_stmt_close(stmt);
12663 }
12664 
12665 
test_truncation()12666 static void test_truncation()
12667 {
12668   MYSQL_STMT *stmt;
12669   const char *stmt_text;
12670   int rc;
12671   uint bind_count;
12672   MYSQL_BIND *bind_array, *my_bind;
12673 
12674   myheader("test_truncation");
12675 
12676   /* Prepare the test table */
12677   rc= mysql_query(mysql, "drop table if exists t1");
12678   myquery(rc);
12679 
12680   stmt_text= "create table t1 ("
12681              "i8 tinyint, ui8 tinyint unsigned, "
12682              "i16 smallint, i16_1 smallint, "
12683              "ui16 smallint unsigned, i32 int, i32_1 int, "
12684              "d double, d_1 double, ch char(30), ch_1 char(30), "
12685              "tx text, tx_1 text, ch_2 char(30) "
12686              ")";
12687   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12688   myquery(rc);
12689 
12690   {
12691     const char insert_text[]=
12692              "insert into t1 VALUES ("
12693              "-10, "                            /* i8 */
12694              "200, "                            /* ui8 */
12695              "32000, "                          /* i16 */
12696              "-32767, "                         /* i16_1 */
12697              "64000, "                          /* ui16 */
12698              "1073741824, "                     /* i32 */
12699              "1073741825, "                     /* i32_1 */
12700              "123.456, "                        /* d */
12701              "-12345678910, "                   /* d_1 */
12702              "'111111111111111111111111111111',"/* ch */
12703              "'abcdef', "                       /* ch_1 */
12704              "'12345 	      ', "              /* tx */
12705              "'12345.67 	      ', "      /* tx_1 */
12706              "'12345.67abc'"                    /* ch_2 */
12707              ")";
12708     rc= mysql_real_query(mysql, insert_text, (ulong)strlen(insert_text));
12709     myquery(rc);
12710   }
12711 
12712   stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, "
12713              "       i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, "
12714              "       d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, "
12715              "       tx_1 c17, ch_2 c18 "
12716              "from t1";
12717 
12718   stmt= mysql_stmt_init(mysql);
12719   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12720   check_execute(stmt, rc);
12721   rc= mysql_stmt_execute(stmt);
12722   check_execute(stmt, rc);
12723   bind_count= (uint) mysql_stmt_field_count(stmt);
12724 
12725   /*************** Fill in the bind structure and bind it **************/
12726   bind_array= malloc(sizeof(MYSQL_BIND) * bind_count);
12727   memset(bind_array, 0, sizeof(MYSQL_BIND) * bind_count);
12728   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12729     my_bind->error= &my_bind->error_value;
12730   my_bind= bind_array;
12731 
12732   my_bind->buffer= malloc(sizeof(uint8));
12733   my_bind->buffer_type= MYSQL_TYPE_TINY;
12734   my_bind->is_unsigned= TRUE;
12735 
12736   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12737   my_bind->buffer= malloc(sizeof(uint32));
12738   my_bind->buffer_type= MYSQL_TYPE_LONG;
12739   my_bind->is_unsigned= TRUE;
12740 
12741   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12742   my_bind->buffer= malloc(sizeof(int8));
12743   my_bind->buffer_type= MYSQL_TYPE_TINY;
12744 
12745   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12746   my_bind->buffer= malloc(sizeof(uint16));
12747   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12748   my_bind->is_unsigned= TRUE;
12749 
12750   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12751   my_bind->buffer= malloc(sizeof(int16));
12752   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12753 
12754   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12755   my_bind->buffer= malloc(sizeof(uint16));
12756   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12757   my_bind->is_unsigned= TRUE;
12758 
12759   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12760   my_bind->buffer= malloc(sizeof(int8));
12761   my_bind->buffer_type= MYSQL_TYPE_TINY;
12762   my_bind->is_unsigned= TRUE;
12763 
12764   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12765   my_bind->buffer= malloc(sizeof(float));
12766   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12767 
12768   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12769   my_bind->buffer= malloc(sizeof(float));
12770   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12771 
12772   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12773   my_bind->buffer= malloc(sizeof(double));
12774   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12775 
12776   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12777   my_bind->buffer= malloc(sizeof(longlong));
12778   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12779 
12780   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12781   my_bind->buffer= malloc(sizeof(ulonglong));
12782   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12783   my_bind->is_unsigned= TRUE;
12784 
12785   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12786   my_bind->buffer= malloc(sizeof(longlong));
12787   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12788 
12789   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12790   my_bind->buffer= malloc(sizeof(longlong));
12791   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12792 
12793   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12794   my_bind->buffer= malloc(sizeof(longlong));
12795   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12796 
12797   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12798   my_bind->buffer= malloc(sizeof(longlong));
12799   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12800 
12801   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12802   my_bind->buffer= malloc(sizeof(double));
12803   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12804 
12805   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12806   my_bind->buffer= malloc(sizeof(double));
12807   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12808 
12809   rc= mysql_stmt_bind_result(stmt, bind_array);
12810   check_execute(stmt, rc);
12811   rc= mysql_stmt_fetch(stmt);
12812   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12813 
12814   /*************** Verify truncation results ***************************/
12815   my_bind= bind_array;
12816 
12817   /* signed tiny -> tiny */
12818   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == -10);
12819 
12820   /* signed tiny -> uint32 */
12821   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12822   DIE_UNLESS(*my_bind->error && * (int32*) my_bind->buffer == -10);
12823 
12824   /* unsigned tiny -> tiny */
12825   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12826   DIE_UNLESS(*my_bind->error && * (uint8*) my_bind->buffer == 200);
12827 
12828   /* short -> ushort */
12829   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12830   DIE_UNLESS(*my_bind->error && * (int16*) my_bind->buffer == -32767);
12831 
12832   /* ushort -> short */
12833   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12834   DIE_UNLESS(*my_bind->error && * (uint16*) my_bind->buffer == 64000);
12835 
12836   /* short -> ushort (no truncation, data is in the range of target type) */
12837   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12838   DIE_UNLESS(! *my_bind->error && * (uint16*) my_bind->buffer == 32000);
12839 
12840   /* ushort -> utiny */
12841   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12842   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == 0);
12843 
12844   /* int -> float: no truncation, the number is a power of two */
12845   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12846   DIE_UNLESS(! *my_bind->error && * (float*) my_bind->buffer == 1073741824);
12847 
12848   /* int -> float: truncation, not enough bits in float */
12849   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12850   DIE_UNLESS(*my_bind->error);
12851 
12852   /* int -> double: no truncation */
12853   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12854   DIE_UNLESS(! *my_bind->error && * (double*) my_bind->buffer == 1073741825);
12855 
12856   /* double -> longlong: fractional part is lost */
12857   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12858 
12859   /* double -> ulonglong, negative fp number to unsigned integer */
12860   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12861   /* Value in the buffer is not defined: don't test it */
12862   DIE_UNLESS(*my_bind->error);
12863 
12864   /* double -> longlong, negative fp number to signed integer: no loss */
12865   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12866   DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == -12345678910LL);
12867 
12868   /* big numeric string -> number */
12869   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12870   DIE_UNLESS(*my_bind->error);
12871 
12872   /* junk string -> number */
12873   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12874   DIE_UNLESS(*my_bind->error && *(longlong*) my_bind->buffer == 0);
12875 
12876   /* string with trailing spaces -> number */
12877   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12878   DIE_UNLESS(! *my_bind->error && *(longlong*) my_bind->buffer == 12345);
12879 
12880   /* string with trailing spaces -> double */
12881   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12882   DIE_UNLESS(! *my_bind->error && *(double*) my_bind->buffer == 12345.67);
12883 
12884   /* string with trailing junk -> double */
12885   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12886   /*
12887     XXX: There must be a truncation error: but it's not the way the server
12888     behaves, so let's leave it for now.
12889   */
12890   DIE_UNLESS(*(double*) my_bind->buffer == 12345.67);
12891   /*
12892     TODO: string -> double,  double -> time, double -> string (truncation
12893           errors are not supported here yet)
12894           longlong -> time/date/datetime
12895           date -> time, date -> timestamp, date -> number
12896           time -> string, time -> date, time -> timestamp,
12897           number -> date string -> date
12898   */
12899   /*************** Cleanup *********************************************/
12900 
12901   mysql_stmt_close(stmt);
12902 
12903   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12904     free(my_bind->buffer);
12905   free(bind_array);
12906 
12907   rc= mysql_query(mysql, "drop table t1");
12908   myquery(rc);
12909 }
12910 
test_truncation_option()12911 static void test_truncation_option()
12912 {
12913   MYSQL_STMT *stmt;
12914   const char *stmt_text;
12915   int rc;
12916   uint8 buf;
12917   my_bool option= 0;
12918   my_bool error;
12919   MYSQL_BIND my_bind;
12920 
12921   myheader("test_truncation_option");
12922 
12923   /* Prepare the test table */
12924   stmt_text= "select -1";
12925 
12926   stmt= mysql_stmt_init(mysql);
12927   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
12928   check_execute(stmt, rc);
12929   rc= mysql_stmt_execute(stmt);
12930   check_execute(stmt, rc);
12931 
12932   memset(&my_bind, 0, sizeof(my_bind));
12933 
12934   my_bind.buffer= (void*) &buf;
12935   my_bind.buffer_type= MYSQL_TYPE_TINY;
12936   my_bind.is_unsigned= TRUE;
12937   my_bind.error= &error;
12938 
12939   rc= mysql_stmt_bind_result(stmt, &my_bind);
12940   check_execute(stmt, rc);
12941   rc= mysql_stmt_fetch(stmt);
12942   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12943   DIE_UNLESS(error);
12944   rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
12945   myquery(rc);
12946   /* need to rebind for the new setting to take effect */
12947   rc= mysql_stmt_bind_result(stmt, &my_bind);
12948   check_execute(stmt, rc);
12949   rc= mysql_stmt_execute(stmt);
12950   check_execute(stmt, rc);
12951   rc= mysql_stmt_fetch(stmt);
12952   check_execute(stmt, rc);
12953   /* The only change is rc - error pointers are still filled in */
12954   DIE_UNLESS(error == 1);
12955   /* restore back the defaults */
12956   option= 1;
12957   mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
12958 
12959   mysql_stmt_close(stmt);
12960 }
12961 
12962 
12963 /* Bug#6761 - mysql_list_fields doesn't work */
12964 
test_bug6761(void)12965 static void test_bug6761(void)
12966 {
12967   const char *stmt_text;
12968   MYSQL_RES *res;
12969   int rc;
12970   myheader("test_bug6761");
12971 
12972   stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
12973   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12974   myquery(rc);
12975 
12976   res= mysql_list_fields(mysql, "t1", "%");
12977   DIE_UNLESS(res && mysql_num_fields(res) == 3);
12978   mysql_free_result(res);
12979 
12980   stmt_text= "DROP TABLE t1";
12981   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
12982   myquery(rc);
12983 }
12984 
12985 
12986 /* Bug#8330 - mysql_stmt_execute crashes (libmysql) */
12987 
test_bug8330()12988 static void test_bug8330()
12989 {
12990   const char *stmt_text;
12991   MYSQL_STMT *stmt[2];
12992   int i, rc;
12993   const char *query= "select a,b from t1 where a=?";
12994   MYSQL_BIND my_bind[2];
12995   long lval[2];
12996 
12997   myheader("test_bug8330");
12998 
12999   stmt_text= "drop table if exists t1";
13000   /* in case some previos test failed */
13001   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13002   myquery(rc);
13003   stmt_text= "create table t1 (a int, b int)";
13004   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13005   myquery(rc);
13006 
13007   memset(my_bind, 0, sizeof(my_bind));
13008   memset(lval, 0, sizeof(lval));
13009   for (i=0; i < 2; i++)
13010   {
13011     stmt[i]= mysql_stmt_init(mysql);
13012     rc= mysql_stmt_prepare(stmt[i], query, (ulong)strlen(query));
13013     check_execute(stmt[i], rc);
13014 
13015     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
13016     my_bind[i].buffer= (void*) &lval[i];
13017     my_bind[i].is_null= 0;
13018     mysql_stmt_bind_param(stmt[i], &my_bind[i]);
13019   }
13020 
13021   rc= mysql_stmt_execute(stmt[0]);
13022   check_execute(stmt[0], rc);
13023 
13024   rc= mysql_stmt_execute(stmt[1]);
13025   DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
13026   rc= mysql_stmt_execute(stmt[0]);
13027   check_execute(stmt[0], rc);
13028 
13029   mysql_stmt_close(stmt[0]);
13030   mysql_stmt_close(stmt[1]);
13031 
13032   stmt_text= "drop table t1";
13033   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13034   myquery(rc);
13035 }
13036 
13037 
13038 /* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */
13039 
test_bug7990()13040 static void test_bug7990()
13041 {
13042   MYSQL_STMT *stmt;
13043   int rc;
13044   myheader("test_bug7990");
13045 
13046   stmt= mysql_stmt_init(mysql);
13047   rc= mysql_stmt_prepare(stmt, "foo", 3);
13048   /*
13049     XXX: the fact that we store errno both in STMT and in
13050     MYSQL is not documented and is subject to change in 5.0
13051   */
13052   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql));
13053   mysql_stmt_close(stmt);
13054   DIE_UNLESS(!mysql_errno(mysql));
13055 }
13056 
13057 /*
13058   Bug #15518 - Reusing a stmt that has failed during prepare
13059   does not clear error
13060 */
13061 
test_bug15518()13062 static void test_bug15518()
13063 {
13064   MYSQL_STMT *stmt;
13065   MYSQL* mysql1;
13066   int rc;
13067   myheader("test_bug15518");
13068 
13069   mysql1= mysql_client_init(NULL);
13070 
13071   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13072                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13073                           CLIENT_MULTI_STATEMENTS))
13074   {
13075     fprintf(stderr, "Failed to connect to the database\n");
13076     DIE_UNLESS(0);
13077   }
13078 
13079   stmt= mysql_stmt_init(mysql1);
13080 
13081   /*
13082     The prepare of foo should fail with errno 1064 since
13083     it's not a valid query
13084   */
13085   rc= mysql_stmt_prepare(stmt, "foo", 3);
13086   if (!opt_silent)
13087     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13088             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13089   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13090 
13091   /*
13092     Use the same stmt and reprepare with another query that
13093     suceeds
13094   */
13095   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13096   if (!opt_silent)
13097     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13098             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13099   DIE_UNLESS(!rc || mysql_stmt_errno(stmt) || mysql_errno(mysql1));
13100 
13101   mysql_stmt_close(stmt);
13102   DIE_UNLESS(!mysql_errno(mysql1));
13103 
13104   /*
13105     part2, when connection to server has been closed
13106     after first prepare
13107   */
13108   stmt= mysql_stmt_init(mysql1);
13109   rc= mysql_stmt_prepare(stmt, "foo", 3);
13110   if (!opt_silent)
13111     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13112             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13113   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13114 
13115   /* Close connection to server */
13116   mysql_close(mysql1);
13117 
13118   /*
13119     Use the same stmt and reprepare with another query that
13120     suceeds. The prepare should fail with error 2013 since
13121     connection to server has been closed.
13122   */
13123   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13124   if (!opt_silent)
13125     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d\n",
13126             rc, mysql_stmt_errno(stmt));
13127   DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13128 
13129   mysql_stmt_close(stmt);
13130 }
13131 
13132 
disable_query_logs()13133 static void disable_query_logs()
13134 {
13135   int rc;
13136   rc= mysql_query(mysql, "set @@global.general_log=off");
13137   myquery(rc);
13138   rc= mysql_query(mysql, "set @@global.slow_query_log=off");
13139   myquery(rc);
13140 }
13141 
13142 
enable_query_logs(int truncate)13143 static void enable_query_logs(int truncate)
13144 {
13145   int rc;
13146 
13147   rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
13148   myquery(rc);
13149 
13150   rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log");
13151   myquery(rc);
13152 
13153   rc= mysql_query(mysql, "set @@global.general_log=on");
13154   myquery(rc);
13155 
13156   rc= mysql_query(mysql, "set @@global.slow_query_log=on");
13157   myquery(rc);
13158 
13159 
13160   if (truncate)
13161   {
13162     rc= mysql_query(mysql, "truncate mysql.general_log");
13163     myquery(rc);
13164 
13165     rc= mysql_query(mysql, "truncate mysql.slow_log");
13166     myquery(rc);
13167   }
13168 }
13169 
13170 
restore_query_logs()13171 static void restore_query_logs()
13172 {
13173   int rc;
13174   rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
13175   myquery(rc);
13176 
13177   rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log");
13178   myquery(rc);
13179 }
13180 
13181 
test_view_sp_list_fields()13182 static void test_view_sp_list_fields()
13183 {
13184   int		rc;
13185   MYSQL_RES     *res;
13186 
13187   myheader("test_view_sp_list_fields");
13188 
13189   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
13190   myquery(rc);
13191   rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
13192   myquery(rc);
13193   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
13194   myquery(rc);
13195   rc= mysql_query(mysql, "create function f1 () returns int return 5");
13196   myquery(rc);
13197   rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
13198   myquery(rc);
13199   rc= mysql_query(mysql, "create table t2 (s1 int);");
13200   myquery(rc);
13201   rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
13202 count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
13203 from t2);");
13204   myquery(rc);
13205   res= mysql_list_fields(mysql, "v1", NullS);
13206   DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0);
13207   rc= mysql_query(mysql, "DROP FUNCTION f1");
13208   myquery(rc);
13209   rc= mysql_query(mysql, "DROP VIEW v1");
13210   myquery(rc);
13211   rc= mysql_query(mysql, "DROP TABLE t1, t2");
13212   mysql_free_result(res);
13213   myquery(rc);
13214 
13215 }
13216 
13217 
13218 /*
13219  Test mysql_real_escape_string_quote() with gbk charset
13220 
13221  The important part is that 0x27 (') is the second-byte in a invalid
13222  two-byte GBK character here. But 0xbf5c is a valid GBK character, so
13223  it needs to be escaped as 0x5cbf27
13224 */
13225 #define TEST_BUG8378_IN  "\xef\xbb\xbf\x27\xbf\x10"
13226 #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
13227 
test_bug8378()13228 static void test_bug8378()
13229 {
13230 #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
13231   MYSQL *lmysql;
13232   char out[9]; /* strlen(TEST_BUG8378)*2+1 */
13233   char buf[256];
13234   int len, rc;
13235 
13236   myheader("test_bug8378");
13237 
13238   if (!opt_silent)
13239     fprintf(stdout, "\n Establishing a test connection ...");
13240   if (!(lmysql= mysql_client_init(NULL)))
13241   {
13242     myerror("mysql_client_init() failed");
13243     exit(1);
13244   }
13245   if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
13246   {
13247     myerror("mysql_options() failed");
13248     exit(1);
13249   }
13250   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
13251                            opt_password, current_db, opt_port,
13252                            opt_unix_socket, 0)))
13253   {
13254     myerror("connection failed");
13255     exit(1);
13256   }
13257   if (!opt_silent)
13258     fprintf(stdout, "OK");
13259 
13260   rc= mysql_query(lmysql, "SET SQL_MODE=''");
13261   myquery(rc);
13262 
13263   len= mysql_real_escape_string_quote(lmysql, out, TEST_BUG8378_IN, 4, '\'');
13264 
13265   /* No escaping should have actually happened. */
13266   DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
13267 
13268   sprintf(buf, "SELECT '%s'", out);
13269 
13270   rc=mysql_real_query(lmysql, buf, (ulong)strlen(buf));
13271   myquery(rc);
13272 
13273   mysql_close(lmysql);
13274 #endif
13275 }
13276 
13277 
test_bug8722()13278 static void test_bug8722()
13279 {
13280   MYSQL_STMT *stmt;
13281   int rc;
13282   const char *stmt_text;
13283 
13284   myheader("test_bug8722");
13285   /* Prepare test data */
13286   stmt_text= "drop table if exists t1, v1";
13287   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13288   myquery(rc);
13289   stmt_text= "CREATE TABLE t1 (c1 varchar(10), c2 varchar(10), c3 varchar(10),"
13290                              " c4 varchar(10), c5 varchar(10), c6 varchar(10),"
13291                              " c7 varchar(10), c8 varchar(10), c9 varchar(10),"
13292                              "c10 varchar(10))";
13293   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13294   myquery(rc);
13295   stmt_text= "INSERT INTO t1 VALUES (1,2,3,4,5,6,7,8,9,10)";
13296   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13297   myquery(rc);
13298   stmt_text= "CREATE VIEW v1 AS SELECT * FROM t1";
13299   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13300   myquery(rc);
13301   /* Note: if you uncomment following block everything works fine */
13302 /*
13303   rc= mysql_query(mysql, "sellect * from v1");
13304   myquery(rc);
13305   mysql_free_result(mysql_store_result(mysql));
13306 */
13307 
13308   stmt= mysql_stmt_init(mysql);
13309   stmt_text= "select * from v1";
13310   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13311   check_execute(stmt, rc);
13312   mysql_stmt_close(stmt);
13313   stmt_text= "drop table if exists t1, v1";
13314   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
13315   myquery(rc);
13316 }
13317 
13318 
open_cursor(const char * query)13319 MYSQL_STMT *open_cursor(const char *query)
13320 {
13321   int rc;
13322   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
13323 
13324   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
13325   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
13326   check_execute(stmt, rc);
13327 
13328   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13329   return stmt;
13330 }
13331 
13332 
test_bug8880()13333 static void test_bug8880()
13334 {
13335   MYSQL_STMT *stmt_list[2], **stmt;
13336   MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
13337   int rc;
13338 
13339   myheader("test_bug8880");
13340 
13341   mysql_query(mysql, "drop table if exists t1");
13342   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13343   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13344   myquery(rc);                                  /* one check is enough */
13345   /*
13346     when inserting 2 rows everything works well
13347     mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
13348   */
13349   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13350     *stmt= open_cursor("select a from t1");
13351   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13352   {
13353     rc= mysql_stmt_execute(*stmt);
13354     check_execute(*stmt, rc);
13355   }
13356   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13357     mysql_stmt_close(*stmt);
13358 }
13359 
13360 
test_bug9159()13361 static void test_bug9159()
13362 {
13363   MYSQL_STMT *stmt;
13364   int rc;
13365   const char *stmt_text= "select a, b from t1";
13366   const unsigned long type= CURSOR_TYPE_READ_ONLY;
13367 
13368   myheader("test_bug9159");
13369 
13370   mysql_query(mysql, "drop table if exists t1");
13371   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13372   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13373   myquery(rc);
13374 
13375   stmt= mysql_stmt_init(mysql);
13376   mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13377   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
13378 
13379   mysql_stmt_execute(stmt);
13380   mysql_stmt_close(stmt);
13381   rc= mysql_query(mysql, "drop table if exists t1");
13382   myquery(rc);
13383 }
13384 
13385 
13386 /* Crash when opening a cursor to a query with DISTICNT and no key */
13387 
test_bug9520()13388 static void test_bug9520()
13389 {
13390   MYSQL_STMT *stmt;
13391   MYSQL_BIND my_bind[1];
13392   char a[6];
13393   ulong a_len;
13394   int rc, row_count= 0;
13395 
13396   myheader("test_bug9520");
13397 
13398   mysql_query(mysql, "drop table if exists t1");
13399   mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
13400                      " primary key (a, b, c))");
13401   rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
13402                   " ('a', 'b', 'c'), ('k', 'l', 'm')");
13403   myquery(rc);
13404 
13405   stmt= open_cursor("select distinct b from t1");
13406 
13407   /*
13408     Not crashes with:
13409     stmt= open_cursor("select distinct a from t1");
13410   */
13411 
13412   rc= mysql_stmt_execute(stmt);
13413   check_execute(stmt, rc);
13414 
13415   memset(my_bind, 0, sizeof(my_bind));
13416   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13417   my_bind[0].buffer= (char*) a;
13418   my_bind[0].buffer_length= (ulong)sizeof(a);
13419   my_bind[0].length= &a_len;
13420 
13421   mysql_stmt_bind_result(stmt, my_bind);
13422 
13423   while (!(rc= mysql_stmt_fetch(stmt)))
13424     row_count++;
13425 
13426   DIE_UNLESS(rc == MYSQL_NO_DATA);
13427 
13428   if (!opt_silent)
13429     printf("Fetched %d rows\n", row_count);
13430   assert(row_count == 3);
13431 
13432   mysql_stmt_close(stmt);
13433 
13434   rc= mysql_query(mysql, "drop table t1");
13435   myquery(rc);
13436 }
13437 
13438 
13439 /*
13440   We can't have more than one cursor open for a prepared statement.
13441   Test re-executions of a PS with cursor; mysql_stmt_reset must close
13442   the cursor attached to the statement, if there is one.
13443 */
13444 
test_bug9478()13445 static void test_bug9478()
13446 {
13447   MYSQL_STMT *stmt;
13448   MYSQL_BIND my_bind[1];
13449   char a[6];
13450   ulong a_len;
13451   int rc, i;
13452   DBUG_ENTER("test_bug9478");
13453 
13454   myheader("test_bug9478");
13455 
13456   mysql_query(mysql, "drop table if exists t1");
13457   mysql_query(mysql, "create table t1 (id integer not null primary key, "
13458                      " name varchar(20) not null)");
13459   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13460                          " (1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13461   myquery(rc);
13462 
13463   stmt= open_cursor("select name from t1 where id=2");
13464 
13465   memset(my_bind, 0, sizeof(my_bind));
13466   memset(a, 0, sizeof(a));
13467   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13468   my_bind[0].buffer= (char*) a;
13469   my_bind[0].buffer_length= (ulong)sizeof(a);
13470   my_bind[0].length= &a_len;
13471   mysql_stmt_bind_result(stmt, my_bind);
13472 
13473   for (i= 0; i < 5; i++)
13474   {
13475     rc= mysql_stmt_execute(stmt);
13476     check_execute(stmt, rc);
13477     rc= mysql_stmt_fetch(stmt);
13478     check_execute(stmt, rc);
13479     if (!opt_silent && i == 0)
13480       printf("Fetched row: %s\n", a);
13481 
13482     /*
13483       The query above is a one-row result set. Therefore, there is no
13484       cursor associated with it, as the server won't bother with opening
13485       a cursor for a one-row result set. The first row was read from the
13486       server in the fetch above. But there is eof packet pending in the
13487       network. mysql_stmt_execute will flush the packet and successfully
13488       execute the statement.
13489     */
13490 
13491     rc= mysql_stmt_execute(stmt);
13492     check_execute(stmt, rc);
13493 
13494     rc= mysql_stmt_fetch(stmt);
13495     check_execute(stmt, rc);
13496     if (!opt_silent && i == 0)
13497       printf("Fetched row: %s\n", a);
13498     rc= mysql_stmt_fetch(stmt);
13499     DIE_UNLESS(rc == MYSQL_NO_DATA);
13500 
13501     {
13502       uchar buff[8];
13503       memset(buff, 0, sizeof(buff));
13504       /* Fill in the fetch packet */
13505       int4store(buff, stmt->stmt_id);
13506       buff[4]= 1;                               /* prefetch rows */
13507       rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
13508                                                (uchar*) buff,
13509                                                sizeof(buff), 0,0,1,NULL) ||
13510            (*mysql->methods->read_query_result)(mysql));
13511       DIE_UNLESS(rc);
13512       if (!opt_silent && i == 0)
13513         printf("Got error (as expected): %s\n", mysql_error(mysql));
13514     }
13515 
13516     rc= mysql_stmt_execute(stmt);
13517     check_execute(stmt, rc);
13518 
13519     rc= mysql_stmt_fetch(stmt);
13520     check_execute(stmt, rc);
13521     if (!opt_silent && i == 0)
13522       printf("Fetched row: %s\n", a);
13523 
13524     rc= mysql_stmt_reset(stmt);
13525     check_execute(stmt, rc);
13526     rc= mysql_stmt_fetch(stmt);
13527     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13528     if (!opt_silent && i == 0)
13529       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13530   }
13531   rc= mysql_stmt_close(stmt);
13532   DIE_UNLESS(rc == 0);
13533 
13534   /* Test the case with a server side cursor */
13535   stmt= open_cursor("select name from t1");
13536 
13537   mysql_stmt_bind_result(stmt, my_bind);
13538 
13539   for (i= 0; i < 5; i++)
13540   {
13541     DBUG_PRINT("loop",("i: %d", i));
13542     rc= mysql_stmt_execute(stmt);
13543     check_execute(stmt, rc);
13544     rc= mysql_stmt_fetch(stmt);
13545     check_execute(stmt, rc);
13546     if (!opt_silent && i == 0)
13547       printf("Fetched row: %s\n", a);
13548     rc= mysql_stmt_execute(stmt);
13549     check_execute(stmt, rc);
13550 
13551     while (! (rc= mysql_stmt_fetch(stmt)))
13552     {
13553       if (!opt_silent && i == 0)
13554         printf("Fetched row: %s\n", a);
13555     }
13556     DIE_UNLESS(rc == MYSQL_NO_DATA);
13557 
13558     rc= mysql_stmt_execute(stmt);
13559     check_execute(stmt, rc);
13560 
13561     rc= mysql_stmt_fetch(stmt);
13562     check_execute(stmt, rc);
13563     if (!opt_silent && i == 0)
13564       printf("Fetched row: %s\n", a);
13565 
13566     rc= mysql_stmt_reset(stmt);
13567     check_execute(stmt, rc);
13568     rc= mysql_stmt_fetch(stmt);
13569     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13570     if (!opt_silent && i == 0)
13571       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13572   }
13573 
13574   rc= mysql_stmt_close(stmt);
13575   DIE_UNLESS(rc == 0);
13576 
13577   rc= mysql_query(mysql, "drop table t1");
13578   myquery(rc);
13579   DBUG_VOID_RETURN;
13580 }
13581 
13582 
13583 /*
13584   Error message is returned for unsupported features.
13585   Test also cursors with non-default PREFETCH_ROWS
13586 */
13587 
test_bug9643()13588 static void test_bug9643()
13589 {
13590   MYSQL_STMT *stmt;
13591   MYSQL_BIND my_bind[1];
13592   int32 a;
13593   int rc;
13594   const char *stmt_text;
13595   int num_rows= 0;
13596   ulong type;
13597   ulong prefetch_rows= 5;
13598 
13599   myheader("test_bug9643");
13600 
13601   mysql_query(mysql, "drop table if exists t1");
13602   mysql_query(mysql, "create table t1 (id integer not null primary key)");
13603   rc= mysql_query(mysql, "insert into t1 (id) values "
13604                          " (1), (2), (3), (4), (5), (6), (7), (8), (9)");
13605   myquery(rc);
13606 
13607   stmt= mysql_stmt_init(mysql);
13608   /* Not implemented in 5.0 */
13609   type= (ulong) CURSOR_TYPE_SCROLLABLE;
13610   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13611   DIE_UNLESS(rc);
13612   if (! opt_silent)
13613     printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13614 
13615   type= (ulong) CURSOR_TYPE_READ_ONLY;
13616   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13617   check_execute(stmt, rc);
13618   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
13619                           (void*) &prefetch_rows);
13620   check_execute(stmt, rc);
13621   stmt_text= "select * from t1";
13622   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13623   check_execute(stmt, rc);
13624 
13625   memset(my_bind, 0, sizeof(my_bind));
13626   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13627   my_bind[0].buffer= (void*) &a;
13628   my_bind[0].buffer_length= (ulong)sizeof(a);
13629   mysql_stmt_bind_result(stmt, my_bind);
13630 
13631   rc= mysql_stmt_execute(stmt);
13632   check_execute(stmt, rc);
13633 
13634   while ((rc= mysql_stmt_fetch(stmt)) == 0)
13635     ++num_rows;
13636   DIE_UNLESS(num_rows == 9);
13637 
13638   rc= mysql_stmt_close(stmt);
13639   DIE_UNLESS(rc == 0);
13640 
13641   rc= mysql_query(mysql, "drop table t1");
13642   myquery(rc);
13643 }
13644 
13645 /*
13646   Bug#11111: fetch from view returns wrong data
13647 */
13648 
test_bug11111()13649 static void test_bug11111()
13650 {
13651   MYSQL_STMT    *stmt;
13652   MYSQL_BIND    my_bind[2];
13653   char          buf[2][20];
13654   ulong         len[2];
13655   int i;
13656   int rc;
13657   const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
13658 
13659   myheader("test_bug11111");
13660 
13661   rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
13662   myquery(rc);
13663   rc= mysql_query(mysql, "drop view if exists t1, t2, v1");
13664   myquery(rc);
13665   rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)");
13666   myquery(rc);
13667   rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)");
13668   myquery(rc);
13669   rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1");
13670   myquery(rc);
13671   rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)");
13672   myquery(rc);
13673   rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
13674   myquery(rc);
13675 
13676   stmt= mysql_stmt_init(mysql);
13677 
13678   mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
13679   mysql_stmt_execute(stmt);
13680 
13681   memset(my_bind, 0, sizeof(my_bind));
13682   for (i=0; i < 2; i++)
13683   {
13684     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
13685     my_bind[i].buffer= (uchar* *)&buf[i];
13686     my_bind[i].buffer_length= 20;
13687     my_bind[i].length= &len[i];
13688   }
13689 
13690   rc= mysql_stmt_bind_result(stmt, my_bind);
13691   check_execute(stmt, rc);
13692 
13693   rc= mysql_stmt_fetch(stmt);
13694   check_execute(stmt, rc);
13695   if (!opt_silent)
13696     printf("return: %s", buf[1]);
13697   DIE_UNLESS(!strcmp(buf[1],"1"));
13698   mysql_stmt_close(stmt);
13699   rc= mysql_query(mysql, "drop view v1");
13700   myquery(rc);
13701   rc= mysql_query(mysql, "drop table t1, t2");
13702   myquery(rc);
13703 }
13704 
13705 /*
13706   Check that proper cleanups are done for prepared statement when
13707   fetching thorugh a cursor.
13708 */
13709 
test_bug10729()13710 static void test_bug10729()
13711 {
13712   MYSQL_STMT *stmt;
13713   MYSQL_BIND my_bind[1];
13714   char a[21];
13715   int rc;
13716   const char *stmt_text;
13717   int i= 0;
13718   const char *name_array[3]= { "aaa", "bbb", "ccc" };
13719   ulong type;
13720 
13721   myheader("test_bug10729");
13722 
13723   mysql_query(mysql, "drop table if exists t1");
13724   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13725                                       "name VARCHAR(20) NOT NULL)");
13726   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13727                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13728   myquery(rc);
13729 
13730   stmt= mysql_stmt_init(mysql);
13731 
13732   type= (ulong) CURSOR_TYPE_READ_ONLY;
13733   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13734   check_execute(stmt, rc);
13735   stmt_text= "select name from t1";
13736   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13737   check_execute(stmt, rc);
13738 
13739   memset(my_bind, 0, sizeof(my_bind));
13740   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13741   my_bind[0].buffer= (void*) a;
13742   my_bind[0].buffer_length= (ulong)sizeof(a);
13743   mysql_stmt_bind_result(stmt, my_bind);
13744 
13745   for (i= 0; i < 3; i++)
13746   {
13747     int row_no= 0;
13748     rc= mysql_stmt_execute(stmt);
13749     check_execute(stmt, rc);
13750     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13751     {
13752       DIE_UNLESS(strcmp(a, name_array[row_no]) == 0);
13753       if (!opt_silent)
13754         printf("%d: %s\n", row_no, a);
13755       ++row_no;
13756     }
13757     DIE_UNLESS(rc == MYSQL_NO_DATA);
13758   }
13759   rc= mysql_stmt_close(stmt);
13760   DIE_UNLESS(rc == 0);
13761 
13762   rc= mysql_query(mysql, "drop table t1");
13763   myquery(rc);
13764 }
13765 
13766 
13767 /*
13768   Check that mysql_next_result works properly in case when one of
13769   the statements used in a multi-statement query is erroneous
13770 */
13771 
test_bug9992()13772 static void test_bug9992()
13773 {
13774   MYSQL *mysql1;
13775   MYSQL_RES* res ;
13776   int   rc;
13777 
13778   myheader("test_bug9992");
13779 
13780   if (!opt_silent)
13781     printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
13782 
13783   mysql1= mysql_client_init(NULL);
13784 
13785   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13786                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13787                           CLIENT_MULTI_STATEMENTS))
13788   {
13789     fprintf(stderr, "Failed to connect to the database\n");
13790     DIE_UNLESS(0);
13791   }
13792 
13793 
13794   /* Sic: SHOW DATABASE is incorrect syntax. */
13795   rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;");
13796 
13797   if (rc)
13798   {
13799     fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1));
13800     DIE_UNLESS(0);
13801   }
13802 
13803   if (!opt_silent)
13804     printf("Testing mysql_store_result/mysql_next_result..\n");
13805 
13806   res= mysql_store_result(mysql1);
13807   DIE_UNLESS(res);
13808   mysql_free_result(res);
13809   rc= mysql_next_result(mysql1);
13810   DIE_UNLESS(rc == 1);                         /* Got errors, as expected */
13811 
13812   if (!opt_silent)
13813     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
13814             mysql_errno(mysql1), mysql_error(mysql1));
13815 
13816   mysql_close(mysql1);
13817 }
13818 
13819 /* Bug#10736: cursors and subqueries, memroot management */
13820 
test_bug10736()13821 static void test_bug10736()
13822 {
13823   MYSQL_STMT *stmt;
13824   MYSQL_BIND my_bind[1];
13825   char a[21];
13826   int rc;
13827   const char *stmt_text;
13828   int i= 0;
13829   ulong type;
13830 
13831   myheader("test_bug10736");
13832 
13833   mysql_query(mysql, "drop table if exists t1");
13834   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13835                                       "name VARCHAR(20) NOT NULL)");
13836   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13837                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13838   myquery(rc);
13839 
13840   stmt= mysql_stmt_init(mysql);
13841 
13842   type= (ulong) CURSOR_TYPE_READ_ONLY;
13843   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13844   check_execute(stmt, rc);
13845   stmt_text= "select name from t1 where name=(select name from t1 where id=2)";
13846   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13847   check_execute(stmt, rc);
13848 
13849   memset(my_bind, 0, sizeof(my_bind));
13850   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13851   my_bind[0].buffer= (void*) a;
13852   my_bind[0].buffer_length= (ulong)sizeof(a);
13853   mysql_stmt_bind_result(stmt, my_bind);
13854 
13855   for (i= 0; i < 3; i++)
13856   {
13857     int row_no= 0;
13858     rc= mysql_stmt_execute(stmt);
13859     check_execute(stmt, rc);
13860     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13861     {
13862       if (!opt_silent)
13863         printf("%d: %s\n", row_no, a);
13864       ++row_no;
13865     }
13866     DIE_UNLESS(rc == MYSQL_NO_DATA);
13867   }
13868   rc= mysql_stmt_close(stmt);
13869   DIE_UNLESS(rc == 0);
13870 
13871   rc= mysql_query(mysql, "drop table t1");
13872   myquery(rc);
13873 }
13874 
13875 /* Bug#10794: cursors, packets out of order */
13876 
test_bug10794()13877 static void test_bug10794()
13878 {
13879   MYSQL_STMT *stmt, *stmt1;
13880   MYSQL_BIND my_bind[2];
13881   char a[21];
13882   int id_val;
13883   ulong a_len;
13884   int rc;
13885   const char *stmt_text;
13886   int i= 0;
13887   ulong type;
13888 
13889   myheader("test_bug10794");
13890 
13891   mysql_query(mysql, "drop table if exists t1");
13892   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13893                                       "name varchar(20) not null)");
13894   stmt= mysql_stmt_init(mysql);
13895   stmt_text= "insert into t1 (id, name) values (?, ?)";
13896   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13897   check_execute(stmt, rc);
13898   memset(my_bind, 0, sizeof(my_bind));
13899   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13900   my_bind[0].buffer= (void*) &id_val;
13901   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
13902   my_bind[1].buffer= (void*) a;
13903   my_bind[1].length= &a_len;
13904   rc= mysql_stmt_bind_param(stmt, my_bind);
13905   check_execute(stmt, rc);
13906   for (i= 0; i < 42; i++)
13907   {
13908     id_val= (i+1)*10;
13909     sprintf(a, "a%d", i);
13910     a_len= (ulong)strlen(a); /* safety against broken sprintf */
13911     rc= mysql_stmt_execute(stmt);
13912     check_execute(stmt, rc);
13913   }
13914   stmt_text= "select name from t1";
13915   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13916   type= (ulong) CURSOR_TYPE_READ_ONLY;
13917   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13918   stmt1= mysql_stmt_init(mysql);
13919   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13920   memset(my_bind, 0, sizeof(my_bind));
13921   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13922   my_bind[0].buffer= (void*) a;
13923   my_bind[0].buffer_length= (ulong)sizeof(a);
13924   my_bind[0].length= &a_len;
13925   rc= mysql_stmt_bind_result(stmt, my_bind);
13926   check_execute(stmt, rc);
13927   rc= mysql_stmt_execute(stmt);
13928   check_execute(stmt, rc);
13929   rc= mysql_stmt_fetch(stmt);
13930   check_execute(stmt, rc);
13931   if (!opt_silent)
13932     printf("Fetched row from stmt: %s\n", a);
13933   /* Don't optimize: an attribute of the original test case */
13934   mysql_stmt_free_result(stmt);
13935   mysql_stmt_reset(stmt);
13936   stmt_text= "select name from t1 where id=10";
13937   rc= mysql_stmt_prepare(stmt1, stmt_text, (ulong)strlen(stmt_text));
13938   check_execute(stmt1, rc);
13939   rc= mysql_stmt_bind_result(stmt1, my_bind);
13940   check_execute(stmt1, rc);
13941   rc= mysql_stmt_execute(stmt1);
13942   while (1)
13943   {
13944     rc= mysql_stmt_fetch(stmt1);
13945     if (rc == MYSQL_NO_DATA)
13946     {
13947       if (!opt_silent)
13948         printf("End of data in stmt1\n");
13949       break;
13950     }
13951     check_execute(stmt1, rc);
13952     if (!opt_silent)
13953       printf("Fetched row from stmt1: %s\n", a);
13954   }
13955   mysql_stmt_close(stmt);
13956   mysql_stmt_close(stmt1);
13957 
13958   rc= mysql_query(mysql, "drop table t1");
13959   myquery(rc);
13960 }
13961 
13962 
13963 /* Bug#11172: cursors, crash on a fetch from a datetime column */
13964 
test_bug11172()13965 static void test_bug11172()
13966 {
13967   MYSQL_STMT *stmt;
13968   MYSQL_BIND bind_in[1], bind_out[2];
13969   MYSQL_TIME hired;
13970   int rc;
13971   const char *stmt_text;
13972   int i= 0, id;
13973   ulong type;
13974 
13975   myheader("test_bug11172");
13976 
13977   mysql_query(mysql, "drop table if exists t1");
13978   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13979                                       "hired date not null)");
13980   rc= mysql_query(mysql,
13981                   "insert into t1 (id, hired) values (1, '1933-08-24'), "
13982                   "(2, '1965-01-01'), (3, '1949-08-17'), (4, '1945-07-07'), "
13983                   "(5, '1941-05-15'), (6, '1978-09-15'), (7, '1936-03-28')");
13984   myquery(rc);
13985   stmt= mysql_stmt_init(mysql);
13986   stmt_text= "SELECT id, hired FROM t1 WHERE hired=?";
13987   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
13988   check_execute(stmt, rc);
13989 
13990   type= (ulong) CURSOR_TYPE_READ_ONLY;
13991   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13992 
13993   memset(bind_in, 0, sizeof(bind_in));
13994   memset(bind_out, 0, sizeof(bind_out));
13995   memset(&hired, 0, sizeof(hired));
13996   hired.year= 1965;
13997   hired.month= 1;
13998   hired.day= 1;
13999   bind_in[0].buffer_type= MYSQL_TYPE_DATE;
14000   bind_in[0].buffer= (void*) &hired;
14001   bind_in[0].buffer_length= (ulong)sizeof(hired);
14002   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
14003   bind_out[0].buffer= (void*) &id;
14004   bind_out[1]= bind_in[0];
14005 
14006   for (i= 0; i < 3; i++)
14007   {
14008     rc= mysql_stmt_bind_param(stmt, bind_in);
14009     check_execute(stmt, rc);
14010     rc= mysql_stmt_bind_result(stmt, bind_out);
14011     check_execute(stmt, rc);
14012     rc= mysql_stmt_execute(stmt);
14013     check_execute(stmt, rc);
14014     while ((rc= mysql_stmt_fetch(stmt)) == 0)
14015     {
14016       if (!opt_silent)
14017         printf("fetched data %d:%d-%d-%d\n", id,
14018                hired.year, hired.month, hired.day);
14019     }
14020     DIE_UNLESS(rc == MYSQL_NO_DATA);
14021     if (!mysql_stmt_free_result(stmt))
14022       mysql_stmt_reset(stmt);
14023   }
14024   mysql_stmt_close(stmt);
14025   mysql_rollback(mysql);
14026   mysql_rollback(mysql);
14027 
14028   rc= mysql_query(mysql, "drop table t1");
14029   myquery(rc);
14030 }
14031 
14032 
14033 /* Bug#11656: cursors, crash on a fetch from a query with distinct. */
14034 
test_bug11656()14035 static void test_bug11656()
14036 {
14037   MYSQL_STMT *stmt;
14038   MYSQL_BIND my_bind[2];
14039   int rc;
14040   const char *stmt_text;
14041   char buf[2][20];
14042   int i= 0;
14043   ulong type;
14044 
14045   myheader("test_bug11656");
14046 
14047   mysql_query(mysql, "drop table if exists t1");
14048 
14049   rc= mysql_query(mysql, "create table t1 ("
14050                   "server varchar(40) not null, "
14051                   "test_kind varchar(1) not null, "
14052                   "test_id varchar(30) not null , "
14053                   "primary key (server,test_kind,test_id))");
14054   myquery(rc);
14055 
14056   stmt_text= "select distinct test_kind, test_id from t1 "
14057              "where server in (?, ?)";
14058   stmt= mysql_stmt_init(mysql);
14059   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14060   check_execute(stmt, rc);
14061   type= (ulong) CURSOR_TYPE_READ_ONLY;
14062   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14063 
14064   memset(my_bind, 0, sizeof(my_bind));
14065   my_stpcpy(buf[0], "pcint502_MY2");
14066   my_stpcpy(buf[1], "*");
14067   for (i=0; i < 2; i++)
14068   {
14069     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
14070     my_bind[i].buffer= (uchar* *)&buf[i];
14071     my_bind[i].buffer_length= (ulong)strlen(buf[i]);
14072   }
14073   mysql_stmt_bind_param(stmt, my_bind);
14074 
14075   rc= mysql_stmt_execute(stmt);
14076   check_execute(stmt, rc);
14077 
14078   rc= mysql_stmt_fetch(stmt);
14079   DIE_UNLESS(rc == MYSQL_NO_DATA);
14080 
14081   mysql_stmt_close(stmt);
14082   rc= mysql_query(mysql, "drop table t1");
14083   myquery(rc);
14084 }
14085 
14086 
14087 /*
14088   Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
14089   and mysql_real_escape_string_quote() does the right thing as a result.
14090 */
14091 
test_bug10214()14092 static void test_bug10214()
14093 {
14094   int   len;
14095   char  out[8];
14096 
14097   myheader("test_bug10214");
14098 
14099   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
14100 
14101   len= mysql_real_escape_string_quote(mysql, out, "a'b\\c", 5, '\'');
14102   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14103 
14104   mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
14105   DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
14106 
14107   len= mysql_real_escape_string_quote(mysql, out, "a'b\\c", 5, '\'');
14108   DIE_UNLESS(memcmp(out, "a''b\\c", len) == 0);
14109 
14110   mysql_query(mysql, "set sql_mode=''");
14111 }
14112 
14113 /*
14114   Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
14115   a deprecated mysql_real_escape_string() function exits with error and the
14116   mysql_real_escape_string_quote() does the right thing as a result.
14117 */
14118 
test_bug21246()14119 static void test_bug21246()
14120 {
14121   int   len;
14122   char  out[11];
14123 
14124   myheader("test_bug21246");
14125 
14126   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
14127 
14128   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14129   DIE_UNLESS(len == 7);
14130   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14131 
14132   len = mysql_real_escape_string_quote(mysql, out, "a'b\\c", 5, '\'');
14133   DIE_UNLESS(len == 7);
14134   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14135 
14136   len = mysql_real_escape_string_quote(mysql, out, "`a'b\\c`", 7, '\'');
14137   DIE_UNLESS(len == 9);
14138   DIE_UNLESS(memcmp(out, "`a\\'b\\\\c`", len) == 0);
14139 
14140   len = mysql_real_escape_string_quote(mysql, out, "`a'b\\c`", 7, '`');
14141   DIE_UNLESS(len == 9);
14142   DIE_UNLESS(memcmp(out, "``a'b\\c``", len) == 0);
14143 
14144   len = mysql_real_escape_string_quote(mysql, out, "`a'b\\c\"", 7, '"');
14145   DIE_UNLESS(len == 10);
14146   DIE_UNLESS(memcmp(out, "`a\\'b\\\\c\\\"", len) == 0);
14147 
14148   mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
14149   DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
14150 
14151   len = mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14152   DIE_UNLESS(len == -1);
14153 
14154   len= mysql_real_escape_string_quote(mysql, out, "a'b\"c", 5, '\'');
14155   DIE_UNLESS(len == 6);
14156   DIE_UNLESS(memcmp(out, "a''b\"c", len) == 0);
14157 
14158   len = mysql_real_escape_string_quote(mysql, out, "a'b\"c", 5, '\"');
14159   DIE_UNLESS(len == 6);
14160   DIE_UNLESS(memcmp(out, "a'b\"\"c", len) == 0);
14161 
14162   len = mysql_real_escape_string_quote(mysql, out, "`a'b\"c`\"", 8, '\"');
14163   DIE_UNLESS(len == 10);
14164   DIE_UNLESS(memcmp(out, "`a'b\"\"c`\"\"", len) == 0);
14165 
14166   len = mysql_real_escape_string_quote(mysql, out, "`a'b\"c`\"", 8, '`');
14167   DIE_UNLESS(len == 10);
14168   DIE_UNLESS(memcmp(out, "``a'b\"c``\"", len) == 0);
14169 
14170   len = mysql_real_escape_string_quote(mysql, out, "\"a'b\"c\"\"", 8, '`');
14171   DIE_UNLESS(len == 8);
14172   DIE_UNLESS(memcmp(out, "\"a'b\"c\"\"", len) == 0);
14173 
14174   mysql_query(mysql, "set sql_mode=''");
14175 }
14176 
test_client_character_set()14177 static void test_client_character_set()
14178 {
14179   MY_CHARSET_INFO cs;
14180   char *csname= (char*) "utf8";
14181   char *csdefault= (char*)mysql_character_set_name(mysql);
14182   int rc;
14183 
14184   myheader("test_client_character_set");
14185 
14186   rc= mysql_set_character_set(mysql, csname);
14187   DIE_UNLESS(rc == 0);
14188 
14189   mysql_get_character_set_info(mysql, &cs);
14190   DIE_UNLESS(!strcmp(cs.csname, "utf8"));
14191   DIE_UNLESS(!strcmp(cs.name, "utf8_general_ci"));
14192   /* Restore the default character set */
14193   rc= mysql_set_character_set(mysql, csdefault);
14194   myquery(rc);
14195 }
14196 
14197 /* Test correct max length for MEDIUMTEXT and LONGTEXT columns */
14198 
test_bug9735()14199 static void test_bug9735()
14200 {
14201   MYSQL_RES *res;
14202   int rc;
14203 
14204   myheader("test_bug9735");
14205 
14206   rc= mysql_query(mysql, "drop table if exists t1");
14207   myquery(rc);
14208   rc= mysql_query(mysql, "create table t1 (a mediumtext, b longtext) "
14209                          "character set latin1");
14210   myquery(rc);
14211   rc= mysql_query(mysql, "select * from t1");
14212   myquery(rc);
14213   res= mysql_store_result(mysql);
14214   verify_prepare_field(res, 0, "a", "a", MYSQL_TYPE_BLOB,
14215                        "t1", "t1", current_db, (1U << 24)-1, 0);
14216   verify_prepare_field(res, 1, "b", "b", MYSQL_TYPE_BLOB,
14217                        "t1", "t1", current_db, ~0U, 0);
14218   mysql_free_result(res);
14219   rc= mysql_query(mysql, "drop table t1");
14220   myquery(rc);
14221 }
14222 
14223 
14224 /* Bug#11183 "mysql_stmt_reset() doesn't reset information about error" */
14225 
test_bug11183()14226 static void test_bug11183()
14227 {
14228   int rc;
14229   MYSQL_STMT *stmt;
14230   char bug_statement[]= "insert into t1 values (1)";
14231 
14232   myheader("test_bug11183");
14233 
14234   mysql_query(mysql, "drop table t1 if exists");
14235   mysql_query(mysql, "create table t1 (a int)");
14236 
14237   stmt= mysql_stmt_init(mysql);
14238   DIE_UNLESS(stmt != 0);
14239 
14240   rc= mysql_stmt_prepare(stmt, bug_statement, (ulong)strlen(bug_statement));
14241   check_execute(stmt, rc);
14242 
14243   rc= mysql_query(mysql, "drop table t1");
14244   myquery(rc);
14245 
14246   /* Trying to execute statement that should fail on execute stage */
14247   rc= mysql_stmt_execute(stmt);
14248   DIE_UNLESS(rc);
14249 
14250   mysql_stmt_reset(stmt);
14251   DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14252 
14253   mysql_query(mysql, "create table t1 (a int)");
14254 
14255   /* Trying to execute statement that should pass ok */
14256   if (mysql_stmt_execute(stmt))
14257   {
14258     mysql_stmt_reset(stmt);
14259     DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14260   }
14261 
14262   mysql_stmt_close(stmt);
14263 
14264   rc= mysql_query(mysql, "drop table t1");
14265   myquery(rc);
14266 }
14267 
test_bug11037()14268 static void test_bug11037()
14269 {
14270   MYSQL_STMT *stmt;
14271   int rc;
14272   const char *stmt_text;
14273 
14274   myheader("test_bug11037");
14275 
14276   mysql_query(mysql, "drop table if exists t1");
14277 
14278   rc= mysql_query(mysql, "create table t1 (id int not null)");
14279   myquery(rc);
14280 
14281   rc= mysql_query(mysql, "insert into t1 values (1)");
14282   myquery(rc);
14283 
14284   stmt_text= "select id FROM t1";
14285   stmt= mysql_stmt_init(mysql);
14286   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14287 
14288   /* expected error */
14289   rc = mysql_stmt_fetch(stmt);
14290   DIE_UNLESS(rc==1);
14291   if (!opt_silent)
14292     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
14293             mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
14294 
14295   rc= mysql_stmt_execute(stmt);
14296   check_execute(stmt, rc);
14297 
14298   rc= mysql_stmt_fetch(stmt);
14299   DIE_UNLESS(rc==0);
14300 
14301   rc= mysql_stmt_fetch(stmt);
14302   DIE_UNLESS(rc==MYSQL_NO_DATA);
14303 
14304   rc= mysql_stmt_fetch(stmt);
14305   DIE_UNLESS(rc==MYSQL_NO_DATA);
14306 
14307   mysql_stmt_close(stmt);
14308   rc= mysql_query(mysql, "drop table t1");
14309   myquery(rc);
14310 }
14311 
14312 /* Bug#10760: cursors, crash in a fetch after rollback. */
14313 
test_bug10760()14314 static void test_bug10760()
14315 {
14316   MYSQL_STMT *stmt;
14317   MYSQL_BIND my_bind[1];
14318   int rc;
14319   const char *stmt_text;
14320   char id_buf[20];
14321   ulong id_len;
14322   int i= 0;
14323   ulong type;
14324 
14325   myheader("test_bug10760");
14326 
14327   mysql_query(mysql, "drop table if exists t1, t2");
14328 
14329   /* create tables */
14330   rc= mysql_query(mysql, "create table t1 (id integer not null primary key)"
14331                          " engine=MyISAM");
14332   myquery(rc);
14333   for (; i < 42; ++i)
14334   {
14335     char buf[100];
14336     sprintf(buf, "insert into t1 (id) values (%d)", i+1);
14337     rc= mysql_query(mysql, buf);
14338     myquery(rc);
14339   }
14340   mysql_autocommit(mysql, FALSE);
14341   /* create statement */
14342   stmt= mysql_stmt_init(mysql);
14343   type= (ulong) CURSOR_TYPE_READ_ONLY;
14344   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14345 
14346   /*
14347     1: check that a deadlock within the same connection
14348     is resolved and an error is returned. The deadlock is modelled
14349     as follows:
14350     con1: open cursor for select * from t1;
14351     con1: insert into t1 (id) values (1)
14352   */
14353   stmt_text= "select id from t1 order by 1";
14354   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14355   check_execute(stmt, rc);
14356   rc= mysql_stmt_execute(stmt);
14357   check_execute(stmt, rc);
14358   rc= mysql_query(mysql, "update t1 set id=id+100");
14359   /*
14360     If cursors are not materialized, the update will return an error;
14361     we mainly test that it won't deadlock.
14362   */
14363   if (rc && !opt_silent)
14364     printf("Got error (as expected): %s\n", mysql_error(mysql));
14365   /*
14366     2: check that MyISAM tables used in cursors survive
14367     COMMIT/ROLLBACK.
14368   */
14369   rc= mysql_rollback(mysql);                  /* should not close the cursor */
14370   myquery(rc);
14371   rc= mysql_stmt_fetch(stmt);
14372   check_execute(stmt, rc);
14373 
14374   /*
14375     3: check that cursors to InnoDB tables are closed (for now) by
14376     COMMIT/ROLLBACK.
14377   */
14378     stmt_text= "select id from t1 order by 1";
14379     rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14380     check_execute(stmt, rc);
14381 
14382     rc= mysql_query(mysql, "alter table t1 engine=InnoDB");
14383     myquery(rc);
14384 
14385     memset(my_bind, 0, sizeof(my_bind));
14386     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14387     my_bind[0].buffer= (void*) id_buf;
14388     my_bind[0].buffer_length= (ulong)sizeof(id_buf);
14389     my_bind[0].length= &id_len;
14390     check_execute(stmt, rc);
14391     mysql_stmt_bind_result(stmt, my_bind);
14392 
14393     rc= mysql_stmt_execute(stmt);
14394     rc= mysql_stmt_fetch(stmt);
14395     DIE_UNLESS(rc == 0);
14396     if (!opt_silent)
14397       printf("Fetched row %s\n", id_buf);
14398     rc= mysql_rollback(mysql);                  /* should close the cursor */
14399     myquery(rc);
14400 #if 0
14401     rc= mysql_stmt_fetch(stmt);
14402     DIE_UNLESS(rc);
14403     if (!opt_silent)
14404       printf("Got error (as expected): %s\n", mysql_error(mysql));
14405 #endif
14406 
14407   mysql_stmt_close(stmt);
14408   rc= mysql_query(mysql, "drop table t1");
14409   myquery(rc);
14410   mysql_autocommit(mysql, TRUE);                /* restore default */
14411 }
14412 
test_bug12001()14413 static void test_bug12001()
14414 {
14415   MYSQL *mysql_local;
14416   MYSQL_RES *result;
14417   const char *query= "DROP TABLE IF EXISTS test_table;"
14418                      "CREATE TABLE test_table(id INT);"
14419                      "INSERT INTO test_table VALUES(10);"
14420                      "UPDATE test_table SET id=20 WHERE id=10;"
14421                      "SELECT * FROM test_table;"
14422                      "INSERT INTO non_existent_table VALUES(11);";
14423   int rc, res;
14424 
14425   myheader("test_bug12001");
14426 
14427   if (!(mysql_local= mysql_client_init(NULL)))
14428   {
14429     fprintf(stdout, "\n mysql_client_init() failed");
14430     exit(1);
14431   }
14432 
14433   /* Create connection that supports multi statements */
14434   if (!mysql_real_connect(mysql_local, opt_host, opt_user,
14435                           opt_password, current_db, opt_port,
14436                           opt_unix_socket, CLIENT_MULTI_STATEMENTS))
14437   {
14438     fprintf(stdout, "\n mysql_real_connect() failed");
14439     exit(1);
14440   }
14441 
14442   rc= mysql_query(mysql_local, query);
14443   myquery(rc);
14444 
14445   do
14446   {
14447     if (mysql_field_count(mysql_local) &&
14448         (result= mysql_use_result(mysql_local)))
14449     {
14450       mysql_free_result(result);
14451     }
14452   }
14453   while (!(res= mysql_next_result(mysql_local)));
14454 
14455   rc= mysql_query(mysql_local, "DROP TABLE IF EXISTS test_table");
14456   myquery(rc);
14457 
14458   mysql_close(mysql_local);
14459   DIE_UNLESS(res==1);
14460 }
14461 
14462 
14463 /* Bug#11909: wrong metadata if fetching from two cursors */
14464 
test_bug11909()14465 static void test_bug11909()
14466 {
14467   MYSQL_STMT *stmt1, *stmt2;
14468   MYSQL_BIND my_bind[7];
14469   int rc;
14470   char firstname[20], midinit[20], lastname[20], workdept[20];
14471   ulong firstname_len, midinit_len, lastname_len, workdept_len;
14472   uint32 empno;
14473   double salary;
14474   float bonus;
14475   const char *stmt_text;
14476 
14477   myheader("test_bug11909");
14478 
14479   stmt_text= "drop table if exists t1";
14480   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14481   myquery(rc);
14482 
14483   stmt_text= "create table t1 ("
14484     "  empno int(11) not null, firstname varchar(20) not null,"
14485     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14486     "  workdept varchar(6) not null, salary double not null,"
14487     "  bonus float not null, primary key (empno)"
14488     ") default charset=latin1 collate=latin1_bin";
14489   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14490   myquery(rc);
14491 
14492   stmt_text= "insert into t1 values "
14493     "(10, 'CHRISTINE', 'I', 'HAAS',     'A00', 52750, 1000), "
14494     "(20, 'MICHAEL',   'L', 'THOMPSON', 'B01', 41250, 800),"
14495     "(30, 'SALLY',     'A', 'KWAN',     'C01', 38250, 800),"
14496     "(50, 'JOHN',      'B', 'GEYER',    'E01', 40175, 800), "
14497     "(60, 'IRVING',    'F', 'STERN',    'D11', 32250, 500)";
14498   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14499   myquery(rc);
14500 
14501   /* ****** Begin of trace ****** */
14502 
14503   stmt1= open_cursor("SELECT empno, firstname, midinit, lastname,"
14504                      "workdept, salary, bonus FROM t1");
14505 
14506   memset(my_bind, 0, sizeof(my_bind));
14507   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14508   my_bind[0].buffer= (void*) &empno;
14509 
14510   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14511   my_bind[1].buffer= (void*) firstname;
14512   my_bind[1].buffer_length= (ulong)sizeof(firstname);
14513   my_bind[1].length= &firstname_len;
14514 
14515   my_bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;
14516   my_bind[2].buffer= (void*) midinit;
14517   my_bind[2].buffer_length= (ulong)sizeof(midinit);
14518   my_bind[2].length= &midinit_len;
14519 
14520   my_bind[3].buffer_type= MYSQL_TYPE_VAR_STRING;
14521   my_bind[3].buffer= (void*) lastname;
14522   my_bind[3].buffer_length= (ulong)sizeof(lastname);
14523   my_bind[3].length= &lastname_len;
14524 
14525   my_bind[4].buffer_type= MYSQL_TYPE_VAR_STRING;
14526   my_bind[4].buffer= (void*) workdept;
14527   my_bind[4].buffer_length= (ulong)sizeof(workdept);
14528   my_bind[4].length= &workdept_len;
14529 
14530   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
14531   my_bind[5].buffer= (void*) &salary;
14532 
14533   my_bind[6].buffer_type= MYSQL_TYPE_FLOAT;
14534   my_bind[6].buffer= (void*) &bonus;
14535   rc= mysql_stmt_bind_result(stmt1, my_bind);
14536   check_execute(stmt1, rc);
14537 
14538   rc= mysql_stmt_execute(stmt1);
14539   check_execute(stmt1, rc);
14540 
14541   rc= mysql_stmt_fetch(stmt1);
14542   DIE_UNLESS(rc == 0);
14543   DIE_UNLESS(empno == 10);
14544   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14545   DIE_UNLESS(strcmp(midinit, "I") == 0);
14546   DIE_UNLESS(strcmp(lastname, "HAAS") == 0);
14547   DIE_UNLESS(strcmp(workdept, "A00") == 0);
14548   DIE_UNLESS(salary == (double) 52750.0);
14549   DIE_UNLESS(bonus == (float) 1000.0);
14550 
14551   stmt2= open_cursor("SELECT empno, firstname FROM t1");
14552   rc= mysql_stmt_bind_result(stmt2, my_bind);
14553   check_execute(stmt2, rc);
14554 
14555   rc= mysql_stmt_execute(stmt2);
14556   check_execute(stmt2, rc);
14557 
14558   rc= mysql_stmt_fetch(stmt2);
14559   DIE_UNLESS(rc == 0);
14560 
14561   DIE_UNLESS(empno == 10);
14562   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14563 
14564   rc= mysql_stmt_reset(stmt2);
14565   check_execute(stmt2, rc);
14566 
14567   /* ERROR: next statement should return 0 */
14568 
14569   rc= mysql_stmt_fetch(stmt1);
14570   DIE_UNLESS(rc == 0);
14571 
14572   mysql_stmt_close(stmt1);
14573   mysql_stmt_close(stmt2);
14574   rc= mysql_rollback(mysql);
14575   myquery(rc);
14576 
14577   rc= mysql_query(mysql, "drop table t1");
14578   myquery(rc);
14579 }
14580 
14581 /* Cursors: opening a cursor to a compilicated query with ORDER BY */
14582 
test_bug11901()14583 static void test_bug11901()
14584 {
14585 /*  MYSQL_STMT *stmt;
14586   MYSQL_BIND my_bind[2]; */
14587   int rc;
14588 /*  char workdept[20];
14589   ulong workdept_len;
14590   uint32 empno; */
14591   const char *stmt_text;
14592 
14593   myheader("test_bug11901");
14594 
14595   stmt_text= "drop table if exists t1, t2";
14596   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14597   myquery(rc);
14598 
14599   stmt_text= "create table t1 ("
14600     "  empno int(11) not null, firstname varchar(20) not null,"
14601     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14602     "  workdept varchar(6) not null, salary double not null,"
14603     "  bonus float not null, primary key (empno), "
14604     " unique key (workdept, empno) "
14605     ") default charset=latin1 collate=latin1_bin";
14606   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14607   myquery(rc);
14608 
14609   stmt_text= "insert into t1 values "
14610      "(10,  'CHRISTINE', 'I', 'HAAS',      'A00', 52750, 1000),"
14611      "(20,  'MICHAEL',   'L', 'THOMPSON',  'B01', 41250, 800), "
14612      "(30,  'SALLY',     'A', 'KWAN',      'C01', 38250, 800), "
14613      "(50,  'JOHN',      'B', 'GEYER',     'E01', 40175, 800), "
14614      "(60,  'IRVING',    'F', 'STERN',     'D11', 32250, 500), "
14615      "(70,  'EVA',       'D', 'PULASKI',   'D21', 36170, 700), "
14616      "(90,  'EILEEN',    'W', 'HENDERSON', 'E11', 29750, 600), "
14617      "(100, 'THEODORE',  'Q', 'SPENSER',   'E21', 26150, 500), "
14618      "(110, 'VINCENZO',  'G', 'LUCCHESSI', 'A00', 46500, 900), "
14619      "(120, 'SEAN',      '',  'O\\'CONNELL', 'A00', 29250, 600), "
14620      "(130, 'DOLORES',   'M', 'QUINTANA',  'C01', 23800, 500), "
14621      "(140, 'HEATHER',   'A', 'NICHOLLS',  'C01', 28420, 600), "
14622      "(150, 'BRUCE',     '',  'ADAMSON',   'D11', 25280, 500), "
14623      "(160, 'ELIZABETH', 'R', 'PIANKA',    'D11', 22250, 400), "
14624      "(170, 'MASATOSHI', 'J', 'YOSHIMURA', 'D11', 24680, 500), "
14625      "(180, 'MARILYN',   'S', 'SCOUTTEN',  'D11', 21340, 500), "
14626      "(190, 'JAMES',     'H', 'WALKER',    'D11', 20450, 400), "
14627      "(200, 'DAVID',     '',  'BROWN',     'D11', 27740, 600), "
14628      "(210, 'WILLIAM',   'T', 'JONES',     'D11', 18270, 400), "
14629      "(220, 'JENNIFER',  'K', 'LUTZ',      'D11', 29840, 600), "
14630      "(230, 'JAMES',     'J', 'JEFFERSON', 'D21', 22180, 400), "
14631      "(240, 'SALVATORE', 'M', 'MARINO',    'D21', 28760, 600), "
14632      "(250, 'DANIEL',    'S', 'SMITH',     'D21', 19180, 400), "
14633      "(260, 'SYBIL',     'P', 'JOHNSON',   'D21', 17250, 300), "
14634      "(270, 'MARIA',     'L', 'PEREZ',     'D21', 27380, 500), "
14635      "(280, 'ETHEL',     'R', 'SCHNEIDER', 'E11', 26250, 500), "
14636      "(290, 'JOHN',      'R', 'PARKER',    'E11', 15340, 300), "
14637      "(300, 'PHILIP',    'X', 'SMITH',     'E11', 17750, 400), "
14638      "(310, 'MAUDE',     'F', 'SETRIGHT',  'E11', 15900, 300), "
14639      "(320, 'RAMLAL',    'V', 'MEHTA',     'E21', 19950, 400), "
14640      "(330, 'WING',      '',  'LEE',       'E21', 25370, 500), "
14641      "(340, 'JASON',     'R', 'GOUNOT',    'E21', 23840, 500)";
14642 
14643   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14644   myquery(rc);
14645 
14646   stmt_text= "create table t2 ("
14647     " deptno varchar(6) not null, deptname varchar(20) not null,"
14648     " mgrno int(11) not null, location varchar(20) not null,"
14649     " admrdept varchar(6) not null, refcntd int(11) not null,"
14650     " refcntu int(11) not null, primary key (deptno)"
14651     ") default charset=latin1 collate=latin1_bin";
14652   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14653   myquery(rc);
14654 
14655   stmt_text= "insert into t2 values "
14656     "('A00', 'SPIFFY COMPUTER SERV', 10, '', 'A00', 0, 0), "
14657     "('B01', 'PLANNING',             20, '', 'A00', 0, 0), "
14658     "('C01', 'INFORMATION CENTER',   30, '', 'A00', 0, 0), "
14659     "('D01', 'DEVELOPMENT CENTER',   0,  '', 'A00', 0, 0),"
14660     "('D11', 'MANUFACTURING SYSTEM', 60, '', 'D01', 0, 0), "
14661     "('D21', 'ADMINISTRATION SYSTE', 70, '', 'D01', 0, 0), "
14662     "('E01', 'SUPPORT SERVICES',     50, '', 'A00', 0, 0), "
14663     "('E11', 'OPERATIONS',           90, '', 'E01', 0, 0), "
14664     "('E21', 'SOFTWARE SUPPORT',     100,'', 'E01', 0, 0)";
14665   rc= mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
14666   myquery(rc);
14667 
14668   /* ****** Begin of trace ****** */
14669 /* WL#1110 - disabled test case failure - crash. */
14670 /*
14671   stmt= open_cursor("select t1.emp, t1.workdept "
14672                     "from (t1 left join t2 on t2.deptno = t1.workdept) "
14673                     "where t2.deptno in "
14674                     "   (select t2.deptno "
14675                     "    from (t1 left join t2 on t2.deptno = t1.workdept) "
14676                     "    where t1.empno = ?) "
14677                     "order by 1");
14678   memset(my_bind, 0, sizeof(my_bind));
14679 
14680   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14681   my_bind[0].buffer= &empno;
14682   rc= mysql_stmt_bind_param(stmt, my_bind);
14683   check_execute(stmt, rc);
14684 
14685   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14686   my_bind[1].buffer= (void*) workdept;
14687   my_bind[1].buffer_length= sizeof(workdept);
14688   my_bind[1].length= &workdept_len;
14689 
14690   rc= mysql_stmt_bind_result(stmt, my_bind);
14691   check_execute(stmt, rc);
14692 
14693   empno= 10;
14694 */
14695   /* ERROR: next statement causes a server crash */
14696 /*
14697   rc= mysql_stmt_execute(stmt);
14698   check_execute(stmt, rc);
14699 
14700   mysql_stmt_close(stmt);
14701 
14702   rc= mysql_query(mysql, "drop table t1, t2");
14703   myquery(rc);
14704 */
14705 }
14706 
14707 /* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */
14708 
test_bug11904()14709 static void test_bug11904()
14710 {
14711   MYSQL_STMT *stmt1;
14712   int rc;
14713   const char *stmt_text;
14714   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
14715   MYSQL_BIND my_bind[2];
14716   int country_id=0;
14717   char row_data[11]= {0};
14718 
14719   myheader("test_bug11904");
14720 
14721   /* create tables */
14722   rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b");
14723   myquery(rc);
14724   rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))");
14725   myquery(rc);
14726 
14727   rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv'),"
14728                           " (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg'),"
14729                           " (3,'berlin'), (3, 'frankfurt')");
14730 
14731   myquery(rc);
14732   mysql_commit(mysql);
14733   /* create statement */
14734   stmt1= mysql_stmt_init(mysql);
14735   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14736 
14737   stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id";
14738 
14739   rc= mysql_stmt_prepare(stmt1, stmt_text, (ulong)strlen(stmt_text));
14740   check_execute(stmt1, rc);
14741 
14742   memset(my_bind, 0, sizeof(my_bind));
14743   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14744   my_bind[0].buffer=& country_id;
14745   my_bind[0].buffer_length= 0;
14746   my_bind[0].length= 0;
14747 
14748   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14749   my_bind[1].buffer=& row_data;
14750   my_bind[1].buffer_length= (ulong)(sizeof(row_data) - 1);
14751   my_bind[1].length= 0;
14752 
14753   rc= mysql_stmt_bind_result(stmt1, my_bind);
14754   check_execute(stmt1, rc);
14755 
14756   rc= mysql_stmt_execute(stmt1);
14757   check_execute(stmt1, rc);
14758 
14759   rc= mysql_stmt_fetch(stmt1);
14760   check_execute(stmt1, rc);
14761   DIE_UNLESS(country_id == 1);
14762   DIE_UNLESS(memcmp(row_data, "plovdiv", 7) == 0);
14763 
14764   rc= mysql_stmt_fetch(stmt1);
14765   check_execute(stmt1, rc);
14766   DIE_UNLESS(country_id == 2);
14767   DIE_UNLESS(memcmp(row_data, "LA", 2) == 0);
14768 
14769   rc= mysql_stmt_fetch(stmt1);
14770   check_execute(stmt1, rc);
14771   DIE_UNLESS(country_id == 3);
14772   DIE_UNLESS(memcmp(row_data, "berlin", 6) == 0);
14773 
14774   rc= mysql_stmt_close(stmt1);
14775   check_execute(stmt1, rc);
14776 
14777   rc= mysql_query(mysql, "drop table bug11904b");
14778   myquery(rc);
14779 }
14780 
14781 
14782 /* Bug#12243: multiple cursors, crash in a fetch after commit. */
14783 
test_bug12243()14784 static void test_bug12243()
14785 {
14786   MYSQL_STMT *stmt1, *stmt2;
14787   int rc;
14788   const char *stmt_text;
14789   ulong type;
14790 
14791   myheader("test_bug12243");
14792 
14793 
14794   /* create tables */
14795   mysql_query(mysql, "drop table if exists t1");
14796   mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
14797   rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
14798   myquery(rc);
14799   mysql_autocommit(mysql, FALSE);
14800   /* create statement */
14801   stmt1= mysql_stmt_init(mysql);
14802   stmt2= mysql_stmt_init(mysql);
14803   type= (ulong) CURSOR_TYPE_READ_ONLY;
14804   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14805   mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14806 
14807   stmt_text= "select a from t1";
14808 
14809   rc= mysql_stmt_prepare(stmt1, stmt_text, (ulong)strlen(stmt_text));
14810   check_execute(stmt1, rc);
14811   rc= mysql_stmt_execute(stmt1);
14812   check_execute(stmt1, rc);
14813   rc= mysql_stmt_fetch(stmt1);
14814   check_execute(stmt1, rc);
14815 
14816   rc= mysql_stmt_prepare(stmt2, stmt_text, (ulong)strlen(stmt_text));
14817   check_execute(stmt2, rc);
14818   rc= mysql_stmt_execute(stmt2);
14819   check_execute(stmt2, rc);
14820   rc= mysql_stmt_fetch(stmt2);
14821   check_execute(stmt2, rc);
14822 
14823   rc= mysql_stmt_close(stmt1);
14824   check_execute(stmt1, rc);
14825   rc= mysql_commit(mysql);
14826   myquery(rc);
14827   rc= mysql_stmt_fetch(stmt2);
14828   check_execute(stmt2, rc);
14829 
14830   mysql_stmt_close(stmt2);
14831   rc= mysql_query(mysql, "drop table t1");
14832   myquery(rc);
14833   mysql_autocommit(mysql, TRUE);                /* restore default */
14834 }
14835 
14836 
14837 /*
14838   Bug#11718: query with function, join and order by returns wrong type
14839 */
14840 
test_bug11718()14841 static void test_bug11718()
14842 {
14843   MYSQL_RES	*res;
14844   int rc;
14845   const char *query= "select str_to_date(concat(f3),'%Y%m%d') from t1,t2 "
14846                      "where f1=f2 order by f1";
14847 
14848   myheader("test_bug11718");
14849 
14850   rc= mysql_query(mysql, "drop table if exists t1, t2");
14851   myquery(rc);
14852   rc= mysql_query(mysql, "create table t1 (f1 int)");
14853   myquery(rc);
14854   rc= mysql_query(mysql, "create table t2 (f2 int, f3 numeric(8))");
14855   myquery(rc);
14856   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14857   myquery(rc);
14858   rc= mysql_query(mysql, "insert into t2 values (1,20050101), (2,20050202)");
14859   myquery(rc);
14860   rc= mysql_query(mysql, query);
14861   myquery(rc);
14862   res = mysql_store_result(mysql);
14863 
14864   if (!opt_silent)
14865     printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
14866            "not DATE");
14867   DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
14868   mysql_free_result(res);
14869   rc= mysql_query(mysql, "drop table t1, t2");
14870   myquery(rc);
14871 }
14872 
14873 
14874 /*
14875   Bug #12925: Bad handling of maximum values in getopt
14876 */
test_bug12925()14877 static void test_bug12925()
14878 {
14879   myheader("test_bug12925");
14880   if (opt_getopt_ll_test)
14881     DIE_UNLESS(opt_getopt_ll_test == 25600*1024*1024LL);
14882 }
14883 
14884 
14885 /*
14886   Bug#14210 "Simple query with > operator on large table gives server
14887   crash"
14888 */
14889 
test_bug14210()14890 static void test_bug14210()
14891 {
14892   MYSQL_STMT *stmt;
14893   int rc, i;
14894   const char *stmt_text;
14895   ulong type;
14896 
14897   myheader("test_bug14210");
14898 
14899   mysql_query(mysql, "drop table if exists t1");
14900   /*
14901     To trigger the problem the table must be InnoDB, although the problem
14902     itself is not InnoDB related. In case the table is MyISAM this test
14903     is harmless.
14904   */
14905   mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB");
14906   rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
14907   myquery(rc);
14908   rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
14909   /* Create a big enough table (more than max_heap_table_size) */
14910   for (i= 0; i < 8; i++)
14911   {
14912     rc= mysql_query(mysql, "insert into t1 (a) select a from t1");
14913     myquery(rc);
14914   }
14915   /* create statement */
14916   stmt= mysql_stmt_init(mysql);
14917   type= (ulong) CURSOR_TYPE_READ_ONLY;
14918   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14919 
14920   stmt_text= "select a from t1";
14921 
14922   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
14923   check_execute(stmt, rc);
14924   rc= mysql_stmt_execute(stmt);
14925   while ((rc= mysql_stmt_fetch(stmt)) == 0)
14926     ;
14927   DIE_UNLESS(rc == MYSQL_NO_DATA);
14928 
14929   rc= mysql_stmt_close(stmt);
14930 
14931   rc= mysql_query(mysql, "drop table t1");
14932   myquery(rc);
14933   rc= mysql_query(mysql, "set @@session.max_heap_table_size=default");
14934   myquery(rc);
14935 }
14936 
14937 /* Bug#13488: wrong column metadata when fetching from cursor */
14938 
test_bug13488()14939 static void test_bug13488()
14940 {
14941   MYSQL_BIND my_bind[3];
14942   MYSQL_STMT *stmt1;
14943   int rc, f1, f2, f3, i;
14944   const ulong type= CURSOR_TYPE_READ_ONLY;
14945   const char *query= "select * from t1 left join t2 on f1=f2 where f1=1";
14946 
14947   myheader("test_bug13488");
14948 
14949   rc= mysql_query(mysql, "drop table if exists t1, t2");
14950   myquery(rc);
14951   rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)");
14952   myquery(rc);
14953   rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, "
14954                   "f3 int not null)");
14955   myquery(rc);
14956   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14957   myquery(rc);
14958   rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)");
14959   myquery(rc);
14960 
14961   memset(my_bind, 0, sizeof(my_bind));
14962   for (i= 0; i < 3; i++)
14963   {
14964     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
14965     my_bind[i].buffer_length= 4;
14966     my_bind[i].length= 0;
14967   }
14968   my_bind[0].buffer=&f1;
14969   my_bind[1].buffer=&f2;
14970   my_bind[2].buffer=&f3;
14971 
14972   stmt1= mysql_stmt_init(mysql);
14973   rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type);
14974   check_execute(stmt1, rc);
14975 
14976   rc= mysql_stmt_prepare(stmt1, query, (ulong)strlen(query));
14977   check_execute(stmt1, rc);
14978 
14979   rc= mysql_stmt_execute(stmt1);
14980   check_execute(stmt1, rc);
14981 
14982   rc= mysql_stmt_bind_result(stmt1, my_bind);
14983   check_execute(stmt1, rc);
14984 
14985   rc= mysql_stmt_fetch(stmt1);
14986   check_execute(stmt1, rc);
14987 
14988   rc= mysql_stmt_free_result(stmt1);
14989   check_execute(stmt1, rc);
14990 
14991   rc= mysql_stmt_reset(stmt1);
14992   check_execute(stmt1, rc);
14993 
14994   rc= mysql_stmt_close(stmt1);
14995   check_execute(stmt1, rc);
14996 
14997   if (!opt_silent)
14998   {
14999     printf("data: f1: %d; f2: %d; f3: %d\n", f1, f2, f3);
15000     printf("data is: %s\n",
15001            (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong");
15002   }
15003   DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
15004   rc= mysql_query(mysql, "drop table t1, t2");
15005   myquery(rc);
15006 }
15007 
15008 /*
15009   Bug#13524: warnings of a previous command are not reset when fetching
15010   from a cursor.
15011 */
15012 
test_bug13524()15013 static void test_bug13524()
15014 {
15015   MYSQL_STMT *stmt;
15016   int rc;
15017   unsigned int warning_count;
15018   const ulong type= CURSOR_TYPE_READ_ONLY;
15019   const char *query= "select * from t1";
15020 
15021   myheader("test_bug13524");
15022 
15023   rc= mysql_query(mysql, "drop table if exists t1, t2");
15024   myquery(rc);
15025   rc= mysql_query(mysql, "create table t1 (a int not null primary key)");
15026   myquery(rc);
15027   rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
15028   myquery(rc);
15029 
15030   stmt= mysql_stmt_init(mysql);
15031   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15032   check_execute(stmt, rc);
15033 
15034   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
15035   check_execute(stmt, rc);
15036 
15037   rc= mysql_stmt_execute(stmt);
15038   check_execute(stmt, rc);
15039 
15040   rc= mysql_stmt_fetch(stmt);
15041   check_execute(stmt, rc);
15042 
15043   warning_count= mysql_warning_count(mysql);
15044   DIE_UNLESS(warning_count == 0);
15045 
15046   /* Check that DROP TABLE produced a warning (no such table) */
15047   rc= mysql_query(mysql, "drop table if exists t2");
15048   myquery(rc);
15049   warning_count= mysql_warning_count(mysql);
15050   DIE_UNLESS(warning_count == 1);
15051 
15052   /*
15053     Check that fetch from a cursor cleared the warning from the previous
15054     command.
15055   */
15056   rc= mysql_stmt_fetch(stmt);
15057   check_execute(stmt, rc);
15058   warning_count= mysql_warning_count(mysql);
15059   DIE_UNLESS(warning_count == 0);
15060 
15061   /* Cleanup */
15062   mysql_stmt_close(stmt);
15063   rc= mysql_query(mysql, "drop table t1");
15064   myquery(rc);
15065 }
15066 
15067 /*
15068   Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
15069 */
15070 
test_bug14845()15071 static void test_bug14845()
15072 {
15073   MYSQL_STMT *stmt;
15074   int rc;
15075   const ulong type= CURSOR_TYPE_READ_ONLY;
15076   const char *query= "select count(*) from t1 where 1 = 0";
15077 
15078   myheader("test_bug14845");
15079 
15080   rc= mysql_query(mysql, "drop table if exists t1");
15081   myquery(rc);
15082   rc= mysql_query(mysql, "create table t1 (id int(11) default null, "
15083                          "name varchar(20) default null)"
15084                          "engine=MyISAM DEFAULT CHARSET=utf8");
15085   myquery(rc);
15086   rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')");
15087   myquery(rc);
15088 
15089   stmt= mysql_stmt_init(mysql);
15090   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15091   check_execute(stmt, rc);
15092 
15093   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
15094   check_execute(stmt, rc);
15095 
15096   rc= mysql_stmt_execute(stmt);
15097   check_execute(stmt, rc);
15098 
15099   rc= mysql_stmt_fetch(stmt);
15100   DIE_UNLESS(rc == 0);
15101 
15102   rc= mysql_stmt_fetch(stmt);
15103   DIE_UNLESS(rc == MYSQL_NO_DATA);
15104 
15105   /* Cleanup */
15106   mysql_stmt_close(stmt);
15107   rc= mysql_query(mysql, "drop table t1");
15108   myquery(rc);
15109 }
15110 
15111 
15112 /*
15113   Bug #15510: mysql_warning_count returns 0 after mysql_stmt_fetch which
15114   should warn
15115 */
test_bug15510()15116 static void test_bug15510()
15117 {
15118   MYSQL_STMT *stmt;
15119   int rc;
15120   const char *query= "select 1 from dual where 1/0";
15121 
15122   myheader("test_bug15510");
15123 
15124   rc= mysql_query(mysql, "set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'");
15125   myquery(rc);
15126 
15127   stmt= mysql_stmt_init(mysql);
15128 
15129   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
15130   check_execute(stmt, rc);
15131 
15132   rc= mysql_stmt_execute(stmt);
15133   check_execute(stmt, rc);
15134 
15135   rc= mysql_stmt_fetch(stmt);
15136   DIE_UNLESS(mysql_warning_count(mysql));
15137 
15138   /* Cleanup */
15139   mysql_stmt_close(stmt);
15140   rc= mysql_query(mysql, "set @@sql_mode=''");
15141   myquery(rc);
15142 }
15143 
15144 
15145 /* Test MYSQL_OPT_RECONNECT, Bug#15719 */
15146 
test_opt_reconnect()15147 static void test_opt_reconnect()
15148 {
15149   MYSQL *lmysql;
15150   my_bool my_true= TRUE;
15151 
15152   myheader("test_opt_reconnect");
15153 
15154   if (!(lmysql= mysql_client_init(NULL)))
15155   {
15156     myerror("mysql_client_init() failed");
15157     exit(1);
15158   }
15159 
15160   if (!opt_silent)
15161     fprintf(stdout, "reconnect before mysql_options: %d\n", lmysql->reconnect);
15162   DIE_UNLESS(lmysql->reconnect == 0);
15163 
15164   if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
15165   {
15166     myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
15167     DIE_UNLESS(0);
15168   }
15169 
15170   /* reconnect should be 1 */
15171   if (!opt_silent)
15172     fprintf(stdout, "reconnect after mysql_options: %d\n", lmysql->reconnect);
15173   DIE_UNLESS(lmysql->reconnect == 1);
15174 
15175   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15176                            opt_password, current_db, opt_port,
15177                            opt_unix_socket, 0)))
15178   {
15179     myerror("connection failed");
15180     DIE_UNLESS(0);
15181   }
15182 
15183   /* reconnect should still be 1 */
15184   if (!opt_silent)
15185     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15186 	    lmysql->reconnect);
15187   DIE_UNLESS(lmysql->reconnect == 1);
15188 
15189   mysql_close(lmysql);
15190 
15191   if (!(lmysql= mysql_client_init(NULL)))
15192   {
15193     myerror("mysql_client_init() failed");
15194     DIE_UNLESS(0);
15195   }
15196 
15197   if (!opt_silent)
15198     fprintf(stdout, "reconnect before mysql_real_connect: %d\n", lmysql->reconnect);
15199   DIE_UNLESS(lmysql->reconnect == 0);
15200 
15201   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15202                            opt_password, current_db, opt_port,
15203                            opt_unix_socket, 0)))
15204   {
15205     myerror("connection failed");
15206     DIE_UNLESS(0);
15207   }
15208 
15209   /* reconnect should still be 0 */
15210   if (!opt_silent)
15211     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15212 	    lmysql->reconnect);
15213   DIE_UNLESS(lmysql->reconnect == 0);
15214 
15215   mysql_close(lmysql);
15216 }
15217 
15218 
15219 #ifndef EMBEDDED_LIBRARY
15220 
test_bug12744()15221 static void test_bug12744()
15222 {
15223   MYSQL_STMT *prep_stmt = NULL;
15224   MYSQL *lmysql;
15225   int rc;
15226   myheader("test_bug12744");
15227 
15228   lmysql= mysql_client_init(NULL);
15229   DIE_UNLESS(lmysql);
15230 
15231   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
15232                           current_db, opt_port, opt_unix_socket, 0))
15233   {
15234     fprintf(stderr, "Failed to connect to the database\n");
15235     DIE_UNLESS(0);
15236   }
15237 
15238   prep_stmt= mysql_stmt_init(lmysql);
15239   rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
15240   DIE_UNLESS(rc == 0);
15241 
15242   mysql_close(lmysql);
15243 
15244   rc= mysql_stmt_execute(prep_stmt);
15245   DIE_UNLESS(rc);
15246   rc= mysql_stmt_reset(prep_stmt);
15247   DIE_UNLESS(rc);
15248   rc= mysql_stmt_close(prep_stmt);
15249   DIE_UNLESS(rc == 0);
15250 }
15251 
15252 #endif /* EMBEDDED_LIBRARY */
15253 
15254 /* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
15255 
test_bug16143()15256 static void test_bug16143()
15257 {
15258   MYSQL_STMT *stmt;
15259   myheader("test_bug16143");
15260 
15261   stmt= mysql_stmt_init(mysql);
15262   /* Check mysql_stmt_sqlstate return "no error" */
15263   DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0);
15264 
15265   mysql_stmt_close(stmt);
15266 }
15267 
15268 
15269 /* Bug #16144: mysql_stmt_attr_get type error */
15270 
test_bug16144()15271 static void test_bug16144()
15272 {
15273   const my_bool flag_orig= (my_bool) 0xde;
15274   my_bool flag= flag_orig;
15275   MYSQL_STMT *stmt;
15276   myheader("test_bug16144");
15277 
15278   /* Check that attr_get returns correct data on little and big endian CPUs */
15279   stmt= mysql_stmt_init(mysql);
15280   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
15281   mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
15282   DIE_UNLESS(flag == flag_orig);
15283 
15284   mysql_stmt_close(stmt);
15285 }
15286 
15287 /*
15288   Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
15289   field length"
15290 */
15291 
test_bug15613()15292 static void test_bug15613()
15293 {
15294   MYSQL_STMT *stmt;
15295   const char *stmt_text;
15296   MYSQL_RES *metadata;
15297   MYSQL_FIELD *field;
15298   int rc;
15299   myheader("test_bug15613");
15300 
15301   /* I. Prepare the table */
15302   rc= mysql_query(mysql, "set names latin1");
15303   myquery(rc);
15304   mysql_query(mysql, "drop table if exists t1");
15305   rc= mysql_query(mysql,
15306                   "create table t1 (t text character set utf8, "
15307                                    "tt tinytext character set utf8, "
15308                                    "mt mediumtext character set utf8, "
15309                                    "lt longtext character set utf8, "
15310                                    "vl varchar(255) character set latin1,"
15311                                    "vb varchar(255) character set binary,"
15312                                    "vu varchar(255) character set utf8)");
15313   myquery(rc);
15314 
15315   stmt= mysql_stmt_init(mysql);
15316 
15317   /* II. Check SELECT metadata */
15318   stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
15319   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
15320   metadata= mysql_stmt_result_metadata(stmt);
15321   field= mysql_fetch_fields(metadata);
15322   if (!opt_silent)
15323   {
15324     printf("Field lengths (client character set is latin1):\n"
15325            "text character set utf8:\t\t%lu\n"
15326            "tinytext character set utf8:\t\t%lu\n"
15327            "mediumtext character set utf8:\t\t%lu\n"
15328            "longtext character set utf8:\t\t%lu\n"
15329            "varchar(255) character set latin1:\t%lu\n"
15330            "varchar(255) character set binary:\t%lu\n"
15331            "varchar(255) character set utf8:\t%lu\n",
15332            field[0].length, field[1].length, field[2].length, field[3].length,
15333            field[4].length, field[5].length, field[6].length);
15334   }
15335   DIE_UNLESS(field[0].length == 65535);
15336   DIE_UNLESS(field[1].length == 255);
15337   DIE_UNLESS(field[2].length == 16777215);
15338   DIE_UNLESS(field[3].length == 4294967295UL);
15339   DIE_UNLESS(field[4].length == 255);
15340   DIE_UNLESS(field[5].length == 255);
15341   DIE_UNLESS(field[6].length == 255);
15342   mysql_free_result(metadata);
15343   mysql_stmt_free_result(stmt);
15344 
15345   /* III. Cleanup */
15346   rc= mysql_query(mysql, "drop table t1");
15347   myquery(rc);
15348   rc= mysql_query(mysql, "set names default");
15349   myquery(rc);
15350   mysql_stmt_close(stmt);
15351 }
15352 
15353 /*
15354   Bug#17667: An attacker has the opportunity to bypass query logging.
15355 
15356   Note! Also tests Bug#21813, where prepared statements are used to
15357   run queries
15358 */
test_bug17667()15359 static void test_bug17667()
15360 {
15361   int rc;
15362   MYSQL_STMT *stmt;
15363   enum query_type { QT_NORMAL, QT_PREPARED};
15364   struct buffer_and_length {
15365     enum query_type qt;
15366     const char *buffer;
15367     const ulong length;
15368   } statements[]= {
15369     { QT_NORMAL, "drop table if exists bug17667", 29 },
15370     { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
15371     { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
15372     { QT_PREPARED,
15373       "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
15374     { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
15375     { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
15376     { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
15377     { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
15378     { QT_NORMAL, "drop table bug17667", 19 },
15379     { QT_NORMAL, NULL, 0 } };
15380 
15381   struct buffer_and_length *statement_cursor;
15382   FILE *log_file;
15383   char *master_log_filename;
15384 
15385   myheader("test_bug17667");
15386 
15387   master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1);
15388   strxmov(master_log_filename, opt_vardir, "/log/master.log", NullS);
15389   if (!opt_silent)
15390     printf("Opening '%s'\n", master_log_filename);
15391   log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0));
15392   free(master_log_filename);
15393 
15394   if (log_file == NULL)
15395   {
15396     if (!opt_silent)
15397     {
15398       printf("Could not find the log file, VARDIR/log/master.log, so "
15399              "test_bug17667 is not run.\n"
15400              "Run test from the mysql-test/mysql-test-run* program to set up "
15401              "correct environment for this test.\n\n");
15402     }
15403     return;
15404   }
15405 
15406   enable_query_logs(1);
15407 
15408   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15409        statement_cursor++)
15410   {
15411     if (statement_cursor->qt == QT_NORMAL)
15412     {
15413       /* Run statement as normal query */
15414       rc= mysql_real_query(mysql, statement_cursor->buffer,
15415                            statement_cursor->length);
15416       myquery(rc);
15417     }
15418     else if (statement_cursor->qt == QT_PREPARED)
15419     {
15420       /*
15421         Run as prepared statement
15422 
15423         NOTE! All these queries should be in the log twice,
15424         one time for prepare and one time for execute
15425       */
15426       stmt= mysql_stmt_init(mysql);
15427 
15428       rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
15429                              statement_cursor->length);
15430       check_execute(stmt, rc);
15431 
15432       rc= mysql_stmt_execute(stmt);
15433       check_execute(stmt, rc);
15434 
15435       mysql_stmt_close(stmt);
15436     }
15437     else
15438     {
15439       DIE_UNLESS(0==1);
15440     }
15441   }
15442 
15443   /* Make sure the server has written the logs to disk before reading it */
15444   rc= mysql_query(mysql, "flush logs");
15445   myquery(rc);
15446 
15447   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15448        statement_cursor++)
15449   {
15450     int expected_hits= 1, hits= 0;
15451     char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15452     /* more than enough room for the query and some marginalia. */
15453 
15454     /* Prepared statments always occurs twice in log */
15455     if (statement_cursor->qt == QT_PREPARED)
15456       expected_hits++;
15457 
15458     /* Loop until we found expected number of log entries */
15459     do {
15460       /* Loop until statement is found in log */
15461       do {
15462         memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15463 
15464         if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15465         {
15466           /* If fgets returned NULL, it indicates either error or EOF */
15467           if (feof(log_file))
15468             DIE("Found EOF before all statements where found");
15469 
15470           fprintf(stderr, "Got error %d while reading from file\n",
15471                   ferror(log_file));
15472           DIE("Read error");
15473         }
15474 
15475       } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15476                          statement_cursor->buffer,
15477                          statement_cursor->length) == NULL);
15478       hits++;
15479     } while (hits < expected_hits);
15480 
15481     if (!opt_silent)
15482       printf("Found statement starting with \"%s\"\n",
15483              statement_cursor->buffer);
15484   }
15485 
15486   restore_query_logs();
15487 
15488   if (!opt_silent)
15489     printf("success.  All queries found intact in the log.\n");
15490 
15491   my_fclose(log_file, MYF(0));
15492 }
15493 
15494 
15495 /*
15496   Bug#14169: type of group_concat() result changed to blob if tmp_table was
15497   used
15498 */
test_bug14169()15499 static void test_bug14169()
15500 {
15501   MYSQL_STMT *stmt;
15502   const char *stmt_text;
15503   MYSQL_RES *res;
15504   MYSQL_FIELD *field;
15505   int rc;
15506 
15507   myheader("test_bug14169");
15508 
15509   rc= mysql_query(mysql, "drop table if exists t1");
15510   myquery(rc);
15511   rc= mysql_query(mysql, "set session group_concat_max_len=1024");
15512   myquery(rc);
15513   rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))");
15514   myquery(rc);
15515   rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255)),"
15516                          "(2,repeat('b',255))");
15517   myquery(rc);
15518   stmt= mysql_stmt_init(mysql);
15519   stmt_text= "select f2,group_concat(f1) from t1 group by f2";
15520   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
15521   myquery(rc);
15522   res= mysql_stmt_result_metadata(stmt);
15523   field= mysql_fetch_fields(res);
15524   if (!opt_silent)
15525     printf("GROUP_CONCAT() result type %i", field[1].type);
15526   DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
15527   mysql_free_result(res);
15528   mysql_stmt_free_result(stmt);
15529   mysql_stmt_close(stmt);
15530 
15531   rc= mysql_query(mysql, "drop table t1");
15532   myquery(rc);
15533 }
15534 
15535 /*
15536    Test that mysql_insert_id() behaves as documented in our manual
15537 */
test_mysql_insert_id()15538 static void test_mysql_insert_id()
15539 {
15540   my_ulonglong res;
15541   int rc;
15542 
15543   myheader("test_mysql_insert_id");
15544 
15545   rc= mysql_query(mysql, "drop table if exists t1");
15546   myquery(rc);
15547   /* table without auto_increment column */
15548   rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
15549   myquery(rc);
15550   rc= mysql_query(mysql, "insert into t1 values (1,'a')");
15551   myquery(rc);
15552   res= mysql_insert_id(mysql);
15553   DIE_UNLESS(res == 0);
15554   rc= mysql_query(mysql, "insert into t1 values (null,'b')");
15555   myquery(rc);
15556   res= mysql_insert_id(mysql);
15557   DIE_UNLESS(res == 0);
15558   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15559   myquery(rc);
15560   res= mysql_insert_id(mysql);
15561   DIE_UNLESS(res == 0);
15562 
15563   /*
15564     Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
15565     sporadically
15566   */
15567   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15568   myquery(rc);
15569   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15570   myquery(rc);
15571   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15572   myquery(rc);
15573   res= mysql_insert_id(mysql);
15574   DIE_UNLESS(res == 0);
15575   rc= mysql_query(mysql, "drop table t2");
15576   myquery(rc);
15577 
15578   rc= mysql_query(mysql, "insert into t1 select null,'d'");
15579   myquery(rc);
15580   res= mysql_insert_id(mysql);
15581   DIE_UNLESS(res == 0);
15582   rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
15583   myquery(rc);
15584   res= mysql_insert_id(mysql);
15585   DIE_UNLESS(res == 300);
15586   rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
15587   myquery(rc);
15588   res= mysql_insert_id(mysql);
15589   /*
15590     Behaviour change: old code used to return 0; but 400 is consistent
15591     with INSERT VALUES, and the manual's section of mysql_insert_id() does not
15592     say INSERT SELECT should be different.
15593   */
15594   DIE_UNLESS(res == 400);
15595 
15596   /* table with auto_increment column */
15597   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255)) ENGINE = MyISAM");
15598   myquery(rc);
15599   rc= mysql_query(mysql, "insert into t2 values (1,'a')");
15600   myquery(rc);
15601   res= mysql_insert_id(mysql);
15602   DIE_UNLESS(res == 1);
15603   /* this should not influence next INSERT if it doesn't have auto_inc */
15604   rc= mysql_query(mysql, "insert into t1 values (10,'e')");
15605   myquery(rc);
15606   res= mysql_insert_id(mysql);
15607   DIE_UNLESS(res == 0);
15608 
15609   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15610   myquery(rc);
15611   res= mysql_insert_id(mysql);
15612   DIE_UNLESS(res == 2);
15613   rc= mysql_query(mysql, "insert into t2 select 5,'c'");
15614   myquery(rc);
15615   res= mysql_insert_id(mysql);
15616   /*
15617     Manual says that for multirow insert this should have been 5, but does not
15618     say for INSERT SELECT. This is a behaviour change: old code used to return
15619     0. We try to be consistent with INSERT VALUES.
15620   */
15621   DIE_UNLESS(res == 5);
15622   rc= mysql_query(mysql, "insert into t2 select null,'d'");
15623   myquery(rc);
15624   res= mysql_insert_id(mysql);
15625   DIE_UNLESS(res == 6);
15626   /* with more than one row */
15627   rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
15628   myquery(rc);
15629   res= mysql_insert_id(mysql);
15630   DIE_UNLESS(res == 11);
15631   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15632   myquery(rc);
15633   res= mysql_insert_id(mysql);
15634   /*
15635     Manual says that for multirow insert this should have been 13, but does
15636     not say for INSERT SELECT. This is a behaviour change: old code used to
15637     return 0. We try to be consistent with INSERT VALUES.
15638   */
15639   DIE_UNLESS(res == 13);
15640   rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
15641   myquery(rc);
15642   res= mysql_insert_id(mysql);
15643   DIE_UNLESS(res == 14);
15644   rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
15645   myquery(rc);
15646   res= mysql_insert_id(mysql);
15647   DIE_UNLESS(res == 16);
15648   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15649   myquery_r(rc);
15650   rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
15651   myquery(rc);
15652   res= mysql_insert_id(mysql);
15653   DIE_UNLESS(res == 0);
15654   rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
15655   myquery_r(rc);
15656   res= mysql_insert_id(mysql);
15657   DIE_UNLESS(res == 0);
15658   rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
15659   myquery(rc);
15660   res= mysql_insert_id(mysql);
15661   DIE_UNLESS(res == 0);
15662   /* mixing autogenerated and explicit values */
15663   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
15664   myquery_r(rc);
15665   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
15666   myquery_r(rc);
15667   rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
15668   myquery(rc);
15669   res= mysql_insert_id(mysql);
15670   /*
15671     according to the manual, this might be 20 or 300, but it looks like
15672     auto_increment column takes priority over last_insert_id().
15673   */
15674   DIE_UNLESS(res == 20);
15675   /* If first autogenerated number fails and 2nd works: */
15676   rc= mysql_query(mysql, "drop table t2");
15677   myquery(rc);
15678   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
15679                   "auto_increment, f2 varchar(255), unique (f2)) ENGINE = MyISAM");
15680   myquery(rc);
15681   rc= mysql_query(mysql, "insert into t2 values (null,'e')");
15682   res= mysql_insert_id(mysql);
15683   DIE_UNLESS(res == 1);
15684   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
15685   myquery(rc);
15686   res= mysql_insert_id(mysql);
15687   DIE_UNLESS(res == 2);
15688   /* If autogenerated fails and explicit works: */
15689   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
15690   myquery(rc);
15691   res= mysql_insert_id(mysql);
15692   /*
15693     Behaviour change: old code returned 3 (first autogenerated, even if it
15694     fails); we now return first successful autogenerated.
15695   */
15696   DIE_UNLESS(res == 13);
15697   /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
15698   rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
15699   myquery(rc);
15700   res= mysql_insert_id(mysql);
15701   DIE_UNLESS(res == 0);
15702   rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
15703   myquery(rc);
15704   res= mysql_insert_id(mysql);
15705   DIE_UNLESS(res == 0);
15706   rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
15707   myquery(rc);
15708   res= mysql_insert_id(mysql);
15709   DIE_UNLESS(res == 372);
15710   /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
15711   rc= mysql_query(mysql, "insert into t2 values (null,'g')");
15712   myquery(rc);
15713   res= mysql_insert_id(mysql);
15714   DIE_UNLESS(res == 15);
15715   rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
15716   myquery(rc);
15717   res= mysql_insert_id(mysql);
15718   DIE_UNLESS(res == 0);
15719   /*
15720     Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
15721     mysql_insert_id() returns the id of the row, instead of not being
15722     affected.
15723   */
15724   rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
15725                   "update f2=concat('we updated ',f2)");
15726   myquery(rc);
15727   res= mysql_insert_id(mysql);
15728   DIE_UNLESS(res == 15);
15729 
15730   rc= mysql_query(mysql, "drop table t1,t2");
15731   myquery(rc);
15732 }
15733 
15734 /*
15735   Test for bug#22028117: MYSQLCLIENT DOES NOT RETURN CORRECT
15736   MYSQL_INSERT_ID VIA DATABASE HANDLE
15737 */
15738 
test_bug22028117()15739 static void test_bug22028117()
15740 {
15741   my_ulonglong res;
15742   int rc;
15743   MYSQL_STMT *stmt;
15744 
15745   myheader("test_bug22028117");
15746 
15747   rc = mysql_query(mysql, "USE test");
15748   myquery(rc);
15749   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15750   myquery(rc);
15751   rc= mysql_query(mysql, "CREATE TABLE t1 ("
15752                          "f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT,"
15753                          "f2 VARCHAR(255))");
15754   myquery(rc);
15755   res= mysql_insert_id(mysql);
15756   DIE_UNLESS(res == 0);
15757 
15758   rc= mysql_query(mysql, "INSERT INTO t1 (f2) VALUES ('a')");
15759   myquery(rc);
15760   res= mysql_insert_id(mysql);
15761   DIE_UNLESS(res == 1);
15762 
15763   rc= mysql_query(mysql, "INSERT INTO t1 (f2) VALUES ('b')");
15764   myquery(rc);
15765   res= mysql_insert_id(mysql);
15766   DIE_UNLESS(res == 2);
15767 
15768   /* Make sure that the value of insert_id is not lost after SELECT */
15769   stmt= mysql_simple_prepare(mysql, "SELECT MAX(f1) FROM t1");
15770   check_stmt(stmt);
15771   rc= mysql_stmt_execute(stmt);
15772   check_execute(stmt, rc);
15773   rc= my_process_stmt_result(stmt);
15774   DIE_UNLESS(rc == 1);
15775   mysql_stmt_close(stmt);
15776 
15777   res= mysql_insert_id(mysql);
15778   DIE_UNLESS(res == 2);
15779 
15780   /* insert_id will be reset to 0 after a new table is created */
15781   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
15782   myquery(rc);
15783 
15784   rc= mysql_query(mysql, "CREATE TABLE t2 ("
15785                          "f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT,"
15786                          "f2 VARCHAR(255))");
15787   myquery(rc);
15788   res= mysql_insert_id(mysql);
15789   DIE_UNLESS(res == 0);
15790 
15791   /*
15792     mysql_insert_id() should return expr when the INSERT query contains
15793     last_insert_id(expr)
15794   */
15795   rc= mysql_query(mysql, "INSERT INTO t1 (f1) VALUES (last_insert_id(100))");
15796   myquery(rc);
15797   res= mysql_insert_id(mysql);
15798   DIE_UNLESS(res == 100);
15799 
15800   rc= mysql_query(mysql, "DROP TABLE t1,t2");
15801   myquery(rc);
15802 }
15803 
15804 /*
15805   Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
15806 */
15807 
test_bug20152()15808 static void test_bug20152()
15809 {
15810   MYSQL_BIND my_bind[1];
15811   MYSQL_STMT *stmt;
15812   MYSQL_TIME tm;
15813   int rc;
15814   const char *query= "INSERT INTO t1 (f1) VALUES (?)";
15815 
15816   myheader("test_bug20152");
15817 
15818   memset(my_bind, 0, sizeof(my_bind));
15819   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
15820   my_bind[0].buffer= (void*)&tm;
15821 
15822   tm.year = 2006;
15823   tm.month = 6;
15824   tm.day = 18;
15825   tm.hour = 14;
15826   tm.minute = 9;
15827   tm.second = 42;
15828 
15829   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15830   myquery(rc);
15831   rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)");
15832   myquery(rc);
15833 
15834   stmt= mysql_stmt_init(mysql);
15835   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
15836   check_execute(stmt, rc);
15837   rc= mysql_stmt_bind_param(stmt, my_bind);
15838   check_execute(stmt, rc);
15839   rc= mysql_stmt_execute(stmt);
15840   check_execute(stmt, rc);
15841   rc= mysql_stmt_close(stmt);
15842   check_execute(stmt, rc);
15843   rc= mysql_query(mysql, "DROP TABLE t1");
15844   myquery(rc);
15845 
15846   if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) {
15847     if (!opt_silent)
15848       printf("OK!");
15849   } else {
15850     printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second);
15851     DIE_UNLESS(0==1);
15852   }
15853 }
15854 
15855 /* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
15856 
test_bug15752()15857 static void test_bug15752()
15858 {
15859   MYSQL mysql_local;
15860   int rc, i;
15861   const int ITERATION_COUNT= 100;
15862   const char *query= "CALL p1()";
15863 
15864   myheader("test_bug15752");
15865 
15866   rc= mysql_query(mysql, "drop procedure if exists p1");
15867   myquery(rc);
15868   rc= mysql_query(mysql, "create procedure p1() select 1");
15869   myquery(rc);
15870 
15871   mysql_client_init(&mysql_local);
15872   if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
15873                            opt_password, current_db, opt_port,
15874                            opt_unix_socket,
15875                            CLIENT_MULTI_STATEMENTS))
15876   {
15877     printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
15878     DIE_UNLESS(0);
15879   }
15880   rc= mysql_real_query(&mysql_local, query, (ulong)strlen(query));
15881   myquery(rc);
15882   mysql_free_result(mysql_store_result(&mysql_local));
15883 
15884   rc= mysql_real_query(&mysql_local, query, (ulong)strlen(query));
15885   DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
15886 
15887   if (! opt_silent)
15888     printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
15889 
15890   /* Check some other commands too */
15891 
15892   DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15893   mysql_free_result(mysql_store_result(&mysql_local));
15894   DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15895 
15896   /* The second problem is not reproducible: add the test case */
15897   for (i = 0; i < ITERATION_COUNT; i++)
15898   {
15899     if (mysql_real_query(&mysql_local, query, (ulong)strlen(query)))
15900     {
15901       printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
15902       break;
15903     }
15904     mysql_free_result(mysql_store_result(&mysql_local));
15905     DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15906     mysql_free_result(mysql_store_result(&mysql_local));
15907     DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15908 
15909   }
15910   mysql_close(&mysql_local);
15911   rc= mysql_query(mysql, "drop procedure p1");
15912   myquery(rc);
15913 }
15914 
15915 /*
15916   Bug#21206: memory corruption when too many cursors are opened at once
15917 
15918   Memory corruption happens when more than 1024 cursors are open
15919   simultaneously.
15920 */
test_bug21206()15921 static void test_bug21206()
15922 {
15923   const size_t cursor_count= 1025;
15924 
15925   const char *create_table[]=
15926   {
15927     "DROP TABLE IF EXISTS t1",
15928     "CREATE TABLE t1 (i INT)",
15929     "INSERT INTO t1 VALUES (1), (2), (3)"
15930   };
15931   const char *query= "SELECT * FROM t1";
15932 
15933   Stmt_fetch *fetch_array=
15934     (Stmt_fetch*) calloc(cursor_count, sizeof(Stmt_fetch));
15935 
15936   Stmt_fetch *fetch;
15937 
15938   DBUG_ENTER("test_bug21206");
15939   myheader("test_bug21206");
15940 
15941   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
15942 
15943   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15944   {
15945     /* Init will exit(1) in case of error */
15946     stmt_fetch_init(fetch, fetch - fetch_array, query);
15947   }
15948 
15949   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15950     stmt_fetch_close(fetch);
15951 
15952   free(fetch_array);
15953 
15954   DBUG_VOID_RETURN;
15955 }
15956 
15957 /*
15958   Ensure we execute the status code while testing
15959 */
15960 
test_status()15961 static void test_status()
15962 {
15963   const char *status;
15964   DBUG_ENTER("test_status");
15965   myheader("test_status");
15966 
15967   if (!(status= mysql_stat(mysql)))
15968   {
15969     myerror("mysql_stat failed");                 /* purecov: inspected */
15970     die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
15971   }
15972   DBUG_VOID_RETURN;
15973 }
15974 
15975 /*
15976   Bug#21726: Incorrect result with multiple invocations of
15977   LAST_INSERT_ID
15978 
15979   Test that client gets updated value of insert_id on UPDATE that uses
15980   LAST_INSERT_ID(expr).
15981   select_query added to test for bug
15982     #26921 Problem in mysql_insert_id() Embedded C API function
15983 */
test_bug21726()15984 static void test_bug21726()
15985 {
15986   const char *create_table[]=
15987   {
15988     "DROP TABLE IF EXISTS t1",
15989     "CREATE TABLE t1 (i INT)",
15990     "INSERT INTO t1 VALUES (1)",
15991   };
15992   const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
15993   int rc;
15994   my_ulonglong insert_id;
15995   const char *select_query= "SELECT * FROM t1";
15996   MYSQL_RES  *result;
15997 
15998   DBUG_ENTER("test_bug21726");
15999   myheader("test_bug21726");
16000 
16001   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
16002 
16003   rc= mysql_query(mysql, update_query);
16004   myquery(rc);
16005   insert_id= mysql_insert_id(mysql);
16006   DIE_UNLESS(insert_id == 2);
16007 
16008   rc= mysql_query(mysql, update_query);
16009   myquery(rc);
16010   insert_id= mysql_insert_id(mysql);
16011   DIE_UNLESS(insert_id == 3);
16012 
16013   rc= mysql_query(mysql, select_query);
16014   myquery(rc);
16015   insert_id= mysql_insert_id(mysql);
16016   DIE_UNLESS(insert_id == 3);
16017   result= mysql_store_result(mysql);
16018   mysql_free_result(result);
16019 
16020   DBUG_VOID_RETURN;
16021 }
16022 
16023 
16024 /*
16025   BUG#23383: mysql_affected_rows() returns different values than
16026   mysql_stmt_affected_rows()
16027 
16028   Test that both mysql_affected_rows() and mysql_stmt_affected_rows()
16029   return -1 on error, 0 when no rows were affected, and (positive) row
16030   count when some rows were affected.
16031 */
test_bug23383()16032 static void test_bug23383()
16033 {
16034   const char *insert_query= "INSERT INTO t1 VALUES (1), (2)";
16035   const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3";
16036   MYSQL_STMT *stmt;
16037   my_ulonglong row_count;
16038   int rc;
16039 
16040   DBUG_ENTER("test_bug23383");
16041   myheader("test_bug23383");
16042 
16043   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16044   myquery(rc);
16045 
16046   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)");
16047   myquery(rc);
16048 
16049   rc= mysql_query(mysql, insert_query);
16050   myquery(rc);
16051   row_count= mysql_affected_rows(mysql);
16052   DIE_UNLESS(row_count == 2);
16053 
16054   rc= mysql_query(mysql, insert_query);
16055   DIE_UNLESS(rc != 0);
16056   row_count= mysql_affected_rows(mysql);
16057   DIE_UNLESS(row_count == (my_ulonglong)-1);
16058 
16059   rc= mysql_query(mysql, update_query);
16060   myquery(rc);
16061   row_count= mysql_affected_rows(mysql);
16062   DIE_UNLESS(row_count == 0);
16063 
16064   rc= mysql_query(mysql, "DELETE FROM t1");
16065   myquery(rc);
16066 
16067   stmt= mysql_stmt_init(mysql);
16068   DIE_UNLESS(stmt != 0);
16069 
16070   rc= mysql_stmt_prepare(stmt, insert_query, (ulong)strlen(insert_query));
16071   check_execute(stmt, rc);
16072 
16073   rc= mysql_stmt_execute(stmt);
16074   check_execute(stmt, rc);
16075   row_count= mysql_stmt_affected_rows(stmt);
16076   DIE_UNLESS(row_count == 2);
16077 
16078   rc= mysql_stmt_execute(stmt);
16079   DIE_UNLESS(rc != 0);
16080   row_count= mysql_stmt_affected_rows(stmt);
16081   DIE_UNLESS(row_count == (my_ulonglong)-1);
16082 
16083   rc= mysql_stmt_prepare(stmt, update_query, (ulong)strlen(update_query));
16084   check_execute(stmt, rc);
16085 
16086   rc= mysql_stmt_execute(stmt);
16087   check_execute(stmt, rc);
16088   row_count= mysql_stmt_affected_rows(stmt);
16089   DIE_UNLESS(row_count == 0);
16090 
16091   rc= mysql_stmt_close(stmt);
16092   check_execute(stmt, rc);
16093 
16094   rc= mysql_query(mysql, "DROP TABLE t1");
16095   myquery(rc);
16096 
16097   DBUG_VOID_RETURN;
16098 }
16099 
16100 
16101 /*
16102   BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for
16103   expression cols
16104 
16105   Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set
16106   to either expression or its alias, and db, org_table, table,
16107   org_name fields are empty strings.
16108 */
test_bug21635()16109 static void test_bug21635()
16110 {
16111   const char *expr[]=
16112   {
16113     "MIN(i)", "MIN(i)",
16114     "MIN(i) AS A1", "A1",
16115     "MAX(i)", "MAX(i)",
16116     "MAX(i) AS A2", "A2",
16117     "COUNT(i)", "COUNT(i)",
16118     "COUNT(i) AS A3", "A3",
16119   };
16120   char query[MAX_TEST_QUERY_LENGTH];
16121   char *query_end;
16122   MYSQL_RES *result;
16123   MYSQL_FIELD *field;
16124   unsigned int field_count, i, j;
16125   int rc;
16126 
16127   DBUG_ENTER("test_bug21635");
16128   myheader("test_bug21635");
16129 
16130   query_end= strxmov(query, "SELECT ", NullS);
16131   for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i)
16132     query_end= strxmov(query_end, expr[i * 2], ", ", NullS);
16133   query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS);
16134   DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH);
16135 
16136   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16137   myquery(rc);
16138   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)");
16139   myquery(rc);
16140   /*
16141     We need this loop to ensure correct behavior with both constant and
16142     non-constant tables.
16143   */
16144   for (j= 0; j < 2 ; j++)
16145   {
16146     rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16147     myquery(rc);
16148 
16149     rc= mysql_real_query(mysql, query, (ulong)(query_end - query));
16150     myquery(rc);
16151 
16152     result= mysql_use_result(mysql);
16153     DIE_UNLESS(result);
16154 
16155   field_count= mysql_field_count(mysql);
16156   for (i= 0; i < field_count; ++i)
16157   {
16158     field= mysql_fetch_field_direct(result, i);
16159     if (!opt_silent)
16160       if (!opt_silent)
16161         printf("%s -> %s ... ", expr[i * 2], field->name);
16162     fflush(stdout);
16163     DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
16164                field->table[0] == 0 && field->org_name[0] == 0);
16165     DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
16166     if (!opt_silent)
16167       if (!opt_silent)
16168         puts("OK");
16169   }
16170 
16171     mysql_free_result(result);
16172   }
16173   rc= mysql_query(mysql, "DROP TABLE t1");
16174   myquery(rc);
16175 
16176   DBUG_VOID_RETURN;
16177 }
16178 
16179 /*
16180   Bug#24179 "select b into $var" fails with --cursor_protocol"
16181   The failure is correct, check that the returned message is meaningful.
16182 */
16183 
test_bug24179()16184 static void test_bug24179()
16185 {
16186   int rc;
16187   MYSQL_STMT *stmt;
16188 
16189   DBUG_ENTER("test_bug24179");
16190   myheader("test_bug24179");
16191 
16192   stmt= open_cursor("select 1 into @a");
16193   rc= mysql_stmt_execute(stmt);
16194   DIE_UNLESS(rc);
16195   if (!opt_silent)
16196   {
16197     printf("Got error (as expected): %d %s\n",
16198            mysql_stmt_errno(stmt),
16199            mysql_stmt_error(stmt));
16200   }
16201   DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
16202   mysql_stmt_close(stmt);
16203 
16204   DBUG_VOID_RETURN;
16205 }
16206 
16207 
16208 /**
16209   Bug#32265 Server returns different metadata if prepared statement is used
16210 */
16211 
test_bug32265()16212 static void test_bug32265()
16213 {
16214   int rc;
16215   MYSQL_STMT *stmt;
16216   MYSQL_FIELD *field;
16217   MYSQL_RES *metadata;
16218 
16219   DBUG_ENTER("test_bug32265");
16220   myheader("test_bug32265");
16221 
16222   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16223   myquery(rc);
16224   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
16225   myquery(rc);
16226   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16227   myquery(rc);
16228   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
16229   myquery(rc);
16230 
16231   stmt= open_cursor("SELECT * FROM t1");
16232   rc= mysql_stmt_execute(stmt);
16233   check_execute(stmt, rc);
16234 
16235   metadata= mysql_stmt_result_metadata(stmt);
16236   field= mysql_fetch_field(metadata);
16237   DIE_UNLESS(field);
16238   DIE_UNLESS(strcmp(field->table, "t1") == 0);
16239   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16240   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16241   mysql_free_result(metadata);
16242   mysql_stmt_close(stmt);
16243 
16244   stmt= open_cursor("SELECT a '' FROM t1 ``");
16245   rc= mysql_stmt_execute(stmt);
16246   check_execute(stmt, rc);
16247 
16248   metadata= mysql_stmt_result_metadata(stmt);
16249   field= mysql_fetch_field(metadata);
16250   DIE_UNLESS(strcmp(field->table, "") == 0);
16251   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16252   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16253   mysql_free_result(metadata);
16254   mysql_stmt_close(stmt);
16255 
16256   stmt= open_cursor("SELECT a '' FROM t1 ``");
16257   rc= mysql_stmt_execute(stmt);
16258   check_execute(stmt, rc);
16259 
16260   metadata= mysql_stmt_result_metadata(stmt);
16261   field= mysql_fetch_field(metadata);
16262   DIE_UNLESS(strcmp(field->table, "") == 0);
16263   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16264   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16265   mysql_free_result(metadata);
16266   mysql_stmt_close(stmt);
16267 
16268   stmt= open_cursor("SELECT * FROM v1");
16269   rc= mysql_stmt_execute(stmt);
16270   check_execute(stmt, rc);
16271 
16272   metadata= mysql_stmt_result_metadata(stmt);
16273   field= mysql_fetch_field(metadata);
16274   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16275   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16276   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16277   mysql_free_result(metadata);
16278   mysql_stmt_close(stmt);
16279 
16280   stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
16281   rc= mysql_stmt_execute(stmt);
16282   check_execute(stmt, rc);
16283 
16284   metadata= mysql_stmt_result_metadata(stmt);
16285   field= mysql_fetch_field(metadata);
16286   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16287   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16288   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16289   mysql_free_result(metadata);
16290   mysql_stmt_close(stmt);
16291 
16292   rc= mysql_query(mysql, "DROP VIEW v1");
16293   myquery(rc);
16294   rc= mysql_query(mysql, "DROP TABLE t1");
16295   myquery(rc);
16296 
16297   DBUG_VOID_RETURN;
16298 }
16299 
16300 /*
16301   Bug#28075 "COM_DEBUG crashes mysqld"
16302 */
16303 
test_bug28075()16304 static void test_bug28075()
16305 {
16306   int rc;
16307 
16308   DBUG_ENTER("test_bug28075");
16309   myheader("test_bug28075");
16310 
16311   rc= mysql_dump_debug_info(mysql);
16312   DIE_UNLESS(rc == 0);
16313 
16314   rc= mysql_ping(mysql);
16315   DIE_UNLESS(rc == 0);
16316 
16317   DBUG_VOID_RETURN;
16318 }
16319 
16320 
16321 /*
16322   Bug#27876 (SF with cyrillic variable name fails during execution (regression))
16323 */
16324 
test_bug27876()16325 static void test_bug27876()
16326 {
16327   int rc;
16328   MYSQL_RES *result;
16329 
16330   uchar utf8_func[] =
16331   {
16332     0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
16333     0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
16334     0xd0, 0xb0,
16335     0x00
16336   };
16337 
16338   uchar utf8_param[] =
16339   {
16340     0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
16341     0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
16342     0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
16343     0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
16344     0x00
16345   };
16346 
16347   char query[500];
16348 
16349   DBUG_ENTER("test_bug27876");
16350   myheader("test_bug27876");
16351 
16352   rc= mysql_query(mysql, "set names utf8");
16353   myquery(rc);
16354 
16355   rc= mysql_query(mysql, "select version()");
16356   myquery(rc);
16357   result= mysql_store_result(mysql);
16358   mytest(result);
16359   mysql_free_result(result);
16360 
16361   sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
16362   rc= mysql_query(mysql, query);
16363   myquery(rc);
16364 
16365   sprintf(query,
16366           "CREATE FUNCTION %s( %s VARCHAR(25))"
16367           " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
16368           (char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
16369   rc= mysql_query(mysql, query);
16370   myquery(rc);
16371   sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
16372   rc= mysql_query(mysql, query);
16373   myquery(rc);
16374   result= mysql_store_result(mysql);
16375   mytest(result);
16376   mysql_free_result(result);
16377 
16378   sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
16379   rc= mysql_query(mysql, query);
16380   myquery(rc);
16381 
16382   rc= mysql_query(mysql, "set names default");
16383   myquery(rc);
16384   DBUG_VOID_RETURN;
16385 }
16386 
16387 
16388 /*
16389   Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
16390   flag is set.
16391 */
16392 
test_bug28505()16393 static void test_bug28505()
16394 {
16395   my_ulonglong res;
16396 
16397   myquery(mysql_query(mysql, "drop table if exists t1"));
16398   myquery(mysql_query(mysql, "create table t1(f1 int primary key)"));
16399   myquery(mysql_query(mysql, "insert into t1 values(1)"));
16400   myquery(mysql_query(mysql,
16401                   "insert into t1 values(1) on duplicate key update f1=1"));
16402   res= mysql_affected_rows(mysql);
16403   DIE_UNLESS(!res);
16404   myquery(mysql_query(mysql, "drop table t1"));
16405 }
16406 
16407 
16408 /*
16409   Bug#28934: server crash when receiving malformed com_execute packets
16410 */
16411 
test_bug28934()16412 static void test_bug28934()
16413 {
16414   my_bool error= 0;
16415   MYSQL_BIND bind[5];
16416   MYSQL_STMT *stmt;
16417   int cnt;
16418 
16419   myquery(mysql_query(mysql, "drop table if exists t1"));
16420   myquery(mysql_query(mysql, "create table t1(id int)"));
16421 
16422   myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)"));
16423   stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)");
16424   check_stmt(stmt);
16425 
16426   memset (&bind, 0, sizeof (bind));
16427   for (cnt= 0; cnt < 5; cnt++)
16428   {
16429     bind[cnt].buffer_type= MYSQL_TYPE_LONG;
16430     bind[cnt].buffer= (char*)&cnt;
16431     bind[cnt].buffer_length= 0;
16432   }
16433   myquery(mysql_stmt_bind_param(stmt, bind));
16434 
16435   stmt->param_count=2;
16436   error= mysql_stmt_execute(stmt);
16437   DIE_UNLESS(error != 0);
16438   myerror(NULL);
16439   mysql_stmt_close(stmt);
16440 
16441   myquery(mysql_query(mysql, "drop table t1"));
16442 }
16443 
16444 /*
16445   Test mysql_change_user() C API and COM_CHANGE_USER
16446 */
16447 
reconnect(MYSQL ** mysql)16448 static void reconnect(MYSQL **mysql)
16449 {
16450   mysql_close(*mysql);
16451   *mysql= mysql_client_init(NULL);
16452   DIE_UNLESS(*mysql != 0);
16453   *mysql= mysql_real_connect(*mysql, opt_host, opt_user,
16454                          opt_password, current_db, opt_port,
16455                          opt_unix_socket, 0);
16456   DIE_UNLESS(*mysql != 0);
16457 }
16458 
16459 
test_change_user()16460 static void test_change_user()
16461 {
16462   char buff[256];
16463   const char *user_pw= "mysqltest_pw";
16464   const char *user_no_pw= "mysqltest_no_pw";
16465   const char *pw= "password";
16466   const char *db= "mysqltest_user_test_database";
16467   int rc;
16468   MYSQL *l_mysql;
16469 
16470   DBUG_ENTER("test_change_user");
16471   myheader("test_change_user");
16472 
16473   l_mysql= mysql_client_init(NULL);
16474   DIE_UNLESS(l_mysql != NULL);
16475 
16476   l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
16477                          opt_password, current_db, opt_port,
16478                          opt_unix_socket, 0);
16479   DIE_UNLESS(l_mysql != 0);
16480 
16481   rc = mysql_query(l_mysql, "set sql_mode=(select replace(@@sql_mode,'NO_AUTO_CREATE_USER',''))");
16482   myquery2(l_mysql, rc);
16483 
16484   /* Prepare environment */
16485   sprintf(buff, "drop database if exists %s", db);
16486   rc= mysql_query(l_mysql, buff);
16487   myquery2(l_mysql, rc);
16488 
16489   sprintf(buff, "create database %s", db);
16490   rc= mysql_query(l_mysql, buff);
16491   myquery2(l_mysql, rc);
16492 
16493   sprintf(buff,
16494           "grant select on %s.* to %s@'%%' identified by '%s'",
16495           db,
16496           user_pw,
16497           pw);
16498   rc= mysql_query(l_mysql, buff);
16499   myquery2(l_mysql, rc);
16500 
16501   sprintf(buff,
16502           "grant select on %s.* to %s@'localhost' identified by '%s'",
16503           db,
16504           user_pw,
16505           pw);
16506   rc= mysql_query(l_mysql, buff);
16507   myquery2(l_mysql, rc);
16508 
16509   sprintf(buff,
16510           "grant select on %s.* to %s@'%%'",
16511           db,
16512           user_no_pw);
16513   rc= mysql_query(l_mysql, buff);
16514   myquery2(l_mysql, rc);
16515 
16516   sprintf(buff,
16517           "grant select on %s.* to %s@'localhost'",
16518           db,
16519           user_no_pw);
16520   rc= mysql_query(l_mysql, buff);
16521   myquery2(l_mysql, rc);
16522 
16523   /* Try some combinations */
16524   rc= mysql_change_user(l_mysql, NULL, NULL, NULL);
16525   DIE_UNLESS(rc);
16526   if (! opt_silent)
16527     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16528   reconnect(&l_mysql);
16529 
16530   rc= mysql_change_user(l_mysql, "", NULL, NULL);
16531   DIE_UNLESS(rc);
16532   if (! opt_silent)
16533     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16534   reconnect(&l_mysql);
16535 
16536   rc= mysql_change_user(l_mysql, "", "", NULL);
16537   DIE_UNLESS(rc);
16538   if (! opt_silent)
16539     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16540   reconnect(&l_mysql);
16541 
16542 
16543   rc= mysql_change_user(l_mysql, "", "", "");
16544   DIE_UNLESS(rc);
16545   if (! opt_silent)
16546     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16547   reconnect(&l_mysql);
16548 
16549   rc= mysql_change_user(l_mysql, NULL, "", "");
16550   DIE_UNLESS(rc);
16551   if (! opt_silent)
16552     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16553   reconnect(&l_mysql);
16554 
16555 
16556   rc= mysql_change_user(l_mysql, NULL, NULL, "");
16557   DIE_UNLESS(rc);
16558   if (! opt_silent)
16559     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16560   reconnect(&l_mysql);
16561 
16562   rc= mysql_change_user(l_mysql, "", NULL, "");
16563   DIE_UNLESS(rc);
16564   if (! opt_silent)
16565     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16566   reconnect(&l_mysql);
16567 
16568   rc= mysql_change_user(l_mysql, user_pw, NULL, "");
16569   DIE_UNLESS(rc);
16570   if (! opt_silent)
16571     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16572   reconnect(&l_mysql);
16573 
16574   rc= mysql_change_user(l_mysql, user_pw, "", "");
16575   DIE_UNLESS(rc);
16576   if (! opt_silent)
16577     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16578   reconnect(&l_mysql);
16579 
16580   rc= mysql_change_user(l_mysql, user_pw, "", NULL);
16581   DIE_UNLESS(rc);
16582   if (! opt_silent)
16583     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16584   reconnect(&l_mysql);
16585 
16586   rc= mysql_change_user(l_mysql, user_pw, NULL, NULL);
16587   DIE_UNLESS(rc);
16588   if (! opt_silent)
16589     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16590   reconnect(&l_mysql);
16591 
16592   rc= mysql_change_user(l_mysql, user_pw, "", db);
16593   DIE_UNLESS(rc);
16594   if (! opt_silent)
16595     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16596   reconnect(&l_mysql);
16597 
16598   rc= mysql_change_user(l_mysql, user_pw, NULL, db);
16599   DIE_UNLESS(rc);
16600   if (! opt_silent)
16601     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16602   reconnect(&l_mysql);
16603 
16604   rc= mysql_change_user(l_mysql, user_pw, pw, db);
16605   myquery2(l_mysql, rc);
16606 
16607   rc= mysql_change_user(l_mysql, user_pw, pw, NULL);
16608   myquery2(l_mysql, rc);
16609 
16610   rc= mysql_change_user(l_mysql, user_pw, pw, "");
16611   myquery2(l_mysql, rc);
16612 
16613   rc= mysql_change_user(l_mysql, user_no_pw, pw, db);
16614   DIE_UNLESS(rc);
16615   if (! opt_silent)
16616     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16617 
16618   rc= mysql_change_user(l_mysql, user_no_pw, pw, "");
16619   DIE_UNLESS(rc);
16620   if (! opt_silent)
16621     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16622   reconnect(&l_mysql);
16623 
16624   rc= mysql_change_user(l_mysql, user_no_pw, pw, NULL);
16625   DIE_UNLESS(rc);
16626   if (! opt_silent)
16627     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16628   reconnect(&l_mysql);
16629 
16630   rc= mysql_change_user(l_mysql, user_no_pw, "", NULL);
16631   myquery2(l_mysql, rc);
16632 
16633   rc= mysql_change_user(l_mysql, user_no_pw, "", "");
16634   myquery2(l_mysql, rc);
16635 
16636   rc= mysql_change_user(l_mysql, user_no_pw, "", db);
16637   myquery2(l_mysql, rc);
16638 
16639   rc= mysql_change_user(l_mysql, user_no_pw, NULL, db);
16640   myquery2(l_mysql, rc);
16641 
16642   rc= mysql_change_user(l_mysql, "", pw, db);
16643   DIE_UNLESS(rc);
16644   if (! opt_silent)
16645     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16646   reconnect(&l_mysql);
16647 
16648   rc= mysql_change_user(l_mysql, "", pw, "");
16649   DIE_UNLESS(rc);
16650   if (! opt_silent)
16651     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16652   reconnect(&l_mysql);
16653 
16654   rc= mysql_change_user(l_mysql, "", pw, NULL);
16655   DIE_UNLESS(rc);
16656   if (! opt_silent)
16657     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16658 
16659   rc= mysql_change_user(l_mysql, NULL, pw, NULL);
16660   DIE_UNLESS(rc);
16661   if (! opt_silent)
16662     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16663   reconnect(&l_mysql);
16664 
16665   rc= mysql_change_user(l_mysql, NULL, NULL, db);
16666   DIE_UNLESS(rc);
16667   if (! opt_silent)
16668     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16669   reconnect(&l_mysql);
16670 
16671   rc= mysql_change_user(l_mysql, NULL, "", db);
16672   DIE_UNLESS(rc);
16673   if (! opt_silent)
16674     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16675   reconnect(&l_mysql);
16676 
16677   rc= mysql_change_user(l_mysql, "", "", db);
16678   DIE_UNLESS(rc);
16679   if (! opt_silent)
16680     printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16681   reconnect(&l_mysql);
16682 
16683   /* Cleanup the environment */
16684 
16685   mysql_close(l_mysql);
16686 
16687   sprintf(buff, "drop database %s", db);
16688   rc= mysql_query(mysql, buff);
16689   myquery(rc);
16690 
16691   sprintf(buff, "drop user %s@'%%'", user_pw);
16692   rc= mysql_query(mysql, buff);
16693   myquery(rc);
16694 
16695   sprintf(buff, "drop user %s@'%%'", user_no_pw);
16696   rc= mysql_query(mysql, buff);
16697   myquery(rc);
16698 
16699   sprintf(buff, "drop user %s@'localhost'", user_pw);
16700   rc= mysql_query(mysql, buff);
16701   myquery(rc);
16702 
16703   sprintf(buff, "drop user %s@'localhost'", user_no_pw);
16704   rc= mysql_query(mysql, buff);
16705   myquery(rc);
16706 
16707   DBUG_VOID_RETURN;
16708 }
16709 
16710 /*
16711   Bug#27592 (stack overrun when storing datetime value using prepared statements)
16712 */
16713 
test_bug27592()16714 static void test_bug27592()
16715 {
16716   const int NUM_ITERATIONS= 40;
16717   int i;
16718   int rc;
16719   MYSQL_STMT *stmt= NULL;
16720   MYSQL_BIND bind[1];
16721   MYSQL_TIME time_val;
16722 
16723   DBUG_ENTER("test_bug27592");
16724   myheader("test_bug27592");
16725 
16726   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16727   mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
16728 
16729   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
16730   DIE_UNLESS(stmt);
16731 
16732   memset(bind, 0, sizeof(bind));
16733 
16734   bind[0].buffer_type= MYSQL_TYPE_DATETIME;
16735   bind[0].buffer= (char *) &time_val;
16736   bind[0].length= NULL;
16737 
16738   for (i= 0; i < NUM_ITERATIONS; i++)
16739   {
16740     time_val.year= 2007;
16741     time_val.month= 6;
16742     time_val.day= 7;
16743     time_val.hour= 18;
16744     time_val.minute= 41;
16745     time_val.second= 3;
16746 
16747     time_val.second_part=0;
16748     time_val.neg=0;
16749 
16750     rc= mysql_stmt_bind_param(stmt, bind);
16751     check_execute(stmt, rc);
16752 
16753     rc= mysql_stmt_execute(stmt);
16754     check_execute(stmt, rc);
16755   }
16756 
16757   mysql_stmt_close(stmt);
16758 
16759   DBUG_VOID_RETURN;
16760 }
16761 
16762 /*
16763   Bug#29687 mysql_stmt_store_result memory leak in libmysqld
16764 */
16765 
test_bug29687()16766 static void test_bug29687()
16767 {
16768   const int NUM_ITERATIONS= 40;
16769   int i;
16770   int rc;
16771   MYSQL_STMT *stmt= NULL;
16772 
16773   DBUG_ENTER("test_bug29687");
16774   myheader("test_bug29687");
16775 
16776   stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2");
16777   DIE_UNLESS(stmt);
16778 
16779   for (i= 0; i < NUM_ITERATIONS; i++)
16780   {
16781     rc= mysql_stmt_execute(stmt);
16782     check_execute(stmt, rc);
16783     mysql_stmt_store_result(stmt);
16784     while (mysql_stmt_fetch(stmt)==0);
16785     mysql_stmt_free_result(stmt);
16786   }
16787 
16788   mysql_stmt_close(stmt);
16789   DBUG_VOID_RETURN;
16790 }
16791 
16792 
16793 /*
16794   Bug #29692  	Single row inserts can incorrectly report a huge number of
16795   row insertions
16796 */
16797 
test_bug29692()16798 static void test_bug29692()
16799 {
16800   MYSQL* conn;
16801 
16802   if (!(conn= mysql_client_init(NULL)))
16803   {
16804     myerror("test_bug29692 init failed");
16805     exit(1);
16806   }
16807 
16808   if (!(mysql_real_connect(conn, opt_host, opt_user,
16809                            opt_password, opt_db ? opt_db:"test", opt_port,
16810                            opt_unix_socket,  CLIENT_FOUND_ROWS)))
16811   {
16812     myerror("test_bug29692 connection failed");
16813     mysql_close(mysql);
16814     exit(1);
16815   }
16816   myquery(mysql_query(conn, "drop table if exists t1"));
16817   myquery(mysql_query(conn, "create table t1(f1 int)"));
16818   myquery(mysql_query(conn, "insert into t1 values(1)"));
16819   DIE_UNLESS(1 == mysql_affected_rows(conn));
16820   myquery(mysql_query(conn, "drop table t1"));
16821   mysql_close(conn);
16822 }
16823 
16824 /**
16825   Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
16826 */
16827 
test_bug29306()16828 static void test_bug29306()
16829 {
16830   MYSQL_FIELD *field;
16831   int rc;
16832   MYSQL_RES *res;
16833 
16834   DBUG_ENTER("test_bug29306");
16835   myheader("test_bug29306");
16836 
16837   rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
16838   myquery(rc);
16839   rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
16840   myquery(rc);
16841   rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
16842   myquery(rc);
16843   rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
16844   myquery(rc);
16845   rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
16846   myquery(rc);
16847 
16848   /* Checking the view */
16849   res= mysql_list_fields(mysql, "view17557", NULL);
16850   while ((field= mysql_fetch_field(res)))
16851   {
16852     if (! opt_silent)
16853     {
16854       printf("field name %s\n", field->name);
16855       printf("field table %s\n", field->table);
16856       printf("field decimals %d\n", field->decimals);
16857       if (field->decimals < 1)
16858         printf("Error! No decimals! \n");
16859       printf("\n\n");
16860     }
16861     DIE_UNLESS(field->decimals == 1);
16862   }
16863   mysql_free_result(res);
16864 
16865   rc= mysql_query(mysql, "DROP TABLE tab17557");
16866   myquery(rc);
16867   rc= mysql_query(mysql, "DROP VIEW view17557");
16868   myquery(rc);
16869 
16870   DBUG_VOID_RETURN;
16871 }
16872 /*
16873   Bug#30472: libmysql doesn't reset charset, insert_id after succ.
16874   mysql_change_user() call row insertions.
16875 */
16876 
bug30472_retrieve_charset_info(MYSQL * con,char * character_set_name,char * character_set_client,char * character_set_results,char * collation_connection)16877 static void bug30472_retrieve_charset_info(MYSQL *con,
16878                                            char *character_set_name,
16879                                            char *character_set_client,
16880                                            char *character_set_results,
16881                                            char *collation_connection)
16882 {
16883   MYSQL_RES *rs;
16884   MYSQL_ROW row;
16885 
16886   /* Get the cached client character set name. */
16887 
16888   strcpy(character_set_name, mysql_character_set_name(con));
16889 
16890   /* Retrieve server character set information. */
16891 
16892   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
16893   DIE_UNLESS(rs= mysql_store_result(con));
16894   DIE_UNLESS(row= mysql_fetch_row(rs));
16895   strcpy(character_set_client, row[1]);
16896   mysql_free_result(rs);
16897 
16898   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
16899   DIE_UNLESS(rs= mysql_store_result(con));
16900   DIE_UNLESS(row= mysql_fetch_row(rs));
16901   strcpy(character_set_results, row[1]);
16902   mysql_free_result(rs);
16903 
16904   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
16905   DIE_UNLESS(rs= mysql_store_result(con));
16906   DIE_UNLESS(row= mysql_fetch_row(rs));
16907   strcpy(collation_connection, row[1]);
16908   mysql_free_result(rs);
16909 }
16910 
test_bug30472()16911 static void test_bug30472()
16912 {
16913   MYSQL con;
16914 
16915   char character_set_name_1[MY_CS_NAME_SIZE];
16916   char character_set_client_1[MY_CS_NAME_SIZE];
16917   char character_set_results_1[MY_CS_NAME_SIZE];
16918   char collation_connnection_1[MY_CS_NAME_SIZE];
16919 
16920   char character_set_name_2[MY_CS_NAME_SIZE];
16921   char character_set_client_2[MY_CS_NAME_SIZE];
16922   char character_set_results_2[MY_CS_NAME_SIZE];
16923   char collation_connnection_2[MY_CS_NAME_SIZE];
16924 
16925   char character_set_name_3[MY_CS_NAME_SIZE];
16926   char character_set_client_3[MY_CS_NAME_SIZE];
16927   char character_set_results_3[MY_CS_NAME_SIZE];
16928   char collation_connnection_3[MY_CS_NAME_SIZE];
16929 
16930   char character_set_name_4[MY_CS_NAME_SIZE];
16931   char character_set_client_4[MY_CS_NAME_SIZE];
16932   char character_set_results_4[MY_CS_NAME_SIZE];
16933   char collation_connnection_4[MY_CS_NAME_SIZE];
16934 
16935   /* Create a new connection. */
16936 
16937   DIE_UNLESS(mysql_client_init(&con));
16938 
16939   DIE_UNLESS(mysql_real_connect(&con,
16940                                 opt_host,
16941                                 opt_user,
16942                                 opt_password,
16943                                 opt_db ? opt_db : "test",
16944                                 opt_port,
16945                                 opt_unix_socket,
16946                                 CLIENT_FOUND_ROWS));
16947 
16948   /* Retrieve character set information. */
16949 
16950   bug30472_retrieve_charset_info(&con,
16951                                  character_set_name_1,
16952                                  character_set_client_1,
16953                                  character_set_results_1,
16954                                  collation_connnection_1);
16955 
16956   /* Switch client character set. */
16957 
16958   DIE_IF(mysql_set_character_set(&con, "utf8"));
16959 
16960   /* Retrieve character set information. */
16961 
16962   bug30472_retrieve_charset_info(&con,
16963                                  character_set_name_2,
16964                                  character_set_client_2,
16965                                  character_set_results_2,
16966                                  collation_connnection_2);
16967 
16968   /*
16969     Check that
16970       1) character set has been switched and
16971       2) new character set is different from the original one.
16972   */
16973 
16974   DIE_UNLESS(strcmp(character_set_name_2, "utf8") == 0);
16975   DIE_UNLESS(strcmp(character_set_client_2, "utf8") == 0);
16976   DIE_UNLESS(strcmp(character_set_results_2, "utf8") == 0);
16977   DIE_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0);
16978 
16979   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
16980   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
16981   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
16982   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
16983 
16984   /* Call mysql_change_user() with the same username, password, database. */
16985 
16986   DIE_IF(mysql_change_user(&con,
16987                            opt_user,
16988                            opt_password,
16989                            opt_db ? opt_db : "test"));
16990 
16991   /* Retrieve character set information. */
16992 
16993   bug30472_retrieve_charset_info(&con,
16994                                  character_set_name_3,
16995                                  character_set_client_3,
16996                                  character_set_results_3,
16997                                  collation_connnection_3);
16998 
16999   /* Check that character set information has been reset. */
17000 
17001   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
17002   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
17003   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
17004   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
17005 
17006   /* Change connection-default character set in the client. */
17007 
17008   mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8");
17009 
17010   /*
17011     Call mysql_change_user() in order to check that new connection will
17012     have UTF8 character set on the client and on the server.
17013   */
17014 
17015   DIE_IF(mysql_change_user(&con,
17016                            opt_user,
17017                            opt_password,
17018                            opt_db ? opt_db : "test"));
17019 
17020   /* Retrieve character set information. */
17021 
17022   bug30472_retrieve_charset_info(&con,
17023                                  character_set_name_4,
17024                                  character_set_client_4,
17025                                  character_set_results_4,
17026                                  collation_connnection_4);
17027 
17028   /* Check that we have UTF8 on the server and on the client. */
17029 
17030   DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
17031   DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
17032   DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
17033   DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
17034 
17035   /* That's it. Cleanup. */
17036 
17037   mysql_close(&con);
17038 }
17039 
bug20023_change_user(MYSQL * con)17040 static void bug20023_change_user(MYSQL *con)
17041 {
17042   DIE_IF(mysql_change_user(con,
17043                            opt_user,
17044                            opt_password,
17045                            opt_db ? opt_db : "test"));
17046 }
17047 
query_str_variable(MYSQL * con,const char * var_name,char * str,size_t len)17048 static my_bool query_str_variable(MYSQL *con,
17049                                   const char *var_name,
17050                                   char *str,
17051                                   size_t len)
17052 {
17053   MYSQL_RES *rs;
17054   MYSQL_ROW row;
17055 
17056   char query_buffer[MAX_TEST_QUERY_LENGTH];
17057 
17058   my_bool is_null;
17059 
17060   my_snprintf(query_buffer, sizeof (query_buffer),
17061               "SELECT %s", var_name);
17062 
17063   DIE_IF(mysql_query(con, query_buffer));
17064   DIE_UNLESS(rs= mysql_store_result(con));
17065   DIE_UNLESS(row= mysql_fetch_row(rs));
17066 
17067   is_null= row[0] == NULL;
17068 
17069   if (!is_null)
17070     my_snprintf(str, len, "%s", row[0]);
17071 
17072   mysql_free_result(rs);
17073 
17074   return is_null;
17075 }
17076 
query_int_variable(MYSQL * con,const char * var_name,int * var_value)17077 static my_bool query_int_variable(MYSQL *con,
17078                                   const char *var_name,
17079                                   int *var_value)
17080 {
17081   char str[32];
17082   my_bool is_null= query_str_variable(con, var_name, str, sizeof(str));
17083 
17084   if (!is_null)
17085     *var_value= atoi(str);
17086 
17087   return is_null;
17088 }
17089 
test_bug20023()17090 static void test_bug20023()
17091 {
17092   MYSQL con;
17093 
17094   int sql_big_selects_orig= 0;
17095   /*
17096     Type of max_join_size is ha_rows, which might be ulong or off_t
17097     depending on the platform or configure options. Preserve the string
17098     to avoid type overflow pitfalls.
17099   */
17100   char max_join_size_orig[32];
17101 
17102   int sql_big_selects_2= 0;
17103   int sql_big_selects_3= 0;
17104   int sql_big_selects_4= 0;
17105   int sql_big_selects_5= 0;
17106 
17107   char query_buffer[MAX_TEST_QUERY_LENGTH];
17108 
17109   /* Create a new connection. */
17110 
17111   DIE_UNLESS(mysql_client_init(&con));
17112 
17113   DIE_UNLESS(mysql_real_connect(&con,
17114                                 opt_host,
17115                                 opt_user,
17116                                 opt_password,
17117                                 opt_db ? opt_db : "test",
17118                                 opt_port,
17119                                 opt_unix_socket,
17120                                 CLIENT_FOUND_ROWS));
17121 
17122   /***********************************************************************
17123     Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
17124   ***********************************************************************/
17125 
17126   query_int_variable(&con,
17127                      "@@session.sql_big_selects",
17128                      &sql_big_selects_orig);
17129 
17130   query_str_variable(&con,
17131                      "@@global.max_join_size",
17132                      max_join_size_orig,
17133                      sizeof(max_join_size_orig));
17134 
17135   /***********************************************************************
17136     Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
17137   ***********************************************************************/
17138 
17139   /* Issue COM_CHANGE_USER. */
17140 
17141   bug20023_change_user(&con);
17142 
17143   /* Query SQL_BIG_SELECTS. */
17144 
17145   query_int_variable(&con,
17146                      "@@session.sql_big_selects",
17147                      &sql_big_selects_2);
17148 
17149   /* Check that SQL_BIG_SELECTS is reset properly. */
17150 
17151   DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2);
17152 
17153   /***********************************************************************
17154     Test that if MAX_JOIN_SIZE set to non-default value,
17155     SQL_BIG_SELECTS will be 0.
17156   ***********************************************************************/
17157 
17158   /* Set MAX_JOIN_SIZE to some non-default value. */
17159 
17160   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000"));
17161   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17162 
17163   /* Issue COM_CHANGE_USER. */
17164 
17165   bug20023_change_user(&con);
17166 
17167   /* Query SQL_BIG_SELECTS. */
17168 
17169   query_int_variable(&con,
17170                      "@@session.sql_big_selects",
17171                      &sql_big_selects_3);
17172 
17173   /* Check that SQL_BIG_SELECTS is 0. */
17174 
17175   DIE_UNLESS(sql_big_selects_3 == 0);
17176 
17177   /***********************************************************************
17178     Test that if MAX_JOIN_SIZE set to default value,
17179     SQL_BIG_SELECTS will be 1.
17180   ***********************************************************************/
17181 
17182   /* Set MAX_JOIN_SIZE to the default value (2^64-1). */
17183 
17184   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17185   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17186 
17187   /* Issue COM_CHANGE_USER. */
17188 
17189   bug20023_change_user(&con);
17190 
17191   /* Query SQL_BIG_SELECTS. */
17192 
17193   query_int_variable(&con,
17194                      "@@session.sql_big_selects",
17195                      &sql_big_selects_4);
17196 
17197   /* Check that SQL_BIG_SELECTS is 1. */
17198 
17199   DIE_UNLESS(sql_big_selects_4 == 1);
17200 
17201   /***********************************************************************
17202     Restore MAX_JOIN_SIZE.
17203     Check that SQL_BIG_SELECTS will be the original one.
17204   ***********************************************************************/
17205 
17206   /* Restore MAX_JOIN_SIZE. */
17207 
17208   my_snprintf(query_buffer,
17209            sizeof (query_buffer),
17210            "SET @@global.max_join_size = %s",
17211            max_join_size_orig);
17212 
17213   DIE_IF(mysql_query(&con, query_buffer));
17214 
17215   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17216   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17217 
17218   /* Issue COM_CHANGE_USER. */
17219 
17220   bug20023_change_user(&con);
17221 
17222   /* Query SQL_BIG_SELECTS. */
17223 
17224   query_int_variable(&con,
17225                      "@@session.sql_big_selects",
17226                      &sql_big_selects_5);
17227 
17228   /* Check that SQL_BIG_SELECTS is 1. */
17229 
17230   DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig);
17231 
17232   /***********************************************************************
17233     That's it. Cleanup.
17234   ***********************************************************************/
17235 
17236   mysql_close(&con);
17237 }
17238 
bug31418_impl()17239 static void bug31418_impl()
17240 {
17241   MYSQL con;
17242 
17243   my_bool is_null;
17244   int rc= 0;
17245 
17246   /* Create a new connection. */
17247 
17248   DIE_UNLESS(mysql_client_init(&con));
17249 
17250   DIE_UNLESS(mysql_real_connect(&con,
17251                                 opt_host,
17252                                 opt_user,
17253                                 opt_password,
17254                                 opt_db ? opt_db : "test",
17255                                 opt_port,
17256                                 opt_unix_socket,
17257                                 CLIENT_FOUND_ROWS));
17258 
17259   /***********************************************************************
17260     Check that lock is free:
17261       - IS_FREE_LOCK() should return 1;
17262       - IS_USED_LOCK() should return NULL;
17263   ***********************************************************************/
17264 
17265   is_null= query_int_variable(&con,
17266                               "IS_FREE_LOCK('bug31418')",
17267                               &rc);
17268   DIE_UNLESS(!is_null && rc);
17269 
17270   is_null= query_int_variable(&con,
17271                               "IS_USED_LOCK('bug31418')",
17272                               &rc);
17273   DIE_UNLESS(is_null);
17274 
17275   /***********************************************************************
17276     Acquire lock and check the lock status (the lock must be in use):
17277       - IS_FREE_LOCK() should return 0;
17278       - IS_USED_LOCK() should return non-zero thread id;
17279   ***********************************************************************/
17280 
17281   query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
17282   DIE_UNLESS(rc);
17283 
17284   is_null= query_int_variable(&con,
17285                               "IS_FREE_LOCK('bug31418')",
17286                               &rc);
17287   DIE_UNLESS(!is_null && !rc);
17288 
17289   is_null= query_int_variable(&con,
17290                               "IS_USED_LOCK('bug31418')",
17291                               &rc);
17292   DIE_UNLESS(!is_null && rc);
17293 
17294   /***********************************************************************
17295     Issue COM_CHANGE_USER command and check the lock status
17296     (the lock must be free):
17297       - IS_FREE_LOCK() should return 1;
17298       - IS_USED_LOCK() should return NULL;
17299   **********************************************************************/
17300 
17301   bug20023_change_user(&con);
17302 
17303   is_null= query_int_variable(&con,
17304                               "IS_FREE_LOCK('bug31418')",
17305                               &rc);
17306   DIE_UNLESS(!is_null && rc);
17307 
17308   is_null= query_int_variable(&con,
17309                               "IS_USED_LOCK('bug31418')",
17310                               &rc);
17311   DIE_UNLESS(is_null);
17312 
17313   /***********************************************************************
17314    That's it. Cleanup.
17315   ***********************************************************************/
17316 
17317   mysql_close(&con);
17318 }
17319 
test_bug31418()17320 static void test_bug31418()
17321 {
17322   /* Run test case for BUG#31418 for three different connections. */
17323 
17324   bug31418_impl();
17325 
17326   bug31418_impl();
17327 
17328   bug31418_impl();
17329 }
17330 
17331 
17332 
17333 /**
17334   Bug#31669 Buffer overflow in mysql_change_user()
17335 */
17336 
17337 #define LARGE_BUFFER_SIZE 2048
17338 
test_bug31669()17339 static void test_bug31669()
17340 {
17341   int rc;
17342   static char buff[LARGE_BUFFER_SIZE+1];
17343 #ifndef EMBEDDED_LIBRARY
17344   static char user[USERNAME_CHAR_LENGTH+1];
17345   static char db[NAME_CHAR_LEN+1];
17346   static char query[LARGE_BUFFER_SIZE*2];
17347 #endif
17348   MYSQL *l_mysql;
17349 
17350 
17351   DBUG_ENTER("test_bug31669");
17352   myheader("test_bug31669");
17353 
17354   l_mysql= mysql_client_init(NULL);
17355   DIE_UNLESS(l_mysql != NULL);
17356 
17357   l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
17358                          opt_password, current_db, opt_port,
17359                          opt_unix_socket, 0);
17360   DIE_UNLESS(l_mysql != 0);
17361 
17362 
17363   rc= mysql_change_user(l_mysql, NULL, NULL, NULL);
17364   DIE_UNLESS(rc);
17365 
17366   reconnect(&l_mysql);
17367 
17368   rc= mysql_change_user(l_mysql, "", "", "");
17369   DIE_UNLESS(rc);
17370   reconnect(&l_mysql);
17371 
17372   memset(buff, 'a', sizeof(buff));
17373   buff[sizeof(buff) - 1] = '\0';
17374 
17375   rc= mysql_change_user(l_mysql, buff, buff, buff);
17376   DIE_UNLESS(rc);
17377   reconnect(&l_mysql);
17378 
17379   rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
17380   DIE_UNLESS(!rc);
17381 
17382 #ifndef EMBEDDED_LIBRARY
17383   memset(db, 'a', sizeof(db));
17384   db[NAME_CHAR_LEN]= 0;
17385   strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
17386   rc= mysql_query(mysql, query);
17387   myquery(rc);
17388 
17389   memset(user, 'b', sizeof(user));
17390   user[USERNAME_CHAR_LENGTH]= 0;
17391   memset(buff, 'c', sizeof(buff));
17392   buff[LARGE_BUFFER_SIZE]= 0;
17393   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
17394                  "'", buff, "' WITH GRANT OPTION", NullS);
17395   rc= mysql_query(mysql, query);
17396   myquery(rc);
17397 
17398   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY "
17399                  "'", buff, "' WITH GRANT OPTION", NullS);
17400   rc= mysql_query(mysql, query);
17401   myquery(rc);
17402 
17403   rc= mysql_query(mysql, "FLUSH PRIVILEGES");
17404   myquery(rc);
17405 
17406   rc= mysql_change_user(l_mysql, user, buff, db);
17407   DIE_UNLESS(!rc);
17408 
17409   user[USERNAME_CHAR_LENGTH-1]= 'a';
17410   rc= mysql_change_user(l_mysql, user, buff, db);
17411   DIE_UNLESS(rc);
17412   reconnect(&l_mysql);
17413 
17414   user[USERNAME_CHAR_LENGTH-1]= 'b';
17415   buff[LARGE_BUFFER_SIZE-1]= 'd';
17416   rc= mysql_change_user(l_mysql, user, buff, db);
17417   DIE_UNLESS(rc);
17418   reconnect(&l_mysql);
17419 
17420   buff[LARGE_BUFFER_SIZE-1]= 'c';
17421   db[NAME_CHAR_LEN-1]= 'e';
17422   rc= mysql_change_user(l_mysql, user, buff, db);
17423   DIE_UNLESS(rc);
17424   reconnect(&l_mysql);
17425 
17426   db[NAME_CHAR_LEN-1]= 'a';
17427   rc= mysql_change_user(l_mysql, user, buff, db);
17428   DIE_UNLESS(!rc);
17429 
17430   rc= mysql_change_user(l_mysql, user + 1, buff + 1, db + 1);
17431   DIE_UNLESS(rc);
17432   reconnect(&l_mysql);
17433 
17434   rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
17435   DIE_UNLESS(!rc);
17436 
17437   strxmov(query, "DROP DATABASE ", db, NullS);
17438   rc= mysql_query(mysql, query);
17439   myquery(rc);
17440 
17441   strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
17442   rc= mysql_query(mysql, query);
17443   myquery(rc);
17444   DIE_UNLESS(mysql_affected_rows(mysql) == 2);
17445 
17446   mysql_close(l_mysql);
17447 #endif
17448 
17449   DBUG_VOID_RETURN;
17450 }
17451 
17452 
17453 /**
17454   Bug#28386 the general log is incomplete
17455 */
17456 
test_bug28386()17457 static void test_bug28386()
17458 {
17459   int rc;
17460   MYSQL_STMT *stmt;
17461   MYSQL_RES *result;
17462   MYSQL_ROW row;
17463   MYSQL_BIND bind;
17464   const char hello[]= "hello world!";
17465 
17466   DBUG_ENTER("test_bug28386");
17467   myheader("test_bug28386");
17468 
17469   rc= mysql_query(mysql, "select @@global.log_output");
17470   myquery(rc);
17471 
17472   result= mysql_store_result(mysql);
17473   DIE_UNLESS(result);
17474 
17475   row= mysql_fetch_row(result);
17476   if (! strstr(row[0], "TABLE"))
17477   {
17478     mysql_free_result(result);
17479     if (! opt_silent)
17480       printf("Skipping the test since logging to tables is not enabled\n");
17481     /* Log output is not to tables */
17482     return;
17483   }
17484   mysql_free_result(result);
17485 
17486   enable_query_logs(1);
17487 
17488   stmt= mysql_simple_prepare(mysql, "SELECT ?");
17489   check_stmt(stmt);
17490 
17491   memset(&bind, 0, sizeof(bind));
17492 
17493   bind.buffer_type= MYSQL_TYPE_STRING;
17494   bind.buffer= (void *) hello;
17495   bind.buffer_length= (ulong)sizeof(hello);
17496 
17497   mysql_stmt_bind_param(stmt, &bind);
17498   mysql_stmt_send_long_data(stmt, 0, hello, (ulong)sizeof(hello));
17499 
17500   rc= mysql_stmt_execute(stmt);
17501   check_execute(stmt, rc);
17502 
17503   rc= my_process_stmt_result(stmt);
17504   DIE_UNLESS(rc == 1);
17505 
17506   rc= mysql_stmt_reset(stmt);
17507   check_execute(stmt, rc);
17508 
17509   rc= mysql_stmt_close(stmt);
17510   DIE_UNLESS(!rc);
17511 
17512   rc= mysql_query(mysql, "select * from mysql.general_log where "
17513                          "command_type='Close stmt' or "
17514                          "command_type='Reset stmt' or "
17515                          "command_type='Long Data'");
17516   myquery(rc);
17517 
17518   result= mysql_store_result(mysql);
17519   mytest(result);
17520 
17521   DIE_UNLESS(mysql_num_rows(result) == 3);
17522 
17523   mysql_free_result(result);
17524 
17525   restore_query_logs();
17526 
17527   DBUG_VOID_RETURN;
17528 }
17529 
17530 
test_wl4166_1()17531 static void test_wl4166_1()
17532 {
17533   MYSQL_STMT *stmt;
17534   int        int_data;
17535   char       str_data[50];
17536   char       tiny_data;
17537   short      small_data;
17538   longlong   big_data;
17539   float      real_data;
17540   double     double_data;
17541   ulong      length[7];
17542   my_bool    is_null[7];
17543   MYSQL_BIND my_bind[7];
17544   int rc;
17545   int i;
17546 
17547   myheader("test_wl4166_1");
17548 
17549   rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
17550   myquery(rc);
17551 
17552   rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
17553                          "col2 varchar(15), col3 int, "
17554                          "col4 smallint, col5 bigint, "
17555                          "col6 float, col7 double, "
17556                          "colX varchar(10) default NULL)");
17557   myquery(rc);
17558 
17559   stmt= mysql_simple_prepare(mysql,
17560     "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
17561     "VALUES(?, ?, ?, ?, ?, ?, ?)");
17562   check_stmt(stmt);
17563 
17564   verify_param_count(stmt, 7);
17565 
17566   memset(my_bind, 0, sizeof(my_bind));
17567   /* tinyint */
17568   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
17569   my_bind[0].buffer= (void *)&tiny_data;
17570   /* string */
17571   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
17572   my_bind[1].buffer= (void *)str_data;
17573   my_bind[1].buffer_length= 1000;                  /* Max string length */
17574   /* integer */
17575   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
17576   my_bind[2].buffer= (void *)&int_data;
17577   /* short */
17578   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
17579   my_bind[3].buffer= (void *)&small_data;
17580   /* bigint */
17581   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
17582   my_bind[4].buffer= (void *)&big_data;
17583   /* float */
17584   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
17585   my_bind[5].buffer= (void *)&real_data;
17586   /* double */
17587   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
17588   my_bind[6].buffer= (void *)&double_data;
17589 
17590   for (i= 0; i < (int) array_elements(my_bind); i++)
17591   {
17592     my_bind[i].length= &length[i];
17593     my_bind[i].is_null= &is_null[i];
17594     is_null[i]= 0;
17595   }
17596 
17597   rc= mysql_stmt_bind_param(stmt, my_bind);
17598   check_execute(stmt, rc);
17599 
17600   int_data= 320;
17601   small_data= 1867;
17602   big_data= 1000;
17603   real_data= 2;
17604   double_data= 6578.001;
17605 
17606   /* now, execute the prepared statement to insert 10 records.. */
17607   for (tiny_data= 0; tiny_data < 10; tiny_data++)
17608   {
17609     length[1]= sprintf(str_data, "MySQL%d", int_data);
17610     rc= mysql_stmt_execute(stmt);
17611     check_execute(stmt, rc);
17612     int_data += 25;
17613     small_data += 10;
17614     big_data += 100;
17615     real_data += 1;
17616     double_data += 10.09;
17617   }
17618 
17619   /* force a re-prepare with some DDL */
17620 
17621   rc= mysql_query(mysql,
17622     "ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
17623   myquery(rc);
17624 
17625   /*
17626     execute the prepared statement again,
17627     without changing the types of parameters already bound.
17628   */
17629 
17630   for (tiny_data= 50; tiny_data < 60; tiny_data++)
17631   {
17632     length[1]= sprintf(str_data, "MySQL%d", int_data);
17633     rc= mysql_stmt_execute(stmt);
17634     check_execute(stmt, rc);
17635     int_data += 25;
17636     small_data += 10;
17637     big_data += 100;
17638     real_data += 1;
17639     double_data += 10.09;
17640   }
17641 
17642   mysql_stmt_close(stmt);
17643 
17644   rc= mysql_query(mysql, "DROP TABLE table_4166");
17645   myquery(rc);
17646 }
17647 
17648 
test_wl4166_2()17649 static void test_wl4166_2()
17650 {
17651   MYSQL_STMT *stmt;
17652   int        c_int;
17653   MYSQL_TIME d_date;
17654   MYSQL_BIND bind_out[2];
17655   int rc;
17656 
17657   myheader("test_wl4166_2");
17658 
17659   rc= mysql_query(mysql, "SET SQL_MODE=''");
17660   myquery(rc);
17661 
17662   rc= mysql_query(mysql, "drop table if exists t1");
17663   myquery(rc);
17664   rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
17665   myquery(rc);
17666   rc= mysql_query(mysql,
17667                   "insert into t1 (c_int, d_date) values (42, '1948-05-15')");
17668   myquery(rc);
17669 
17670   stmt= mysql_simple_prepare(mysql, "select * from t1");
17671   check_stmt(stmt);
17672 
17673   memset(bind_out, 0, sizeof(bind_out));
17674   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
17675   bind_out[0].buffer= (void*) &c_int;
17676 
17677   bind_out[1].buffer_type= MYSQL_TYPE_DATE;
17678   bind_out[1].buffer= (void*) &d_date;
17679 
17680   rc= mysql_stmt_bind_result(stmt, bind_out);
17681   check_execute(stmt, rc);
17682 
17683   /* int -> varchar transition */
17684 
17685   rc= mysql_query(mysql,
17686                   "alter table t1 change column c_int c_int varchar(11)");
17687   myquery(rc);
17688 
17689   rc= mysql_stmt_execute(stmt);
17690   check_execute(stmt, rc);
17691 
17692   rc= mysql_stmt_fetch(stmt);
17693   check_execute(stmt, rc);
17694 
17695   DIE_UNLESS(c_int == 42);
17696   DIE_UNLESS(d_date.year == 1948);
17697   DIE_UNLESS(d_date.month == 5);
17698   DIE_UNLESS(d_date.day == 15);
17699 
17700   rc= mysql_stmt_fetch(stmt);
17701   DIE_UNLESS(rc == MYSQL_NO_DATA);
17702 
17703   /* varchar to int retrieval with truncation */
17704 
17705   rc= mysql_query(mysql, "update t1 set c_int='abcde'");
17706   myquery(rc);
17707 
17708   rc= mysql_stmt_execute(stmt);
17709   check_execute(stmt, rc);
17710 
17711   rc= mysql_stmt_fetch(stmt);
17712   check_execute_r(stmt, rc);
17713 
17714   DIE_UNLESS(c_int == 0);
17715 
17716   rc= mysql_stmt_fetch(stmt);
17717   DIE_UNLESS(rc == MYSQL_NO_DATA);
17718 
17719   /* alter table and increase the number of columns */
17720   rc= mysql_query(mysql, "alter table t1 add column d_int int");
17721   myquery(rc);
17722 
17723   rc= mysql_stmt_execute(stmt);
17724   check_execute_r(stmt, rc);
17725 
17726   rc= mysql_stmt_reset(stmt);
17727   check_execute(stmt, rc);
17728 
17729   /* decrease the number of columns */
17730   rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
17731   myquery(rc);
17732 
17733   rc= mysql_stmt_execute(stmt);
17734   check_execute_r(stmt, rc);
17735 
17736   mysql_stmt_close(stmt);
17737   rc= mysql_query(mysql, "drop table t1");
17738   myquery(rc);
17739 
17740 }
17741 
17742 
17743 /**
17744   Test how warnings generated during assignment of parameters
17745   are (currently not) preserve in case of reprepare.
17746 */
17747 
test_wl4166_3()17748 static void test_wl4166_3()
17749 {
17750   int rc;
17751   MYSQL_STMT *stmt;
17752   MYSQL_BIND my_bind[1];
17753   MYSQL_TIME tm[1];
17754 
17755   myheader("test_wl4166_3");
17756 
17757   rc= mysql_query(mysql, "drop table if exists t1");
17758   myquery(rc);
17759 
17760   rc= mysql_query(mysql, "create table t1 (year datetime)");
17761   myquery(rc);
17762 
17763   stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)");
17764   check_stmt(stmt);
17765   verify_param_count(stmt, 1);
17766 
17767   memset(my_bind, 0, sizeof(my_bind));
17768   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17769   my_bind[0].buffer= &tm[0];
17770 
17771   rc= mysql_stmt_bind_param(stmt, my_bind);
17772   check_execute(stmt, rc);
17773 
17774   tm[0].year= 10000;
17775   tm[0].month= 1; tm[0].day= 1;
17776   tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
17777   tm[0].second_part= 0; tm[0].neg= 0;
17778 
17779   /* Cause a statement reprepare */
17780   rc= mysql_query(mysql, "alter table t1 add column c int");
17781   myquery(rc);
17782 
17783   rc= mysql_stmt_execute(stmt);
17784   check_execute(stmt, rc);
17785   /*
17786     Sic: only one warning, instead of two. The warning
17787     about data truncation when assigning a parameter is lost.
17788     This is a bug.
17789   */
17790   my_process_warnings(mysql, 1);
17791 
17792   verify_col_data("t1", "year", "0000-00-00 00:00:00");
17793 
17794   mysql_stmt_close(stmt);
17795 
17796   rc= mysql_query(mysql, "drop table t1");
17797   myquery(rc);
17798 }
17799 
17800 
17801 /**
17802   Test that long data parameters, as well as parameters
17803   that were originally in a different character set, are
17804   preserved in case of reprepare.
17805 */
17806 
test_wl4166_4()17807 static void test_wl4166_4()
17808 {
17809   MYSQL_STMT *stmt;
17810   int rc;
17811   const char *stmt_text;
17812   MYSQL_BIND bind_array[2];
17813 
17814   /* Represented as numbers to keep UTF8 tools from clobbering them. */
17815   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
17816   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
17817   char buf1[16], buf2[16];
17818   ulong buf1_len, buf2_len;
17819 
17820   myheader("test_wl4166_4");
17821 
17822   rc= mysql_query(mysql, "drop table if exists t1");
17823   myquery(rc);
17824 
17825   /*
17826     Create table with binary columns, set session character set to cp1251,
17827     client character set to koi8, and make sure that there is conversion
17828     on insert and no conversion on select
17829   */
17830   rc= mysql_query(mysql,
17831                   "create table t1 (c1 varbinary(255), c2 varbinary(255))");
17832   myquery(rc);
17833   rc= mysql_query(mysql, "set character_set_client=koi8r, "
17834                          "character_set_connection=cp1251, "
17835                          "character_set_results=koi8r");
17836   myquery(rc);
17837 
17838   memset(bind_array, 0, sizeof(bind_array));
17839 
17840   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
17841 
17842   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
17843   bind_array[1].buffer= (void *) koi8;
17844   bind_array[1].buffer_length= (ulong)strlen(koi8);
17845 
17846   stmt= mysql_stmt_init(mysql);
17847   check_stmt(stmt);
17848 
17849   stmt_text= "insert into t1 (c1, c2) values (?, ?)";
17850 
17851   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
17852   check_execute(stmt, rc);
17853 
17854   mysql_stmt_bind_param(stmt, bind_array);
17855 
17856   mysql_stmt_send_long_data(stmt, 0, koi8, (ulong)strlen(koi8));
17857 
17858   /* Cause a reprepare at statement execute */
17859   rc= mysql_query(mysql, "alter table t1 add column d int");
17860   myquery(rc);
17861 
17862   rc= mysql_stmt_execute(stmt);
17863   check_execute(stmt, rc);
17864 
17865   stmt_text= "select c1, c2 from t1";
17866 
17867   /* c1 and c2 are binary so no conversion will be done on select */
17868   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
17869   check_execute(stmt, rc);
17870 
17871   rc= mysql_stmt_execute(stmt);
17872   check_execute(stmt, rc);
17873 
17874   bind_array[0].buffer= buf1;
17875   bind_array[0].buffer_length= (ulong)sizeof(buf1);
17876   bind_array[0].length= &buf1_len;
17877 
17878   bind_array[1].buffer= buf2;
17879   bind_array[1].buffer_length= (ulong)sizeof(buf2);
17880   bind_array[1].length= &buf2_len;
17881 
17882   mysql_stmt_bind_result(stmt, bind_array);
17883 
17884   rc= mysql_stmt_fetch(stmt);
17885   check_execute(stmt, rc);
17886 
17887   DIE_UNLESS(buf1_len == strlen(cp1251));
17888   DIE_UNLESS(buf2_len == strlen(cp1251));
17889   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
17890   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
17891 
17892   rc= mysql_stmt_fetch(stmt);
17893   DIE_UNLESS(rc == MYSQL_NO_DATA);
17894 
17895   mysql_stmt_close(stmt);
17896 
17897   rc= mysql_query(mysql, "drop table t1");
17898   myquery(rc);
17899   rc= mysql_query(mysql, "set names default");
17900   myquery(rc);
17901 }
17902 
17903 /**
17904   Bug#36004 mysql_stmt_prepare resets the list of warnings
17905 */
17906 
test_bug36004()17907 static void test_bug36004()
17908 {
17909   int rc, warning_count= 0;
17910   MYSQL_STMT *stmt;
17911 
17912   DBUG_ENTER("test_bug36004");
17913   myheader("test_bug36004");
17914 
17915   rc= mysql_query(mysql, "drop table if exists inexistant");
17916   myquery(rc);
17917 
17918   DIE_UNLESS(mysql_warning_count(mysql) == 1);
17919   query_int_variable(mysql, "@@warning_count", &warning_count);
17920   DIE_UNLESS(warning_count);
17921 
17922   stmt= mysql_simple_prepare(mysql, "select 1");
17923   check_stmt(stmt);
17924 
17925   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17926   query_int_variable(mysql, "@@warning_count", &warning_count);
17927   /* behaviour changed by WL#5928 */
17928   if (mysql_get_server_version(mysql) < 50702)
17929     DIE_UNLESS(warning_count);
17930   else
17931     DIE_UNLESS(!warning_count);
17932 
17933   rc= mysql_stmt_execute(stmt);
17934   check_execute(stmt, rc);
17935 
17936   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17937   mysql_stmt_close(stmt);
17938 
17939   query_int_variable(mysql, "@@warning_count", &warning_count);
17940   /* behaviour changed by WL#5928 */
17941   if (mysql_get_server_version(mysql) < 50702)
17942     DIE_UNLESS(warning_count);
17943   else
17944     DIE_UNLESS(!warning_count);
17945 
17946   stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
17947   check_stmt(stmt);
17948 
17949   query_int_variable(mysql, "@@warning_count", &warning_count);
17950   DIE_UNLESS(warning_count == 0);
17951   mysql_stmt_close(stmt);
17952 
17953   DBUG_VOID_RETURN;
17954 }
17955 
17956 /**
17957   Test that COM_REFRESH issues a implicit commit.
17958 */
17959 
test_wl4284_1()17960 static void test_wl4284_1()
17961 {
17962   int rc;
17963   MYSQL_ROW row;
17964   MYSQL_RES *result;
17965 
17966   DBUG_ENTER("test_wl4284_1");
17967   myheader("test_wl4284_1");
17968 
17969   /* set AUTOCOMMIT to OFF */
17970   rc= mysql_autocommit(mysql, FALSE);
17971   myquery(rc);
17972 
17973   rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
17974   myquery(rc);
17975 
17976   rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
17977   myquery(rc);
17978 
17979   rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
17980   myquery(rc);
17981 
17982   rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
17983   myquery(rc);
17984 
17985   rc= mysql_rollback(mysql);
17986   myquery(rc);
17987 
17988   rc= mysql_query(mysql, "SELECT * FROM trans");
17989   myquery(rc);
17990 
17991   result= mysql_use_result(mysql);
17992   mytest(result);
17993 
17994   row= mysql_fetch_row(result);
17995   mytest(row);
17996 
17997   mysql_free_result(result);
17998 
17999   /* set AUTOCOMMIT to ON */
18000   rc= mysql_autocommit(mysql, TRUE);
18001   myquery(rc);
18002 
18003   rc= mysql_query(mysql, "DROP TABLE trans");
18004   myquery(rc);
18005 
18006   DBUG_VOID_RETURN;
18007 }
18008 
18009 
test_bug38486(void)18010 static void test_bug38486(void)
18011 {
18012   MYSQL_STMT *stmt;
18013   const char *stmt_text;
18014   unsigned long type= CURSOR_TYPE_READ_ONLY;
18015 
18016   DBUG_ENTER("test_bug38486");
18017   myheader("test_bug38486");
18018 
18019   stmt= mysql_stmt_init(mysql);
18020   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18021   stmt_text= "CREATE TABLE t1 (a INT)";
18022   mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
18023   mysql_stmt_execute(stmt);
18024   mysql_stmt_close(stmt);
18025 
18026   stmt= mysql_stmt_init(mysql);
18027   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18028   stmt_text= "INSERT INTO t1 VALUES (1)";
18029   mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
18030   mysql_stmt_execute(stmt);
18031   mysql_stmt_close(stmt);
18032 
18033   DBUG_VOID_RETURN;
18034 }
18035 
18036 
18037 /**
18038      Bug# 33831 mysql_real_connect() should fail if
18039      given an already connected MYSQL handle.
18040 */
18041 
test_bug33831(void)18042 static void test_bug33831(void)
18043 {
18044   MYSQL *l_mysql;
18045 
18046   DBUG_ENTER("test_bug33831");
18047 
18048   if (!(l_mysql= mysql_client_init(NULL)))
18049   {
18050     myerror("mysql_client_init() failed");
18051     DIE_UNLESS(0);
18052   }
18053   if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
18054                            opt_password, current_db, opt_port,
18055                            opt_unix_socket, 0)))
18056   {
18057     myerror("connection failed");
18058     DIE_UNLESS(0);
18059   }
18060 
18061   if (mysql_real_connect(l_mysql, opt_host, opt_user,
18062                          opt_password, current_db, opt_port,
18063                          opt_unix_socket, 0))
18064   {
18065     myerror("connection should have failed");
18066     DIE_UNLESS(0);
18067   }
18068 
18069   mysql_close(l_mysql);
18070 
18071   DBUG_VOID_RETURN;
18072 }
18073 
18074 
test_bug40365(void)18075 static void test_bug40365(void)
18076 {
18077   uint         rc, i;
18078   MYSQL_STMT   *stmt= 0;
18079   MYSQL_BIND   my_bind[2];
18080   my_bool      is_null[2]= {0};
18081   MYSQL_TIME   tm[2];
18082 
18083   DBUG_ENTER("test_bug40365");
18084 
18085   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18086   myquery(rc);
18087   rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \
18088                                           c2 DATE)");
18089   myquery(rc);
18090 
18091   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)");
18092   check_stmt(stmt);
18093   verify_param_count(stmt, 2);
18094 
18095   memset(my_bind, 0, sizeof(my_bind));
18096   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
18097   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
18098   for (i= 0; i < (int) array_elements(my_bind); i++)
18099   {
18100     my_bind[i].buffer= (void *) &tm[i];
18101     my_bind[i].is_null= &is_null[i];
18102   }
18103 
18104   rc= mysql_stmt_bind_param(stmt, my_bind);
18105   check_execute(stmt, rc);
18106 
18107   for (i= 0; i < (int) array_elements(my_bind); i++)
18108   {
18109     tm[i].neg= 0;
18110     tm[i].second_part= 0;
18111     tm[i].year= 2009;
18112     tm[i].month= 2;
18113     tm[i].day= 29;
18114     tm[i].hour= 0;
18115     tm[i].minute= 0;
18116     tm[i].second= 0;
18117   }
18118   rc= mysql_stmt_execute(stmt);
18119   check_execute(stmt, rc);
18120 
18121   rc= mysql_commit(mysql);
18122   myquery(rc);
18123   mysql_stmt_close(stmt);
18124 
18125   stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1");
18126   check_stmt(stmt);
18127 
18128   rc= mysql_stmt_bind_result(stmt, my_bind);
18129   check_execute(stmt, rc);
18130 
18131   rc= mysql_stmt_execute(stmt);
18132   check_execute(stmt, rc);
18133 
18134   rc= mysql_stmt_store_result(stmt);
18135   check_execute(stmt, rc);
18136 
18137   rc= mysql_stmt_fetch(stmt);
18138   check_execute(stmt, rc);
18139 
18140   if (!opt_silent)
18141     fprintf(stdout, "\n");
18142 
18143   for (i= 0; i < array_elements(my_bind); i++)
18144   {
18145     if (!opt_silent)
18146       fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d ",
18147               i, tm[i].year, tm[i].month, tm[i].day);
18148     DIE_UNLESS(tm[i].year == 0);
18149     DIE_UNLESS(tm[i].month == 0);
18150     DIE_UNLESS(tm[i].day == 0);
18151   }
18152   mysql_stmt_close(stmt);
18153   rc= mysql_commit(mysql);
18154   myquery(rc);
18155 
18156   DBUG_VOID_RETURN;
18157 }
18158 
18159 
18160 /**
18161   Subtest for Bug#43560. Verifies that a loss of connection on the server side
18162   is handled well by the mysql_stmt_execute() call, i.e., no SIGSEGV due to
18163   a vio socket that is cleared upon closed connection.
18164 
18165   Assumes the presence of the close_conn_after_stmt_execute debug feature in
18166   the server. Verifies that it is connected to a debug server before proceeding
18167   with the test.
18168  */
test_bug43560(void)18169 static void test_bug43560(void)
18170 {
18171   MYSQL*       conn;
18172   uint         rc;
18173   MYSQL_STMT   *stmt= 0;
18174   MYSQL_BIND   bind;
18175   my_bool      is_null= 0;
18176   char         buffer[256];
18177   const uint   BUFSIZE= sizeof(buffer);
18178   const char*  values[] = {"eins", "zwei", "drei", "viele", NULL};
18179   const char   insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
18180   ulong        length;
18181   const unsigned int drop_db= opt_drop_db;
18182 
18183   DBUG_ENTER("test_bug43560");
18184   myheader("test_bug43560");
18185 
18186   /* Make sure we only run against a debug server. */
18187   if (!strstr(mysql->server_version, "debug"))
18188   {
18189     fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
18190     DBUG_VOID_RETURN;
18191   }
18192 
18193   /*
18194     Set up a separate connection for this test to avoid messing up the
18195     general MYSQL object used in other subtests. Use TCP protocol to avoid
18196     problems with the buffer semantics of AF_UNIX, and turn off auto reconnect.
18197   */
18198   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
18199 
18200   rc= mysql_query(conn, "DROP TABLE IF EXISTS t1");
18201   myquery(rc);
18202   rc= mysql_query(conn,
18203     "CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))");
18204   myquery(rc);
18205 
18206   stmt= mysql_stmt_init(conn);
18207   check_stmt(stmt);
18208   rc= mysql_stmt_prepare(stmt, insert_str, (ulong)strlen(insert_str));
18209   check_execute(stmt, rc);
18210 
18211   memset(&bind, 0, sizeof(bind));
18212   bind.buffer_type= MYSQL_TYPE_STRING;
18213   bind.buffer_length= BUFSIZE;
18214   bind.buffer= buffer;
18215   bind.is_null= &is_null;
18216   bind.length= &length;
18217   rc= mysql_stmt_bind_param(stmt, &bind);
18218   check_execute(stmt, rc);
18219 
18220   /* First execute; should succeed. */
18221   strncpy(buffer, values[0], BUFSIZE);
18222   length= (ulong)strlen(buffer);
18223   rc= mysql_stmt_execute(stmt);
18224   check_execute(stmt, rc);
18225 
18226   /*
18227     Set up the server to close this session's server-side socket after
18228     next execution of prep statement.
18229   */
18230   rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'");
18231   myquery(rc);
18232 
18233   /* Second execute; should fail due to socket closed during execution. */
18234   strncpy(buffer, values[1], BUFSIZE);
18235   length= (ulong)strlen(buffer);
18236   rc= mysql_stmt_execute(stmt);
18237   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18238 
18239   /*
18240     Third execute; should fail (connection already closed), or SIGSEGV in
18241     case of a Bug#43560 type regression in which case the whole test fails.
18242   */
18243   strncpy(buffer, values[2], BUFSIZE);
18244   length= (ulong)strlen(buffer);
18245   rc= mysql_stmt_execute(stmt);
18246   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18247 
18248   mysql_stmt_close(stmt);
18249 
18250   opt_drop_db= 0;
18251   client_disconnect(conn);
18252   rc= mysql_query(mysql, "DROP TABLE t1");
18253   myquery(rc);
18254   opt_drop_db= drop_db;
18255 
18256   DBUG_VOID_RETURN;
18257 }
18258 
18259 
18260 /**
18261   Bug#36326: nested transaction and select
18262 */
18263 
test_bug36326()18264 static void test_bug36326()
18265 {
18266   int rc;
18267 
18268   DBUG_ENTER("test_bug36326");
18269   myheader("test_bug36326");
18270 
18271   rc= mysql_autocommit(mysql, TRUE);
18272   myquery(rc);
18273   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18274   myquery(rc);
18275   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
18276   myquery(rc);
18277   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
18278   myquery(rc);
18279   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
18280   myquery(rc);
18281   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576");
18282   myquery(rc);
18283   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18284   DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
18285   rc= mysql_query(mysql, "BEGIN");
18286   myquery(rc);
18287   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
18288   rc= mysql_query(mysql, "SELECT * FROM t1");
18289   myquery(rc);
18290   rc= my_process_result(mysql);
18291   DIE_UNLESS(rc == 1);
18292   rc= mysql_rollback(mysql);
18293   myquery(rc);
18294   rc= mysql_query(mysql, "ROLLBACK");
18295   myquery(rc);
18296   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18297   rc= mysql_query(mysql, "SELECT * FROM t1");
18298   myquery(rc);
18299   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18300   rc= my_process_result(mysql);
18301   DIE_UNLESS(rc == 1);
18302   rc= mysql_query(mysql, "DROP TABLE t1");
18303   myquery(rc);
18304   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = DEFAULT");
18305   myquery(rc);
18306 
18307   DBUG_VOID_RETURN;
18308 }
18309 
18310 /**
18311   Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
18312              string value.
18313 */
18314 
test_bug41078(void)18315 static void test_bug41078(void)
18316 {
18317   uint         rc;
18318   MYSQL_STMT   *stmt= 0;
18319   MYSQL_BIND   param, result;
18320   ulong        cursor_type= CURSOR_TYPE_READ_ONLY;
18321   ulong        len;
18322   char         str[64];
18323   const char   param_str[]= "abcdefghijklmn";
18324   my_bool      is_null, error;
18325 
18326   DBUG_ENTER("test_bug41078");
18327 
18328   rc= mysql_query(mysql, "SET NAMES UTF8");
18329   myquery(rc);
18330 
18331   stmt= mysql_simple_prepare(mysql, "SELECT ?");
18332   check_stmt(stmt);
18333   verify_param_count(stmt, 1);
18334 
18335   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type);
18336   check_execute(stmt, rc);
18337 
18338   memset(&param, 0, sizeof(param));
18339   param.buffer_type= MYSQL_TYPE_STRING;
18340   param.buffer= (void *) param_str;
18341   len= sizeof(param_str) - 1;
18342   param.length= &len;
18343 
18344   rc= mysql_stmt_bind_param(stmt, &param);
18345   check_execute(stmt, rc);
18346 
18347   rc= mysql_stmt_execute(stmt);
18348   check_execute(stmt, rc);
18349 
18350   memset(&result, 0, sizeof(result));
18351   result.buffer_type= MYSQL_TYPE_STRING;
18352   result.buffer= str;
18353   result.buffer_length= (ulong)sizeof(str);
18354   result.is_null= &is_null;
18355   result.length= &len;
18356   result.error=  &error;
18357 
18358   rc= mysql_stmt_bind_result(stmt, &result);
18359   check_execute(stmt, rc);
18360 
18361   rc= mysql_stmt_store_result(stmt);
18362   check_execute(stmt, rc);
18363 
18364   rc= mysql_stmt_fetch(stmt);
18365   check_execute(stmt, rc);
18366 
18367   DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str));
18368 
18369   mysql_stmt_close(stmt);
18370 
18371   DBUG_VOID_RETURN;
18372 }
18373 
18374 /**
18375   Bug#45010: invalid memory reads during parsing some strange statements
18376 */
test_bug45010()18377 static void test_bug45010()
18378 {
18379   int rc;
18380   const char query1[]= "select a.\x80",
18381              query2[]= "describe `table\xef";
18382 
18383   DBUG_ENTER("test_bug45010");
18384   myheader("test_bug45010");
18385 
18386   rc= mysql_query(mysql, "set names utf8");
18387   myquery(rc);
18388 
18389   /* \x80 (-128) could be used as a index of ident_map. */
18390   rc= mysql_real_query(mysql, query1, (ulong)(sizeof(query1) - 1));
18391   DIE_UNLESS(rc);
18392 
18393   /* \xef (-17) could be used to skip 3 bytes past the buffer end. */
18394   rc= mysql_real_query(mysql, query2, (ulong)(sizeof(query2) - 1));
18395   DIE_UNLESS(rc);
18396 
18397   rc= mysql_query(mysql, "set names default");
18398   myquery(rc);
18399 
18400   DBUG_VOID_RETURN;
18401 }
18402 
18403 /**
18404   Bug#44495: Prepared Statement:
18405              CALL p(<x>) - `thd->get_protocol() == &thd->protocol_text' failed
18406 */
18407 
test_bug44495()18408 static void test_bug44495()
18409 {
18410   int rc;
18411   MYSQL con;
18412   MYSQL_STMT *stmt;
18413 
18414   DBUG_ENTER("test_bug44495");
18415   myheader("test_44495");
18416 
18417   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18418   myquery(rc);
18419 
18420   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN arg VARCHAR(25))"
18421                          "  BEGIN SET @stmt = CONCAT('SELECT \"', arg, '\"');"
18422                          "  PREPARE ps1 FROM @stmt;"
18423                          "  EXECUTE ps1;"
18424                          "  DROP PREPARE ps1;"
18425                          "END;");
18426   myquery(rc);
18427 
18428   DIE_UNLESS(mysql_client_init(&con));
18429 
18430   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18431                                 current_db, opt_port, opt_unix_socket,
18432                                 CLIENT_MULTI_RESULTS));
18433 
18434   stmt= mysql_simple_prepare(&con, "CALL p1('abc')");
18435   check_stmt(stmt);
18436 
18437   rc= mysql_stmt_execute(stmt);
18438   check_execute(stmt, rc);
18439 
18440   rc= my_process_stmt_result(stmt);
18441   DIE_UNLESS(rc == 1);
18442 
18443   mysql_stmt_close(stmt);
18444 
18445   mysql_close(&con);
18446 
18447   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18448   myquery(rc);
18449 
18450   DBUG_VOID_RETURN;
18451 }
18452 
test_bug53371()18453 static void test_bug53371()
18454 {
18455   int rc;
18456   MYSQL_RES *result;
18457 
18458   myheader("test_bug53371");
18459 
18460   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18461   myquery(rc);
18462   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
18463   myquery(rc);
18464   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18465 
18466   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18467   myquery(rc);
18468   rc= mysql_query(mysql, "CREATE DATABASE bug53371");
18469   myquery(rc);
18470   rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
18471   myquery(rc);
18472 
18473   rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
18474   myquery(rc);
18475 
18476   rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
18477   DIE_UNLESS(rc);
18478   DIE_UNLESS(mysql_errno(mysql) == 1142);
18479 
18480   result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
18481   DIE_IF(result);
18482 
18483   result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
18484   DIE_IF(result);
18485 
18486   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
18487   myquery(rc);
18488   rc= mysql_query(mysql, "DROP TABLE t1");
18489   myquery(rc);
18490   rc= mysql_query(mysql, "DROP DATABASE bug53371");
18491   myquery(rc);
18492   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18493   myquery(rc);
18494 }
18495 
18496 
18497 
18498 /**
18499   Bug#42373: libmysql can mess a connection at connect
18500 */
test_bug42373()18501 static void test_bug42373()
18502 {
18503   int rc;
18504   MYSQL con;
18505   MYSQL_STMT *stmt;
18506 
18507   DBUG_ENTER("test_bug42373");
18508   myheader("test_42373");
18509 
18510   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18511   myquery(rc);
18512 
18513   rc= mysql_query(mysql, "CREATE PROCEDURE p1()"
18514                          "  BEGIN"
18515                          "  SELECT 1;"
18516                          "  INSERT INTO t1 VALUES (2);"
18517                          "END;");
18518   myquery(rc);
18519 
18520   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18521   myquery(rc);
18522 
18523   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18524   myquery(rc);
18525 
18526   /* Try with a stored procedure. */
18527   DIE_UNLESS(mysql_client_init(&con));
18528 
18529   mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()");
18530 
18531   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18532                                 current_db, opt_port, opt_unix_socket,
18533                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18534 
18535   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18536   check_stmt(stmt);
18537 
18538   rc= mysql_stmt_execute(stmt);
18539   check_execute(stmt, rc);
18540 
18541   rc= my_process_stmt_result(stmt);
18542   DIE_UNLESS(rc == 1);
18543 
18544   mysql_stmt_close(stmt);
18545   mysql_close(&con);
18546 
18547   /* Now try with a multi-statement. */
18548   DIE_UNLESS(mysql_client_init(&con));
18549 
18550   mysql_options(&con, MYSQL_INIT_COMMAND,
18551                 "SELECT 3; INSERT INTO t1 VALUES (4)");
18552 
18553   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18554                                 current_db, opt_port, opt_unix_socket,
18555                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18556 
18557   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18558   check_stmt(stmt);
18559 
18560   rc= mysql_stmt_execute(stmt);
18561   check_execute(stmt, rc);
18562 
18563   rc= my_process_stmt_result(stmt);
18564   DIE_UNLESS(rc == 2);
18565 
18566   mysql_stmt_close(stmt);
18567   mysql_close(&con);
18568 
18569   rc= mysql_query(mysql, "DROP TABLE t1");
18570   myquery(rc);
18571 
18572   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18573   myquery(rc);
18574 
18575   DBUG_VOID_RETURN;
18576 }
18577 
18578 
18579 /**
18580   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18581 */
18582 
test_bug54041_impl()18583 static void test_bug54041_impl()
18584 {
18585   int rc;
18586   MYSQL_STMT *stmt;
18587   MYSQL_BIND bind;
18588 
18589   DBUG_ENTER("test_bug54041");
18590   myheader("test_bug54041");
18591 
18592   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18593   myquery(rc);
18594 
18595   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18596   myquery(rc);
18597 
18598   stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?");
18599   check_stmt(stmt);
18600   verify_param_count(stmt, 1);
18601 
18602   memset(&bind, 0, sizeof(bind));
18603 
18604   /* Any type that does not support long data handling. */
18605   bind.buffer_type= MYSQL_TYPE_LONG;
18606 
18607   rc= mysql_stmt_bind_param(stmt, &bind);
18608   check_execute(stmt, rc);
18609 
18610   /*
18611     Trick the client API into sending a long data packet for
18612     the parameter. Long data is only supported for string and
18613     binary types.
18614   */
18615   stmt->params[0].buffer_type= MYSQL_TYPE_STRING;
18616 
18617   rc= mysql_stmt_send_long_data(stmt, 0, "data", 5);
18618   check_execute(stmt, rc);
18619 
18620   /* Undo API violation. */
18621   stmt->params[0].buffer_type= MYSQL_TYPE_LONG;
18622 
18623   rc= mysql_stmt_execute(stmt);
18624   /* Incorrect arguments. */
18625   check_execute_r(stmt, rc);
18626 
18627   mysql_stmt_close(stmt);
18628 
18629   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18630   myquery(rc);
18631 
18632   DBUG_VOID_RETURN;
18633 }
18634 
18635 
18636 /**
18637   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18638 */
18639 
test_bug54041()18640 static void test_bug54041()
18641 {
18642   enable_query_logs(0);
18643   test_bug54041_impl();
18644   disable_query_logs();
18645   test_bug54041_impl();
18646   restore_query_logs();
18647 }
18648 
18649 
18650 /**
18651   Bug#47485: mysql_store_result returns a result set for a prepared statement
18652 */
test_bug47485()18653 static void test_bug47485()
18654 {
18655   MYSQL_STMT   *stmt;
18656   MYSQL_RES    *res;
18657   MYSQL_BIND    bind[2];
18658   int           rc;
18659   const char*   sql_select = "SELECT 1, 'a'";
18660   int           int_data;
18661   char          str_data[16];
18662   my_bool       is_null[2];
18663   my_bool       error[2];
18664   ulong         length[2];
18665 
18666   DBUG_ENTER("test_bug47485");
18667   myheader("test_bug47485");
18668 
18669   stmt= mysql_stmt_init(mysql);
18670   check_stmt(stmt);
18671   rc= mysql_stmt_prepare(stmt, sql_select, (ulong)strlen(sql_select));
18672   check_execute(stmt, rc);
18673 
18674   rc= mysql_stmt_execute(stmt);
18675   check_execute(stmt, rc);
18676 
18677   res = mysql_store_result(mysql);
18678   DIE_UNLESS(res == NULL);
18679 
18680   mysql_stmt_reset(stmt);
18681 
18682   rc= mysql_stmt_execute(stmt);
18683   check_execute(stmt, rc);
18684 
18685   res = mysql_use_result(mysql);
18686   DIE_UNLESS(res == NULL);
18687 
18688   mysql_stmt_reset(stmt);
18689 
18690   memset(bind, 0, sizeof(bind));
18691   bind[0].buffer_type= MYSQL_TYPE_LONG;
18692   bind[0].buffer= (char *)&int_data;
18693   bind[0].is_null= &is_null[0];
18694   bind[0].length= &length[0];
18695   bind[0].error= &error[0];
18696 
18697   bind[1].buffer_type= MYSQL_TYPE_STRING;
18698   bind[1].buffer= (char *)str_data;
18699   bind[1].buffer_length= (ulong)sizeof(str_data);
18700   bind[1].is_null= &is_null[1];
18701   bind[1].length= &length[1];
18702   bind[1].error= &error[1];
18703 
18704   rc= mysql_stmt_bind_result(stmt, bind);
18705   check_execute(stmt, rc);
18706 
18707   rc= mysql_stmt_execute(stmt);
18708   check_execute(stmt, rc);
18709 
18710   rc= mysql_stmt_store_result(stmt);
18711   check_execute(stmt, rc);
18712 
18713   while (!(rc= mysql_stmt_fetch(stmt)))
18714     ;
18715 
18716   DIE_UNLESS(rc == MYSQL_NO_DATA);
18717 
18718   mysql_stmt_reset(stmt);
18719 
18720   memset(bind, 0, sizeof(bind));
18721   bind[0].buffer_type= MYSQL_TYPE_LONG;
18722   bind[0].buffer= (char *)&int_data;
18723   bind[0].is_null= &is_null[0];
18724   bind[0].length= &length[0];
18725   bind[0].error= &error[0];
18726 
18727   bind[1].buffer_type= MYSQL_TYPE_STRING;
18728   bind[1].buffer= (char *)str_data;
18729   bind[1].buffer_length= (ulong)sizeof(str_data);
18730   bind[1].is_null= &is_null[1];
18731   bind[1].length= &length[1];
18732   bind[1].error= &error[1];
18733 
18734   rc= mysql_stmt_bind_result(stmt, bind);
18735   check_execute(stmt, rc);
18736 
18737   rc= mysql_stmt_execute(stmt);
18738   check_execute(stmt, rc);
18739 
18740   while (!(rc= mysql_stmt_fetch(stmt)))
18741     ;
18742 
18743   DIE_UNLESS(rc == MYSQL_NO_DATA);
18744 
18745   mysql_stmt_close(stmt);
18746 
18747   DBUG_VOID_RETURN;
18748 }
18749 
18750 
18751 /*
18752   Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server
18753 */
test_bug58036()18754 static void test_bug58036()
18755 {
18756   MYSQL *conn;
18757   enum mysql_ssl_mode ssl_mode= SSL_MODE_DISABLED;
18758   DBUG_ENTER("test_bug47485");
18759   myheader("test_bug58036");
18760 
18761   /* Part1: try to connect with ucs2 client character set */
18762   conn= mysql_client_init(NULL);
18763   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18764   mysql_options(conn, MYSQL_OPT_SSL_MODE, &ssl_mode);
18765   if (mysql_real_connect(conn, opt_host, opt_user,
18766                          opt_password,  opt_db ? opt_db : "test",
18767                          opt_port, opt_unix_socket, 0))
18768   {
18769     if (!opt_silent)
18770       printf("mysql_real_connect() succeeded (failure expected)\n");
18771     mysql_close(conn);
18772     DIE("");
18773   }
18774 
18775   if (!opt_silent)
18776     printf("Got mysql_real_connect() error (expected): %s (%d)\n",
18777            mysql_error(conn), mysql_errno(conn));
18778   DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR);
18779   mysql_close(conn);
18780 
18781 
18782   /*
18783     Part2:
18784     - connect with latin1
18785     - then change client character set to ucs2
18786     - then try mysql_change_user()
18787   */
18788   conn= mysql_client_init(NULL);
18789   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1");
18790   if (!mysql_real_connect(conn, opt_host, opt_user,
18791                          opt_password, opt_db ? opt_db : "test",
18792                          opt_port, opt_unix_socket, 0))
18793   {
18794     if (!opt_silent)
18795       printf("mysql_real_connect() failed: %s (%d)\n",
18796              mysql_error(conn), mysql_errno(conn));
18797     mysql_close(conn);
18798     DIE("");
18799   }
18800 
18801   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18802   if (!mysql_change_user(conn, opt_user, opt_password, NULL))
18803   {
18804     if (!opt_silent)
18805       printf("mysql_change_user() succedded, error expected!");
18806     mysql_close(conn);
18807     DIE("");
18808   }
18809 
18810   if (!opt_silent)
18811     printf("Got mysql_change_user() error (expected): %s (%d)\n",
18812            mysql_error(conn), mysql_errno(conn));
18813   mysql_close(conn);
18814 
18815   DBUG_VOID_RETURN;
18816 }
18817 
18818 
18819 /*
18820   Bug#49972: Crash in prepared statements.
18821 
18822   The following case lead to a server crash:
18823     - Use binary protocol;
18824     - Prepare a statement with OUT-parameter;
18825     - Execute the statement;
18826     - Cause re-prepare of the statement (change dependencies);
18827     - Execute the statement again -- crash here.
18828 */
18829 
test_bug49972()18830 static void test_bug49972()
18831 {
18832   int rc;
18833   MYSQL_STMT *stmt;
18834 
18835   MYSQL_BIND in_param_bind;
18836   MYSQL_BIND out_param_bind;
18837   int int_data= 0;
18838   my_bool is_null= FALSE;
18839 
18840   DBUG_ENTER("test_bug49972");
18841   myheader("test_bug49972");
18842 
18843   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
18844   myquery(rc);
18845 
18846   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18847   myquery(rc);
18848 
18849   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18850   myquery(rc);
18851 
18852   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a");
18853   myquery(rc);
18854 
18855   stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)");
18856   check_stmt(stmt);
18857 
18858   memset(&in_param_bind, 0, sizeof (in_param_bind));
18859 
18860   in_param_bind.buffer_type= MYSQL_TYPE_LONG;
18861   in_param_bind.buffer= (char *) &int_data;
18862   in_param_bind.length= 0;
18863   in_param_bind.is_null= 0;
18864 
18865   rc= mysql_stmt_bind_param(stmt, &in_param_bind);
18866 
18867   rc= mysql_stmt_execute(stmt);
18868   check_execute(stmt, rc);
18869 
18870   {
18871     memset(&out_param_bind, 0, sizeof (out_param_bind));
18872 
18873     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18874     out_param_bind.is_null= &is_null;
18875     out_param_bind.buffer= &int_data;
18876     out_param_bind.buffer_length= (ulong)sizeof (int_data);
18877 
18878     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18879     check_execute(stmt, rc);
18880 
18881     rc= mysql_stmt_fetch(stmt);
18882     rc= mysql_stmt_fetch(stmt);
18883     assert(rc == MYSQL_NO_DATA);
18884 
18885     mysql_stmt_next_result(stmt);
18886     mysql_stmt_fetch(stmt);
18887   }
18888 
18889   rc= mysql_query(mysql, "DROP FUNCTION f1");
18890   myquery(rc);
18891 
18892   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18893   myquery(rc);
18894 
18895   rc= mysql_stmt_execute(stmt);
18896   check_execute(stmt, rc);
18897 
18898   {
18899     memset(&out_param_bind, 0, sizeof (out_param_bind));
18900 
18901     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18902     out_param_bind.is_null= &is_null;
18903     out_param_bind.buffer= &int_data;
18904     out_param_bind.buffer_length= (ulong)sizeof (int_data);
18905 
18906     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18907     check_execute(stmt, rc);
18908 
18909     rc= mysql_stmt_fetch(stmt);
18910     rc= mysql_stmt_fetch(stmt);
18911     assert(rc == MYSQL_NO_DATA);
18912 
18913     mysql_stmt_next_result(stmt);
18914     mysql_stmt_fetch(stmt);
18915   }
18916 
18917   mysql_stmt_close(stmt);
18918 
18919   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18920   myquery(rc);
18921 
18922   rc= mysql_query(mysql, "DROP FUNCTION f1");
18923   myquery(rc);
18924 
18925   DBUG_VOID_RETURN;
18926 }
18927 
18928 
18929 /*
18930   Bug #56976:   Severe Denial Of Service in prepared statements
18931 */
test_bug56976()18932 static void test_bug56976()
18933 {
18934   MYSQL_STMT   *stmt;
18935   MYSQL_BIND    bind[1];
18936   int           rc;
18937   const char*   query = "SELECT LENGTH(?)";
18938   char *long_buffer;
18939   unsigned long i, packet_len = 256 * 1024L;
18940   unsigned long dos_len    = 8 * 1024 * 1024L;
18941 
18942   DBUG_ENTER("test_bug56976");
18943   myheader("test_bug56976");
18944 
18945   stmt= mysql_stmt_init(mysql);
18946   check_stmt(stmt);
18947 
18948   rc= mysql_stmt_prepare(stmt, query, (ulong)strlen(query));
18949   check_execute(stmt, rc);
18950 
18951   memset(bind, 0, sizeof(bind));
18952   bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;
18953 
18954   rc= mysql_stmt_bind_param(stmt, bind);
18955   check_execute(stmt, rc);
18956 
18957   long_buffer= (char*) my_malloc(PSI_NOT_INSTRUMENTED,
18958                                  packet_len, MYF(0));
18959   DIE_UNLESS(long_buffer);
18960 
18961   memset(long_buffer, 'a', packet_len);
18962 
18963   for (i= 0; i < dos_len / packet_len; i++)
18964   {
18965     rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len);
18966     check_execute(stmt, rc);
18967   }
18968 
18969   my_free(long_buffer);
18970   rc= mysql_stmt_execute(stmt);
18971 
18972   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);
18973 
18974   mysql_stmt_close(stmt);
18975 
18976   DBUG_VOID_RETURN;
18977 }
18978 
18979 
18980 /**
18981   Bug#57058 SERVER_QUERY_WAS_SLOW not wired up.
18982 */
18983 
test_bug57058()18984 static void test_bug57058()
18985 {
18986   MYSQL_RES *res;
18987   int rc;
18988 
18989   DBUG_ENTER("test_bug57058");
18990   myheader("test_bug57058");
18991 
18992   rc= mysql_query(mysql, "set @@session.long_query_time=0.1");
18993   myquery(rc);
18994 
18995   DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW));
18996 
18997   rc= mysql_query(mysql, "select sleep(1)");
18998   myquery(rc);
18999 
19000   /*
19001     Important: the flag is sent in the last EOF packet of
19002     the query, the one which ends the result. Read the
19003     result to see the "slow" status.
19004   */
19005   res= mysql_store_result(mysql);
19006 
19007   DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW);
19008 
19009   mysql_free_result(res);
19010 
19011   rc= mysql_query(mysql, "set @@session.long_query_time=default");
19012   myquery(rc);
19013 
19014   DBUG_VOID_RETURN;
19015 }
19016 
19017 
19018 /**
19019   Bug#11766854: 60075: MYSQL_LOAD_CLIENT_PLUGIN DOESN'T CLEAR ERROR
19020 */
19021 
test_bug11766854()19022 static void test_bug11766854()
19023 {
19024   struct st_mysql_client_plugin *plugin;
19025 
19026   DBUG_ENTER("test_bug11766854");
19027   myheader("test_bug11766854");
19028 
19029   plugin= mysql_load_plugin(mysql, "foo", -1, 0);
19030   DIE_UNLESS(plugin == 0);
19031 
19032   plugin= mysql_load_plugin(mysql, "qa_auth_client", -1, 0);
19033   DIE_UNLESS(plugin != 0);
19034   DIE_IF(mysql_errno(mysql));
19035 
19036   DBUG_VOID_RETURN;
19037 }
19038 
19039 /**
19040   Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR
19041                        CHAR/VARCHAR/TEXT COLUMNS IN VIEWS
19042 */
test_bug12337762()19043 static void test_bug12337762()
19044 {
19045   int rc,i=0;
19046   MYSQL_RES *result;
19047   MYSQL_FIELD *field;
19048   unsigned int tab_charsetnr[3]= {0};
19049 
19050   DBUG_ENTER("test_bug12337762");
19051   myheader("test_bug12337762");
19052 
19053   /*
19054     Creating table with specific charset.
19055   */
19056   rc= mysql_query(mysql, "drop table if exists charset_tab");
19057   rc= mysql_query(mysql, "create table charset_tab("\
19058                          "txt1 varchar(32) character set Latin1,"\
19059                          "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
19060                          "txt3 varchar(32) character set utf8 collate utf8_bin"\
19061 						 ")");
19062 
19063   DIE_UNLESS(rc == 0);
19064   DIE_IF(mysql_errno(mysql));
19065 
19066   /*
19067     Creating view from table created earlier.
19068   */
19069   rc= mysql_query(mysql, "drop view if exists charset_view");
19070   rc= mysql_query(mysql, "create view charset_view as "\
19071                          "select * from charset_tab;");
19072   DIE_UNLESS(rc == 0);
19073   DIE_IF(mysql_errno(mysql));
19074 
19075   /*
19076     Checking field information for table.
19077   */
19078   result= mysql_list_fields(mysql, "charset_tab", NULL);
19079   DIE_IF(mysql_errno(mysql));
19080   i=0;
19081   while((field= mysql_fetch_field(result)))
19082   {
19083     printf("field name %s\n", field->name);
19084     printf("field table %s\n", field->table);
19085     printf("field type %d\n", field->type);
19086     printf("field charset %d\n", field->charsetnr);
19087     tab_charsetnr[i++]= field->charsetnr;
19088     printf("\n");
19089   }
19090   mysql_free_result(result);
19091 
19092   /*
19093     Checking field information for view.
19094   */
19095   result= mysql_list_fields(mysql, "charset_view", NULL);
19096   DIE_IF(mysql_errno(mysql));
19097   i=0;
19098   while((field= mysql_fetch_field(result)))
19099   {
19100     printf("field name %s\n", field->name);
19101     printf("field table %s\n", field->table);
19102     printf("field type %d\n", field->type);
19103     printf("field charset %d\n", field->charsetnr);
19104     printf("\n");
19105     /*
19106       charset value for field must be same for both, view and table.
19107     */
19108     DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
19109   }
19110   mysql_free_result(result);
19111 
19112   DBUG_VOID_RETURN;
19113 }
19114 
19115 /**
19116   Bug#54790: Use of non-blocking mode for sockets limits performance
19117 */
19118 
test_bug54790()19119 static void test_bug54790()
19120 {
19121   int rc;
19122   MYSQL *lmysql;
19123   uint timeout= 2;
19124   enum mysql_ssl_mode ssl_mode= SSL_MODE_DISABLED;
19125 
19126   DBUG_ENTER("test_bug54790");
19127   myheader("test_bug54790");
19128 
19129   lmysql= mysql_client_init(NULL);
19130   DIE_UNLESS(lmysql);
19131 
19132   rc= mysql_options(lmysql, MYSQL_OPT_READ_TIMEOUT, &timeout);
19133   DIE_UNLESS(!rc);
19134 
19135   mysql_options(lmysql, MYSQL_OPT_SSL_MODE, &ssl_mode);
19136   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
19137                           opt_db ? opt_db : "test", opt_port,
19138                           opt_unix_socket, 0))
19139   {
19140     mysql= lmysql;
19141     myerror("mysql_real_connect failed");
19142     mysql_close(lmysql);
19143     exit(1);
19144   }
19145 
19146   rc= mysql_query(lmysql, "SELECT SLEEP(100);");
19147   myquery_r(rc);
19148 
19149   /* A timeout error (ER_NET_READ_INTERRUPTED) would be more appropriate. */
19150   DIE_UNLESS(mysql_errno(lmysql) == CR_SERVER_LOST);
19151 
19152   mysql_close(lmysql);
19153 
19154   DBUG_VOID_RETURN;
19155 }
19156 
19157 
19158 /*
19159   BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
19160 */
19161 
test_bug11754979()19162 static void test_bug11754979()
19163 {
19164   MYSQL* conn;
19165   DBUG_ENTER("test_bug11754979");
19166 
19167   myheader("test_bug11754979");
19168   DIE_UNLESS((conn= mysql_client_init(NULL)));
19169   DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
19170              opt_password, opt_db ? opt_db:"test", opt_port,
19171              opt_unix_socket,  CLIENT_FOUND_ROWS));
19172   myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
19173   myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
19174   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
19175   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
19176                             "ON DUPLICATE KEY UPDATE id = 4"));
19177   DIE_UNLESS(mysql_affected_rows(conn) == 2);
19178   myquery(mysql_query(conn, "DROP TABLE t1"));
19179   mysql_close(conn);
19180 
19181   DBUG_VOID_RETURN;
19182 }
19183 
19184 
19185 /*
19186   Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
19187 */
test_bug13001491()19188 static void test_bug13001491()
19189 {
19190   int rc;
19191   char query[MAX_TEST_QUERY_LENGTH];
19192   MYSQL *c;
19193 
19194   myheader("test_bug13001491");
19195 
19196   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19197            "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
19198            opt_host ? opt_host : "'localhost'");
19199 
19200   rc= mysql_query(mysql, query);
19201   myquery(rc);
19202 
19203   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19204            "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
19205            opt_host ? opt_host : "'localhost'");
19206 
19207   rc= mysql_query(mysql, query);
19208   myquery(rc);
19209 
19210   c= mysql_client_init(NULL);
19211 
19212   DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
19213                                 current_db, opt_port, opt_unix_socket,
19214                                 CLIENT_MULTI_STATEMENTS |
19215                                 CLIENT_MULTI_RESULTS));
19216 
19217   rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
19218   myquery(rc);
19219 
19220   rc= mysql_query(c,
19221     "CREATE PROCEDURE p1() "
19222     "BEGIN "
19223     " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
19224     " SELECT COUNT(*) "
19225     " FROM INFORMATION_SCHEMA.PROCESSLIST "
19226     " GROUP BY user "
19227     " ORDER BY NULL "
19228     " INTO @a; "
19229     "END");
19230   myquery(rc);
19231 
19232   rc= mysql_query(c, "CALL p1()");
19233   myquery(rc);
19234 
19235   mysql_free_result(mysql_store_result(c));
19236 
19237   /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
19238   rc= mysql_refresh(c, REFRESH_GRANT |
19239                        REFRESH_TABLES | REFRESH_HOSTS |
19240                        REFRESH_STATUS | REFRESH_THREADS);
19241   myquery(rc);
19242 
19243   /*
19244     Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
19245     fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
19246     location.
19247   */
19248   mysql_refresh(c, REFRESH_LOG);
19249 
19250   rc= mysql_query(c, "DROP PROCEDURE p1");
19251   myquery(rc);
19252 
19253   mysql_close(c);
19254   c= NULL;
19255 
19256   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19257            "DROP USER mysqltest_u1@%s",
19258            opt_host ? opt_host : "'localhost'");
19259 
19260   rc= mysql_query(mysql, query);
19261   myquery(rc);
19262 }
19263 
19264 
19265 /*
19266   WL#5968: Implement START TRANSACTION READ (WRITE|ONLY);
19267   Check that the SERVER_STATUS_IN_TRANS_READONLY flag is set properly.
19268 */
test_wl5968()19269 static void test_wl5968()
19270 {
19271   int rc;
19272 
19273   myheader("test_wl5968");
19274 
19275   if (mysql_get_server_version(mysql) < 50600)
19276   {
19277     if (!opt_silent)
19278       fprintf(stdout, "Skipping test_wl5968: "
19279               "tested feature does not exist in versions before MySQL 5.6\n");
19280     return;
19281   }
19282 
19283   rc= mysql_query(mysql, "START TRANSACTION");
19284   myquery(rc);
19285   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19286   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19287   rc= mysql_query(mysql, "COMMIT");
19288   myquery(rc);
19289   rc= mysql_query(mysql, "START TRANSACTION READ ONLY");
19290   myquery(rc);
19291   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19292   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY);
19293   rc= mysql_query(mysql, "COMMIT");
19294   myquery(rc);
19295   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
19296   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19297   rc= mysql_query(mysql, "START TRANSACTION");
19298   myquery(rc);
19299   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19300   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19301   rc= mysql_query(mysql, "COMMIT");
19302   myquery(rc);
19303 }
19304 
19305 
19306 /*
19307   WL#5924: Add connect string processing to mysql
19308 */
test_wl5924()19309 static void test_wl5924()
19310 {
19311   int rc;
19312   MYSQL *l_mysql;
19313   MYSQL_RES *res;
19314   MYSQL_ROW row;
19315 
19316   myheader("test_wl5924");
19317 
19318   if (mysql_get_server_version(mysql) < 50600)
19319   {
19320     if (!opt_silent)
19321       fprintf(stdout, "Skipping test_wl5924: "
19322               "tested feature does not exist in versions before MySQL 5.6\n");
19323     return;
19324   }
19325 
19326   l_mysql= mysql_client_init(NULL);
19327   DIE_UNLESS(l_mysql != NULL);
19328 
19329   /* we want a non-default character set */
19330   rc= mysql_set_character_set(l_mysql, "cp1251");
19331   DIE_UNLESS(rc == 0);
19332 
19333   /* put in an attr */
19334   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19335                      "key1", "value1");
19336   DIE_UNLESS(rc == 0);
19337 
19338   /* put a second attr */
19339   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19340                      "key2", "value2");
19341   DIE_UNLESS(rc == 0);
19342 
19343   /* put the second attr again : should fail */
19344   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19345                      "key2", "value2");
19346   DIE_UNLESS(rc != 0);
19347 
19348   /* delete the second attr */
19349   rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
19350                     "key2");
19351   DIE_UNLESS(rc == 0);
19352 
19353   /* put the second attr again : should pass */
19354   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19355                      "key2", "value2");
19356   DIE_UNLESS(rc == 0);
19357 
19358   /* full reset */
19359   rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_RESET, NULL);
19360   DIE_UNLESS(rc == 0);
19361 
19362   /* put the second attr again : should pass */
19363   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19364                      "key2", "value2");
19365   DIE_UNLESS(rc == 0);
19366 
19367   /* full reset */
19368   rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_RESET, NULL);
19369   DIE_UNLESS(rc == 0);
19370 
19371   /* add a third attr */
19372   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19373                      "key3", "value3");
19374   DIE_UNLESS(rc == 0);
19375 
19376   /* add a fourth attr */
19377   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19378                      "key4", "value4");
19379   DIE_UNLESS(rc == 0);
19380 
19381   /* add a non-ascii attr */
19382   /* note : this is Георги, Кодинов in windows-1251 */
19383   rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19384                      "\xc3\xe5\xee\xf0\xe3\xe8",
19385                      "\xca\xee\xe4\xe8\xed\xee\xe2");
19386   DIE_UNLESS(rc == 0);
19387 
19388   l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
19389                          opt_password, current_db, opt_port,
19390                          opt_unix_socket, 0);
19391   DIE_UNLESS(l_mysql != 0);
19392 
19393   rc= mysql_query(l_mysql,
19394                   "SELECT ATTR_NAME, ATTR_VALUE "
19395                   " FROM performance_schema.session_account_connect_attrs"
19396                   " WHERE ATTR_NAME IN ('key1','key2','key3','key4',"
19397                   "  '\xc3\xe5\xee\xf0\xe3\xe8') AND"
19398                   "  PROCESSLIST_ID = CONNECTION_ID() ORDER BY ATTR_NAME");
19399   myquery2(l_mysql,rc);
19400   res= mysql_use_result(l_mysql);
19401   DIE_UNLESS(res);
19402 
19403   row= mysql_fetch_row(res);
19404   DIE_UNLESS(row);
19405   DIE_UNLESS(0 == strcmp(row[0], "key3"));
19406   DIE_UNLESS(0 == strcmp(row[1], "value3"));
19407 
19408   row= mysql_fetch_row(res);
19409   DIE_UNLESS(row);
19410   DIE_UNLESS(0 == strcmp(row[0], "key4"));
19411   DIE_UNLESS(0 == strcmp(row[1], "value4"));
19412 
19413   row= mysql_fetch_row(res);
19414   DIE_UNLESS(row);
19415   DIE_UNLESS(0 == strcmp(row[0], "\xc3\xe5\xee\xf0\xe3\xe8"));
19416   DIE_UNLESS(0 == strcmp(row[1], "\xca\xee\xe4\xe8\xed\xee\xe2"));
19417 
19418   mysql_free_result(res);
19419 
19420   l_mysql->reconnect= 1;
19421   rc= mysql_reconnect(l_mysql);
19422   myquery2(l_mysql,rc);
19423 
19424   mysql_close(l_mysql);
19425 }
19426 
19427 
19428 /*
19429   WL#56587: Protocol support for password expiration
19430 */
test_wl6587()19431 static void test_wl6587()
19432 {
19433   int rc;
19434   MYSQL *l_mysql, *r_mysql;
19435   my_bool can;
19436 
19437   myheader("test_wl6587");
19438 
19439   if (mysql_get_server_version(mysql) < 50600)
19440   {
19441     if (!opt_silent)
19442       fprintf(stdout, "Skipping test_wl6587: "
19443               "tested feature does not exist in versions before MySQL 5.6\n");
19444     return;
19445   }
19446 
19447   /* initialize the server user */
19448   rc= mysql_query(mysql,
19449                   "CREATE USER wl6587_cli@localhost IDENTIFIED BY 'wl6587'");
19450   myquery(rc);
19451   rc= mysql_query(mysql, "ALTER USER wl6587_cli@localhost PASSWORD EXPIRE");
19452   myquery(rc);
19453 
19454   /* prepare the connection */
19455   l_mysql= mysql_client_init(NULL);
19456   DIE_UNLESS(l_mysql != NULL);
19457 
19458   /* connect must fail : the flag is off by default */
19459   r_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19460                               "wl6587", "test", opt_port,
19461                               opt_unix_socket, 0);
19462   DIE_UNLESS(r_mysql == 0);
19463   mysql_close(l_mysql);
19464 
19465   l_mysql= mysql_client_init(NULL);
19466   DIE_UNLESS(l_mysql != NULL);
19467 
19468   /* try the last argument. should work */
19469   l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19470                          "wl6587", "test", opt_port,
19471                          opt_unix_socket,
19472                          CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS);
19473   DIE_UNLESS(l_mysql != 0);
19474 
19475   /* must fail : sandbox mode */
19476   rc= mysql_query(l_mysql, "SELECT USER()");
19477   myerror2(l_mysql,NULL);
19478   DIE_UNLESS(rc != 0);
19479 
19480   mysql_close(l_mysql);
19481 
19482   /* try setting the option */
19483 
19484   l_mysql= mysql_client_init(NULL);
19485   DIE_UNLESS(l_mysql != NULL);
19486 
19487   can= TRUE;
19488   rc= mysql_options(l_mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &can);
19489   DIE_UNLESS(rc == 0);
19490 
19491   l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19492                          "wl6587", "test", opt_port,
19493                          opt_unix_socket, 0);
19494   DIE_UNLESS(l_mysql != 0);
19495 
19496   /* must fail : sandbox mode */
19497   rc= mysql_query(l_mysql, "SELECT USER()");
19498   myerror2(l_mysql,NULL);
19499   DIE_UNLESS(rc != 0);
19500 
19501   mysql_close(l_mysql);
19502 
19503   /* try change user against an expired account */
19504 
19505   l_mysql= mysql_client_init(NULL);
19506   DIE_UNLESS(l_mysql != NULL);
19507 
19508   can= FALSE;
19509   rc= mysql_options(l_mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &can);
19510   DIE_UNLESS(rc == 0);
19511 
19512 
19513   l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
19514                          opt_password, current_db, opt_port,
19515                          opt_unix_socket, 0);
19516   DIE_UNLESS(l_mysql != 0);
19517 
19518   rc= mysql_change_user(l_mysql, "wl6587_cli", "wl6587", "test");
19519   DIE_UNLESS(rc == TRUE);
19520 
19521   mysql_close(l_mysql);
19522 
19523   /* cleanup */
19524   rc= mysql_query(mysql, "DROP USER wl6587_cli@localhost");
19525   myquery(rc);
19526 }
19527 
19528 #ifndef EMBEDDED_LIBRARY
19529 /*
19530   Bug #17309863 AUTO RECONNECT DOES NOT WORK WITH 5.6 LIBMYSQLCLIENT
19531 */
test_bug17309863()19532 static void test_bug17309863()
19533 {
19534   MYSQL *lmysql;
19535   unsigned long thread_id;
19536   char query[MAX_TEST_QUERY_LENGTH];
19537   int rc;
19538 
19539   myheader("test_bug17309863");
19540 
19541   if (!opt_silent)
19542     fprintf(stdout, "\n Establishing a test connection ...");
19543   if (!(lmysql= mysql_client_init(NULL)))
19544   {
19545     myerror("mysql_client_init() failed");
19546     exit(1);
19547   }
19548   lmysql->reconnect= 1;
19549   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
19550                            opt_password, current_db, opt_port,
19551                            opt_unix_socket, 0)))
19552   {
19553     myerror("connection failed");
19554     exit(1);
19555   }
19556   if (!opt_silent)
19557     fprintf(stdout, "OK");
19558 
19559   thread_id= mysql_thread_id(lmysql);
19560   sprintf(query, "KILL %lu", thread_id);
19561 
19562   /*
19563     Running the "KILL <thread_id>" query in a separate connection.
19564   */
19565   if (thread_query(query))
19566     exit(1);
19567 
19568   /*
19569     The above KILL statement should have closed our connection. But reconnect
19570     flag allows to detect this before sending query and re-establish it without
19571     returning an error.
19572   */
19573   rc= mysql_query(lmysql, "SELECT 'bug17309863'");
19574   myquery(rc);
19575 
19576   mysql_close(lmysql);
19577 }
19578 #endif
19579 
test_wl5928()19580 static void test_wl5928()
19581 {
19582   MYSQL_STMT *stmt;
19583   int         rc;
19584   MYSQL_RES  *result;
19585 
19586   myheader("test_wl5928");
19587 
19588   if (mysql_get_server_version(mysql) < 50702)
19589   {
19590     if (!opt_silent)
19591       fprintf(stdout, "Skipping test_wl5928: "
19592               "tested feature does not exist in versions before MySQL 5.7.2\n");
19593     return;
19594   }
19595 
19596   stmt= mysql_simple_prepare(mysql, "SHOW WARNINGS");
19597   DIE_UNLESS(stmt == NULL);
19598   stmt= mysql_simple_prepare(mysql, "SHOW ERRORS");
19599   DIE_UNLESS(stmt == NULL);
19600   stmt= mysql_simple_prepare(mysql, "SHOW COUNT(*) WARNINGS");
19601   DIE_UNLESS(stmt == NULL);
19602   stmt= mysql_simple_prepare(mysql, "SHOW COUNT(*) ERRORS");
19603   DIE_UNLESS(stmt == NULL);
19604   stmt= mysql_simple_prepare(mysql, "SELECT @@warning_count");
19605   DIE_UNLESS(stmt == NULL);
19606   stmt= mysql_simple_prepare(mysql, "SELECT @@error_count");
19607   DIE_UNLESS(stmt == NULL);
19608   stmt= mysql_simple_prepare(mysql, "GET DIAGNOSTICS");
19609   DIE_UNLESS(stmt == NULL);
19610 
19611   rc= mysql_query(mysql, "SET SQL_MODE=''");
19612   myquery(rc);
19613 
19614   /* PREPARE */
19615 
19616   stmt= mysql_simple_prepare(mysql, "CREATE TABLE t1 (f1 INT) ENGINE=UNKNOWN");
19617   DIE_UNLESS(mysql_warning_count(mysql) == 2);
19618   check_stmt(stmt);
19619 
19620   /* SHOW WARNINGS.  (Will keep diagnostics) */
19621   rc= mysql_query(mysql, "SHOW WARNINGS");
19622   myquery(rc);
19623   result= mysql_store_result(mysql);
19624   mytest(result);
19625   rc= my_process_result_set(result);
19626   DIE_UNLESS(rc == 2);
19627   mysql_free_result(result);
19628 
19629   /* EXEC */
19630   rc= mysql_stmt_execute(stmt);
19631   check_execute(stmt, rc);
19632   DIE_UNLESS(mysql_warning_count(mysql) == 0);
19633 
19634   /* SHOW WARNINGS.  (Will keep diagnostics) */
19635   rc= mysql_query(mysql, "SHOW WARNINGS");
19636   myquery(rc);
19637   result= mysql_store_result(mysql);
19638   mytest(result);
19639   rc= my_process_result_set(result);
19640   DIE_UNLESS(rc == 0);
19641   mysql_free_result(result);
19642 
19643   /* clean up */
19644   mysql_stmt_close(stmt);
19645 
19646   stmt= mysql_simple_prepare(mysql, "SELECT 1");
19647   check_stmt(stmt);
19648   rc= mysql_stmt_execute(stmt);
19649   check_execute(stmt, rc);
19650   mysql_stmt_close(stmt);
19651 
19652   myquery(rc);
19653 }
19654 
test_wl6797()19655 static void test_wl6797()
19656 {
19657   MYSQL_STMT *stmt;
19658   int        rc;
19659   const char *stmt_text;
19660   my_ulonglong res;
19661 
19662   myheader("test_wl6797");
19663 
19664   if (mysql_get_server_version(mysql) < 50703)
19665   {
19666     if (!opt_silent)
19667       fprintf(stdout, "Skipping test_wl6797: "
19668              "tested feature does not exist in versions before MySQL 5.7.3\n");
19669     return;
19670   }
19671   /* clean up the session */
19672   rc= mysql_reset_connection(mysql);
19673   DIE_UNLESS(rc == 0);
19674 
19675   /* do prepare of a query */
19676   mysql_query(mysql, "use test");
19677   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
19678   mysql_query(mysql, "CREATE TABLE t1 (a int)");
19679 
19680   stmt= mysql_stmt_init(mysql);
19681   stmt_text= "INSERT INTO t1 VALUES (1), (2)";
19682 
19683   rc= mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
19684   check_execute(stmt, rc);
19685 
19686   /* Execute the insert statement */
19687   rc= mysql_stmt_execute(stmt);
19688   check_execute(stmt, rc);
19689 
19690   /*
19691    clean the session this should remove the prepare statement
19692    from the cache.
19693   */
19694   rc= mysql_reset_connection(mysql);
19695   DIE_UNLESS(rc == 0);
19696 
19697   /* this below stmt should report error */
19698   rc= mysql_stmt_execute(stmt);
19699   DIE_IF(rc == 0);
19700 
19701   /*
19702    bug#17653288: MYSQL_RESET_CONNECTION DOES NOT RESET LAST_INSERT_ID
19703   */
19704 
19705   rc= mysql_query(mysql, "CREATE TABLE t2 (a int NOT NULL PRIMARY KEY"\
19706                          " auto_increment)");
19707   myquery(rc);
19708   rc= mysql_query(mysql, "INSERT INTO t2 VALUES (null)");
19709   myquery(rc);
19710   res= mysql_insert_id(mysql);
19711   DIE_UNLESS(res == 1);
19712   rc= mysql_reset_connection(mysql);
19713   DIE_UNLESS(rc == 0);
19714   res= mysql_insert_id(mysql);
19715   DIE_UNLESS(res == 0);
19716 
19717   rc= mysql_query(mysql, "INSERT INTO t2 VALUES (last_insert_id(100))");
19718   myquery(rc);
19719   res= mysql_insert_id(mysql);
19720   DIE_UNLESS(res == 100);
19721   rc= mysql_reset_connection(mysql);
19722   DIE_UNLESS(rc == 0);
19723   res= mysql_insert_id(mysql);
19724   DIE_UNLESS(res == 0);
19725 
19726   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
19727   mysql_query(mysql, "DROP TABLE IF EXISTS t2");
19728   mysql_stmt_close(stmt);
19729 }
19730 
19731 
test_wl6791()19732 static void test_wl6791()
19733 {
19734   int        rc;
19735   uint       idx;
19736   MYSQL      *l_mysql;
19737   enum mysql_option
19738   uint_opts[] = {
19739     MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT,
19740     MYSQL_OPT_PROTOCOL, MYSQL_OPT_LOCAL_INFILE, MYSQL_OPT_SSL_MODE
19741   },
19742   my_bool_opts[] = {
19743     MYSQL_OPT_COMPRESS, MYSQL_OPT_USE_REMOTE_CONNECTION,
19744     MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION,
19745     MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
19746     MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_OPT_SSL_ENFORCE,
19747     MYSQL_ENABLE_CLEARTEXT_PLUGIN, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
19748   },
19749   const_char_opts[] = {
19750     MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
19751     MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME,
19752 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
19753     /* mysql_options() is a no-op on non-supporting platforms. */
19754     MYSQL_SHARED_MEMORY_BASE_NAME,
19755 #endif
19756     MYSQL_SET_CLIENT_IP, MYSQL_OPT_BIND, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
19757     MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT, MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH,
19758     MYSQL_OPT_SSL_CIPHER, MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
19759     MYSQL_SERVER_PUBLIC_KEY
19760   },
19761   err_opts[] = {
19762     MYSQL_OPT_NAMED_PIPE, MYSQL_OPT_CONNECT_ATTR_RESET,
19763     MYSQL_OPT_CONNECT_ATTR_DELETE, MYSQL_INIT_COMMAND
19764   };
19765 
19766   myheader("test_wl6791");
19767 
19768   /* prepare the connection */
19769   l_mysql = mysql_client_init(NULL);
19770   DIE_UNLESS(l_mysql != NULL);
19771 
19772   for (idx= 0; idx < sizeof(uint_opts) / sizeof(enum mysql_option); idx++)
19773   {
19774     uint opt_before= 1, opt_after= 0;
19775 
19776     if (!opt_silent)
19777       fprintf(stdout, "testing uint option #%d (%d)\n", idx,
19778               (int) uint_opts[idx]);
19779     rc= mysql_options(l_mysql, uint_opts[idx], &opt_before);
19780     DIE_UNLESS(rc == 0);
19781 
19782     rc = mysql_get_option(l_mysql, uint_opts[idx], &opt_after);
19783     DIE_UNLESS(rc == 0);
19784 
19785     DIE_UNLESS(opt_before == opt_after);
19786   }
19787 
19788   for (idx= 0; idx < sizeof(my_bool_opts) / sizeof(enum mysql_option); idx++)
19789   {
19790     my_bool opt_before = TRUE, opt_after = FALSE;
19791 
19792     if (!opt_silent)
19793       fprintf(stdout, "testing my_bool option #%d (%d)\n", idx,
19794       (int)my_bool_opts[idx]);
19795 
19796     rc = mysql_options(l_mysql, my_bool_opts[idx], &opt_before);
19797     DIE_UNLESS(rc == 0);
19798 
19799     rc = mysql_get_option(l_mysql, my_bool_opts[idx], &opt_after);
19800     DIE_UNLESS(rc == 0);
19801 
19802     DIE_UNLESS(opt_before == opt_after);
19803   }
19804 
19805   for (idx= 0; idx < sizeof(const_char_opts) / sizeof(enum mysql_option); idx++)
19806   {
19807     const char *opt_before = "TEST", *opt_after = NULL;
19808 
19809     if (!opt_silent)
19810       fprintf(stdout, "testing const char * option #%d (%d)\n", idx,
19811       (int)const_char_opts[idx]);
19812 
19813     rc = mysql_options(l_mysql, const_char_opts[idx], opt_before);
19814     DIE_UNLESS(rc == 0);
19815 
19816     rc = mysql_get_option(l_mysql, const_char_opts[idx], &opt_after);
19817     DIE_UNLESS(rc == 0);
19818 
19819     DIE_UNLESS(opt_before && opt_after &&
19820                0 == strcmp(opt_before, opt_after));
19821   }
19822 
19823   for (idx= 0; idx < sizeof(err_opts) / sizeof(enum mysql_option); idx++)
19824   {
19825     void *dummy_arg;
19826     if (!opt_silent)
19827       fprintf(stdout, "testing invalid option #%d (%d)\n", idx,
19828       (int)err_opts[idx]);
19829 
19830     rc = mysql_get_option(l_mysql, err_opts[idx], &dummy_arg);
19831     DIE_UNLESS(rc != 0);
19832   }
19833 
19834   /* clean up */
19835   mysql_close(l_mysql);
19836 }
19837 
19838 #define QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE \
19839   rc= mysql_query(mysql, "SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE," \
19840   " COUNT_EXECUTE, OWNER_OBJECT_TYPE, OWNER_OBJECT_SCHEMA, OWNER_OBJECT_NAME" \
19841   " from performance_schema.prepared_statements_instances where" \
19842   " sql_text like \"%ps_t1%\""); \
19843   myquery(rc); \
19844   result= mysql_store_result(mysql); \
19845   mytest(result); \
19846   (void) my_process_result_set(result); \
19847   mysql_free_result(result);
19848 
test_wl5768()19849 static void test_wl5768()
19850 {
19851   MYSQL_RES  *result;
19852   MYSQL_STMT *stmt, *sp_stmt;
19853   MYSQL_BIND bind[1];
19854   long       int_data;
19855   int        rc;
19856 
19857   myheader("test_wl5768");
19858 
19859   if (mysql_get_server_version(mysql) < 50704)
19860   {
19861     if (!opt_silent)
19862       fprintf(stdout, "Skipping test_wl5768: "
19863               "tested feature does not exist in versions before MySQL 5.7.4\n");
19864     return;
19865   }
19866 
19867   rc= mysql_query(mysql, "DROP TABLE IF EXISTS ps_t1");
19868   myquery(rc);
19869 
19870   rc= mysql_query(mysql, "CREATE TABLE ps_t1(Id INT)");
19871   myquery(rc);
19872 
19873   // Prepare an insert statement.
19874   stmt= mysql_simple_prepare(mysql, "INSERT INTO ps_t1 VALUES(?)");
19875   check_stmt(stmt);
19876   verify_param_count(stmt, 1);
19877 
19878   // Query P_S table.
19879   QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE;
19880 
19881   memset(bind, 0, sizeof (bind));
19882   bind[0].buffer_type= MYSQL_TYPE_LONG;
19883   bind[0].buffer= (long *) &int_data;
19884   bind[0].length= 0;
19885   bind[0].is_null= 0;
19886   rc= mysql_stmt_bind_param(stmt, bind);
19887   check_execute(stmt, rc);
19888 
19889   // Set the data to be inserted.
19890   int_data= 25;
19891 
19892   // Execute the prepared statement.
19893   rc= mysql_stmt_execute(stmt);
19894   check_execute(stmt, rc);
19895 
19896   // Query P_S table.
19897   QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE;
19898 
19899   // execute the prepared statement for 3 more times to check COUNT_EXECUTE
19900   rc= mysql_stmt_execute(stmt);
19901   check_execute(stmt, rc);
19902 
19903   int_data= 74;
19904 
19905   rc= mysql_stmt_execute(stmt);
19906   check_execute(stmt, rc);
19907 
19908   int_data= 123;
19909 
19910   rc= mysql_stmt_execute(stmt);
19911   check_execute(stmt, rc);
19912 
19913   // Query P_S table.
19914   QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE;
19915 
19916   // Deallocate/Close the prepared statement.
19917   mysql_stmt_close(stmt);
19918 
19919   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS proc");
19920   myquery(rc);
19921 
19922   // Check the instrumentation of the statement prepared in a stored procedure
19923   rc= mysql_query(mysql, "CREATE PROCEDURE proc(IN a INT)"
19924                          "BEGIN"
19925                          "  SET @stmt = CONCAT('UPDATE ps_t1 SET Id = ? WHERE Id > 100');"
19926                          "  PREPARE st FROM @stmt;"
19927                          "  EXECUTE st USING @a;"
19928                          "  DEALLOCATE PREPARE st;"
19929                          "END;");
19930   myquery(rc);
19931 
19932   sp_stmt= mysql_simple_prepare(mysql, "CALL proc(?)");
19933   check_stmt(sp_stmt);
19934   verify_param_count(sp_stmt, 1);
19935 
19936   memset(bind, 0, sizeof (bind));
19937   bind[0].buffer_type= MYSQL_TYPE_LONG;
19938   bind[0].buffer= (long *) &int_data;
19939   bind[0].length= 0;
19940   bind[0].is_null= 0;
19941   rc= mysql_stmt_bind_param(sp_stmt, bind);
19942   check_execute(sp_stmt, rc);
19943 
19944   int_data= 100;
19945 
19946   // Execute the prepared statement.
19947   rc= mysql_stmt_execute(sp_stmt);
19948   check_execute(sp_stmt, rc);
19949 
19950   // Query P_S table.
19951   QUERY_PREPARED_STATEMENTS_INSTANCES_TABLE;
19952 
19953   // Deallocate/Close the prepared statement.
19954   mysql_stmt_close(sp_stmt);
19955 
19956   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS proc");
19957   myquery(rc);
19958 
19959   rc= mysql_query(mysql, "DROP TABLE IF EXISTS ps_t1");
19960   myquery(rc);
19961 }
19962 
19963 
19964 /**
19965    BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST()
19966 */
test_bug17512527()19967 static void test_bug17512527()
19968 {
19969   MYSQL *conn1, *conn2;
19970   MYSQL_STMT *stmt1, *stmt2;
19971   const char *stmt1_txt= "SELECT NOW();";
19972   const char *stmt2_txt= "SELECT 1;";
19973   unsigned long thread_id;
19974   char query[MAX_TEST_QUERY_LENGTH];
19975   int rc;
19976 
19977   conn1= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
19978   conn2= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 0);
19979 
19980   stmt1 = mysql_stmt_init(conn1);
19981   check_stmt(stmt1);
19982   rc= mysql_stmt_prepare(stmt1, stmt1_txt, strlen(stmt1_txt));
19983   check_execute(stmt1, rc);
19984 
19985   thread_id= mysql_thread_id(conn1);
19986   sprintf(query, "KILL %lu", thread_id);
19987   if (thread_query(query))
19988     exit(1);
19989 
19990   /*
19991     After the connection is killed, the connection is
19992     re-established due to the reconnect flag.
19993   */
19994   stmt2 = mysql_stmt_init(conn1);
19995   check_stmt(stmt2);
19996 
19997   rc= mysql_stmt_prepare(stmt2, stmt2_txt, strlen(stmt2_txt));
19998   check_execute(stmt1, rc);
19999 
20000   mysql_stmt_close(stmt2);
20001   mysql_stmt_close(stmt1);
20002 
20003   mysql_close(conn1);
20004   mysql_close(conn2);
20005 }
20006 
20007 
20008 /**
20009    BUG#20810928: CANNOT SHUTDOWN MYSQL USING JDBC DRIVER
20010 */
test_bug20810928()20011 static void test_bug20810928()
20012 {
20013   MYSQL *l_mysql;
20014   int rc;
20015   uint error_code;
20016 
20017   myheader("test_bug20810928");
20018 
20019   /* initialize the server user */
20020   rc= mysql_query(mysql,
20021                   "CREATE USER bug20810928@localhost IDENTIFIED BY 'bug20810928'");
20022   myquery(rc);
20023 
20024   /* prepare the connection */
20025   l_mysql= mysql_client_init(NULL);
20026   DIE_UNLESS(l_mysql != NULL);
20027 
20028   l_mysql= mysql_real_connect(l_mysql, opt_host, "bug20810928",
20029                               "bug20810928", "test", opt_port,
20030                               opt_unix_socket, 0);
20031 
20032   /*
20033     Try the 0 length shutdown command.
20034     Should fail with the right error code to avoid server restart.
20035   */
20036   rc= simple_command(l_mysql, COM_SHUTDOWN, NULL, 0, 0);
20037   DIE_UNLESS(rc != 0);
20038 
20039   /* check if it's the right error */
20040   error_code= mysql_errno(l_mysql);
20041   DIE_UNLESS(error_code == ER_SPECIFIC_ACCESS_DENIED_ERROR);
20042 
20043   mysql_close(l_mysql);
20044 
20045   /* clean up the server user */
20046   rc= mysql_query(mysql, "DROP USER bug20810928@localhost");
20047   myquery(rc);
20048 }
20049 
20050 
20051 /**
20052    WL#8016: Parser for optimizer hints
20053 */
test_wl8016()20054 static void test_wl8016()
20055 {
20056   MYSQL_RES *result;
20057   int        rc;
20058 
20059   myheader("test_wl8016");
20060 
20061   rc= mysql_query(mysql, "SELECT /*+ ");
20062   DIE_UNLESS(rc);
20063 
20064   rc= mysql_query(mysql, "SELECT /*+ ICP(`test");
20065   DIE_UNLESS(rc);
20066 
20067   rc= mysql_query(mysql, "SELECT /*+ ICP(`test*/ 1");
20068   myquery(rc);
20069 
20070   rc= mysql_query(mysql, "SELECT /*+ ICP(`test*/`*/ 1");
20071   DIE_UNLESS(rc);
20072 
20073   /* get the result */
20074   result= mysql_store_result(mysql);
20075   mytest(result);
20076 
20077   (void) my_process_result_set(result);
20078   mysql_free_result(result);
20079 }
20080 
20081 struct execute_test_query
20082 {
20083   const char *create;
20084   const char *select;
20085   const char *drop;
20086 };
20087 
20088 /**
20089   test_bug20645725 helper function
20090 */
execute_and_test(struct execute_test_query * query,char quote,int result,const char * string,const char * expected,my_bool recursive)20091 static void execute_and_test(struct execute_test_query *query, char quote,
20092                              int result, const char* string,
20093                              const char* expected, my_bool recursive)
20094 {
20095   MYSQL_STMT *stmt;
20096   const char *stmt_text;
20097   int rc;
20098   MYSQL_BIND my_bind[1];
20099   char query_buffer[100];
20100   char param_buffer[50];
20101   char buff[50];
20102   ulong length;
20103 
20104   sprintf(param_buffer, "%c%s%c", quote, string, quote);
20105   sprintf(query_buffer, query->create, param_buffer);
20106 
20107   rc = mysql_real_query(mysql, query_buffer, (ulong)strlen(query_buffer));
20108   DIE_UNLESS(rc == result);
20109   if (result != 0) return;
20110   myquery(rc);
20111 
20112   stmt = mysql_stmt_init(mysql);
20113 
20114   memset(my_bind, 0, sizeof(my_bind));
20115   my_bind[0].buffer = buff;
20116   my_bind[0].length = &length;
20117   my_bind[0].buffer_length = (ulong)sizeof(buff);
20118   my_bind[0].buffer_type = MYSQL_TYPE_STRING;
20119 
20120   mysql_stmt_bind_param(stmt, my_bind);
20121 
20122   stmt_text = query->select;
20123   rc = mysql_stmt_prepare(stmt, stmt_text, (ulong)strlen(stmt_text));
20124   check_execute(stmt, rc);
20125   rc = mysql_stmt_execute(stmt);
20126   check_execute(stmt, rc);
20127 
20128   mysql_stmt_bind_result(stmt, my_bind);
20129 
20130   rc = mysql_stmt_fetch(stmt);
20131   DIE_UNLESS(rc == 0);
20132   DIE_UNLESS(length == (ulong)strlen(expected));
20133   DIE_UNLESS(strcmp(buff, expected) == 0);
20134   rc = mysql_stmt_fetch(stmt);
20135   DIE_UNLESS(rc == MYSQL_NO_DATA);
20136 
20137   mysql_stmt_close(stmt);
20138 
20139   sprintf(query_buffer, query->drop, param_buffer);
20140 
20141   rc = mysql_real_query(mysql, query_buffer, (ulong)strlen(query_buffer));
20142   myquery(rc);
20143 
20144   if (recursive != 0)
20145   {
20146     length = mysql_real_escape_string_quote(mysql, param_buffer, expected,
20147                                             (ulong)strlen(expected), quote);
20148     DIE_UNLESS(length != (ulong)-1);
20149 
20150     execute_and_test(query, quote, result, param_buffer, expected, 0);
20151   }
20152 }
20153 
20154 /**
20155   BUG#20645725 GRAVE ACCENT CHARACTER (`) IS NOT FOLLOWED WITH BACKSLASH
20156                WHEN ESCAPING IT
20157 */
test_bug20645725()20158 static void test_bug20645725()
20159 {
20160   const char *stmt_text;
20161   const char *modes[2];
20162   struct execute_test_query query;
20163   int rc;
20164   int i;
20165 
20166   myheader("test_bug20645725");
20167 
20168   stmt_text = "DROP DATABASE IF EXISTS supertest";
20169   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20170   myquery(rc);
20171 
20172   stmt_text = "CREATE DATABASE supertest";
20173   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20174   myquery(rc);
20175 
20176   stmt_text = "USE supertest";
20177   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20178   myquery(rc);
20179 
20180   stmt_text = "DROP TABLE IF EXISTS t1";
20181   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20182   myquery(rc);
20183   stmt_text = "CREATE TABLE t1 (a TEXT)";
20184   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20185   myquery(rc);
20186 
20187   modes[0]= "SET sql_mode=''";
20188   modes[1]= "SET sql_mode='ANSI_QUOTES'";
20189 
20190   query.create= "INSERT INTO t1 VALUES(%s)";
20191   query.drop= "DELETE FROM t1; -- %s";
20192   query.select= "SELECT a FROM t1";
20193 
20194   for (i = 0; i < (int)(sizeof(modes)/sizeof(modes[0])); i++)
20195   {
20196     rc = mysql_real_query(mysql, modes[i], (ulong)strlen(modes[i]));
20197     myquery(rc);
20198 
20199     execute_and_test(&query, '\'', 0, "aaa",       "aaa",   1);
20200     execute_and_test(&query, '\'', 0, "a\\'",      "a'",    1);
20201     execute_and_test(&query, '\'', 0, "''",        "'",     1);
20202     execute_and_test(&query, '\'', 0, "a''",       "a'",    1);
20203     execute_and_test(&query, '\'', 0, "a''b",      "a'b",   1);
20204     execute_and_test(&query, '\'', 0, "a\\'''\\'", "a'''",  1);
20205     execute_and_test(&query, '\'', 0, "a\\`",      "a`",    1);
20206     execute_and_test(&query, '\'', 0, "a\\n",      "a\n",   1);
20207     execute_and_test(&query, '\'', 0, "a``",       "a``",   1);
20208     execute_and_test(&query, '\'', 0, "a\\``\\`",  "a```",  1);
20209     execute_and_test(&query, '\'', 0, "b\"",       "b\"",   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, '"',  i, "b\\\"\"\"", "b\"\"", 1);
20216     execute_and_test(&query, '"',  i, "d\\'e",     "d'e",   1);
20217     execute_and_test(&query, '`',  1, "",          "",      0);
20218   }
20219 
20220   modes[0]= "SET sql_mode='NO_BACKSLASH_ESCAPES'";
20221   modes[1]= "SET sql_mode='NO_BACKSLASH_ESCAPES,ANSI_QUOTES'";
20222 
20223   for (i = 0; i < (int)(sizeof(modes)/sizeof(modes[0])); i++)
20224   {
20225     rc = mysql_real_query(mysql, modes[i], (ulong)strlen(modes[i]));
20226     myquery(rc);
20227 
20228     execute_and_test(&query, '\'', 0, "aaa",       "aaa",      1);
20229     execute_and_test(&query, '\'', 1, "a\\'",      "",         0);
20230     execute_and_test(&query, '\'', 0, "''",        "'",        1);
20231     execute_and_test(&query, '\'', 0, "a''",       "a'",       1);
20232     execute_and_test(&query, '\'', 0, "a''b",      "a'b",      1);
20233     execute_and_test(&query, '\'', 1, "a\\'''\\'", "",         0);
20234     execute_and_test(&query, '\'', 0, "a\\`",      "a\\`",     1);
20235     execute_and_test(&query, '\'', 0, "a\\n",      "a\\n",     1);
20236     execute_and_test(&query, '\'', 0, "a``",       "a``",      1);
20237     execute_and_test(&query, '\'', 0, "a\\``\\`",  "a\\``\\`", 1);
20238     execute_and_test(&query, '\'', 0, "b\"",       "b\"",      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, '"',  1, "b\\\"\"\"", "",         0);
20244     execute_and_test(&query, '"',  i, "d\\'e",     "d\\'e",    1);
20245     execute_and_test(&query, '`',  1, "",          "",         1);
20246   }
20247 
20248   stmt_text = "DROP TABLE t1";
20249   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20250   myquery(rc);
20251 
20252   stmt_text = "SET sql_mode=''";
20253   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20254   myquery(rc);
20255 
20256   query.create= "CREATE TABLE %s (a INT)";
20257   query.drop= "DROP TABLE %s";
20258   query.select= "SHOW TABLES";
20259 
20260   execute_and_test(&query, '`', 0, "ccc",     "ccc",     1);
20261   execute_and_test(&query, '`', 0, "c``cc",   "c`cc",    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, '`', 1, "c\\`cc",  "",        0);
20265   execute_and_test(&query, '`', 0, "c\"cc",   "c\"cc",   1);
20266   execute_and_test(&query, '`', 0, "c\\\"cc", "c\\\"cc", 1);
20267   execute_and_test(&query, '`', 0, "c\"\"cc", "c\"\"cc", 1);
20268 
20269   stmt_text = "SET sql_mode='ANSI_QUOTES'";
20270   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20271   myquery(rc);
20272 
20273   execute_and_test(&query, '"', 0, "a\"\"a", "a\"a",   0);
20274   execute_and_test(&query, '"', 1, "a\\\"b", "",       0);
20275   execute_and_test(&query, '"', 0, "c\\'cc", "c\\'cc", 0);
20276 
20277   modes[0]= "SET sql_mode='NO_BACKSLASH_ESCAPES'";
20278   modes[1]= "SET sql_mode='NO_BACKSLASH_ESCAPES,ANSI_QUOTES'";
20279 
20280   for (i = 0; i < (int)(sizeof(modes)/sizeof(modes[0])); i++)
20281   {
20282     rc = mysql_real_query(mysql, modes[i], (ulong)strlen(modes[i]));
20283     myquery(rc);
20284 
20285     execute_and_test(&query, '`', 0, "ccc",     "ccc",     1);
20286     execute_and_test(&query, '`', 0, "c``cc",   "c`cc",    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, '`', 1, "c\\`cc",  "",        0);
20290     execute_and_test(&query, '`', 0, "c\"cc",   "c\"cc",   1);
20291     execute_and_test(&query, '`', 0, "c\\\"cc", "c\\\"cc", 1);
20292     execute_and_test(&query, '`', 0, "c\"\"cc", "c\"\"cc", 1);
20293   }
20294 
20295   stmt_text = "DROP DATABASE supertest";
20296   rc = mysql_real_query(mysql, stmt_text, (ulong)strlen(stmt_text));
20297   myquery(rc);
20298 }
20299 
20300 
20301 /**
20302   Bug#20444737  STRING::CHOP ASSERTS ON NAUGHTY TABLE NAMES
20303 */
test_bug20444737()20304 static void test_bug20444737()
20305 {
20306   char query[MAX_TEST_QUERY_LENGTH];
20307   FILE       *test_file;
20308   char       *master_test_filename;
20309   ulong length;
20310   int rc;
20311   const char *test_dir= getenv("MYSQL_TEST_DIR");
20312   const char db_query[]="USE client_test_db";
20313 
20314   myheader("Test_bug20444737");
20315   master_test_filename = (char *) malloc(strlen(test_dir) +
20316                          strlen("/std_data/bug20444737.sql") + 1);
20317   strxmov(master_test_filename, test_dir, "/std_data/bug20444737.sql", NullS);
20318   if (!opt_silent)
20319     fprintf(stdout, "Opening '%s'\n", master_test_filename);
20320   test_file= my_fopen(master_test_filename, (int)(O_RDONLY | O_BINARY), MYF(0));
20321   if (test_file == NULL)
20322   {
20323     fprintf(stderr, "Error in opening file");
20324     free(master_test_filename);
20325     DIE("File open error");
20326   }
20327   else if(fgets(query, MAX_TEST_QUERY_LENGTH, test_file) == NULL)
20328   {
20329     free(master_test_filename);
20330     /* If fgets returned NULL, it indicates either error or EOF */
20331     if (feof(test_file))
20332       DIE("Found EOF before all statements were found");
20333 
20334     fprintf(stderr, "Got error %d while reading from file\n",
20335             ferror(test_file));
20336     DIE("Read error");
20337   }
20338 
20339   rc= mysql_real_query(mysql, db_query, (ulong)strlen(db_query));
20340   myquery(rc);
20341   length= (ulong)strlen(query);
20342   fprintf(stdout, "Query is %s\n", query);
20343   rc= mysql_real_query(mysql, query, (ulong)length);
20344   myquery(rc);
20345 
20346   free(master_test_filename);
20347   my_fclose(test_file, MYF(0));
20348 }
20349 
20350 
20351 /**
20352   Bug#21104470 WL8132:ASSERTION `! IS_SET()' FAILED.
20353 */
test_bug21104470()20354 static void test_bug21104470()
20355 {
20356   MYSQL_RES *result;
20357   int rc;
20358 
20359   myheader("test_bug21104470");
20360 
20361   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20362   myquery(rc);
20363 
20364   rc= mysql_query(mysql, "CREATE TABLE t1(j1 JSON, j2 JSON NOT NULL)");
20365   myquery(rc);
20366 
20367   /* This call used to crash the server. */
20368   result= mysql_list_fields(mysql, "t1", NULL);
20369   mytest(result);
20370 
20371   rc= my_process_result_set(result);
20372   DIE_UNLESS(rc == 0);
20373 
20374   verify_prepare_field(result, 0, "j1", "j1", MYSQL_TYPE_JSON,
20375                        "t1", "t1", current_db, UINT_MAX32, 0);
20376 
20377   verify_prepare_field(result, 1, "j2", "j2", MYSQL_TYPE_JSON,
20378                        "t1", "t1", current_db, UINT_MAX32, 0);
20379 
20380   mysql_free_result(result);
20381   myquery(mysql_query(mysql, "DROP TABLE t1"));
20382 }
20383 
20384 
20385 /**
20386   Bug#21293012 ASSERT `!IS_NULL()' FAILED AT FIELD_JSON::VAL_JSON
20387   ON NEW CONN TO DB WITH VIEW
20388 */
test_bug21293012()20389 static void test_bug21293012()
20390 {
20391   MYSQL_RES *result;
20392   int rc;
20393 
20394   myheader("test_bug21293012");
20395 
20396   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20397   myquery(rc);
20398 
20399   rc= mysql_query(mysql, "CREATE TABLE t1(j1 JSON, j2 JSON NOT NULL)");
20400   myquery(rc);
20401 
20402   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
20403   myquery(rc);
20404 
20405   /* This call used to crash the server. */
20406   result= mysql_list_fields(mysql, "v1", NULL);
20407   mytest(result);
20408 
20409   rc= my_process_result_set(result);
20410   DIE_UNLESS(rc == 0);
20411 
20412   verify_prepare_field(result, 0, "j1", "j1", MYSQL_TYPE_JSON,
20413                        "v1", "v1", current_db, UINT_MAX32, 0);
20414 
20415   verify_prepare_field(result, 1, "j2", "j2", MYSQL_TYPE_JSON,
20416                        "v1", "v1", current_db, UINT_MAX32, 0);
20417 
20418   mysql_free_result(result);
20419   myquery(mysql_query(mysql, "DROP VIEW v1"));
20420   myquery(mysql_query(mysql, "DROP TABLE t1"));
20421 }
20422 
test_bug21199582()20423 static void test_bug21199582()
20424 {
20425   int rc= 0;
20426   int recCnt[]={3,4,1};
20427   int i= 0;
20428 	char query[512]={0};
20429 	MYSQL_BIND in_param_bind;
20430   MYSQL_BIND out_param_bind2;
20431   int in_data= 0;
20432   char cout_data[100]={0};
20433   int rows_number= 0;
20434   int num_fields= 0;
20435   MYSQL_RES *result = NULL;
20436   MYSQL_STMT *stmt;
20437   unsigned long cur_type= CURSOR_TYPE_READ_ONLY;
20438   int iLoop= 0;
20439 
20440   myheader("test_bug21199582");
20441 
20442   for (; i < 2; ++i)
20443   {
20444     iLoop= 0;
20445 
20446     myquery(mysql_query(mysql, "drop procedure if exists p3"));
20447     myquery(mysql_query(mysql, "drop table if exists abcd"));
20448     myquery(mysql_query(mysql, "create table abcd(id int,c char(4))"));
20449     myquery(mysql_query(mysql, "insert into abcd values(1,'a'),(2,'b'),(3,'c')"));
20450 
20451     if(i)
20452     {
20453       sprintf(query,"create procedure p3(INOUT p1 Integer) BEGIN select c from abcd;insert into abcd values(4,'d');"
20454       "select id from abcd;SET NAMES 'utf8';set autocommit = ON;SET p1 = 9999;END");
20455     }
20456     else
20457     {
20458       sprintf(query,"create procedure p3(INOUT p1 Integer) BEGIN select id from abcd;insert into abcd values(4,'d');"
20459       "select id from abcd;SET NAMES 'utf8';set autocommit = ON;SET p1 = 9999;END");
20460     }
20461 
20462     rc = mysql_query(mysql, query);
20463     DIE_UNLESS(rc == 0);
20464 
20465     stmt= mysql_stmt_init(mysql);
20466     DIE_UNLESS(stmt);
20467 
20468     rc = mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &cur_type);
20469     DIE_UNLESS(rc == 0);
20470 
20471     sprintf(query,"call p3(?)");
20472     rc = mysql_stmt_prepare(stmt, query, strlen(query));
20473     DIE_UNLESS(rc == 0);
20474 
20475     memset(&in_param_bind,0,sizeof(in_param_bind));
20476     memset(&out_param_bind2,0,sizeof(out_param_bind2));
20477     in_data= 0;
20478     in_param_bind.buffer_type= MYSQL_TYPE_LONG;
20479     in_param_bind.buffer= (char *) &in_data;
20480     in_param_bind.length= 0;
20481     in_param_bind.is_null= 0;
20482 
20483     out_param_bind2.buffer_type= MYSQL_TYPE_STRING;
20484     out_param_bind2.buffer= (char *) cout_data;
20485     out_param_bind2.length= 0;
20486     out_param_bind2.is_null= 0;
20487     out_param_bind2.buffer_length= (ulong)sizeof(cout_data);
20488 
20489     rc= mysql_stmt_bind_param(stmt, &in_param_bind);
20490     check_execute(stmt, rc);
20491 
20492     rc= mysql_stmt_execute(stmt);
20493     check_execute(stmt, rc);
20494 
20495     rows_number= 0;
20496 
20497     do
20498     {
20499       num_fields = mysql_stmt_field_count(stmt);
20500 
20501       if(num_fields > 0)
20502       {
20503         memset(cout_data,0,sizeof(cout_data));
20504         result = mysql_stmt_result_metadata(stmt);
20505         if(result)
20506         {
20507           rows_number= mysql_stmt_num_rows(stmt);
20508           DIE_UNLESS(rows_number == recCnt[iLoop]);
20509 
20510           rc= mysql_stmt_bind_result(stmt, &out_param_bind2);
20511           check_execute(stmt, rc);
20512 
20513           while (!mysql_stmt_fetch(stmt));
20514 
20515           mysql_free_result(result);
20516         }
20517       }
20518       rc= mysql_stmt_next_result(stmt);
20519       ++iLoop;
20520     }
20521     while(rc==0);
20522 
20523     rc= mysql_stmt_free_result(stmt);
20524     DIE_UNLESS(rc == 0);
20525 
20526     mysql_stmt_close(stmt);
20527   }
20528 }
20529 
20530 
20531 /**
20532   Bug#20821550 ADD MYSQL_GET_PARAMETERS FUNCTIONALITY TO MYSQL_GET_OPTION()
20533 */
test_bug20821550()20534 static void test_bug20821550()
20535 {
20536   MYSQL *mysql_ptr= NULL;
20537   int ret_val;
20538   ulong max_allowed_packet_value= 8192*2;
20539   ulong net_buffer_length_value= 8192*4;
20540   ulong save_max_allowed_packet_value= 0;
20541   ulong save_net_buffer_length_value= 0;
20542   ulong ret_max_allowed_packet_value= 0;
20543   ulong ret_net_buffer_length_value= 0;
20544 
20545   myheader("test_bug20821550");
20546 
20547   /* Try setting/getting values without MYSQL object */
20548 
20549   /* Fetch default values and validate */
20550   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20551                             &save_max_allowed_packet_value);
20552   DIE_UNLESS(ret_val == 0);
20553   DIE_UNLESS(save_max_allowed_packet_value == 1024L*1024L*1024L);
20554 
20555   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20556                             &save_net_buffer_length_value);
20557   DIE_UNLESS(ret_val == 0);
20558   DIE_UNLESS(save_net_buffer_length_value == 8192);
20559 
20560   /* Now set global values */
20561   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20562                          &max_allowed_packet_value);
20563   DIE_UNLESS(ret_val == 0);
20564 
20565   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20566                          &net_buffer_length_value);
20567   DIE_UNLESS(ret_val == 0);
20568 
20569   /* Check that global values are set */
20570   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20571                             &ret_max_allowed_packet_value);
20572   DIE_UNLESS(ret_val == 0);
20573   DIE_UNLESS(ret_max_allowed_packet_value == max_allowed_packet_value);
20574 
20575   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20576                             &ret_net_buffer_length_value);
20577   DIE_UNLESS(ret_val == 0);
20578   DIE_UNLESS(ret_net_buffer_length_value == net_buffer_length_value);
20579 
20580   /* Restore default values */
20581   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20582                          &save_max_allowed_packet_value);
20583   DIE_UNLESS(ret_val == 0);
20584 
20585   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20586                          &save_net_buffer_length_value);
20587   DIE_UNLESS(ret_val == 0);
20588 
20589   /* Create MYSQL object */
20590 
20591   if (!(mysql_ptr= mysql_client_init(NULL)))
20592   {
20593     myerror("mysql_client_init() failed");
20594     exit(1);
20595   }
20596 
20597   /* Now try setting/getting values with MYSQL object */
20598 
20599   mysql_ptr= mysql_real_connect(mysql_ptr, opt_host, opt_user, opt_password,
20600                                 "test", opt_port, opt_unix_socket, 0);
20601 
20602   /* By default, session values of max_allowed_packet is 0 */
20603   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20604                             &ret_max_allowed_packet_value);
20605   DIE_UNLESS(ret_val == 0);
20606   DIE_UNLESS(ret_max_allowed_packet_value == 0);
20607 
20608   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20609                             &ret_net_buffer_length_value);
20610   DIE_UNLESS(ret_val == 0);
20611   DIE_UNLESS(ret_net_buffer_length_value == save_net_buffer_length_value);
20612 
20613   DIE_UNLESS(mysql_ptr->net.max_packet_size == save_max_allowed_packet_value);
20614 
20615   mysql_close(mysql_ptr);
20616 
20617   if (!(mysql_ptr= mysql_client_init(NULL)))
20618   {
20619     myerror("mysql_client_init() failed");
20620     exit(1);
20621   }
20622 
20623   /* Set session value for max_allowed_packet */
20624   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20625                          &max_allowed_packet_value);
20626   DIE_UNLESS(ret_val == 0);
20627 
20628   /* net_buffer_length only has global value */
20629   ret_val= mysql_options(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20630                          &net_buffer_length_value);
20631   DIE_UNLESS(ret_val == 0);
20632 
20633   /* Get session value of max_allowed_packet */
20634   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_MAX_ALLOWED_PACKET,
20635                             &ret_max_allowed_packet_value);
20636   DIE_UNLESS(ret_val == 0);
20637   DIE_UNLESS(ret_max_allowed_packet_value == max_allowed_packet_value);
20638 
20639   ret_val= mysql_get_option(mysql_ptr, MYSQL_OPT_NET_BUFFER_LENGTH,
20640                             &ret_net_buffer_length_value);
20641   DIE_UNLESS(ret_val == 0);
20642   DIE_UNLESS(ret_net_buffer_length_value == net_buffer_length_value);
20643 
20644   /* mysql_real_connect() prefers session value of max_allowed_packet */
20645   mysql_ptr= mysql_real_connect(mysql_ptr, opt_host, opt_user, opt_password,
20646                                 "test", opt_port, opt_unix_socket, 0);
20647 
20648   /* Session value is used for net.max_allowed_size */
20649   DIE_UNLESS(mysql_ptr->net.max_packet_size == max_allowed_packet_value);
20650 
20651   /* Get global value of max_allowed_packet */
20652   ret_val= mysql_get_option(NULL, MYSQL_OPT_MAX_ALLOWED_PACKET,
20653                             &ret_max_allowed_packet_value);
20654   DIE_UNLESS(ret_val == 0);
20655   DIE_UNLESS(ret_max_allowed_packet_value == save_max_allowed_packet_value);
20656 
20657   mysql_close(mysql_ptr);
20658 
20659 }
20660 
check_warning(MYSQL * conn)20661 static void check_warning(MYSQL *conn)
20662 {
20663   MYSQL_RES *result;
20664   int        rc;
20665 
20666   rc= mysql_query(conn, "SHOW WARNINGS");
20667   myquery(rc);
20668   result= mysql_store_result(conn);
20669   mytest(result);
20670   rc= my_process_result_set(result);
20671   DIE_UNLESS(rc == 1);
20672   mysql_free_result(result);
20673 }
20674 
test_wl8754()20675 static void test_wl8754()
20676 {
20677   MYSQL_RES     *res;
20678   MYSQL         *conn;
20679   int           rc;
20680   unsigned long thread_id;
20681   const char    *stmt_text;
20682 
20683   myheader("test_wl8754");
20684 
20685   /* Check that mysql_list_fields reports deprecated warning. */
20686   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20687   myquery(rc);
20688   stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
20689   rc= mysql_real_query(mysql, stmt_text, (ulong) strlen(stmt_text));
20690   myquery(rc);
20691 
20692   res= mysql_list_fields(mysql, "t1", "%");
20693   mysql_free_result(res);
20694 
20695   check_warning(mysql);
20696 
20697   stmt_text= "DROP TABLE t1";
20698   rc= mysql_real_query(mysql, stmt_text, (ulong) strlen(stmt_text));
20699   myquery(rc);
20700 
20701   /* Check that mysql_refresh() reports deprecated warning. */
20702   rc= mysql_refresh(mysql, REFRESH_TABLES);
20703   myquery(rc);
20704 
20705   check_warning(mysql);
20706 
20707   /* Run a dummy query to clear diagnostics. */
20708   rc= mysql_query(mysql, "SELECT 1");
20709   myquery(rc);
20710   /* Get the result. */
20711   res= mysql_store_result(mysql);
20712   mytest(res);
20713   (void) my_process_result_set(res);
20714   mysql_free_result(res);
20715 
20716   /* Check that mysql_list_processes() reports deprecated warning. */
20717   res= mysql_list_processes(mysql);
20718   mysql_free_result(res);
20719 
20720   check_warning(mysql);
20721 
20722   /* Check that mysql_kill() reports deprecated warning. */
20723   if (!(conn= mysql_client_init(NULL)))
20724   {
20725     myerror("mysql_client_init() failed");
20726     exit(1);
20727   }
20728   conn->reconnect= 1;
20729   if (!(mysql_real_connect(conn, opt_host, opt_user,
20730                            opt_password, current_db, opt_port,
20731                            opt_unix_socket, 0)))
20732   {
20733     myerror("connection failed");
20734     exit(1);
20735   }
20736   thread_id= mysql_thread_id(conn);
20737   /*
20738     Kill connection would have killed the existing connection which clears
20739     the THD state and reconnects with a new THD thus there will be no
20740     warnings.
20741   */
20742   mysql_kill(conn, (unsigned long) thread_id);
20743   mysql_close(conn);
20744  }
20745 
20746 /*
20747   BUG#17883203: MYSQL EMBEDDED MYSQL_STMT_EXECUTE RETURN
20748                 "MALFORMED COMMUNICATION PACKET" ERROR
20749 */
20750 #define BUG17883203_STRING_SIZE 100
20751 
test_bug17883203()20752 static void test_bug17883203()
20753 {
20754   MYSQL_STMT *stmt;
20755   MYSQL_BIND bind;
20756   char str_data[BUG17883203_STRING_SIZE];
20757   my_bool is_null;
20758   my_bool error;
20759   unsigned long length;
20760   const char stmt_text[] ="SELECT VERSION()";
20761   int rc;
20762 
20763   myheader("test_bug17883203");
20764 
20765   stmt = mysql_stmt_init(mysql);
20766   check_stmt(stmt);
20767   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
20768   check_execute(stmt, rc);
20769   rc= mysql_stmt_execute(stmt);
20770   check_execute(stmt, rc);
20771   memset(&bind, 0, sizeof(bind));
20772 
20773   bind.buffer_type= MYSQL_TYPE_STRING;
20774   bind.buffer= (char *)str_data;
20775   bind.buffer_length= BUG17883203_STRING_SIZE;
20776   bind.is_null= &is_null;
20777   bind.length= &length;
20778   bind.error= &error;
20779 
20780   rc= mysql_stmt_bind_result(stmt, &bind);
20781   check_execute(stmt, rc);
20782   rc= mysql_stmt_fetch(stmt);
20783   check_execute(stmt, rc);
20784 
20785   if (!opt_silent)
20786   {
20787     fprintf(stdout, "\n Version: %s", str_data);
20788   }
20789   mysql_stmt_close(stmt);
20790 }
20791 
20792 /*
20793   Bug#22559575: "the statement (1) has no open cursor" pops
20794                 sometimes with prepared+query_cache
20795 */
bug22559575_base(unsigned long type)20796 static void bug22559575_base(unsigned long type)
20797 {
20798   MYSQL_STMT *stmt;
20799   int rc;
20800   const char stmt_text[] ="SELECT a FROM t22559575";
20801   MYSQL_RES *prepare_meta = NULL;
20802   MYSQL_BIND bind[1];
20803   short data;
20804   unsigned long length;
20805 
20806   stmt = mysql_stmt_init(mysql);
20807   check_stmt(stmt);
20808   if (type == CURSOR_TYPE_READ_ONLY)
20809   {
20810     rc = mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*)&type);
20811     check_execute(stmt, rc);
20812   }
20813   rc = mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
20814   check_execute(stmt, rc);
20815   prepare_meta = mysql_stmt_result_metadata(stmt);
20816   DIE_UNLESS(prepare_meta != NULL);
20817   rc= mysql_stmt_execute(stmt);
20818   check_execute(stmt, rc);
20819 
20820   memset(bind, 0, sizeof(bind));
20821   bind[0].buffer_type= MYSQL_TYPE_SHORT;
20822   bind[0].buffer= (void *)&data;
20823   bind[0].length= &length;
20824   rc= mysql_stmt_bind_result(stmt, bind);
20825   check_execute(stmt, rc);
20826 
20827   rc= mysql_stmt_store_result(stmt);
20828   check_execute(stmt, rc);
20829 
20830   rc= mysql_stmt_fetch(stmt);
20831   check_execute(stmt, rc);
20832   DIE_UNLESS(data == 1);
20833 
20834   mysql_free_result(prepare_meta);
20835   rc= mysql_stmt_close(stmt);
20836   check_execute(stmt, rc);
20837 }
20838 
test_bug22559575()20839 static void test_bug22559575()
20840 {
20841   int rc;
20842 
20843   rc= mysql_query(mysql, "CREATE TABLE t22559575(a SMALLINT)");
20844   myquery(rc);
20845   rc= mysql_query(mysql, "INSERT INTO t22559575 VALUES (1)");
20846   myquery(rc);
20847 
20848   /* Should not cache */
20849   bug22559575_base(CURSOR_TYPE_READ_ONLY);
20850   bug22559575_base(CURSOR_TYPE_READ_ONLY);
20851   /* Should save to cache */
20852   bug22559575_base(CURSOR_TYPE_NO_CURSOR);
20853   /* Should use cache */
20854   bug22559575_base(CURSOR_TYPE_NO_CURSOR);
20855   /* should not use cache */
20856   bug22559575_base(CURSOR_TYPE_READ_ONLY);
20857 
20858   rc= mysql_query(mysql, "DROP TABLE t22559575");
20859   myquery(rc);
20860 }
20861 
20862 
20863 /**
20864    BUG#19894382 - SERVER SIDE PREPARED STATEMENTS LEADS TO POTENTIAL OFF-BY-SECOND
20865                   TIMESTAMP ON SLAVE
20866 */
test_bug19894382()20867 static void test_bug19894382()
20868 {
20869   MYSQL_STMT *stmt1;
20870   const char *stmt1_txt= "INSERT INTO client_test_db.bug19894382 VALUES"
20871                          " ('master', ?, ?, ?, ?, ?, ?);";
20872   my_bool    is_null= 0;
20873   MYSQL_BIND bind_val[6];
20874   MYSQL_TIME tm[6];
20875   MYSQL_TIME tm_common;
20876   ulong      length= sizeof(MYSQL_TIME);
20877   int ind;
20878   int rc;
20879 
20880   myheader("test_bug19894382");
20881 
20882   rc= mysql_query(mysql, "DROP TABLE IF EXISTS client_test_db.bug19894382;");
20883   myquery(rc);
20884   rc= mysql_query(mysql, "CREATE TABLE client_test_db.bug19894382(f1 CHAR(64),"
20885                          " f2 TIME, f3 TIMESTAMP NULL, f4 DATETIME,"
20886                          " f5 TIME(3), f6 TIMESTAMP(3) NULL,"
20887                          " f7 DATETIME(3));");
20888   myquery(rc);
20889 
20890   stmt1 = mysql_stmt_init(mysql);
20891   check_stmt(stmt1);
20892 
20893   // Prepare statement
20894   rc= mysql_stmt_prepare(stmt1, stmt1_txt, strlen(stmt1_txt));
20895   check_execute(stmt1, rc);
20896 
20897   // Prepare and bind values.
20898   tm_common.year= 2015;
20899   tm_common.month= 4;
20900   tm_common.day= 24;
20901   tm_common.hour= 7;
20902   tm_common.minute= 30;
20903   tm_common.second= 30;
20904   tm_common.second_part= 5010;
20905   tm_common.neg= 0;
20906   tm_common.time_type= MYSQL_TIMESTAMP_NONE;
20907 
20908   memset(bind_val, 0, sizeof(MYSQL_BIND) * 6);
20909   for (ind= 0; ind < 6; ind++)
20910   {
20911     tm[ind]= tm_common;
20912     bind_val[ind].buffer= (void *) &tm[ind];
20913     bind_val[ind].is_null= &is_null;
20914     bind_val[ind].length= &length;
20915     bind_val[ind].buffer_length= sizeof(MYSQL_TIME);
20916     switch(ind%3)
20917     {
20918     case 0:
20919       tm[ind].year= tm[ind].month= tm[ind].day= 0;
20920       bind_val[ind].buffer_type= MYSQL_TYPE_TIME;
20921       tm[ind].time_type= MYSQL_TIMESTAMP_TIME;
20922       break;
20923     case 1:
20924       bind_val[ind].buffer_type= MYSQL_TYPE_TIMESTAMP;
20925       tm[ind].time_type= MYSQL_TIMESTAMP_DATETIME;
20926       break;
20927     case 2:
20928       bind_val[ind].buffer_type= MYSQL_TYPE_DATETIME;
20929       tm[ind].time_type= MYSQL_TIMESTAMP_DATETIME;
20930       break;
20931     }
20932   }
20933   rc= mysql_stmt_bind_param(stmt1, bind_val);
20934   check_execute(stmt1, rc);
20935 
20936   /* Execute the insert statement */
20937   rc= mysql_stmt_execute(stmt1);
20938   check_execute(stmt1, rc);
20939   for (ind= 0; ind < 6; ind++)
20940   {
20941     tm[ind].second_part= 501900;
20942   }
20943   /* Execute the insert statement */
20944   rc= mysql_stmt_execute(stmt1);
20945   check_execute(stmt1, rc);
20946 
20947   rc= mysql_commit(mysql);
20948   myquery(rc);
20949 
20950   mysql_stmt_close(stmt1);
20951 }
20952 
test_bug25701141()20953 static void test_bug25701141()
20954 {
20955   MYSQL_STMT *stmt;
20956   int rc;
20957   MYSQL_BIND my_bind[2];
20958   char query[MAX_TEST_QUERY_LENGTH];
20959   const char* input1= "abcdefgh";
20960   const char* input2=  "mnopqrst";
20961   const ulong type = CURSOR_TYPE_READ_ONLY;
20962 
20963   myheader("test_bug25701141");
20964 
20965   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20966   myquery(rc);
20967 
20968   rc= mysql_query(mysql, "CREATE TABLE t1( "
20969       "id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,"
20970       "serial CHAR(10) NOT NULL,"
20971       "pretty CHAR(20) DEFAULT NULL,"
20972       "CONSTRAINT UNIQUE KEY unique_serial (serial) USING HASH,"
20973       "INDEX pretty_index USING HASH (pretty)"
20974       ") ENGINE = InnoDB CHARSET = utf8 COLLATE = utf8_bin");
20975   myquery(rc);
20976 
20977   my_stpcpy(query, "INSERT IGNORE INTO t1 SET `serial`=?, `pretty`=?");
20978   stmt= mysql_simple_prepare(mysql, query);
20979   check_stmt(stmt);
20980 
20981   memset(my_bind, 0, sizeof(my_bind));
20982   my_bind[0].buffer_type = MYSQL_TYPE_STRING;
20983   my_bind[0].buffer = (char*)input1;
20984   my_bind[0].buffer_length = (ulong)strlen(input1);
20985 
20986   my_bind[1].buffer_type = MYSQL_TYPE_STRING;
20987   my_bind[1].buffer = (char*)input2;
20988   my_bind[1].buffer_length = (ulong)strlen(input2);
20989 
20990   rc= mysql_stmt_bind_param(stmt, my_bind);
20991   check_execute(stmt, rc);
20992   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &type);
20993 
20994   /* Execute */
20995   rc= mysql_stmt_execute(stmt);
20996   check_execute(stmt, rc);
20997   mysql_stmt_close(stmt);
20998 
20999   myquery(mysql_query(mysql, "DROP TABLE t1"));
21000 }
21001 
test_bug27443252()21002 static void test_bug27443252()
21003 {
21004   MYSQL_STMT *stmt;
21005   MYSQL_BIND my_bind[1];
21006   int rc;
21007   int32 a;
21008   int row_count=0;
21009   int column_count=0;
21010   MYSQL_RES *metadata = NULL;
21011 
21012   myheader("test_bug27443252");
21013 
21014   rc= mysql_query(mysql, "drop procedure if exists p1");
21015   myquery(rc);
21016   rc= mysql_query(mysql, "drop table if exists p1");
21017   myquery(rc);
21018   rc= mysql_query(mysql, "create table t1 (id int)");
21019   myquery(rc);
21020   rc= mysql_query(mysql, "create procedure p1() begin select * from t1; end");
21021   myquery(rc);
21022 
21023   /* Case 1 - Procedure call with empty result set */
21024   stmt= open_cursor("call p1");
21025   /* This should not result in hang */
21026   rc= mysql_stmt_execute(stmt);
21027   check_execute(stmt, rc);
21028 
21029   metadata = mysql_stmt_result_metadata(stmt);
21030   if (metadata)
21031   {
21032     column_count = mysql_num_fields(metadata);
21033     DIE_UNLESS(column_count == 1);
21034   }
21035 
21036   memset(my_bind, 0, sizeof(my_bind));
21037   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
21038   my_bind[0].buffer= (void*)&a;
21039   my_bind[0].buffer_length= (ulong)sizeof(a);
21040   rc= mysql_stmt_bind_result(stmt, my_bind);
21041   check_execute(stmt, rc);
21042 
21043   while (!mysql_stmt_fetch(stmt))
21044     row_count++;
21045   DIE_UNLESS(row_count == 0);
21046 
21047   rc = mysql_stmt_next_result(stmt);
21048   check_execute(stmt, rc);
21049   rc= mysql_stmt_free_result(stmt);
21050   check_execute(stmt, rc);
21051   mysql_free_result(metadata);
21052   mysql_stmt_close(stmt);
21053 
21054   /* Case 2 - SELECT with empty result set */
21055   row_count= 0;
21056   stmt= open_cursor("select * from t1");
21057   rc= mysql_stmt_execute(stmt);
21058   check_execute(stmt, rc);
21059 
21060   memset(my_bind, 0, sizeof(my_bind));
21061   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
21062   my_bind[0].buffer= (void*)&a;
21063   my_bind[0].buffer_length= (ulong)sizeof(a);
21064 
21065   rc= mysql_stmt_bind_result(stmt, my_bind);
21066   check_execute(stmt, rc);
21067 
21068   while (!mysql_stmt_fetch(stmt))
21069     row_count++;
21070   DIE_UNLESS(row_count == 0);
21071   mysql_stmt_close(stmt);
21072 
21073   /* Case 3 - Procedure call with non-empty result set */
21074   rc= mysql_query(mysql, "insert into t1 (id) values "
21075                           " (1), (2), (3)");
21076   myquery(rc);
21077   row_count= 0;
21078   stmt= open_cursor("call p1");
21079   rc= mysql_stmt_execute(stmt);
21080   check_execute(stmt, rc);
21081 
21082   memset(my_bind, 0, sizeof(my_bind));
21083   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
21084   my_bind[0].buffer= (void*)&a;
21085   my_bind[0].buffer_length= (ulong)sizeof(a);
21086   rc= mysql_stmt_bind_result(stmt, my_bind);
21087   check_execute(stmt, rc);
21088 
21089   while (!mysql_stmt_fetch(stmt))
21090     row_count++;
21091   DIE_UNLESS(row_count == 3);
21092 
21093   rc = mysql_stmt_next_result(stmt);
21094   check_execute(stmt, rc);
21095   rc= mysql_stmt_free_result(stmt);
21096   check_execute(stmt, rc);
21097   mysql_stmt_close(stmt);
21098 
21099   /* Case 4 - SELECT with Non-empty result set */
21100   row_count= 0;
21101   stmt= open_cursor("select * from t1");
21102   rc= mysql_stmt_execute(stmt);
21103   check_execute(stmt, rc);
21104 
21105   memset(my_bind, 0, sizeof(my_bind));
21106   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
21107   my_bind[0].buffer= (void*)&a;
21108   my_bind[0].buffer_length= (ulong)sizeof(a);
21109   rc= mysql_stmt_bind_result(stmt, my_bind);
21110   check_execute(stmt, rc);
21111 
21112   while (!mysql_stmt_fetch(stmt))
21113     row_count++;
21114   DIE_UNLESS(row_count == 3);
21115 
21116   rc= mysql_stmt_free_result(stmt);
21117   check_execute(stmt, rc);
21118   mysql_stmt_close(stmt);
21119 
21120   /* Cleanup */
21121   rc= mysql_query(mysql, "drop table t1");
21122   myquery(rc);
21123   rc= mysql_query(mysql, "drop procedure p1");
21124   myquery(rc);
21125 }
21126 
21127 
test_bug32391415()21128 static void test_bug32391415()
21129 {
21130   MYSQL *lmysql;
21131   MYSQL_ROW row;
21132   MYSQL_RES *res;
21133   int rc;
21134 
21135   myheader("test_bug32391415");
21136 
21137   lmysql= mysql_client_init(NULL);
21138   DIE_UNLESS(lmysql != NULL);
21139 
21140   lmysql= mysql_real_connect(lmysql, opt_host, opt_user,
21141                          opt_password, current_db, opt_port,
21142                          opt_unix_socket, 0);
21143   DIE_UNLESS(lmysql != 0);
21144   if (!opt_silent)
21145     fprintf(stdout, "Established a test connection\n");
21146 
21147   rc= mysql_query(lmysql, "CREATE USER b32391415@localhost");
21148   myquery2(lmysql, rc);
21149   rc= mysql_query(lmysql, "GRANT ALL PRIVILEGES ON *.* TO b32391415@localhost");
21150   myquery2(lmysql, rc);
21151 
21152   if (!opt_silent)
21153     fprintf(stdout, "Created the user\n");
21154 
21155   /* put in an attr */
21156   rc= mysql_options4(lmysql, MYSQL_OPT_CONNECT_ATTR_ADD,
21157                      "key1", "value1");
21158   DIE_UNLESS(rc == 0);
21159 
21160   rc= mysql_change_user(lmysql, "b32391415", NULL, NULL);
21161   myquery2(lmysql, rc);
21162 
21163   /* success: the query attribute should be present */
21164   rc= mysql_query(lmysql,
21165                   "SELECT ATTR_NAME, ATTR_VALUE "
21166                   " FROM performance_schema.session_account_connect_attrs"
21167                   " WHERE ATTR_NAME IN ('key1') AND"
21168                   "  PROCESSLIST_ID = CONNECTION_ID() ORDER BY ATTR_NAME");
21169   myquery2(lmysql,rc);
21170   res = mysql_use_result(lmysql);
21171   DIE_UNLESS(res);
21172 
21173   row= mysql_fetch_row(res);
21174   DIE_UNLESS(row);
21175   DIE_UNLESS(0 == strcmp(row[0], "key1"));
21176   DIE_UNLESS(0 == strcmp(row[1], "value1"));
21177   if (!opt_silent)
21178     fprintf(stdout, "Checked the query attribute\n");
21179 
21180   mysql_free_result(res);
21181 
21182   mysql_close(lmysql);
21183 
21184   rc= mysql_query(mysql, "DROP USER b32391415@localhost");
21185   myquery2(mysql, rc);
21186 }
21187 
21188 static struct my_tests_st my_tests[]= {
21189   { "disable_query_logs", disable_query_logs },
21190   { "test_view_sp_list_fields", test_view_sp_list_fields },
21191   { "client_query", client_query },
21192   { "test_prepare_insert_update", test_prepare_insert_update},
21193 #if NOT_YET_WORKING
21194   { "test_drop_temp", test_drop_temp },
21195 #endif
21196   { "test_fetch_seek", test_fetch_seek },
21197   { "test_fetch_nobuffs", test_fetch_nobuffs },
21198   { "test_open_direct", test_open_direct },
21199   { "test_fetch_null", test_fetch_null },
21200   { "test_ps_null_param", test_ps_null_param },
21201   { "test_fetch_date", test_fetch_date },
21202   { "test_fetch_str", test_fetch_str },
21203   { "test_fetch_long", test_fetch_long },
21204   { "test_fetch_short", test_fetch_short },
21205   { "test_fetch_tiny", test_fetch_tiny },
21206   { "test_fetch_bigint", test_fetch_bigint },
21207   { "test_fetch_float", test_fetch_float },
21208   { "test_fetch_double", test_fetch_double },
21209   { "test_bind_result_ext", test_bind_result_ext },
21210   { "test_bind_result_ext1", test_bind_result_ext1 },
21211   { "test_select_direct", test_select_direct },
21212   { "test_select_prepare", test_select_prepare },
21213   { "test_select", test_select },
21214   { "test_select_version", test_select_version },
21215   { "test_ps_conj_select", test_ps_conj_select },
21216   { "test_select_show_table", test_select_show_table },
21217   { "test_func_fields", test_func_fields },
21218   { "test_long_data", test_long_data },
21219   { "test_insert", test_insert },
21220   { "test_set_variable", test_set_variable },
21221   { "test_select_show", test_select_show },
21222   { "test_prepare_noparam", test_prepare_noparam },
21223   { "test_bind_result", test_bind_result },
21224   { "test_prepare_simple", test_prepare_simple },
21225   { "test_prepare", test_prepare },
21226   { "test_null", test_null },
21227   { "test_debug_example", test_debug_example },
21228   { "test_update", test_update },
21229   { "test_simple_update", test_simple_update },
21230   { "test_simple_delete", test_simple_delete },
21231   { "test_double_compare", test_double_compare },
21232   { "client_store_result", client_store_result },
21233   { "client_use_result", client_use_result },
21234   { "test_tran_bdb", test_tran_bdb },
21235   { "test_tran_innodb", test_tran_innodb },
21236   { "test_prepare_ext", test_prepare_ext },
21237   { "test_prepare_syntax", test_prepare_syntax },
21238   { "test_field_names", test_field_names },
21239   { "test_field_flags", test_field_flags },
21240   { "test_long_data_str", test_long_data_str },
21241   { "test_long_data_str1", test_long_data_str1 },
21242   { "test_long_data_bin", test_long_data_bin },
21243   { "test_warnings", test_warnings },
21244   { "test_errors", test_errors },
21245   { "test_prepare_resultset", test_prepare_resultset },
21246   { "test_stmt_close", test_stmt_close },
21247   { "test_prepare_field_result", test_prepare_field_result },
21248   { "test_multi_stmt", test_multi_stmt },
21249   { "test_multi_statements", test_multi_statements },
21250   { "test_prepare_multi_statements", test_prepare_multi_statements },
21251   { "test_store_result", test_store_result },
21252   { "test_store_result1", test_store_result1 },
21253   { "test_store_result2", test_store_result2 },
21254   { "test_subselect", test_subselect },
21255   { "test_date", test_date },
21256   { "test_date_frac", test_date_frac },
21257   { "test_temporal_param", test_temporal_param },
21258   { "test_date_date", test_date_date },
21259   { "test_date_time", test_date_time },
21260   { "test_date_ts", test_date_ts },
21261   { "test_date_dt", test_date_dt },
21262   { "test_prepare_alter", test_prepare_alter },
21263   { "test_manual_sample", test_manual_sample },
21264   { "test_pure_coverage", test_pure_coverage },
21265   { "test_buffers", test_buffers },
21266   { "test_ushort_bug", test_ushort_bug },
21267   { "test_sshort_bug", test_sshort_bug },
21268   { "test_stiny_bug", test_stiny_bug },
21269   { "test_field_misc", test_field_misc },
21270   { "test_set_option", test_set_option },
21271 #ifdef EMBEDDED_LIBRARY
21272   { "test_embedded_start_stop", test_embedded_start_stop },
21273 #endif
21274 #ifndef EMBEDDED_LIBRARY
21275   { "test_prepare_grant", test_prepare_grant },
21276 #endif
21277   { "test_frm_bug", test_frm_bug },
21278   { "test_explain_bug", test_explain_bug },
21279   { "test_decimal_bug", test_decimal_bug },
21280   { "test_nstmts", test_nstmts },
21281   { "test_logs;", test_logs },
21282   { "test_cuted_rows", test_cuted_rows },
21283   { "test_fetch_offset", test_fetch_offset },
21284   { "test_fetch_column", test_fetch_column },
21285   { "test_mem_overun", test_mem_overun },
21286   { "test_list_fields", test_list_fields },
21287   { "test_free_result", test_free_result },
21288   { "test_free_store_result", test_free_store_result },
21289   { "test_sqlmode", test_sqlmode },
21290   { "test_ts", test_ts },
21291   { "test_bug1115", test_bug1115 },
21292   { "test_bug1180", test_bug1180 },
21293   { "test_bug1500", test_bug1500 },
21294   { "test_bug1644", test_bug1644 },
21295   { "test_bug1946", test_bug1946 },
21296   { "test_bug2248", test_bug2248 },
21297   { "test_parse_error_and_bad_length", test_parse_error_and_bad_length },
21298   { "test_bug2247", test_bug2247 },
21299   { "test_subqueries", test_subqueries },
21300   { "test_bad_union", test_bad_union },
21301   { "test_distinct", test_distinct },
21302   { "test_subqueries_ref", test_subqueries_ref },
21303   { "test_union", test_union },
21304   { "test_bug3117", test_bug3117 },
21305   { "test_join", test_join },
21306   { "test_selecttmp", test_selecttmp },
21307   { "test_create_drop", test_create_drop },
21308   { "test_rename", test_rename },
21309   { "test_do_set", test_do_set },
21310   { "test_multi", test_multi },
21311   { "test_insert_select", test_insert_select },
21312   { "test_bind_nagative", test_bind_nagative },
21313   { "test_derived", test_derived },
21314   { "test_xjoin", test_xjoin },
21315   { "test_bug3035", test_bug3035 },
21316   { "test_union2", test_union2 },
21317   { "test_bug1664", test_bug1664 },
21318   { "test_union_param", test_union_param },
21319   { "test_order_param", test_order_param },
21320   { "test_ps_i18n", test_ps_i18n },
21321   { "test_bug3796", test_bug3796 },
21322   { "test_bug4026", test_bug4026 },
21323   { "test_bug4079", test_bug4079 },
21324   { "test_bug4236", test_bug4236 },
21325   { "test_bug4030", test_bug4030 },
21326   { "test_bug5126", test_bug5126 },
21327   { "test_bug4231", test_bug4231 },
21328   { "test_bug5399", test_bug5399 },
21329   { "test_bug5194", test_bug5194 },
21330   { "test_bug5315", test_bug5315 },
21331   { "test_bug6049", test_bug6049 },
21332   { "test_bug6058", test_bug6058 },
21333   { "test_bug6059", test_bug6059 },
21334   { "test_bug6046", test_bug6046 },
21335   { "test_bug6081", test_bug6081 },
21336   { "test_bug6096", test_bug6096 },
21337   { "test_datetime_ranges", test_datetime_ranges },
21338   { "test_bug4172", test_bug4172 },
21339   { "test_conversion", test_conversion },
21340   { "test_rewind", test_rewind },
21341   { "test_bug6761", test_bug6761 },
21342   { "test_view", test_view },
21343   { "test_view_where", test_view_where },
21344   { "test_view_2where", test_view_2where },
21345   { "test_view_star", test_view_star },
21346   { "test_view_insert", test_view_insert },
21347   { "test_left_join_view", test_left_join_view },
21348   { "test_view_insert_fields", test_view_insert_fields },
21349   { "test_basic_cursors", test_basic_cursors },
21350   { "test_cursors_with_union", test_cursors_with_union },
21351   { "test_cursors_with_procedure", test_cursors_with_procedure },
21352   { "test_truncation", test_truncation },
21353   { "test_truncation_option", test_truncation_option },
21354   { "test_client_character_set", test_client_character_set },
21355   { "test_bug8330", test_bug8330 },
21356   { "test_bug7990", test_bug7990 },
21357   { "test_bug8378", test_bug8378 },
21358   { "test_bug8722", test_bug8722 },
21359   { "test_bug8880", test_bug8880 },
21360   { "test_bug9159", test_bug9159 },
21361   { "test_bug9520", test_bug9520 },
21362   { "test_bug9478", test_bug9478 },
21363   { "test_bug9643", test_bug9643 },
21364   { "test_bug10729", test_bug10729 },
21365   { "test_bug11111", test_bug11111 },
21366   { "test_bug9992", test_bug9992 },
21367   { "test_bug10736", test_bug10736 },
21368   { "test_bug10794", test_bug10794 },
21369   { "test_bug11172", test_bug11172 },
21370   { "test_bug11656", test_bug11656 },
21371   { "test_bug10214", test_bug10214 },
21372   { "test_bug21246", test_bug21246 },
21373   { "test_bug9735", test_bug9735 },
21374   { "test_bug11183", test_bug11183 },
21375   { "test_bug11037", test_bug11037 },
21376   { "test_bug10760", test_bug10760 },
21377   { "test_bug12001", test_bug12001 },
21378   { "test_bug11718", test_bug11718 },
21379   { "test_bug12925", test_bug12925 },
21380   { "test_bug11909", test_bug11909 },
21381   { "test_bug11901", test_bug11901 },
21382   { "test_bug11904", test_bug11904 },
21383   { "test_bug12243", test_bug12243 },
21384   { "test_bug14210", test_bug14210 },
21385   { "test_bug13488", test_bug13488 },
21386   { "test_bug13524", test_bug13524 },
21387   { "test_bug14845", test_bug14845 },
21388   { "test_opt_reconnect", test_opt_reconnect },
21389   { "test_bug15510", test_bug15510},
21390 #ifndef EMBEDDED_LIBRARY
21391   { "test_bug12744", test_bug12744 },
21392 #endif
21393   { "test_bug16143", test_bug16143 },
21394   { "test_bug16144", test_bug16144 },
21395   { "test_bug15613", test_bug15613 },
21396   { "test_bug20152", test_bug20152 },
21397   { "test_bug14169", test_bug14169 },
21398   { "test_bug17667", test_bug17667 },
21399   { "test_bug15752", test_bug15752 },
21400   { "test_mysql_insert_id", test_mysql_insert_id },
21401   { "test_bug19671", test_bug19671 },
21402   { "test_bug21206", test_bug21206 },
21403   { "test_bug21726", test_bug21726 },
21404   { "test_bug15518", test_bug15518 },
21405   { "test_bug23383", test_bug23383 },
21406   { "test_bug32265", test_bug32265 },
21407   { "test_bug21635", test_bug21635 },
21408   { "test_status",   test_status   },
21409   { "test_bug24179", test_bug24179 },
21410   { "test_ps_query_cache", test_ps_query_cache },
21411   { "test_bug28075", test_bug28075 },
21412   { "test_bug27876", test_bug27876 },
21413   { "test_bug28505", test_bug28505 },
21414   { "test_bug28934", test_bug28934 },
21415   { "test_bug27592", test_bug27592 },
21416   { "test_bug29687", test_bug29687 },
21417   { "test_bug29692", test_bug29692 },
21418   { "test_bug29306", test_bug29306 },
21419   { "test_change_user", test_change_user },
21420   { "test_bug30472", test_bug30472 },
21421   { "test_bug20023", test_bug20023 },
21422   { "test_bug45010", test_bug45010 },
21423   { "test_bug53371", test_bug53371 },
21424   { "test_bug31418", test_bug31418 },
21425   { "test_bug31669", test_bug31669 },
21426   { "test_bug28386", test_bug28386 },
21427   { "test_wl4166_1", test_wl4166_1 },
21428   { "test_wl4166_2", test_wl4166_2 },
21429   { "test_wl4166_3", test_wl4166_3 },
21430   { "test_wl4166_4", test_wl4166_4 },
21431   { "test_bug36004", test_bug36004 },
21432   { "test_wl4284_1", test_wl4284_1 },
21433   { "test_wl4435",   test_wl4435 },
21434   { "test_wl4435_2", test_wl4435_2 },
21435   { "test_wl4435_3", test_wl4435_3 },
21436   { "test_bug38486", test_bug38486 },
21437   { "test_bug33831", test_bug33831 },
21438   { "test_bug40365", test_bug40365 },
21439   { "test_bug43560", test_bug43560 },
21440   { "test_bug36326", test_bug36326 },
21441   { "test_bug41078", test_bug41078 },
21442   { "test_bug44495", test_bug44495 },
21443   { "test_bug49972", test_bug49972 },
21444   { "test_bug42373", test_bug42373 },
21445   { "test_bug54041", test_bug54041 },
21446   { "test_bug47485", test_bug47485 },
21447   { "test_bug58036", test_bug58036 },
21448   { "test_bug57058", test_bug57058 },
21449   { "test_bug56976", test_bug56976 },
21450   { "test_bug11766854", test_bug11766854 },
21451   { "test_bug54790", test_bug54790 },
21452   { "test_bug12337762", test_bug12337762 },
21453   { "test_bug11754979", test_bug11754979 },
21454   { "test_bug13001491", test_bug13001491 },
21455   { "test_wl5968", test_wl5968 },
21456   { "test_wl5924", test_wl5924 },
21457   { "test_wl6587", test_wl6587 },
21458   { "test_wl5928", test_wl5928 },
21459   { "test_wl6797", test_wl6797 },
21460   { "test_wl6791", test_wl6791 },
21461   { "test_wl5768", test_wl5768 },
21462 #ifndef EMBEDDED_LIBRARY
21463   { "test_bug17309863", test_bug17309863},
21464 #endif
21465   { "test_bug17512527", test_bug17512527},
21466   { "test_bug20810928", test_bug20810928 },
21467   { "test_wl8016", test_wl8016},
21468   { "test_bug20645725", test_bug20645725 },
21469   { "test_bug20444737", test_bug20444737},
21470   { "test_bug21104470", test_bug21104470 },
21471   { "test_bug21293012", test_bug21293012 },
21472   { "test_bug21199582", test_bug21199582 },
21473   { "test_bug20821550", test_bug20821550 },
21474   { "test_wl8754", test_wl8754 },
21475   { "test_bug17883203", test_bug17883203 },
21476   { "test_bug22559575", test_bug22559575 },
21477   { "test_bug19894382", test_bug19894382 },
21478   { "test_bug22028117", test_bug22028117 },
21479   { "test_bug25701141", test_bug25701141 },
21480   { "test_bug27443252", test_bug27443252 },
21481   { "test_bug32391415", test_bug32391415 },
21482   { 0, 0 }
21483 };
21484 
21485 
get_my_tests()21486 static struct my_tests_st *get_my_tests() { return my_tests; }
21487