1 /* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
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 as published by
5    the Free Software Foundation; version 2 of the License.
6 
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11 
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
15 
16 /***************************************************************************
17  This is a test sample to test the new features in MySQL client-server
18  protocol
19 
20  Main author: venu ( venu@mysql.com )
21 ***************************************************************************/
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     strmov(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   strmov(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   strmov(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   strmov(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   strmov(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   strmov(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   myheader("test_wl4435");
525   mct_start_logging("test_wl4435");
526 
527   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
528   myquery(rc);
529 
530   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p2");
531   myquery(rc);
532 
533   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
534   myquery(rc);
535 
536   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
537   myquery(rc);
538 
539   rc= mysql_query(mysql, "CREATE TABLE t1(a1 INT, a2 CHAR(32), "
540                        "  a3 DOUBLE(4, 2), a4 DECIMAL(3, 1))");
541   myquery(rc);
542 
543   rc= mysql_query(mysql, "CREATE TABLE t2(b0 INT, b1 INT, b2 CHAR(32), "
544                        "  b3 DOUBLE(4, 2), b4 DECIMAL(3, 1))");
545   myquery(rc);
546 
547   rc= mysql_query(mysql, "INSERT INTO t1 VALUES"
548     "(1, '11', 12.34, 56.7), "
549     "(2, '12', 56.78, 90.1), "
550     "(3, '13', 23.45, 67.8)");
551   myquery(rc);
552 
553   rc= mysql_query(mysql, "INSERT INTO t2 VALUES"
554     "(100, 10, '110', 70.70, 10.1), "
555     "(200, 20, '120', 80.80, 20.2), "
556     "(300, 30, '130', 90.90, 30.3)");
557   myquery(rc);
558 
559   rc= mysql_query(mysql,
560     "CREATE PROCEDURE p1("
561     "   IN v0 INT, "
562     "   OUT v_str_1 CHAR(32), "
563     "   OUT v_dbl_1 DOUBLE(4, 2), "
564     "   OUT v_dec_1 DECIMAL(6, 3), "
565     "   OUT v_int_1 INT, "
566     "   IN v1 INT, "
567     "   INOUT v_str_2 CHAR(64), "
568     "   INOUT v_dbl_2 DOUBLE(5, 3), "
569     "   INOUT v_dec_2 DECIMAL(7, 4), "
570     "   INOUT v_int_2 INT)"
571     "BEGIN "
572     "   SET v0 = -1; "
573     "   SET v1 = -1; "
574     "   SET v_str_1 = 'test_1'; "
575     "   SET v_dbl_1 = 12.34; "
576     "   SET v_dec_1 = 567.891; "
577     "   SET v_int_1 = 2345; "
578     "   SET v_str_2 = 'test_2'; "
579     "   SET v_dbl_2 = 67.891; "
580     "   SET v_dec_2 = 234.6789; "
581     "   SET v_int_2 = 6789; "
582     "   SELECT * FROM t1; "
583     "   SELECT * FROM t2; "
584     "END");
585   myquery(rc);
586 
587   rc= mysql_query(mysql,
588     "CREATE PROCEDURE p2("
589     "   IN i1 VARCHAR(255) CHARACTER SET koi8r, "
590     "   OUT o1 VARCHAR(255) CHARACTER SET cp1251, "
591     "   OUT o2 VARBINARY(255)) "
592     "BEGIN "
593     "   SET o1 = i1; "
594     "   SET o2 = i1; "
595     "END");
596   myquery(rc);
597 
598   strmov(query, "CALL p1(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
599   stmt= mysql_simple_prepare(mysql, query);
600   check_stmt(stmt);
601 
602   /* Init PS-parameters. */
603 
604   bzero((char *) ps_params, sizeof (ps_params));
605 
606   /* - v0 -- INT */
607 
608   ps_params[0].buffer_type= MYSQL_TYPE_LONG;
609   ps_params[0].buffer= (char *) &int_data[0];
610   ps_params[0].length= 0;
611   ps_params[0].is_null= 0;
612 
613   /* - v_str_1 -- CHAR(32) */
614 
615   ps_params[1].buffer_type= MYSQL_TYPE_STRING;
616   ps_params[1].buffer= (char *) str_data[0];
617   ps_params[1].buffer_length= WL4435_STRING_SIZE;
618   ps_params[1].length= &str_length;
619   ps_params[1].is_null= 0;
620 
621   /* - v_dbl_1 -- DOUBLE */
622 
623   ps_params[2].buffer_type= MYSQL_TYPE_DOUBLE;
624   ps_params[2].buffer= (char *) &dbl_data[0];
625   ps_params[2].length= 0;
626   ps_params[2].is_null= 0;
627 
628   /* - v_dec_1 -- DECIMAL */
629 
630   ps_params[3].buffer_type= MYSQL_TYPE_NEWDECIMAL;
631   ps_params[3].buffer= (char *) dec_data[0];
632   ps_params[3].buffer_length= WL4435_STRING_SIZE;
633   ps_params[3].length= 0;
634   ps_params[3].is_null= 0;
635 
636   /* - v_int_1 -- INT */
637 
638   ps_params[4].buffer_type= MYSQL_TYPE_LONG;
639   ps_params[4].buffer= (char *) &int_data[0];
640   ps_params[4].length= 0;
641   ps_params[4].is_null= 0;
642 
643   /* - v1 -- INT */
644 
645   ps_params[5].buffer_type= MYSQL_TYPE_LONG;
646   ps_params[5].buffer= (char *) &int_data[0];
647   ps_params[5].length= 0;
648   ps_params[5].is_null= 0;
649 
650   /* - v_str_2 -- CHAR(32) */
651 
652   ps_params[6].buffer_type= MYSQL_TYPE_STRING;
653   ps_params[6].buffer= (char *) str_data[0];
654   ps_params[6].buffer_length= WL4435_STRING_SIZE;
655   ps_params[6].length= &str_length;
656   ps_params[6].is_null= 0;
657 
658   /* - v_dbl_2 -- DOUBLE */
659 
660   ps_params[7].buffer_type= MYSQL_TYPE_DOUBLE;
661   ps_params[7].buffer= (char *) &dbl_data[0];
662   ps_params[7].length= 0;
663   ps_params[7].is_null= 0;
664 
665   /* - v_dec_2 -- DECIMAL */
666 
667   ps_params[8].buffer_type= MYSQL_TYPE_DECIMAL;
668   ps_params[8].buffer= (char *) dec_data[0];
669   ps_params[8].buffer_length= WL4435_STRING_SIZE;
670   ps_params[8].length= 0;
671   ps_params[8].is_null= 0;
672 
673   /* - v_int_2 -- INT */
674 
675   ps_params[9].buffer_type= MYSQL_TYPE_LONG;
676   ps_params[9].buffer= (char *) &int_data[0];
677   ps_params[9].length= 0;
678   ps_params[9].is_null= 0;
679 
680   /* Bind parameters. */
681 
682   rc= mysql_stmt_bind_param(stmt, ps_params);
683 
684   /* Execute! */
685 
686   for (exec_counter= 0; exec_counter < 3; ++exec_counter)
687   {
688     int i;
689     int num_fields;
690     MYSQL_BIND *rs_bind;
691 
692     mct_log("\nexec_counter: %d\n", (int) exec_counter);
693 
694     rc= mysql_stmt_execute(stmt);
695     check_execute(stmt, rc);
696 
697     while (1)
698     {
699       MYSQL_FIELD *fields;
700 
701       MYSQL_RES *rs_metadata= mysql_stmt_result_metadata(stmt);
702 
703       num_fields= mysql_stmt_field_count(stmt);
704       fields= mysql_fetch_fields(rs_metadata);
705 
706       rs_bind= (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
707       bzero(rs_bind, sizeof (MYSQL_BIND) * num_fields);
708 
709       mct_log("num_fields: %d\n", (int) num_fields);
710 
711       for (i = 0; i < num_fields; ++i)
712       {
713         mct_log("  - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
714                 "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
715                 "type: %d; decimals: %d\n",
716                 (int) i,
717                 (const char *) fields[i].name,
718                 (const char *) fields[i].org_name,
719                 (const char *) fields[i].table,
720                 (const char *) fields[i].org_table,
721                 (const char *) fields[i].db,
722                 (const char *) fields[i].catalog,
723                 (int) fields[i].length,
724                 (int) fields[i].max_length,
725                 (int) fields[i].type,
726                 (int) fields[i].decimals);
727 
728         rs_bind[i].buffer_type= fields[i].type;
729         rs_bind[i].is_null= &is_null;
730 
731         switch (fields[i].type)
732         {
733           case MYSQL_TYPE_LONG:
734             rs_bind[i].buffer= (char *) &(int_data[i]);
735             rs_bind[i].buffer_length= sizeof (int_data);
736             break;
737 
738           case MYSQL_TYPE_STRING:
739             rs_bind[i].buffer= (char *) str_data[i];
740             rs_bind[i].buffer_length= WL4435_STRING_SIZE;
741             rs_bind[i].length= &str_length;
742             break;
743 
744           case MYSQL_TYPE_DOUBLE:
745             rs_bind[i].buffer= (char *) &dbl_data[i];
746             rs_bind[i].buffer_length= sizeof (dbl_data);
747             break;
748 
749           case MYSQL_TYPE_NEWDECIMAL:
750             rs_bind[i].buffer= (char *) dec_data[i];
751             rs_bind[i].buffer_length= WL4435_STRING_SIZE;
752             rs_bind[i].length= &str_length;
753             break;
754 
755           default:
756             fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
757             exit(1);
758         }
759       }
760 
761       rc= mysql_stmt_bind_result(stmt, rs_bind);
762       check_execute(stmt, rc);
763 
764       mct_log("Data:\n");
765 
766       while (1)
767       {
768         int rc= mysql_stmt_fetch(stmt);
769 
770         if (rc == 1 || rc == MYSQL_NO_DATA)
771           break;
772 
773         mct_log(" ");
774 
775         for (i = 0; i < num_fields; ++i)
776         {
777           switch (rs_bind[i].buffer_type)
778           {
779             case MYSQL_TYPE_LONG:
780               mct_log(" int: %ld;",
781                       (long) *((int *) rs_bind[i].buffer));
782               break;
783 
784             case MYSQL_TYPE_STRING:
785               mct_log(" str: '%s';",
786                       (char *) rs_bind[i].buffer);
787               break;
788 
789             case MYSQL_TYPE_DOUBLE:
790               mct_log(" dbl: %lf;",
791                       (double) *((double *) rs_bind[i].buffer));
792               break;
793 
794             case MYSQL_TYPE_NEWDECIMAL:
795               mct_log(" dec: '%s';",
796                       (char *) rs_bind[i].buffer);
797               break;
798 
799             default:
800               printf("  unexpected type (%d)\n",
801                 rs_bind[i].buffer_type);
802           }
803         }
804         mct_log("\n");
805       }
806 
807       mct_log("EOF\n");
808 
809       rc= mysql_stmt_next_result(stmt);
810       mct_log("mysql_stmt_next_result(): %d; field_count: %d\n",
811               (int) rc, (int) mysql->field_count);
812 
813       free(rs_bind);
814       mysql_free_result(rs_metadata);
815 
816       if (rc > 0)
817       {
818         printf("Error: %s (errno: %d)\n",
819                mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
820         DIE(rc > 0);
821       }
822 
823       if (rc)
824         break;
825 
826       if (!mysql->field_count)
827       {
828         /* This is the last OK-packet. No more resultsets. */
829         break;
830       }
831     }
832 
833   }
834 
835   mysql_stmt_close(stmt);
836 
837   mct_close_log();
838 
839   rc= mysql_commit(mysql);
840   myquery(rc);
841 
842   /* i18n part of test case. */
843 
844   {
845     const char *str_koi8r= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
846     const char *str_cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
847     char o1_buffer[255];
848     ulong o1_length;
849     char o2_buffer[255];
850     ulong o2_length;
851 
852     MYSQL_BIND rs_bind[2];
853 
854     strmov(query, "CALL p2(?, ?, ?)");
855     stmt= mysql_simple_prepare(mysql, query);
856     check_stmt(stmt);
857 
858     /* Init PS-parameters. */
859 
860     bzero((char *) ps_params, sizeof (ps_params));
861 
862     ps_params[0].buffer_type= MYSQL_TYPE_STRING;
863     ps_params[0].buffer= (char *) str_koi8r;
864     ps_params[0].buffer_length= strlen(str_koi8r);
865 
866     ps_params[1].buffer_type= MYSQL_TYPE_STRING;
867     ps_params[1].buffer= o1_buffer;
868     ps_params[1].buffer_length= 0;
869 
870     ps_params[2].buffer_type= MYSQL_TYPE_STRING;
871     ps_params[2].buffer= o2_buffer;
872     ps_params[2].buffer_length= 0;
873 
874     /* Bind parameters. */
875 
876     rc= mysql_stmt_bind_param(stmt, ps_params);
877     check_execute(stmt, rc);
878 
879     /* Prevent converting to character_set_results. */
880 
881     rc= mysql_query(mysql, "SET NAMES binary");
882     myquery(rc);
883 
884     /* Execute statement. */
885 
886     rc= mysql_stmt_execute(stmt);
887     check_execute(stmt, rc);
888 
889     /* Bind result. */
890 
891     bzero(rs_bind, sizeof (rs_bind));
892 
893     rs_bind[0].buffer_type= MYSQL_TYPE_STRING;
894     rs_bind[0].buffer= o1_buffer;
895     rs_bind[0].buffer_length= sizeof (o1_buffer);
896     rs_bind[0].length= &o1_length;
897 
898     rs_bind[1].buffer_type= MYSQL_TYPE_BLOB;
899     rs_bind[1].buffer= o2_buffer;
900     rs_bind[1].buffer_length= sizeof (o2_buffer);
901     rs_bind[1].length= &o2_length;
902 
903     rc= mysql_stmt_bind_result(stmt, rs_bind);
904     check_execute(stmt, rc);
905 
906     /* Fetch result. */
907 
908     rc= mysql_stmt_fetch(stmt);
909     check_execute(stmt, rc);
910 
911     /* Check result. */
912 
913     DIE_UNLESS(o1_length == strlen(str_cp1251));
914     DIE_UNLESS(o2_length == strlen(str_koi8r));
915     DIE_UNLESS(!memcmp(o1_buffer, str_cp1251, o1_length));
916     DIE_UNLESS(!memcmp(o2_buffer, str_koi8r, o2_length));
917 
918     rc= mysql_stmt_fetch(stmt);
919     DIE_UNLESS(rc == MYSQL_NO_DATA);
920 
921     rc= mysql_stmt_next_result(stmt);
922     DIE_UNLESS(rc == 0 && mysql->field_count == 0);
923 
924     mysql_stmt_close(stmt);
925 
926     rc= mysql_commit(mysql);
927     myquery(rc);
928   }
929 }
930 
test_wl4435_2()931 static void test_wl4435_2()
932 {
933   MYSQL_STMT *stmt;
934   int  i;
935   int  rc;
936   char query[MAX_TEST_QUERY_LENGTH];
937 
938   myheader("test_wl4435_2");
939   mct_start_logging("test_wl4435_2");
940 
941   /*
942     Do a few iterations so that we catch any problem with incorrect
943     handling/flushing prepared statement results.
944   */
945 
946   for (i= 0; i < 10; ++i)
947   {
948     /*
949       Prepare a procedure. That can be moved out of the loop, but it was
950       left in the loop for the sake of having as many statements as
951       possible.
952     */
953 
954     rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
955     myquery(rc);
956 
957     rc= mysql_query(mysql,
958       "CREATE PROCEDURE p1()"
959       "BEGIN "
960       "  SELECT 1; "
961       "  SELECT 2, 3 UNION SELECT 4, 5; "
962       "  SELECT 6, 7, 8; "
963       "END");
964     myquery(rc);
965 
966     /* Invoke a procedure, that returns several result sets. */
967 
968     strmov(query, "CALL p1()");
969     stmt= mysql_simple_prepare(mysql, query);
970     check_stmt(stmt);
971 
972     /* Execute! */
973 
974     rc= mysql_stmt_execute(stmt);
975     check_execute(stmt, rc);
976 
977     /* Flush all the results. */
978 
979     mysql_stmt_close(stmt);
980 
981     /* Clean up. */
982     rc= mysql_commit(mysql);
983     myquery(rc);
984 
985     rc= mysql_query(mysql, "DROP PROCEDURE p1");
986     myquery(rc);
987   }
988 }
989 
990 
991 #define WL4435_TEST(sql_type, sql_value, \
992                     c_api_in_type, c_api_out_type, \
993                     c_type, c_type_ext, \
994                     printf_args, assert_condition) \
995 \
996   do { \
997   int rc; \
998   MYSQL_STMT *ps; \
999   MYSQL_BIND psp; \
1000   MYSQL_RES *rs_metadata; \
1001   MYSQL_FIELD *fields; \
1002   c_type pspv c_type_ext; \
1003   my_bool psp_null; \
1004   \
1005   bzero(&pspv, sizeof (pspv)); \
1006   \
1007   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); \
1008   myquery(rc); \
1009   \
1010   rc= mysql_query(mysql, \
1011     "CREATE PROCEDURE p1(OUT v " sql_type ") SET v = " sql_value ";"); \
1012   myquery(rc); \
1013   \
1014   ps = mysql_simple_prepare(mysql, "CALL p1(?)"); \
1015   check_stmt(ps); \
1016   \
1017   bzero(&psp, sizeof (psp)); \
1018   psp.buffer_type= c_api_in_type; \
1019   psp.is_null= &psp_null; \
1020   psp.buffer= (char *) &pspv; \
1021   psp.buffer_length= sizeof (psp); \
1022   \
1023   rc= mysql_stmt_bind_param(ps, &psp); \
1024   check_execute(ps, rc); \
1025   \
1026   rc= mysql_stmt_execute(ps); \
1027   check_execute(ps, rc); \
1028   \
1029   DIE_UNLESS(mysql->server_status & SERVER_PS_OUT_PARAMS); \
1030   DIE_UNLESS(mysql_stmt_field_count(ps) == 1); \
1031   \
1032   rs_metadata= mysql_stmt_result_metadata(ps); \
1033   fields= mysql_fetch_fields(rs_metadata); \
1034   \
1035   rc= mysql_stmt_bind_result(ps, &psp); \
1036   check_execute(ps, rc); \
1037   \
1038   rc= mysql_stmt_fetch(ps); \
1039   DIE_UNLESS(rc == 0); \
1040   \
1041   DIE_UNLESS(fields[0].type == c_api_out_type); \
1042   printf printf_args; \
1043   printf("; in type: %d; out type: %d\n", \
1044          (int) c_api_in_type, (int) c_api_out_type); \
1045   \
1046   rc= mysql_stmt_fetch(ps); \
1047   DIE_UNLESS(rc == MYSQL_NO_DATA); \
1048   \
1049   rc= mysql_stmt_next_result(ps); \
1050   DIE_UNLESS(rc == 0); \
1051   \
1052   mysql_stmt_free_result(ps); \
1053   mysql_stmt_close(ps); \
1054   \
1055   DIE_UNLESS(assert_condition); \
1056   \
1057   } while (0)
1058 
test_wl4435_3()1059 static void test_wl4435_3()
1060 {
1061   char tmp[255];
1062 
1063   puts("");
1064 
1065   // The following types are not supported:
1066   //   - ENUM
1067   //   - SET
1068   //
1069   // The following types are supported but can not be used for
1070   // OUT-parameters:
1071   //   - MEDIUMINT;
1072   //   - BIT(..);
1073   //
1074   // The problem is that those types are not supported for IN-parameters,
1075   // and OUT-parameters should be bound as IN-parameters before execution.
1076   //
1077   // The following types should not be used:
1078   //   - MYSQL_TYPE_YEAR (use MYSQL_TYPE_SHORT instead);
1079   //   - MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB
1080   //     (use MYSQL_TYPE_BLOB instead);
1081 
1082   WL4435_TEST("TINYINT", "127",
1083               MYSQL_TYPE_TINY, MYSQL_TYPE_TINY,
1084               char, ,
1085               ("  - TINYINT / char / MYSQL_TYPE_TINY:\t\t\t %d", (int) pspv),
1086               pspv == 127);
1087 
1088   WL4435_TEST("SMALLINT", "32767",
1089               MYSQL_TYPE_SHORT, MYSQL_TYPE_SHORT,
1090               short, ,
1091               ("  - SMALLINT / short / MYSQL_TYPE_SHORT:\t\t %d", (int) pspv),
1092               pspv == 32767);
1093 
1094   WL4435_TEST("INT", "2147483647",
1095               MYSQL_TYPE_LONG, MYSQL_TYPE_LONG,
1096               int, ,
1097               ("  - INT / int / MYSQL_TYPE_LONG:\t\t\t %d", pspv),
1098               pspv == 2147483647l);
1099 
1100   WL4435_TEST("BIGINT", "9223372036854775807",
1101               MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG,
1102               long long, ,
1103               ("  - BIGINT / long long / MYSQL_TYPE_LONGLONG:\t\t %lld", pspv),
1104               pspv == 9223372036854775807ll);
1105 
1106   WL4435_TEST("TIMESTAMP", "'2007-11-18 15:01:02'",
1107               MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP,
1108               MYSQL_TIME, ,
1109               ("  - TIMESTAMP / MYSQL_TIME / MYSQL_TYPE_TIMESTAMP:\t "
1110                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1111                (int) pspv.year, (int) pspv.month, (int) pspv.day,
1112                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1113               pspv.year == 2007 && pspv.month == 11 && pspv.day == 18 &&
1114               pspv.hour == 15 && pspv.minute == 1 && pspv.second == 2);
1115 
1116   WL4435_TEST("DATETIME", "'1234-11-12 12:34:59'",
1117               MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME,
1118               MYSQL_TIME, ,
1119               ("  - DATETIME / MYSQL_TIME / MYSQL_TYPE_DATETIME:\t "
1120                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1121                (int) pspv.year, (int) pspv.month, (int) pspv.day,
1122                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1123               pspv.year == 1234 && pspv.month == 11 && pspv.day == 12 &&
1124               pspv.hour == 12 && pspv.minute == 34 && pspv.second == 59);
1125 
1126   WL4435_TEST("TIME", "'123:45:01'",
1127               MYSQL_TYPE_TIME, MYSQL_TYPE_TIME,
1128               MYSQL_TIME, ,
1129               ("  - TIME / MYSQL_TIME / MYSQL_TYPE_TIME:\t\t "
1130                "%.3d:%.2d:%.2d",
1131                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1132               pspv.hour == 123 && pspv.minute == 45 && pspv.second == 1);
1133 
1134   WL4435_TEST("DATE", "'1234-11-12'",
1135               MYSQL_TYPE_DATE, MYSQL_TYPE_DATE,
1136               MYSQL_TIME, ,
1137               ("  - DATE / MYSQL_TIME / MYSQL_TYPE_DATE:\t\t "
1138                "%.4d-%.2d-%.2d",
1139                (int) pspv.year, (int) pspv.month, (int) pspv.day),
1140               pspv.year == 1234 && pspv.month == 11 && pspv.day == 12);
1141 
1142   WL4435_TEST("YEAR", "'2010'",
1143               MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR,
1144               short, ,
1145               ("  - YEAR / short / MYSQL_TYPE_SHORT:\t\t\t %.4d", (int) pspv),
1146               pspv == 2010);
1147 
1148   WL4435_TEST("FLOAT(7, 4)", "123.4567",
1149               MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT,
1150               float, ,
1151               ("  - FLOAT / float / MYSQL_TYPE_FLOAT:\t\t\t %g", (double) pspv),
1152               pspv - 123.4567 < 0.0001);
1153 
1154   WL4435_TEST("DOUBLE(8, 5)", "123.45678",
1155               MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE,
1156               double, ,
1157               ("  - DOUBLE / double / MYSQL_TYPE_DOUBLE:\t\t %g", (double) pspv),
1158               pspv - 123.45678 < 0.00001);
1159 
1160   WL4435_TEST("DECIMAL(9, 6)", "123.456789",
1161               MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL,
1162               char, [255],
1163               ("  - DECIMAL / char[] / MYSQL_TYPE_NEWDECIMAL:\t\t '%s'", (char *) pspv),
1164               !strcmp(pspv, "123.456789"));
1165 
1166   WL4435_TEST("CHAR(32)", "REPEAT('C', 16)",
1167               MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1168               char, [255],
1169               ("  - CHAR(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1170               !strcmp(pspv, "CCCCCCCCCCCCCCCC"));
1171 
1172   WL4435_TEST("VARCHAR(32)", "REPEAT('V', 16)",
1173               MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1174               char, [255],
1175               ("  - VARCHAR(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1176               !strcmp(pspv, "VVVVVVVVVVVVVVVV"));
1177 
1178   WL4435_TEST("TINYTEXT", "REPEAT('t', 16)",
1179               MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1180               char, [255],
1181               ("  - TINYTEXT / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1182               !strcmp(pspv, "tttttttttttttttt"));
1183 
1184   WL4435_TEST("TEXT", "REPEAT('t', 16)",
1185               MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1186               char, [255],
1187               ("  - TEXT / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1188               !strcmp(pspv, "tttttttttttttttt"));
1189 
1190   WL4435_TEST("MEDIUMTEXT", "REPEAT('t', 16)",
1191               MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1192               char, [255],
1193               ("  - MEDIUMTEXT / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1194               !strcmp(pspv, "tttttttttttttttt"));
1195 
1196   WL4435_TEST("LONGTEXT", "REPEAT('t', 16)",
1197               MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1198               char, [255],
1199               ("  - LONGTEXT / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1200               !strcmp(pspv, "tttttttttttttttt"));
1201 
1202   WL4435_TEST("BINARY(32)", "REPEAT('\1', 16)",
1203               MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1204               char, [255],
1205               ("  - BINARY(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1206               memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1207 
1208   WL4435_TEST("VARBINARY(32)", "REPEAT('\1', 16)",
1209               MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1210               char, [255],
1211               ("  - VARBINARY(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1212               memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1213 
1214   WL4435_TEST("TINYBLOB", "REPEAT('\2', 16)",
1215               MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1216               char, [255],
1217               ("  - TINYBLOB / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1218               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1219 
1220   WL4435_TEST("BLOB", "REPEAT('\2', 16)",
1221               MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1222               char, [255],
1223               ("  - BLOB / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1224               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1225 
1226   WL4435_TEST("MEDIUMBLOB", "REPEAT('\2', 16)",
1227               MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1228               char, [255],
1229               ("  - MEDIUMBLOB / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1230               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1231 
1232   WL4435_TEST("LONGBLOB", "REPEAT('\2', 16)",
1233               MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1234               char, [255],
1235               ("  - LONGBLOB / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1236               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1237 }
1238 
1239 
1240 /* Test simple prepare field results */
1241 
test_prepare_field_result()1242 static void test_prepare_field_result()
1243 {
1244   MYSQL_STMT *stmt;
1245   MYSQL_RES  *result;
1246   int        rc;
1247   char query[MAX_TEST_QUERY_LENGTH];
1248 
1249   myheader("test_prepare_field_result");
1250 
1251   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_field_result");
1252   myquery(rc);
1253 
1254   rc= mysql_query(mysql, "CREATE TABLE test_prepare_field_result(int_c int, "
1255                          "var_c varchar(50), ts_c timestamp, "
1256                          "char_c char(4), date_c date, extra tinyint)");
1257   myquery(rc);
1258 
1259   /* insert */
1260   strmov(query, "SELECT int_c, var_c, date_c as date, ts_c, char_c FROM "
1261                 " test_prepare_field_result as t1 WHERE int_c=?");
1262   stmt= mysql_simple_prepare(mysql, query);
1263   check_stmt(stmt);
1264 
1265   verify_param_count(stmt, 1);
1266 
1267   result= mysql_stmt_result_metadata(stmt);
1268   mytest(result);
1269 
1270   my_print_result_metadata(result);
1271 
1272   if (!opt_silent)
1273     fprintf(stdout, "\n\n field attributes:\n");
1274   verify_prepare_field(result, 0, "int_c", "int_c", MYSQL_TYPE_LONG,
1275                        "t1", "test_prepare_field_result", current_db, 11, 0);
1276   verify_prepare_field(result, 1, "var_c", "var_c", MYSQL_TYPE_VAR_STRING,
1277                        "t1", "test_prepare_field_result", current_db, 50, 0);
1278   verify_prepare_field(result, 2, "date", "date_c", MYSQL_TYPE_DATE,
1279                        "t1", "test_prepare_field_result", current_db, 10, 0);
1280   verify_prepare_field(result, 3, "ts_c", "ts_c", MYSQL_TYPE_TIMESTAMP,
1281                        "t1", "test_prepare_field_result", current_db, 19, 0);
1282   verify_prepare_field(result, 4, "char_c", "char_c",
1283                        (mysql_get_server_version(mysql) <= 50000 ?
1284                         MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING),
1285                        "t1", "test_prepare_field_result", current_db, 4, 0);
1286 
1287   verify_field_count(result, 5);
1288   mysql_free_result(result);
1289   mysql_stmt_close(stmt);
1290 }
1291 
1292 
1293 /* Test simple prepare field results */
1294 
test_prepare_syntax()1295 static void test_prepare_syntax()
1296 {
1297   MYSQL_STMT *stmt;
1298   int        rc;
1299   char query[MAX_TEST_QUERY_LENGTH];
1300 
1301   myheader("test_prepare_syntax");
1302 
1303   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_syntax");
1304   myquery(rc);
1305 
1306   rc= mysql_query(mysql, "CREATE TABLE test_prepare_syntax("
1307                          "id int, name varchar(50), extra int)");
1308   myquery(rc);
1309 
1310   strmov(query, "INSERT INTO test_prepare_syntax VALUES(?");
1311   stmt= mysql_simple_prepare(mysql, query);
1312   check_stmt_r(stmt);
1313 
1314   strmov(query, "SELECT id, name FROM test_prepare_syntax WHERE id=? AND WHERE");
1315   stmt= mysql_simple_prepare(mysql, query);
1316   check_stmt_r(stmt);
1317 
1318   /* now fetch the results ..*/
1319   rc= mysql_commit(mysql);
1320   myquery(rc);
1321 }
1322 
1323 
1324 /* Test a simple prepare */
1325 
test_prepare()1326 static void test_prepare()
1327 {
1328   MYSQL_STMT *stmt;
1329   int        rc, i;
1330   int        int_data, o_int_data;
1331   char       str_data[50], data[50];
1332   char       tiny_data, o_tiny_data;
1333   short      small_data, o_small_data;
1334   longlong   big_data, o_big_data;
1335   float      real_data, o_real_data;
1336   double     double_data, o_double_data;
1337   ulong      length[7], len;
1338   my_bool    is_null[7];
1339   char	     llbuf[22];
1340   MYSQL_BIND my_bind[7];
1341   char query[MAX_TEST_QUERY_LENGTH];
1342 
1343   myheader("test_prepare");
1344 
1345   rc= mysql_autocommit(mysql, TRUE);
1346   myquery(rc);
1347 
1348   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
1349   myquery(rc);
1350 
1351   rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 tinyint, "
1352                          "col2 varchar(15), col3 int, "
1353                          "col4 smallint, col5 bigint, "
1354                          "col6 float, col7 double )");
1355   myquery(rc);
1356 
1357   /* insert by prepare */
1358   strxmov(query, "INSERT INTO my_prepare VALUES(?, ?, ?, ?, ?, ?, ?)", NullS);
1359   stmt= mysql_simple_prepare(mysql, query);
1360   check_stmt(stmt);
1361 
1362   verify_param_count(stmt, 7);
1363 
1364   bzero((char*) my_bind, sizeof(my_bind));
1365 
1366   /* tinyint */
1367   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1368   my_bind[0].buffer= (void *)&tiny_data;
1369   /* string */
1370   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1371   my_bind[1].buffer= (void *)str_data;
1372   my_bind[1].buffer_length= 1000;                  /* Max string length */
1373   /* integer */
1374   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
1375   my_bind[2].buffer= (void *)&int_data;
1376   /* short */
1377   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
1378   my_bind[3].buffer= (void *)&small_data;
1379   /* bigint */
1380   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
1381   my_bind[4].buffer= (void *)&big_data;
1382   /* float */
1383   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
1384   my_bind[5].buffer= (void *)&real_data;
1385   /* double */
1386   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
1387   my_bind[6].buffer= (void *)&double_data;
1388 
1389   for (i= 0; i < (int) array_elements(my_bind); i++)
1390   {
1391     my_bind[i].length= &length[i];
1392     my_bind[i].is_null= &is_null[i];
1393     is_null[i]= 0;
1394   }
1395 
1396   rc= mysql_stmt_bind_param(stmt, my_bind);
1397   check_execute(stmt, rc);
1398 
1399   int_data= 320;
1400   small_data= 1867;
1401   big_data= 1000;
1402   real_data= 2;
1403   double_data= 6578.001;
1404 
1405   /* now, execute the prepared statement to insert 10 records.. */
1406   for (tiny_data= 0; tiny_data < 100; tiny_data++)
1407   {
1408     length[1]= sprintf(str_data, "MySQL%d", int_data);
1409     rc= mysql_stmt_execute(stmt);
1410     check_execute(stmt, rc);
1411     int_data += 25;
1412     small_data += 10;
1413     big_data += 100;
1414     real_data += 1;
1415     double_data += 10.09;
1416   }
1417 
1418   mysql_stmt_close(stmt);
1419 
1420   /* now fetch the results ..*/
1421   rc= mysql_commit(mysql);
1422   myquery(rc);
1423 
1424   /* test the results now, only one row should exist */
1425   rc= my_stmt_result("SELECT * FROM my_prepare");
1426   DIE_UNLESS(tiny_data == (char) rc);
1427 
1428   stmt= mysql_simple_prepare(mysql, "SELECT * FROM my_prepare");
1429   check_stmt(stmt);
1430 
1431   rc= mysql_stmt_bind_result(stmt, my_bind);
1432   check_execute(stmt, rc);
1433 
1434   /* get the result */
1435   rc= mysql_stmt_execute(stmt);
1436   check_execute(stmt, rc);
1437 
1438   o_int_data= 320;
1439   o_small_data= 1867;
1440   o_big_data= 1000;
1441   o_real_data= 2;
1442   o_double_data= 6578.001;
1443 
1444   /* now, execute the prepared statement to insert 10 records.. */
1445   for (o_tiny_data= 0; o_tiny_data < 100; o_tiny_data++)
1446   {
1447     len= sprintf(data, "MySQL%d", o_int_data);
1448 
1449     rc= mysql_stmt_fetch(stmt);
1450     check_execute(stmt, rc);
1451 
1452     if (!opt_silent)
1453     {
1454       fprintf(stdout, "\n");
1455       fprintf(stdout, "\n\t tiny   : %d (%lu)", tiny_data, length[0]);
1456       fprintf(stdout, "\n\t short  : %d (%lu)", small_data, length[3]);
1457       fprintf(stdout, "\n\t int    : %d (%lu)", int_data, length[2]);
1458       fprintf(stdout, "\n\t big    : %s (%lu)", llstr(big_data, llbuf),
1459               length[4]);
1460 
1461       fprintf(stdout, "\n\t float  : %f (%lu)", real_data, length[5]);
1462       fprintf(stdout, "\n\t double : %f (%lu)", double_data, length[6]);
1463 
1464       fprintf(stdout, "\n\t str    : %s (%lu)", str_data, length[1]);
1465     }
1466 
1467     DIE_UNLESS(tiny_data == o_tiny_data);
1468     DIE_UNLESS(is_null[0] == 0);
1469     DIE_UNLESS(length[0] == 1);
1470 
1471     DIE_UNLESS(int_data == o_int_data);
1472     DIE_UNLESS(length[2] == 4);
1473 
1474     DIE_UNLESS(small_data == o_small_data);
1475     DIE_UNLESS(length[3] == 2);
1476 
1477     DIE_UNLESS(big_data == o_big_data);
1478     DIE_UNLESS(length[4] == 8);
1479 
1480     DIE_UNLESS(real_data == o_real_data);
1481     DIE_UNLESS(length[5] == 4);
1482 
1483     DIE_UNLESS(cmp_double(&double_data, &o_double_data));
1484     DIE_UNLESS(length[6] == 8);
1485 
1486     DIE_UNLESS(strcmp(data, str_data) == 0);
1487     DIE_UNLESS(length[1] == len);
1488 
1489     o_int_data += 25;
1490     o_small_data += 10;
1491     o_big_data += 100;
1492     o_real_data += 1;
1493     o_double_data += 10.09;
1494   }
1495 
1496   rc= mysql_stmt_fetch(stmt);
1497   DIE_UNLESS(rc == MYSQL_NO_DATA);
1498 
1499   mysql_stmt_close(stmt);
1500 
1501 }
1502 
1503 
1504 /* Test double comparision */
1505 
test_double_compare()1506 static void test_double_compare()
1507 {
1508   MYSQL_STMT *stmt;
1509   int        rc;
1510   char       real_data[10], tiny_data;
1511   double     double_data;
1512   MYSQL_RES  *result;
1513   MYSQL_BIND my_bind[3];
1514   ulong      length[3];
1515   char query[MAX_TEST_QUERY_LENGTH];
1516 
1517   myheader("test_double_compare");
1518 
1519   rc= mysql_autocommit(mysql, TRUE);
1520   myquery(rc);
1521 
1522   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_double_compare");
1523   myquery(rc);
1524 
1525   rc= mysql_query(mysql, "CREATE TABLE test_double_compare(col1 tinyint, "
1526                          " col2 float, col3 double )");
1527   myquery(rc);
1528 
1529   rc= mysql_query(mysql, "INSERT INTO test_double_compare "
1530                          "VALUES (1, 10.2, 34.5)");
1531   myquery(rc);
1532 
1533   strmov(query, "UPDATE test_double_compare SET col1=100 "
1534                 "WHERE col1 = ? AND col2 = ? AND COL3 = ?");
1535   stmt= mysql_simple_prepare(mysql, query);
1536   check_stmt(stmt);
1537 
1538   verify_param_count(stmt, 3);
1539 
1540   /* Always bzero bind array because there can be internal members */
1541   bzero((char*) my_bind, sizeof(my_bind));
1542 
1543   /* tinyint */
1544   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1545   my_bind[0].buffer= (void *)&tiny_data;
1546 
1547   /* string->float */
1548   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1549   my_bind[1].buffer= (void *)&real_data;
1550   my_bind[1].buffer_length= sizeof(real_data);
1551   my_bind[1].length= &length[1];
1552   length[1]= 10;
1553 
1554   /* double */
1555   my_bind[2].buffer_type= MYSQL_TYPE_DOUBLE;
1556   my_bind[2].buffer= (void *)&double_data;
1557 
1558   tiny_data= 1;
1559   strmov(real_data, "10.2");
1560   double_data= 34.5;
1561   rc= mysql_stmt_bind_param(stmt, my_bind);
1562   check_execute(stmt, rc);
1563 
1564   rc= mysql_stmt_execute(stmt);
1565   check_execute(stmt, rc);
1566 
1567   verify_affected_rows(0);
1568 
1569   mysql_stmt_close(stmt);
1570 
1571   /* now fetch the results ..*/
1572   rc= mysql_commit(mysql);
1573   myquery(rc);
1574 
1575   /* test the results now, only one row should exist */
1576   rc= mysql_query(mysql, "SELECT * FROM test_double_compare");
1577   myquery(rc);
1578 
1579   /* get the result */
1580   result= mysql_store_result(mysql);
1581   mytest(result);
1582 
1583   rc= my_process_result_set(result);
1584   DIE_UNLESS((int)tiny_data == rc);
1585   mysql_free_result(result);
1586 }
1587 
1588 
1589 /* Test simple null */
1590 
test_null()1591 static void test_null()
1592 {
1593   MYSQL_STMT *stmt;
1594   int        rc;
1595   uint       nData;
1596   MYSQL_BIND my_bind[2];
1597   my_bool    is_null[2];
1598   char query[MAX_TEST_QUERY_LENGTH];
1599 
1600   myheader("test_null");
1601 
1602   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_null");
1603   myquery(rc);
1604 
1605   rc= mysql_query(mysql, "CREATE TABLE test_null(col1 int, col2 varchar(50))");
1606   myquery(rc);
1607 
1608   /* insert by prepare, wrong column name */
1609   strmov(query, "INSERT INTO test_null(col3, col2) VALUES(?, ?)");
1610   stmt= mysql_simple_prepare(mysql, query);
1611   check_stmt_r(stmt);
1612 
1613   strmov(query, "INSERT INTO test_null(col1, col2) VALUES(?, ?)");
1614   stmt= mysql_simple_prepare(mysql, query);
1615   check_stmt(stmt);
1616 
1617   verify_param_count(stmt, 2);
1618 
1619   /* Always bzero all members of bind parameter */
1620   bzero((char*) my_bind, sizeof(my_bind));
1621 
1622   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1623   my_bind[0].is_null= &is_null[0];
1624   is_null[0]= 1;
1625   my_bind[1]= my_bind[0];
1626 
1627   rc= mysql_stmt_bind_param(stmt, my_bind);
1628   check_execute(stmt, rc);
1629 
1630   /* now, execute the prepared statement to insert 10 records.. */
1631   for (nData= 0; nData<10; nData++)
1632   {
1633     rc= mysql_stmt_execute(stmt);
1634     check_execute(stmt, rc);
1635   }
1636 
1637   /* Re-bind with MYSQL_TYPE_NULL */
1638   my_bind[0].buffer_type= MYSQL_TYPE_NULL;
1639   is_null[0]= 0; /* reset */
1640   my_bind[1]= my_bind[0];
1641 
1642   rc= mysql_stmt_bind_param(stmt, my_bind);
1643   check_execute(stmt, rc);
1644 
1645   for (nData= 0; nData<10; nData++)
1646   {
1647     rc= mysql_stmt_execute(stmt);
1648     check_execute(stmt, rc);
1649   }
1650 
1651   mysql_stmt_close(stmt);
1652 
1653   /* now fetch the results ..*/
1654   rc= mysql_commit(mysql);
1655   myquery(rc);
1656 
1657   nData*= 2;
1658   rc= my_stmt_result("SELECT * FROM test_null");;
1659   DIE_UNLESS((int) nData == rc);
1660 
1661   /* Fetch results */
1662   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1663   my_bind[0].buffer= (void *)&nData; /* this buffer won't be altered */
1664   my_bind[0].length= 0;
1665   my_bind[1]= my_bind[0];
1666   my_bind[0].is_null= &is_null[0];
1667   my_bind[1].is_null= &is_null[1];
1668 
1669   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_null");
1670   check_stmt(stmt);
1671 
1672   rc= mysql_stmt_execute(stmt);
1673   check_execute(stmt, rc);
1674 
1675   rc= mysql_stmt_bind_result(stmt, my_bind);
1676   check_execute(stmt, rc);
1677 
1678   rc= 0;
1679   is_null[0]= is_null[1]= 0;
1680   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1681   {
1682     DIE_UNLESS(is_null[0]);
1683     DIE_UNLESS(is_null[1]);
1684     rc++;
1685     is_null[0]= is_null[1]= 0;
1686   }
1687   DIE_UNLESS(rc == (int) nData);
1688   mysql_stmt_close(stmt);
1689 }
1690 
1691 
1692 /* Test for NULL as PS parameter (BUG#3367, BUG#3371) */
1693 
test_ps_null_param()1694 static void test_ps_null_param()
1695 {
1696   MYSQL_STMT *stmt;
1697   int        rc;
1698 
1699   MYSQL_BIND in_bind;
1700   my_bool    in_is_null;
1701   long int   in_long;
1702 
1703   MYSQL_BIND out_bind;
1704   ulong      out_length;
1705   my_bool    out_is_null;
1706   char       out_str_data[20];
1707 
1708   const char *queries[]= {"select ?", "select ?+1",
1709                     "select col1 from test_ps_nulls where col1 <=> ?",
1710                     NULL
1711                     };
1712   const char **cur_query= queries;
1713 
1714   myheader("test_null_ps_param_in_result");
1715 
1716   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ps_nulls");
1717   myquery(rc);
1718 
1719   rc= mysql_query(mysql, "CREATE TABLE test_ps_nulls(col1 int)");
1720   myquery(rc);
1721 
1722   rc= mysql_query(mysql, "INSERT INTO test_ps_nulls values (1), (null)");
1723   myquery(rc);
1724 
1725   /* Always bzero all members of bind parameter */
1726   bzero((char*) &in_bind, sizeof(in_bind));
1727   bzero((char*) &out_bind, sizeof(out_bind));
1728 
1729   in_bind.buffer_type= MYSQL_TYPE_LONG;
1730   in_bind.is_null= &in_is_null;
1731   in_bind.length= 0;
1732   in_bind.buffer= (void *)&in_long;
1733   in_is_null= 1;
1734   in_long= 1;
1735 
1736   out_bind.buffer_type= MYSQL_TYPE_STRING;
1737   out_bind.is_null= &out_is_null;
1738   out_bind.length= &out_length;
1739   out_bind.buffer= out_str_data;
1740   out_bind.buffer_length= array_elements(out_str_data);
1741 
1742   /* Execute several queries, all returning NULL in result. */
1743   for(cur_query= queries; *cur_query; cur_query++)
1744   {
1745     char query[MAX_TEST_QUERY_LENGTH];
1746     strmov(query, *cur_query);
1747     stmt= mysql_simple_prepare(mysql, query);
1748     check_stmt(stmt);
1749     verify_param_count(stmt, 1);
1750 
1751     rc= mysql_stmt_bind_param(stmt, &in_bind);
1752     check_execute(stmt, rc);
1753     rc= mysql_stmt_bind_result(stmt, &out_bind);
1754     check_execute(stmt, rc);
1755     rc= mysql_stmt_execute(stmt);
1756     check_execute(stmt, rc);
1757     rc= mysql_stmt_fetch(stmt);
1758     DIE_UNLESS(rc != MYSQL_NO_DATA);
1759     DIE_UNLESS(out_is_null);
1760     rc= mysql_stmt_fetch(stmt);
1761     DIE_UNLESS(rc == MYSQL_NO_DATA);
1762     mysql_stmt_close(stmt);
1763   }
1764 }
1765 
1766 
1767 /* Test fetch null */
1768 
test_fetch_null()1769 static void test_fetch_null()
1770 {
1771   MYSQL_STMT *stmt;
1772   int        rc;
1773   int        i, nData;
1774   MYSQL_BIND my_bind[11];
1775   ulong      length[11];
1776   my_bool    is_null[11];
1777   char query[MAX_TEST_QUERY_LENGTH];
1778 
1779   myheader("test_fetch_null");
1780 
1781   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null");
1782   myquery(rc);
1783 
1784   rc= mysql_query(mysql, "CREATE TABLE test_fetch_null("
1785                          " col1 tinyint, col2 smallint, "
1786                          " col3 int, col4 bigint, "
1787                          " col5 float, col6 double, "
1788                          " col7 date, col8 time, "
1789                          " col9 varbinary(10), "
1790                          " col10 varchar(50), "
1791                          " col11 char(20))");
1792   myquery(rc);
1793 
1794   rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) "
1795                          "VALUES (1000), (88), (389789)");
1796   myquery(rc);
1797 
1798   rc= mysql_commit(mysql);
1799   myquery(rc);
1800 
1801   /* fetch */
1802   bzero((char*) my_bind, sizeof(my_bind));
1803   for (i= 0; i < (int) array_elements(my_bind); i++)
1804   {
1805     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
1806     my_bind[i].is_null= &is_null[i];
1807     my_bind[i].length= &length[i];
1808   }
1809   my_bind[i-1].buffer= (void *)&nData;              /* Last column is not null */
1810 
1811   strmov((char *)query , "SELECT * FROM test_fetch_null");
1812 
1813   rc= my_stmt_result(query);
1814   DIE_UNLESS(rc == 3);
1815 
1816   stmt= mysql_simple_prepare(mysql, query);
1817   check_stmt(stmt);
1818 
1819   rc= mysql_stmt_bind_result(stmt, my_bind);
1820   check_execute(stmt, rc);
1821 
1822   rc= mysql_stmt_execute(stmt);
1823   check_execute(stmt, rc);
1824 
1825   rc= 0;
1826   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1827   {
1828     rc++;
1829     for (i= 0; i < 10; i++)
1830     {
1831       if (!opt_silent)
1832         fprintf(stdout, "\n data[%d] : %s", i,
1833                 is_null[i] ? "NULL" : "NOT NULL");
1834       DIE_UNLESS(is_null[i]);
1835     }
1836     if (!opt_silent)
1837       fprintf(stdout, "\n data[%d]: %d", i, nData);
1838     DIE_UNLESS(nData == 1000 || nData == 88 || nData == 389789);
1839     DIE_UNLESS(is_null[i] == 0);
1840     DIE_UNLESS(length[i] == 4);
1841   }
1842   DIE_UNLESS(rc == 3);
1843   mysql_stmt_close(stmt);
1844 }
1845 
1846 
1847 /* Test simple select */
1848 
test_select_version()1849 static void test_select_version()
1850 {
1851   MYSQL_STMT *stmt;
1852   int        rc;
1853 
1854   myheader("test_select_version");
1855 
1856   stmt= mysql_simple_prepare(mysql, "SELECT @@version");
1857   check_stmt(stmt);
1858 
1859   verify_param_count(stmt, 0);
1860 
1861   rc= mysql_stmt_execute(stmt);
1862   check_execute(stmt, rc);
1863 
1864   my_process_stmt_result(stmt);
1865   mysql_stmt_close(stmt);
1866 }
1867 
1868 
1869 /* Test simple show */
1870 
test_select_show_table()1871 static void test_select_show_table()
1872 {
1873   MYSQL_STMT *stmt;
1874   int        rc, i;
1875 
1876   myheader("test_select_show_table");
1877 
1878   stmt= mysql_simple_prepare(mysql, "SHOW TABLES FROM mysql");
1879   check_stmt(stmt);
1880 
1881   verify_param_count(stmt, 0);
1882 
1883   for (i= 1; i < 3; i++)
1884   {
1885     rc= mysql_stmt_execute(stmt);
1886     check_execute(stmt, rc);
1887   }
1888 
1889   my_process_stmt_result(stmt);
1890   mysql_stmt_close(stmt);
1891 }
1892 
1893 
1894 /* Test simple select to debug */
1895 
test_select_direct()1896 static void test_select_direct()
1897 {
1898   int        rc;
1899   MYSQL_RES  *result;
1900 
1901   myheader("test_select_direct");
1902 
1903   rc= mysql_autocommit(mysql, TRUE);
1904   myquery(rc);
1905 
1906   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
1907   myquery(rc);
1908 
1909   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
1910                                                  " id2 float, "
1911                                                  " id3 double, "
1912                                                  " name varchar(50))");
1913   myquery(rc);
1914 
1915   /* insert a row and commit the transaction */
1916   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')");
1917   myquery(rc);
1918 
1919   rc= mysql_commit(mysql);
1920   myquery(rc);
1921 
1922   rc= mysql_query(mysql, "SELECT * FROM test_select");
1923   myquery(rc);
1924 
1925   /* get the result */
1926   result= mysql_store_result(mysql);
1927   mytest(result);
1928 
1929   (void) my_process_result_set(result);
1930   mysql_free_result(result);
1931 }
1932 
1933 
1934 /* Test simple select with prepare */
1935 
test_select_prepare()1936 static void test_select_prepare()
1937 {
1938   int        rc;
1939   MYSQL_STMT *stmt;
1940 
1941   myheader("test_select_prepare");
1942 
1943   rc= mysql_autocommit(mysql, TRUE);
1944   myquery(rc);
1945 
1946   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
1947   myquery(rc);
1948 
1949   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
1950   myquery(rc);
1951 
1952   /* insert a row and commit the transaction */
1953   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
1954   myquery(rc);
1955 
1956   rc= mysql_commit(mysql);
1957   myquery(rc);
1958 
1959   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
1960   check_stmt(stmt);
1961 
1962   rc= mysql_stmt_execute(stmt);
1963   check_execute(stmt, rc);
1964 
1965   rc= my_process_stmt_result(stmt);
1966   DIE_UNLESS(rc == 1);
1967   mysql_stmt_close(stmt);
1968 
1969   rc= mysql_query(mysql, "DROP TABLE test_select");
1970   myquery(rc);
1971 
1972   rc= mysql_query(mysql, "CREATE TABLE test_select(id tinyint, id1 int, "
1973                                                 "  id2 float, id3 float, "
1974                                                 "  name varchar(50))");
1975   myquery(rc);
1976 
1977   /* insert a row and commit the transaction */
1978   rc= mysql_query(mysql, "INSERT INTO test_select(id, id1, id2, name) VALUES(10, 5, 2.3, 'venu')");
1979   myquery(rc);
1980 
1981   rc= mysql_commit(mysql);
1982   myquery(rc);
1983 
1984   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
1985   check_stmt(stmt);
1986 
1987   rc= mysql_stmt_execute(stmt);
1988   check_execute(stmt, rc);
1989 
1990   rc= my_process_stmt_result(stmt);
1991   DIE_UNLESS(rc == 1);
1992   mysql_stmt_close(stmt);
1993 }
1994 
1995 
1996 /* Test simple select */
1997 
test_select()1998 static void test_select()
1999 {
2000   MYSQL_STMT *stmt;
2001   int        rc;
2002   char       szData[25];
2003   int        nData= 1;
2004   MYSQL_BIND my_bind[2];
2005   ulong length[2];
2006   char query[MAX_TEST_QUERY_LENGTH];
2007 
2008   myheader("test_select");
2009 
2010   rc= mysql_autocommit(mysql, TRUE);
2011   myquery(rc);
2012 
2013   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2014   myquery(rc);
2015 
2016   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
2017   myquery(rc);
2018 
2019   /* insert a row and commit the transaction */
2020   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
2021   myquery(rc);
2022 
2023   /* now insert the second row, and roll back the transaction */
2024   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(20, 'mysql')");
2025   myquery(rc);
2026 
2027   rc= mysql_commit(mysql);
2028   myquery(rc);
2029 
2030   strmov(query, "SELECT * FROM test_select WHERE id= ? "
2031                 "AND CONVERT(name USING utf8) =?");
2032   stmt= mysql_simple_prepare(mysql, query);
2033   check_stmt(stmt);
2034 
2035   verify_param_count(stmt, 2);
2036 
2037   /* Always bzero all members of bind parameter */
2038   bzero((char*) my_bind, sizeof(my_bind));
2039 
2040   /* string data */
2041   nData= 10;
2042   strmov(szData, (char *)"venu");
2043   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2044   my_bind[1].buffer= (void *)szData;
2045   my_bind[1].buffer_length= 4;
2046   my_bind[1].length= &length[1];
2047   length[1]= 4;
2048 
2049   my_bind[0].buffer= (void *)&nData;
2050   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2051 
2052   rc= mysql_stmt_bind_param(stmt, my_bind);
2053   check_execute(stmt, rc);
2054 
2055   rc= mysql_stmt_execute(stmt);
2056   check_execute(stmt, rc);
2057 
2058   rc= my_process_stmt_result(stmt);
2059   DIE_UNLESS(rc == 1);
2060 
2061   mysql_stmt_close(stmt);
2062 }
2063 
2064 
2065 /*
2066   Test for BUG#3420 ("select id1, value1 from t where id= ? or value= ?"
2067   returns all rows in the table)
2068 */
2069 
test_ps_conj_select()2070 static void test_ps_conj_select()
2071 {
2072   MYSQL_STMT *stmt;
2073   int        rc;
2074   MYSQL_BIND my_bind[2];
2075   int32      int_data;
2076   char       str_data[32];
2077   unsigned long str_length;
2078   char query[MAX_TEST_QUERY_LENGTH];
2079   myheader("test_ps_conj_select");
2080 
2081   rc= mysql_query(mysql, "drop table if exists t1");
2082   myquery(rc);
2083 
2084   rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2085                          "value2 varchar(100), value1 varchar(100))");
2086   myquery(rc);
2087 
2088   rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2089                           "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2090   myquery(rc);
2091 
2092   strmov(query, "select id1, value1 from t1 where id1= ? or "
2093                 "CONVERT(value1 USING utf8)= ?");
2094   stmt= mysql_simple_prepare(mysql, query);
2095   check_stmt(stmt);
2096 
2097   verify_param_count(stmt, 2);
2098 
2099   /* Always bzero all members of bind parameter */
2100   bzero((char*) my_bind, sizeof(my_bind));
2101 
2102   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2103   my_bind[0].buffer= (void *)&int_data;
2104 
2105   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2106   my_bind[1].buffer= (void *)str_data;
2107   my_bind[1].buffer_length= array_elements(str_data);
2108   my_bind[1].length= &str_length;
2109 
2110   rc= mysql_stmt_bind_param(stmt, my_bind);
2111   check_execute(stmt, rc);
2112 
2113   int_data= 1;
2114   strmov(str_data, "hh");
2115   str_length= strlen(str_data);
2116 
2117   rc= mysql_stmt_execute(stmt);
2118   check_execute(stmt, rc);
2119 
2120   rc= my_process_stmt_result(stmt);
2121   DIE_UNLESS(rc == 3);
2122 
2123   mysql_stmt_close(stmt);
2124 }
2125 
2126 
2127 /* reads Qcache_hits from server and returns its value */
query_cache_hits(MYSQL * conn)2128 static uint query_cache_hits(MYSQL *conn)
2129 {
2130   MYSQL_RES *res;
2131   MYSQL_ROW row;
2132   int rc;
2133   uint result;
2134 
2135   rc= mysql_query(conn, "show status like 'qcache_hits'");
2136   myquery(rc);
2137   res= mysql_use_result(conn);
2138   DIE_UNLESS(res);
2139 
2140   row= mysql_fetch_row(res);
2141   DIE_UNLESS(row);
2142 
2143   result= atoi(row[1]);
2144   mysql_free_result(res);
2145   return result;
2146 }
2147 
2148 
2149 /*
2150   utility for the next test; expects 3 rows in the result from a SELECT,
2151   compares each row/field with an expected value.
2152  */
2153 #define test_ps_query_cache_result(i1,s1,l1,i2,s2,l2,i3,s3,l3)    \
2154   r_metadata= mysql_stmt_result_metadata(stmt);                   \
2155   DIE_UNLESS(r_metadata != NULL);                                 \
2156   rc= mysql_stmt_fetch(stmt);                                     \
2157   check_execute(stmt, rc);                                        \
2158   if (!opt_silent)                                                \
2159     fprintf(stdout, "\n row 1: %d, %s(%lu)", r_int_data,          \
2160             r_str_data, r_str_length);                            \
2161   DIE_UNLESS((r_int_data == i1) && (r_str_length == l1) &&        \
2162              (strcmp(r_str_data, s1) == 0));                      \
2163   rc= mysql_stmt_fetch(stmt);                                     \
2164   check_execute(stmt, rc);                                        \
2165   if (!opt_silent)                                                \
2166     fprintf(stdout, "\n row 2: %d, %s(%lu)", r_int_data,          \
2167             r_str_data, r_str_length);                            \
2168   DIE_UNLESS((r_int_data == i2) && (r_str_length == l2) &&        \
2169              (strcmp(r_str_data, s2) == 0));                      \
2170   rc= mysql_stmt_fetch(stmt);                                     \
2171   check_execute(stmt, rc);                                        \
2172   if (!opt_silent)                                                \
2173     fprintf(stdout, "\n row 3: %d, %s(%lu)", r_int_data,          \
2174             r_str_data, r_str_length);                            \
2175   DIE_UNLESS((r_int_data == i3) && (r_str_length == l3) &&        \
2176              (strcmp(r_str_data, s3) == 0));                      \
2177   rc= mysql_stmt_fetch(stmt);                                     \
2178   DIE_UNLESS(rc == MYSQL_NO_DATA);                                \
2179   mysql_free_result(r_metadata);
2180 
2181 
2182 /*
2183   Test that prepared statements make use of the query cache just as normal
2184   statements (BUG#735).
2185 */
test_ps_query_cache()2186 static void test_ps_query_cache()
2187 {
2188   MYSQL      *lmysql= mysql;
2189   MYSQL_STMT *stmt;
2190   int        rc;
2191   MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */
2192   int32      p_int_data, r_int_data;
2193   char       p_str_data[32], r_str_data[32];
2194   unsigned long p_str_length, r_str_length;
2195   MYSQL_RES  *r_metadata;
2196   char       query[MAX_TEST_QUERY_LENGTH];
2197   uint       hits1, hits2;
2198   enum enum_test_ps_query_cache
2199   {
2200     /*
2201       We iterate the same prepare/executes block, but have iterations where
2202       we vary the query cache conditions.
2203     */
2204     /* the query cache is enabled for the duration of prep&execs: */
2205     TEST_QCACHE_ON= 0,
2206     /*
2207       same but using a new connection (to see if qcache serves results from
2208       the previous connection as it should):
2209     */
2210     TEST_QCACHE_ON_WITH_OTHER_CONN,
2211     /*
2212       First border case: disables the query cache before prepare and
2213       re-enables it before execution (to test if we have no bug then):
2214     */
2215     TEST_QCACHE_OFF_ON,
2216     /*
2217       Second border case: enables the query cache before prepare and
2218       disables it before execution:
2219     */
2220     TEST_QCACHE_ON_OFF
2221   };
2222   enum enum_test_ps_query_cache iteration;
2223 
2224   myheader("test_ps_query_cache");
2225 
2226   rc= mysql_query(mysql, "SET SQL_MODE=''");
2227   myquery(rc);
2228 
2229   /* prepare the table */
2230 
2231   rc= mysql_query(mysql, "drop table if exists t1");
2232   myquery(rc);
2233 
2234   rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2235                          "value2 varchar(100), value1 varchar(100))");
2236   myquery(rc);
2237 
2238   rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2239                           "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2240   myquery(rc);
2241 
2242   for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++)
2243   {
2244 
2245     switch (iteration) {
2246     case TEST_QCACHE_ON:
2247     case TEST_QCACHE_ON_OFF:
2248       rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2249       myquery(rc);
2250       break;
2251     case TEST_QCACHE_OFF_ON:
2252       rc= mysql_query(lmysql, "set global query_cache_size=0");
2253       myquery(rc);
2254       break;
2255     case TEST_QCACHE_ON_WITH_OTHER_CONN:
2256       if (!opt_silent)
2257         fprintf(stdout, "\n Establishing a test connection ...");
2258       if (!(lmysql= mysql_client_init(NULL)))
2259       {
2260         printf("mysql_client_init() failed");
2261         DIE_UNLESS(0);
2262       }
2263       if (!(mysql_real_connect(lmysql, opt_host, opt_user,
2264                                opt_password, current_db, opt_port,
2265                                opt_unix_socket, 0)))
2266       {
2267         printf("connection failed");
2268         mysql_close(lmysql);
2269         DIE_UNLESS(0);
2270       }
2271       rc= mysql_query(lmysql, "SET SQL_MODE=''");
2272       myquery(rc);
2273 
2274       if (!opt_silent)
2275         fprintf(stdout, "OK");
2276     }
2277 
2278     strmov(query, "select id1, value1 from t1 where id1= ? or "
2279            "CONVERT(value1 USING utf8)= ?");
2280     stmt= mysql_simple_prepare(lmysql, query);
2281     check_stmt(stmt);
2282 
2283     verify_param_count(stmt, 2);
2284 
2285     switch (iteration) {
2286     case TEST_QCACHE_OFF_ON:
2287       rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2288       myquery(rc);
2289       break;
2290     case TEST_QCACHE_ON_OFF:
2291       rc= mysql_query(lmysql, "set global query_cache_size=0");
2292       myquery(rc);
2293     default:
2294       break;
2295     }
2296 
2297     bzero((char*) p_bind, sizeof(p_bind));
2298     p_bind[0].buffer_type= MYSQL_TYPE_LONG;
2299     p_bind[0].buffer= (void *)&p_int_data;
2300     p_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2301     p_bind[1].buffer= (void *)p_str_data;
2302     p_bind[1].buffer_length= array_elements(p_str_data);
2303     p_bind[1].length= &p_str_length;
2304 
2305     rc= mysql_stmt_bind_param(stmt, p_bind);
2306     check_execute(stmt, rc);
2307 
2308     p_int_data= 1;
2309     strmov(p_str_data, "hh");
2310     p_str_length= strlen(p_str_data);
2311 
2312     bzero((char*) r_bind, sizeof(r_bind));
2313     r_bind[0].buffer_type= MYSQL_TYPE_LONG;
2314     r_bind[0].buffer= (void *)&r_int_data;
2315     r_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2316     r_bind[1].buffer= (void *)r_str_data;
2317     r_bind[1].buffer_length= array_elements(r_str_data);
2318     r_bind[1].length= &r_str_length;
2319 
2320     rc= mysql_stmt_bind_result(stmt, r_bind);
2321     check_execute(stmt, rc);
2322 
2323     rc= mysql_stmt_execute(stmt);
2324     check_execute(stmt, rc);
2325 
2326     test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2327 
2328     /* now retry with the same parameter values and see qcache hits */
2329     hits1= query_cache_hits(lmysql);
2330     rc= mysql_stmt_execute(stmt);
2331     check_execute(stmt, rc);
2332     test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2333     hits2= query_cache_hits(lmysql);
2334     switch(iteration) {
2335     case TEST_QCACHE_ON_WITH_OTHER_CONN:
2336     case TEST_QCACHE_ON:                 /* should have hit */
2337       DIE_UNLESS(hits2-hits1 == 1);
2338       break;
2339     case TEST_QCACHE_OFF_ON:
2340     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2341       DIE_UNLESS(hits2-hits1 == 0);
2342       break;
2343     }
2344 
2345     /* now modify parameter values and see qcache hits */
2346     strmov(p_str_data, "ii");
2347     p_str_length= strlen(p_str_data);
2348     rc= mysql_stmt_execute(stmt);
2349     check_execute(stmt, rc);
2350     test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2351     hits1= query_cache_hits(lmysql);
2352 
2353     switch(iteration) {
2354     case TEST_QCACHE_ON:
2355     case TEST_QCACHE_OFF_ON:
2356     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2357       DIE_UNLESS(hits2-hits1 == 0);
2358       break;
2359     case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2360       DIE_UNLESS(hits1-hits2 == 1);
2361       break;
2362     }
2363 
2364     rc= mysql_stmt_execute(stmt);
2365     check_execute(stmt, rc);
2366 
2367     test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2368     hits2= query_cache_hits(lmysql);
2369 
2370     mysql_stmt_close(stmt);
2371 
2372     switch(iteration) {
2373     case TEST_QCACHE_ON:                 /* should have hit */
2374       DIE_UNLESS(hits2-hits1 == 1);
2375       break;
2376     case TEST_QCACHE_OFF_ON:
2377     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2378       DIE_UNLESS(hits2-hits1 == 0);
2379       break;
2380     case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2381       DIE_UNLESS(hits2-hits1 == 1);
2382       break;
2383     }
2384 
2385   } /* for(iteration=...) */
2386 
2387   if (lmysql != mysql)
2388     mysql_close(lmysql);
2389 
2390   rc= mysql_query(mysql, "set global query_cache_size=0");
2391   myquery(rc);
2392 }
2393 
2394 
2395 /* Test BUG#1115 (incorrect string parameter value allocation) */
2396 
test_bug1115()2397 static void test_bug1115()
2398 {
2399   MYSQL_STMT *stmt;
2400   int rc;
2401   MYSQL_BIND my_bind[1];
2402   ulong length[1];
2403   char szData[11];
2404   char query[MAX_TEST_QUERY_LENGTH];
2405 
2406   myheader("test_bug1115");
2407 
2408   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2409   myquery(rc);
2410 
2411   rc= mysql_query(mysql, "CREATE TABLE test_select(\
2412 session_id  char(9) NOT NULL, \
2413     a       int(8) unsigned NOT NULL, \
2414     b        int(5) NOT NULL, \
2415     c      int(5) NOT NULL, \
2416     d  datetime NOT NULL)");
2417   myquery(rc);
2418   rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2419                          "(\"abc\", 1, 2, 3, 2003-08-30), "
2420                          "(\"abd\", 1, 2, 3, 2003-08-30), "
2421                          "(\"abf\", 1, 2, 3, 2003-08-30), "
2422                          "(\"abg\", 1, 2, 3, 2003-08-30), "
2423                          "(\"abh\", 1, 2, 3, 2003-08-30), "
2424                          "(\"abj\", 1, 2, 3, 2003-08-30), "
2425                          "(\"abk\", 1, 2, 3, 2003-08-30), "
2426                          "(\"abl\", 1, 2, 3, 2003-08-30), "
2427                          "(\"abq\", 1, 2, 3, 2003-08-30) ");
2428   myquery(rc);
2429   rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2430                          "(\"abw\", 1, 2, 3, 2003-08-30), "
2431                          "(\"abe\", 1, 2, 3, 2003-08-30), "
2432                          "(\"abr\", 1, 2, 3, 2003-08-30), "
2433                          "(\"abt\", 1, 2, 3, 2003-08-30), "
2434                          "(\"aby\", 1, 2, 3, 2003-08-30), "
2435                          "(\"abu\", 1, 2, 3, 2003-08-30), "
2436                          "(\"abi\", 1, 2, 3, 2003-08-30), "
2437                          "(\"abo\", 1, 2, 3, 2003-08-30), "
2438                          "(\"abp\", 1, 2, 3, 2003-08-30), "
2439                          "(\"abz\", 1, 2, 3, 2003-08-30), "
2440                          "(\"abx\", 1, 2, 3, 2003-08-30)");
2441   myquery(rc);
2442 
2443   strmov(query, "SELECT * FROM test_select WHERE "
2444                 "CONVERT(session_id USING utf8)= ?");
2445   stmt= mysql_simple_prepare(mysql, query);
2446   check_stmt(stmt);
2447 
2448   verify_param_count(stmt, 1);
2449 
2450   /* Always bzero all members of bind parameter */
2451   bzero((char*) my_bind, sizeof(my_bind));
2452 
2453   strmov(szData, (char *)"abc");
2454   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2455   my_bind[0].buffer= (void *)szData;
2456   my_bind[0].buffer_length= 10;
2457   my_bind[0].length= &length[0];
2458   length[0]= 3;
2459 
2460   rc= mysql_stmt_bind_param(stmt, my_bind);
2461   check_execute(stmt, rc);
2462 
2463   rc= mysql_stmt_execute(stmt);
2464   check_execute(stmt, rc);
2465 
2466   rc= my_process_stmt_result(stmt);
2467   DIE_UNLESS(rc == 1);
2468 
2469   strmov(szData, (char *)"venu");
2470   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2471   my_bind[0].buffer= (void *)szData;
2472   my_bind[0].buffer_length= 10;
2473   my_bind[0].length= &length[0];
2474   length[0]= 4;
2475   my_bind[0].is_null= 0;
2476 
2477   rc= mysql_stmt_bind_param(stmt, my_bind);
2478   check_execute(stmt, rc);
2479 
2480   rc= mysql_stmt_execute(stmt);
2481   check_execute(stmt, rc);
2482 
2483   rc= my_process_stmt_result(stmt);
2484   DIE_UNLESS(rc == 0);
2485 
2486   strmov(szData, (char *)"abc");
2487   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2488   my_bind[0].buffer= (void *)szData;
2489   my_bind[0].buffer_length= 10;
2490   my_bind[0].length= &length[0];
2491   length[0]= 3;
2492   my_bind[0].is_null= 0;
2493 
2494   rc= mysql_stmt_bind_param(stmt, my_bind);
2495   check_execute(stmt, rc);
2496 
2497   rc= mysql_stmt_execute(stmt);
2498   check_execute(stmt, rc);
2499 
2500   rc= my_process_stmt_result(stmt);
2501   DIE_UNLESS(rc == 1);
2502 
2503   mysql_stmt_close(stmt);
2504 }
2505 
2506 
2507 /* Test BUG#1180 (optimized away part of WHERE clause) */
2508 
test_bug1180()2509 static void test_bug1180()
2510 {
2511   MYSQL_STMT *stmt;
2512   int rc;
2513   MYSQL_BIND my_bind[1];
2514   ulong length[1];
2515   char szData[11];
2516   char query[MAX_TEST_QUERY_LENGTH];
2517 
2518   myheader("test_select_bug");
2519 
2520   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2521   myquery(rc);
2522 
2523   rc= mysql_query(mysql, "CREATE TABLE test_select(session_id  char(9) NOT NULL)");
2524   myquery(rc);
2525   rc= mysql_query(mysql, "INSERT INTO test_select VALUES (\"abc\")");
2526   myquery(rc);
2527 
2528   strmov(query, "SELECT * FROM test_select WHERE ?= \"1111\" and "
2529                 "session_id= \"abc\"");
2530   stmt= mysql_simple_prepare(mysql, query);
2531   check_stmt(stmt);
2532 
2533   verify_param_count(stmt, 1);
2534 
2535   /* Always bzero all members of bind parameter */
2536   bzero((char*) my_bind, sizeof(my_bind));
2537 
2538   strmov(szData, (char *)"abc");
2539   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2540   my_bind[0].buffer= (void *)szData;
2541   my_bind[0].buffer_length= 10;
2542   my_bind[0].length= &length[0];
2543   length[0]= 3;
2544   my_bind[0].is_null= 0;
2545 
2546   rc= mysql_stmt_bind_param(stmt, my_bind);
2547   check_execute(stmt, rc);
2548 
2549   rc= mysql_stmt_execute(stmt);
2550   check_execute(stmt, rc);
2551 
2552   rc= my_process_stmt_result(stmt);
2553   DIE_UNLESS(rc == 0);
2554 
2555   strmov(szData, (char *)"1111");
2556   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2557   my_bind[0].buffer= (void *)szData;
2558   my_bind[0].buffer_length= 10;
2559   my_bind[0].length= &length[0];
2560   length[0]= 4;
2561   my_bind[0].is_null= 0;
2562 
2563   rc= mysql_stmt_bind_param(stmt, my_bind);
2564   check_execute(stmt, rc);
2565 
2566   rc= mysql_stmt_execute(stmt);
2567   check_execute(stmt, rc);
2568 
2569   rc= my_process_stmt_result(stmt);
2570   DIE_UNLESS(rc == 1);
2571 
2572   strmov(szData, (char *)"abc");
2573   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2574   my_bind[0].buffer= (void *)szData;
2575   my_bind[0].buffer_length= 10;
2576   my_bind[0].length= &length[0];
2577   length[0]= 3;
2578   my_bind[0].is_null= 0;
2579 
2580   rc= mysql_stmt_bind_param(stmt, my_bind);
2581   check_execute(stmt, rc);
2582 
2583   rc= mysql_stmt_execute(stmt);
2584   check_execute(stmt, rc);
2585 
2586   rc= my_process_stmt_result(stmt);
2587   DIE_UNLESS(rc == 0);
2588 
2589   mysql_stmt_close(stmt);
2590 }
2591 
2592 
2593 /*
2594   Test BUG#1644 (Insertion of more than 3 NULL columns with parameter
2595   binding fails)
2596 */
2597 
test_bug1644()2598 static void test_bug1644()
2599 {
2600   MYSQL_STMT *stmt;
2601   MYSQL_RES *result;
2602   MYSQL_ROW row;
2603   MYSQL_BIND my_bind[4];
2604   int num;
2605   my_bool isnull;
2606   int rc, i;
2607   char query[MAX_TEST_QUERY_LENGTH];
2608 
2609   myheader("test_bug1644");
2610 
2611   rc= mysql_query(mysql, "DROP TABLE IF EXISTS foo_dfr");
2612   myquery(rc);
2613 
2614   rc= mysql_query(mysql,
2615            "CREATE TABLE foo_dfr(col1 int, col2 int, col3 int, col4 int);");
2616   myquery(rc);
2617 
2618   strmov(query, "INSERT INTO foo_dfr VALUES (?, ?, ?, ? )");
2619   stmt= mysql_simple_prepare(mysql, query);
2620   check_stmt(stmt);
2621 
2622   verify_param_count(stmt, 4);
2623 
2624   /* Always bzero all members of bind parameter */
2625   bzero((char*) my_bind, sizeof(my_bind));
2626 
2627   num= 22;
2628   isnull= 0;
2629   for (i= 0 ; i < 4 ; i++)
2630   {
2631     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
2632     my_bind[i].buffer= (void *)&num;
2633     my_bind[i].is_null= &isnull;
2634   }
2635 
2636   rc= mysql_stmt_bind_param(stmt, my_bind);
2637   check_execute(stmt, rc);
2638 
2639   rc= mysql_stmt_execute(stmt);
2640   check_execute(stmt, rc);
2641 
2642   isnull= 1;
2643   for (i= 0 ; i < 4 ; i++)
2644     my_bind[i].is_null= &isnull;
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= 0;
2653   num= 88;
2654   for (i= 0 ; i < 4 ; i++)
2655     my_bind[i].is_null= &isnull;
2656 
2657   rc= mysql_stmt_bind_param(stmt, my_bind);
2658   check_execute(stmt, rc);
2659 
2660   rc= mysql_stmt_execute(stmt);
2661   check_execute(stmt, rc);
2662 
2663   mysql_stmt_close(stmt);
2664 
2665   rc= mysql_query(mysql, "SELECT * FROM foo_dfr");
2666   myquery(rc);
2667 
2668   result= mysql_store_result(mysql);
2669   mytest(result);
2670 
2671   rc= my_process_result_set(result);
2672   DIE_UNLESS(rc == 3);
2673 
2674   mysql_data_seek(result, 0);
2675 
2676   row= mysql_fetch_row(result);
2677   mytest(row);
2678   for (i= 0 ; i < 4 ; i++)
2679   {
2680     DIE_UNLESS(strcmp(row[i], "22") == 0);
2681   }
2682   row= mysql_fetch_row(result);
2683   mytest(row);
2684   for (i= 0 ; i < 4 ; i++)
2685   {
2686     DIE_UNLESS(row[i] == 0);
2687   }
2688   row= mysql_fetch_row(result);
2689   mytest(row);
2690   for (i= 0 ; i < 4 ; i++)
2691   {
2692     DIE_UNLESS(strcmp(row[i], "88") == 0);
2693   }
2694   row= mysql_fetch_row(result);
2695   mytest_r(row);
2696 
2697   mysql_free_result(result);
2698 }
2699 
2700 
2701 /* Test simple select show */
2702 
test_select_show()2703 static void test_select_show()
2704 {
2705   MYSQL_STMT *stmt;
2706   int        rc;
2707   char query[MAX_TEST_QUERY_LENGTH];
2708 
2709   myheader("test_select_show");
2710 
2711   mysql_autocommit(mysql, TRUE);
2712 
2713   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_show");
2714   myquery(rc);
2715 
2716   rc= mysql_query(mysql, "CREATE TABLE test_show(id int(4) NOT NULL primary "
2717                          " key, name char(2))");
2718   myquery(rc);
2719 
2720   stmt= mysql_simple_prepare(mysql, "show columns from test_show");
2721   check_stmt(stmt);
2722 
2723   verify_param_count(stmt, 0);
2724 
2725   rc= mysql_stmt_execute(stmt);
2726   check_execute(stmt, rc);
2727 
2728   my_process_stmt_result(stmt);
2729   mysql_stmt_close(stmt);
2730 
2731   stmt= mysql_simple_prepare(mysql, "show tables from mysql like ?");
2732   check_stmt_r(stmt);
2733 
2734   strxmov(query, "show tables from ", current_db, " like \'test_show\'", NullS);
2735   stmt= mysql_simple_prepare(mysql, query);
2736   check_stmt(stmt);
2737 
2738   rc= mysql_stmt_execute(stmt);
2739   check_execute(stmt, rc);
2740 
2741   my_process_stmt_result(stmt);
2742   mysql_stmt_close(stmt);
2743 
2744   stmt= mysql_simple_prepare(mysql, "describe test_show");
2745   check_stmt(stmt);
2746 
2747   rc= mysql_stmt_execute(stmt);
2748   check_execute(stmt, rc);
2749 
2750   my_process_stmt_result(stmt);
2751   mysql_stmt_close(stmt);
2752 
2753   stmt= mysql_simple_prepare(mysql, "show keys from test_show");
2754   check_stmt(stmt);
2755 
2756   rc= mysql_stmt_execute(stmt);
2757   check_execute(stmt, rc);
2758 
2759   rc= my_process_stmt_result(stmt);
2760   DIE_UNLESS(rc == 1);
2761   mysql_stmt_close(stmt);
2762 }
2763 
2764 
2765 /* Test simple update */
2766 
test_simple_update()2767 static void test_simple_update()
2768 {
2769   MYSQL_STMT *stmt;
2770   int        rc;
2771   char       szData[25];
2772   int        nData= 1;
2773   MYSQL_RES  *result;
2774   MYSQL_BIND my_bind[2];
2775   ulong      length[2];
2776   char query[MAX_TEST_QUERY_LENGTH];
2777 
2778   myheader("test_simple_update");
2779 
2780   rc= mysql_autocommit(mysql, TRUE);
2781   myquery(rc);
2782 
2783   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
2784   myquery(rc);
2785 
2786   rc= mysql_query(mysql, "CREATE TABLE test_update(col1 int, "
2787                          " col2 varchar(50), col3 int )");
2788   myquery(rc);
2789 
2790   rc= mysql_query(mysql, "INSERT INTO test_update VALUES(1, 'MySQL', 100)");
2791   myquery(rc);
2792 
2793   verify_affected_rows(1);
2794 
2795   rc= mysql_commit(mysql);
2796   myquery(rc);
2797 
2798   /* insert by prepare */
2799   strmov(query, "UPDATE test_update SET col2= ? WHERE col1= ?");
2800   stmt= mysql_simple_prepare(mysql, query);
2801   check_stmt(stmt);
2802 
2803   verify_param_count(stmt, 2);
2804 
2805   /* Always bzero all members of bind parameter */
2806   bzero((char*) my_bind, sizeof(my_bind));
2807 
2808   nData= 1;
2809   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2810   my_bind[0].buffer= szData;                /* string data */
2811   my_bind[0].buffer_length= sizeof(szData);
2812   my_bind[0].length= &length[0];
2813   length[0]= sprintf(szData, "updated-data");
2814 
2815   my_bind[1].buffer= (void *) &nData;
2816   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
2817 
2818   rc= mysql_stmt_bind_param(stmt, my_bind);
2819   check_execute(stmt, rc);
2820 
2821   rc= mysql_stmt_execute(stmt);
2822   check_execute(stmt, rc);
2823   verify_affected_rows(1);
2824 
2825   mysql_stmt_close(stmt);
2826 
2827   /* now fetch the results ..*/
2828   rc= mysql_commit(mysql);
2829   myquery(rc);
2830 
2831   /* test the results now, only one row should exist */
2832   rc= mysql_query(mysql, "SELECT * FROM test_update");
2833   myquery(rc);
2834 
2835   /* get the result */
2836   result= mysql_store_result(mysql);
2837   mytest(result);
2838 
2839   rc= my_process_result_set(result);
2840   DIE_UNLESS(rc == 1);
2841   mysql_free_result(result);
2842 }
2843 
2844 
2845 /* Test simple long data handling */
2846 
test_long_data()2847 static void test_long_data()
2848 {
2849   MYSQL_STMT *stmt;
2850   int        rc, int_data;
2851   char       *data= NullS;
2852   MYSQL_RES  *result;
2853   MYSQL_BIND my_bind[3];
2854   char query[MAX_TEST_QUERY_LENGTH];
2855 
2856   myheader("test_long_data");
2857 
2858   rc= mysql_autocommit(mysql, TRUE);
2859   myquery(rc);
2860 
2861   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
2862   myquery(rc);
2863 
2864   rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, "
2865                          "      col2 long varchar, col3 long varbinary)");
2866   myquery(rc);
2867 
2868   strmov(query, "INSERT INTO test_long_data(col1, col2) VALUES(?)");
2869   stmt= mysql_simple_prepare(mysql, query);
2870   check_stmt_r(stmt);
2871 
2872   strmov(query, "INSERT INTO test_long_data(col1, col2, col3) VALUES(?, ?, ?)");
2873   stmt= mysql_simple_prepare(mysql, query);
2874   check_stmt(stmt);
2875 
2876   verify_param_count(stmt, 3);
2877 
2878   /* Always bzero all members of bind parameter */
2879   bzero((char*) my_bind, sizeof(my_bind));
2880 
2881   my_bind[0].buffer= (void *)&int_data;
2882   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2883 
2884   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2885 
2886   my_bind[2]= my_bind[1];
2887   rc= mysql_stmt_bind_param(stmt, my_bind);
2888   check_execute(stmt, rc);
2889 
2890   int_data= 999;
2891   data= (char *)"Michael";
2892 
2893   /* supply data in pieces */
2894   rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
2895   data= (char *)" 'Monty' Widenius";
2896   rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
2897   check_execute(stmt, rc);
2898   rc= mysql_stmt_send_long_data(stmt, 2, "Venu (venu@mysql.com)", 4);
2899   check_execute(stmt, rc);
2900 
2901   /* execute */
2902   rc= mysql_stmt_execute(stmt);
2903   if (!opt_silent)
2904     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
2905   check_execute(stmt, rc);
2906 
2907   rc= mysql_commit(mysql);
2908   myquery(rc);
2909 
2910   /* now fetch the results ..*/
2911   rc= mysql_query(mysql, "SELECT * FROM test_long_data");
2912   myquery(rc);
2913 
2914   /* get the result */
2915   result= mysql_store_result(mysql);
2916   mytest(result);
2917 
2918   rc= my_process_result_set(result);
2919   DIE_UNLESS(rc == 1);
2920   mysql_free_result(result);
2921 
2922   verify_col_data("test_long_data", "col1", "999");
2923   verify_col_data("test_long_data", "col2", "Michael 'Monty' Widenius");
2924   verify_col_data("test_long_data", "col3", "Venu");
2925   mysql_stmt_close(stmt);
2926 }
2927 
2928 
2929 /* Test long data (string) handling */
2930 
test_long_data_str()2931 static void test_long_data_str()
2932 {
2933   MYSQL_STMT *stmt;
2934   int        rc, i;
2935   char       data[255];
2936   long       length;
2937   ulong      length1;
2938   MYSQL_RES  *result;
2939   MYSQL_BIND my_bind[2];
2940   my_bool    is_null[2];
2941   char query[MAX_TEST_QUERY_LENGTH];
2942 
2943   myheader("test_long_data_str");
2944 
2945   rc= mysql_autocommit(mysql, TRUE);
2946   myquery(rc);
2947 
2948   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
2949   myquery(rc);
2950 
2951   rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(id int, longstr long varchar)");
2952   myquery(rc);
2953 
2954   strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
2955   stmt= mysql_simple_prepare(mysql, query);
2956   check_stmt(stmt);
2957 
2958   verify_param_count(stmt, 2);
2959 
2960   /* Always bzero all members of bind parameter */
2961   bzero((char*) my_bind, sizeof(my_bind));
2962 
2963   my_bind[0].buffer= (void *)&length;
2964   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2965   my_bind[0].is_null= &is_null[0];
2966   is_null[0]= 0;
2967   length= 0;
2968 
2969   my_bind[1].buffer= data;                          /* string data */
2970   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2971   my_bind[1].length= &length1;
2972   my_bind[1].is_null= &is_null[1];
2973   is_null[1]= 0;
2974   rc= mysql_stmt_bind_param(stmt, my_bind);
2975   check_execute(stmt, rc);
2976 
2977   length= 40;
2978   strmov(data, "MySQL AB");
2979 
2980   /* supply data in pieces */
2981   for(i= 0; i < 4; i++)
2982   {
2983     rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 5);
2984     check_execute(stmt, rc);
2985   }
2986   /* execute */
2987   rc= mysql_stmt_execute(stmt);
2988   if (!opt_silent)
2989     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
2990   check_execute(stmt, rc);
2991 
2992   mysql_stmt_close(stmt);
2993 
2994   rc= mysql_commit(mysql);
2995   myquery(rc);
2996 
2997   /* now fetch the results ..*/
2998   rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr FROM test_long_data_str");
2999   myquery(rc);
3000 
3001   /* get the result */
3002   result= mysql_store_result(mysql);
3003   mytest(result);
3004 
3005   rc= my_process_result_set(result);
3006   DIE_UNLESS(rc == 1);
3007   mysql_free_result(result);
3008 
3009   sprintf(data, "%d", i*5);
3010   verify_col_data("test_long_data_str", "LENGTH(longstr)", data);
3011   data[0]= '\0';
3012   while (i--)
3013    strxmov(data, data, "MySQL", NullS);
3014   verify_col_data("test_long_data_str", "longstr", data);
3015 
3016   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3017   myquery(rc);
3018 }
3019 
3020 
3021 /* Test long data (string) handling */
3022 
test_long_data_str1()3023 static void test_long_data_str1()
3024 {
3025   MYSQL_STMT *stmt;
3026   int        rc, i;
3027   char       data[255];
3028   long       length;
3029   ulong      max_blob_length, blob_length, length1;
3030   my_bool    true_value;
3031   MYSQL_RES  *result;
3032   MYSQL_BIND my_bind[2];
3033   MYSQL_FIELD *field;
3034   char query[MAX_TEST_QUERY_LENGTH];
3035 
3036   myheader("test_long_data_str1");
3037 
3038   rc= mysql_autocommit(mysql, TRUE);
3039   myquery(rc);
3040 
3041   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
3042   myquery(rc);
3043 
3044   rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(longstr long varchar, blb long varbinary)");
3045   myquery(rc);
3046 
3047   strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
3048   stmt= mysql_simple_prepare(mysql, query);
3049   check_stmt(stmt);
3050 
3051   verify_param_count(stmt, 2);
3052 
3053   /* Always bzero all members of bind parameter */
3054   bzero((char*) my_bind, sizeof(my_bind));
3055 
3056   my_bind[0].buffer= data;            /* string data */
3057   my_bind[0].buffer_length= sizeof(data);
3058   my_bind[0].length= &length1;
3059   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3060   length1= 0;
3061 
3062   my_bind[1]= my_bind[0];
3063   my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3064 
3065   rc= mysql_stmt_bind_param(stmt, my_bind);
3066   check_execute(stmt, rc);
3067   length= sprintf(data, "MySQL AB");
3068 
3069   /* supply data in pieces */
3070   for (i= 0; i < 3; i++)
3071   {
3072     rc= mysql_stmt_send_long_data(stmt, 0, data, length);
3073     check_execute(stmt, rc);
3074 
3075     rc= mysql_stmt_send_long_data(stmt, 1, data, 2);
3076     check_execute(stmt, rc);
3077   }
3078 
3079   /* execute */
3080   rc= mysql_stmt_execute(stmt);
3081   if (!opt_silent)
3082     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3083   check_execute(stmt, rc);
3084 
3085   mysql_stmt_close(stmt);
3086 
3087   rc= mysql_commit(mysql);
3088   myquery(rc);
3089 
3090   /* now fetch the results ..*/
3091   rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr, LENGTH(blb), blb FROM test_long_data_str");
3092   myquery(rc);
3093 
3094   /* get the result */
3095   result= mysql_store_result(mysql);
3096 
3097   mysql_field_seek(result, 1);
3098   field= mysql_fetch_field(result);
3099   max_blob_length= field->max_length;
3100 
3101   mytest(result);
3102 
3103   rc= my_process_result_set(result);
3104   DIE_UNLESS(rc == 1);
3105   mysql_free_result(result);
3106 
3107   sprintf(data, "%ld", (long)i*length);
3108   verify_col_data("test_long_data_str", "length(longstr)", data);
3109 
3110   sprintf(data, "%d", i*2);
3111   verify_col_data("test_long_data_str", "length(blb)", data);
3112 
3113   /* Test length of field->max_length */
3114   stmt= mysql_simple_prepare(mysql, "SELECT * from test_long_data_str");
3115   check_stmt(stmt);
3116   verify_param_count(stmt, 0);
3117 
3118   rc= mysql_stmt_execute(stmt);
3119   check_execute(stmt, rc);
3120 
3121   rc= mysql_stmt_store_result(stmt);
3122   check_execute(stmt, rc);
3123 
3124   result= mysql_stmt_result_metadata(stmt);
3125   field= mysql_fetch_fields(result);
3126 
3127   /* First test what happens if STMT_ATTR_UPDATE_MAX_LENGTH is not used */
3128   DIE_UNLESS(field->max_length == 0);
3129   mysql_free_result(result);
3130 
3131   /* Enable updating of field->max_length */
3132   true_value= 1;
3133   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &true_value);
3134   rc= mysql_stmt_execute(stmt);
3135   check_execute(stmt, rc);
3136 
3137   rc= mysql_stmt_store_result(stmt);
3138   check_execute(stmt, rc);
3139 
3140   result= mysql_stmt_result_metadata(stmt);
3141   field= mysql_fetch_fields(result);
3142 
3143   DIE_UNLESS(field->max_length == max_blob_length);
3144 
3145   /* Fetch results into a data buffer that is smaller than data */
3146   bzero((char*) my_bind, sizeof(*my_bind));
3147   my_bind[0].buffer_type= MYSQL_TYPE_BLOB;
3148   my_bind[0].buffer= (void *) &data; /* this buffer won't be altered */
3149   my_bind[0].buffer_length= 16;
3150   my_bind[0].length= &blob_length;
3151   my_bind[0].error= &my_bind[0].error_value;
3152   rc= mysql_stmt_bind_result(stmt, my_bind);
3153   data[16]= 0;
3154 
3155   rc= mysql_stmt_fetch(stmt);
3156   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
3157   DIE_UNLESS(my_bind[0].error_value);
3158   DIE_UNLESS(strlen(data) == 16);
3159   DIE_UNLESS(blob_length == max_blob_length);
3160 
3161   /* Fetch all data */
3162   bzero((char*) (my_bind+1), sizeof(*my_bind));
3163   my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3164   my_bind[1].buffer= (void *) &data; /* this buffer won't be altered */
3165   my_bind[1].buffer_length= sizeof(data);
3166   my_bind[1].length= &blob_length;
3167   bzero(data, sizeof(data));
3168   mysql_stmt_fetch_column(stmt, my_bind+1, 0, 0);
3169   DIE_UNLESS(strlen(data) == max_blob_length);
3170 
3171   mysql_free_result(result);
3172   mysql_stmt_close(stmt);
3173 
3174   /* Drop created table */
3175   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3176   myquery(rc);
3177 }
3178 
3179 
3180 /* Test long data (binary) handling */
3181 
test_long_data_bin()3182 static void test_long_data_bin()
3183 {
3184   MYSQL_STMT *stmt;
3185   int        rc;
3186   char       data[255];
3187   long       length;
3188   MYSQL_RES  *result;
3189   MYSQL_BIND my_bind[2];
3190   char query[MAX_TEST_QUERY_LENGTH];
3191 
3192 
3193   myheader("test_long_data_bin");
3194 
3195   rc= mysql_autocommit(mysql, TRUE);
3196   myquery(rc);
3197 
3198   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_bin");
3199   myquery(rc);
3200 
3201   rc= mysql_query(mysql, "CREATE TABLE test_long_data_bin(id int, longbin long varbinary)");
3202   myquery(rc);
3203 
3204   strmov(query, "INSERT INTO test_long_data_bin VALUES(?, ?)");
3205   stmt= mysql_simple_prepare(mysql, query);
3206   check_stmt(stmt);
3207 
3208   verify_param_count(stmt, 2);
3209 
3210   /* Always bzero all members of bind parameter */
3211   bzero((char*) my_bind, sizeof(my_bind));
3212 
3213   my_bind[0].buffer= (void *)&length;
3214   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3215   length= 0;
3216 
3217   my_bind[1].buffer= data;           /* string data */
3218   my_bind[1].buffer_type= MYSQL_TYPE_LONG_BLOB;
3219   rc= mysql_stmt_bind_param(stmt, my_bind);
3220   check_execute(stmt, rc);
3221 
3222   length= 10;
3223   strmov(data, "MySQL AB");
3224 
3225   /* supply data in pieces */
3226   {
3227     int i;
3228     for (i= 0; i < 100; i++)
3229     {
3230       rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 4);
3231       check_execute(stmt, rc);
3232     }
3233   }
3234   /* execute */
3235   rc= mysql_stmt_execute(stmt);
3236   if (!opt_silent)
3237     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3238   check_execute(stmt, rc);
3239 
3240   mysql_stmt_close(stmt);
3241 
3242   rc= mysql_commit(mysql);
3243   myquery(rc);
3244 
3245   /* now fetch the results ..*/
3246   rc= mysql_query(mysql, "SELECT LENGTH(longbin), longbin FROM test_long_data_bin");
3247   myquery(rc);
3248 
3249   /* get the result */
3250   result= mysql_store_result(mysql);
3251   mytest(result);
3252 
3253   rc= my_process_result_set(result);
3254   DIE_UNLESS(rc == 1);
3255   mysql_free_result(result);
3256 }
3257 
3258 
3259 /* Test simple delete */
3260 
test_simple_delete()3261 static void test_simple_delete()
3262 {
3263   MYSQL_STMT *stmt;
3264   int        rc;
3265   char       szData[30]= {0};
3266   int        nData= 1;
3267   MYSQL_RES  *result;
3268   MYSQL_BIND my_bind[2];
3269   ulong length[2];
3270   char query[MAX_TEST_QUERY_LENGTH];
3271 
3272   myheader("test_simple_delete");
3273 
3274   rc= mysql_autocommit(mysql, TRUE);
3275   myquery(rc);
3276 
3277   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_simple_delete");
3278   myquery(rc);
3279 
3280   rc= mysql_query(mysql, "CREATE TABLE test_simple_delete(col1 int, \
3281                                 col2 varchar(50), col3 int )");
3282   myquery(rc);
3283 
3284   rc= mysql_query(mysql, "INSERT INTO test_simple_delete VALUES(1, 'MySQL', 100)");
3285   myquery(rc);
3286 
3287   verify_affected_rows(1);
3288 
3289   rc= mysql_commit(mysql);
3290   myquery(rc);
3291 
3292   /* insert by prepare */
3293   strmov(query, "DELETE FROM test_simple_delete WHERE col1= ? AND "
3294                 "CONVERT(col2 USING utf8)= ? AND col3= 100");
3295   stmt= mysql_simple_prepare(mysql, query);
3296   check_stmt(stmt);
3297 
3298   verify_param_count(stmt, 2);
3299 
3300   /* Always bzero all members of bind parameter */
3301   bzero((char*) my_bind, sizeof(my_bind));
3302 
3303   nData= 1;
3304   strmov(szData, "MySQL");
3305   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3306   my_bind[1].buffer= szData;               /* string data */
3307   my_bind[1].buffer_length= sizeof(szData);
3308   my_bind[1].length= &length[1];
3309   length[1]= 5;
3310 
3311   my_bind[0].buffer= (void *)&nData;
3312   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3313 
3314   rc= mysql_stmt_bind_param(stmt, my_bind);
3315   check_execute(stmt, rc);
3316 
3317   rc= mysql_stmt_execute(stmt);
3318   check_execute(stmt, rc);
3319 
3320   verify_affected_rows(1);
3321 
3322   mysql_stmt_close(stmt);
3323 
3324   /* now fetch the results ..*/
3325   rc= mysql_commit(mysql);
3326   myquery(rc);
3327 
3328   /* test the results now, only one row should exist */
3329   rc= mysql_query(mysql, "SELECT * FROM test_simple_delete");
3330   myquery(rc);
3331 
3332   /* get the result */
3333   result= mysql_store_result(mysql);
3334   mytest(result);
3335 
3336   rc= my_process_result_set(result);
3337   DIE_UNLESS(rc == 0);
3338   mysql_free_result(result);
3339 }
3340 
3341 
3342 /* Test simple update */
3343 
test_update()3344 static void test_update()
3345 {
3346   MYSQL_STMT *stmt;
3347   int        rc;
3348   char       szData[25];
3349   int        nData= 1;
3350   MYSQL_RES  *result;
3351   MYSQL_BIND my_bind[2];
3352   ulong length[2];
3353   char query[MAX_TEST_QUERY_LENGTH];
3354 
3355   myheader("test_update");
3356 
3357   rc= mysql_autocommit(mysql, TRUE);
3358   myquery(rc);
3359 
3360   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
3361   myquery(rc);
3362 
3363   rc= mysql_query(mysql, "CREATE TABLE test_update("
3364                                "col1 int primary key auto_increment, "
3365                                "col2 varchar(50), col3 int )");
3366   myquery(rc);
3367 
3368   strmov(query, "INSERT INTO test_update(col2, col3) VALUES(?, ?)");
3369   stmt= mysql_simple_prepare(mysql, query);
3370   check_stmt(stmt);
3371 
3372   verify_param_count(stmt, 2);
3373 
3374   /* Always bzero all members of bind parameter */
3375   bzero((char*) my_bind, sizeof(my_bind));
3376 
3377   /* string data */
3378   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3379   my_bind[0].buffer= szData;
3380   my_bind[0].buffer_length= sizeof(szData);
3381   my_bind[0].length= &length[0];
3382   length[0]= sprintf(szData, "inserted-data");
3383 
3384   my_bind[1].buffer= (void *)&nData;
3385   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3386 
3387   rc= mysql_stmt_bind_param(stmt, my_bind);
3388   check_execute(stmt, rc);
3389 
3390   nData= 100;
3391   rc= mysql_stmt_execute(stmt);
3392   check_execute(stmt, rc);
3393 
3394   verify_affected_rows(1);
3395   mysql_stmt_close(stmt);
3396 
3397   strmov(query, "UPDATE test_update SET col2= ? WHERE col3= ?");
3398   stmt= mysql_simple_prepare(mysql, query);
3399   check_stmt(stmt);
3400 
3401   verify_param_count(stmt, 2);
3402   nData= 100;
3403 
3404   /* Always bzero all members of bind parameter */
3405   bzero((char*) my_bind, sizeof(my_bind));
3406 
3407   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3408   my_bind[0].buffer= szData;
3409   my_bind[0].buffer_length= sizeof(szData);
3410   my_bind[0].length= &length[0];
3411   length[0]= sprintf(szData, "updated-data");
3412 
3413   my_bind[1].buffer= (void *)&nData;
3414   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3415 
3416   rc= mysql_stmt_bind_param(stmt, my_bind);
3417   check_execute(stmt, rc);
3418 
3419   rc= mysql_stmt_execute(stmt);
3420   check_execute(stmt, rc);
3421   verify_affected_rows(1);
3422 
3423   mysql_stmt_close(stmt);
3424 
3425   /* now fetch the results ..*/
3426   rc= mysql_commit(mysql);
3427   myquery(rc);
3428 
3429   /* test the results now, only one row should exist */
3430   rc= mysql_query(mysql, "SELECT * FROM test_update");
3431   myquery(rc);
3432 
3433   /* get the result */
3434   result= mysql_store_result(mysql);
3435   mytest(result);
3436 
3437   rc= my_process_result_set(result);
3438   DIE_UNLESS(rc == 1);
3439   mysql_free_result(result);
3440 }
3441 
3442 
3443 /* Test prepare without parameters */
3444 
test_prepare_noparam()3445 static void test_prepare_noparam()
3446 {
3447   MYSQL_STMT *stmt;
3448   int        rc;
3449   MYSQL_RES  *result;
3450   char query[MAX_TEST_QUERY_LENGTH];
3451 
3452   myheader("test_prepare_noparam");
3453 
3454   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
3455   myquery(rc);
3456 
3457 
3458   rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 int, col2 varchar(50))");
3459   myquery(rc);
3460 
3461   /* insert by prepare */
3462   strmov(query, "INSERT INTO my_prepare VALUES(10, 'venu')");
3463   stmt= mysql_simple_prepare(mysql, query);
3464   check_stmt(stmt);
3465 
3466   verify_param_count(stmt, 0);
3467 
3468   rc= mysql_stmt_execute(stmt);
3469   check_execute(stmt, rc);
3470 
3471   mysql_stmt_close(stmt);
3472 
3473   /* now fetch the results ..*/
3474   rc= mysql_commit(mysql);
3475   myquery(rc);
3476 
3477   /* test the results now, only one row should exist */
3478   rc= mysql_query(mysql, "SELECT * FROM my_prepare");
3479   myquery(rc);
3480 
3481   /* get the result */
3482   result= mysql_store_result(mysql);
3483   mytest(result);
3484 
3485   rc= my_process_result_set(result);
3486   DIE_UNLESS(rc == 1);
3487   mysql_free_result(result);
3488 }
3489 
3490 
3491 /* Test simple bind result */
3492 
test_bind_result()3493 static void test_bind_result()
3494 {
3495   MYSQL_STMT *stmt;
3496   int        rc;
3497   int        nData;
3498   ulong      length1;
3499   char       szData[100];
3500   MYSQL_BIND my_bind[2];
3501   my_bool    is_null[2];
3502 
3503   myheader("test_bind_result");
3504 
3505   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3506   myquery(rc);
3507 
3508   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(col1 int , col2 varchar(50))");
3509   myquery(rc);
3510 
3511   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(10, 'venu')");
3512   myquery(rc);
3513 
3514   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(20, 'MySQL')");
3515   myquery(rc);
3516 
3517   rc= mysql_query(mysql, "INSERT INTO test_bind_result(col2) VALUES('monty')");
3518   myquery(rc);
3519 
3520   rc= mysql_commit(mysql);
3521   myquery(rc);
3522 
3523   /* fetch */
3524 
3525   bzero((char*) my_bind, sizeof(my_bind));
3526   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3527   my_bind[0].buffer= (void *) &nData;      /* integer data */
3528   my_bind[0].is_null= &is_null[0];
3529 
3530   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3531   my_bind[1].buffer= szData;                /* string data */
3532   my_bind[1].buffer_length= sizeof(szData);
3533   my_bind[1].length= &length1;
3534   my_bind[1].is_null= &is_null[1];
3535 
3536   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
3537   check_stmt(stmt);
3538 
3539   rc= mysql_stmt_bind_result(stmt, my_bind);
3540   check_execute(stmt, rc);
3541 
3542   rc= mysql_stmt_execute(stmt);
3543   check_execute(stmt, rc);
3544 
3545   rc= mysql_stmt_fetch(stmt);
3546   check_execute(stmt, rc);
3547 
3548   if (!opt_silent)
3549     fprintf(stdout, "\n row 1: %d, %s(%lu)", nData, szData, length1);
3550   DIE_UNLESS(nData == 10);
3551   DIE_UNLESS(strcmp(szData, "venu") == 0);
3552   DIE_UNLESS(length1 == 4);
3553 
3554   rc= mysql_stmt_fetch(stmt);
3555   check_execute(stmt, rc);
3556 
3557   if (!opt_silent)
3558     fprintf(stdout, "\n row 2: %d, %s(%lu)", nData, szData, length1);
3559   DIE_UNLESS(nData == 20);
3560   DIE_UNLESS(strcmp(szData, "MySQL") == 0);
3561   DIE_UNLESS(length1 == 5);
3562 
3563   rc= mysql_stmt_fetch(stmt);
3564   check_execute(stmt, rc);
3565 
3566   if (!opt_silent && is_null[0])
3567     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
3568   DIE_UNLESS(is_null[0]);
3569   DIE_UNLESS(strcmp(szData, "monty") == 0);
3570   DIE_UNLESS(length1 == 5);
3571 
3572   rc= mysql_stmt_fetch(stmt);
3573   DIE_UNLESS(rc == MYSQL_NO_DATA);
3574 
3575   mysql_stmt_close(stmt);
3576 }
3577 
3578 
3579 /* Test ext bind result */
3580 
test_bind_result_ext()3581 static void test_bind_result_ext()
3582 {
3583   MYSQL_STMT *stmt;
3584   int        rc, i;
3585   uchar      t_data;
3586   short      s_data;
3587   int        i_data;
3588   longlong   b_data;
3589   float      f_data;
3590   double     d_data;
3591   char       szData[20], bData[20];
3592   ulong       szLength, bLength;
3593   MYSQL_BIND my_bind[8];
3594   ulong      length[8];
3595   my_bool    is_null[8];
3596   char	     llbuf[22];
3597   myheader("test_bind_result_ext");
3598 
3599   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3600   myquery(rc);
3601 
3602   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, "
3603                                                       " c2 smallint, "
3604                                                       " c3 int, c4 bigint, "
3605                                                       " c5 float, c6 double, "
3606                                                       " c7 varbinary(10), "
3607                                                       " c8 varchar(50))");
3608   myquery(rc);
3609 
3610   rc= mysql_query(mysql, "INSERT INTO test_bind_result "
3611                          "VALUES (19, 2999, 3999, 4999999, "
3612                          " 2345.6, 5678.89563, 'venu', 'mysql')");
3613   myquery(rc);
3614 
3615   rc= mysql_commit(mysql);
3616   myquery(rc);
3617 
3618   bzero((char*) my_bind, sizeof(my_bind));
3619   for (i= 0; i < (int) array_elements(my_bind); i++)
3620   {
3621     my_bind[i].length=  &length[i];
3622     my_bind[i].is_null= &is_null[i];
3623   }
3624 
3625   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
3626   my_bind[0].buffer= (void *)&t_data;
3627 
3628   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
3629   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
3630 
3631   my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
3632   my_bind[1].buffer= (void *)&s_data;
3633 
3634   my_bind[2].buffer= (void *)&i_data;
3635   my_bind[3].buffer= (void *)&b_data;
3636 
3637   my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
3638   my_bind[4].buffer= (void *)&f_data;
3639 
3640   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
3641   my_bind[5].buffer= (void *)&d_data;
3642 
3643   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
3644   my_bind[6].buffer= (void *)szData;
3645   my_bind[6].buffer_length= sizeof(szData);
3646   my_bind[6].length= &szLength;
3647 
3648   my_bind[7].buffer_type= MYSQL_TYPE_TINY_BLOB;
3649   my_bind[7].buffer= (void *)&bData;
3650   my_bind[7].length= &bLength;
3651   my_bind[7].buffer_length= sizeof(bData);
3652 
3653   stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3654   check_stmt(stmt);
3655 
3656   rc= mysql_stmt_bind_result(stmt, my_bind);
3657   check_execute(stmt, rc);
3658 
3659   rc= mysql_stmt_execute(stmt);
3660   check_execute(stmt, rc);
3661 
3662   rc= mysql_stmt_fetch(stmt);
3663   check_execute(stmt, rc);
3664 
3665   if (!opt_silent)
3666   {
3667     fprintf(stdout, "\n data (tiny)   : %d", t_data);
3668     fprintf(stdout, "\n data (short)  : %d", s_data);
3669     fprintf(stdout, "\n data (int)    : %d", i_data);
3670     fprintf(stdout, "\n data (big)    : %s", llstr(b_data, llbuf));
3671 
3672     fprintf(stdout, "\n data (float)  : %f", f_data);
3673     fprintf(stdout, "\n data (double) : %f", d_data);
3674 
3675     fprintf(stdout, "\n data (str)    : %s(%lu)", szData, szLength);
3676 
3677     bData[bLength]= '\0';                         /* bData is binary */
3678     fprintf(stdout, "\n data (bin)    : %s(%lu)", bData, bLength);
3679   }
3680 
3681   DIE_UNLESS(t_data == 19);
3682   DIE_UNLESS(s_data == 2999);
3683   DIE_UNLESS(i_data == 3999);
3684   DIE_UNLESS(b_data == 4999999);
3685   /*DIE_UNLESS(f_data == 2345.60);*/
3686   /*DIE_UNLESS(d_data == 5678.89563);*/
3687   DIE_UNLESS(strcmp(szData, "venu") == 0);
3688   DIE_UNLESS(strncmp(bData, "mysql", 5) == 0);
3689   DIE_UNLESS(szLength == 4);
3690   DIE_UNLESS(bLength == 5);
3691 
3692   rc= mysql_stmt_fetch(stmt);
3693   DIE_UNLESS(rc == MYSQL_NO_DATA);
3694 
3695   mysql_stmt_close(stmt);
3696 }
3697 
3698 
3699 /* Test ext bind result */
3700 
test_bind_result_ext1()3701 static void test_bind_result_ext1()
3702 {
3703   MYSQL_STMT *stmt;
3704   uint       i;
3705   int        rc;
3706   char       t_data[20];
3707   float      s_data;
3708   short      i_data;
3709   uchar      b_data;
3710   int        f_data;
3711   long       bData;
3712   char       d_data[20];
3713   double     szData;
3714   MYSQL_BIND my_bind[8];
3715   ulong      length[8];
3716   my_bool    is_null[8];
3717   myheader("test_bind_result_ext1");
3718 
3719   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3720   myquery(rc);
3721 
3722   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, \
3723                                                         c3 int, c4 bigint, \
3724                                                         c5 float, c6 double, \
3725                                                         c7 varbinary(10), \
3726                                                         c8 varchar(10))");
3727   myquery(rc);
3728 
3729   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(120, 2999, 3999, 54, \
3730                                                               2.6, 58.89, \
3731                                                               '206', '6.7')");
3732   myquery(rc);
3733 
3734   rc= mysql_commit(mysql);
3735   myquery(rc);
3736 
3737   bzero((char*) my_bind, sizeof(my_bind));
3738   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3739   my_bind[0].buffer= (void *) t_data;
3740   my_bind[0].buffer_length= sizeof(t_data);
3741   my_bind[0].error= &my_bind[0].error_value;
3742 
3743   my_bind[1].buffer_type= MYSQL_TYPE_FLOAT;
3744   my_bind[1].buffer= (void *)&s_data;
3745   my_bind[1].buffer_length= 0;
3746   my_bind[1].error= &my_bind[1].error_value;
3747 
3748   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
3749   my_bind[2].buffer= (void *)&i_data;
3750   my_bind[2].buffer_length= 0;
3751   my_bind[2].error= &my_bind[2].error_value;
3752 
3753   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
3754   my_bind[3].buffer= (void *)&b_data;
3755   my_bind[3].buffer_length= 0;
3756   my_bind[3].error= &my_bind[3].error_value;
3757 
3758   my_bind[4].buffer_type= MYSQL_TYPE_LONG;
3759   my_bind[4].buffer= (void *)&f_data;
3760   my_bind[4].buffer_length= 0;
3761   my_bind[4].error= &my_bind[4].error_value;
3762 
3763   my_bind[5].buffer_type= MYSQL_TYPE_STRING;
3764   my_bind[5].buffer= (void *)d_data;
3765   my_bind[5].buffer_length= sizeof(d_data);
3766   my_bind[5].error= &my_bind[5].error_value;
3767 
3768   my_bind[6].buffer_type= MYSQL_TYPE_LONG;
3769   my_bind[6].buffer= (void *)&bData;
3770   my_bind[6].buffer_length= 0;
3771   my_bind[6].error= &my_bind[6].error_value;
3772 
3773   my_bind[7].buffer_type= MYSQL_TYPE_DOUBLE;
3774   my_bind[7].buffer= (void *)&szData;
3775   my_bind[7].buffer_length= 0;
3776   my_bind[7].error= &my_bind[7].error_value;
3777 
3778   for (i= 0; i < array_elements(my_bind); i++)
3779   {
3780     my_bind[i].is_null= &is_null[i];
3781     my_bind[i].length= &length[i];
3782   }
3783 
3784   stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3785   check_stmt(stmt);
3786 
3787   rc= mysql_stmt_bind_result(stmt, my_bind);
3788   check_execute(stmt, rc);
3789 
3790   rc= mysql_stmt_execute(stmt);
3791   check_execute(stmt, rc);
3792 
3793   rc= mysql_stmt_fetch(stmt);
3794   printf("rc=%d\n", rc);
3795   DIE_UNLESS(rc == 0);
3796 
3797   if (!opt_silent)
3798   {
3799     fprintf(stdout, "\n data (tiny)   : %s(%lu)", t_data, length[0]);
3800     fprintf(stdout, "\n data (short)  : %f(%lu)", s_data, length[1]);
3801     fprintf(stdout, "\n data (int)    : %d(%lu)", i_data, length[2]);
3802     fprintf(stdout, "\n data (big)    : %d(%lu)", b_data, length[3]);
3803 
3804     fprintf(stdout, "\n data (float)  : %d(%lu)", f_data, length[4]);
3805     fprintf(stdout, "\n data (double) : %s(%lu)", d_data, length[5]);
3806 
3807     fprintf(stdout, "\n data (bin)    : %ld(%lu)", bData, length[6]);
3808     fprintf(stdout, "\n data (str)    : %g(%lu)", szData, length[7]);
3809   }
3810 
3811   DIE_UNLESS(strcmp(t_data, "120") == 0);
3812   DIE_UNLESS(i_data == 3999);
3813   DIE_UNLESS(f_data == 2);
3814   DIE_UNLESS(strcmp(d_data, "58.89") == 0);
3815   DIE_UNLESS(b_data == 54);
3816 
3817   DIE_UNLESS(length[0] == 3);
3818   DIE_UNLESS(length[1] == 4);
3819   DIE_UNLESS(length[2] == 2);
3820   DIE_UNLESS(length[3] == 1);
3821   DIE_UNLESS(length[4] == 4);
3822   DIE_UNLESS(length[5] == 5);
3823   DIE_UNLESS(length[6] == 4);
3824   DIE_UNLESS(length[7] == 8);
3825 
3826   rc= mysql_stmt_fetch(stmt);
3827   DIE_UNLESS(rc == MYSQL_NO_DATA);
3828 
3829   mysql_stmt_close(stmt);
3830 }
3831 
3832 
3833 /* Generalized fetch conversion routine for all basic types */
3834 
bind_fetch(int row_count)3835 static void bind_fetch(int row_count)
3836 {
3837   MYSQL_STMT   *stmt;
3838   int          rc, i, count= row_count;
3839   int32        data[10];
3840   int8         i8_data;
3841   int16        i16_data;
3842   int32        i32_data;
3843   longlong     i64_data;
3844   float        f_data;
3845   double       d_data;
3846   char         s_data[10];
3847   ulong        length[10];
3848   MYSQL_BIND   my_bind[7];
3849   my_bool      is_null[7];
3850 
3851   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_bind_fetch VALUES "
3852                                     "(?, ?, ?, ?, ?, ?, ?)");
3853   check_stmt(stmt);
3854 
3855   verify_param_count(stmt, 7);
3856 
3857   /* Always bzero all members of bind parameter */
3858   bzero((char*) my_bind, sizeof(my_bind));
3859 
3860   for (i= 0; i < (int) array_elements(my_bind); i++)
3861   {
3862     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
3863     my_bind[i].buffer= (void *) &data[i];
3864   }
3865   rc= mysql_stmt_bind_param(stmt, my_bind);
3866   check_execute(stmt, rc);
3867 
3868   while (count--)
3869   {
3870     rc= 10+count;
3871     for (i= 0; i < (int) array_elements(my_bind); i++)
3872     {
3873       data[i]= rc+i;
3874       rc+= 12;
3875     }
3876     rc= mysql_stmt_execute(stmt);
3877     check_execute(stmt, rc);
3878   }
3879 
3880   rc= mysql_commit(mysql);
3881   myquery(rc);
3882 
3883   mysql_stmt_close(stmt);
3884 
3885   rc= my_stmt_result("SELECT * FROM test_bind_fetch");
3886   DIE_UNLESS(row_count == rc);
3887 
3888   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_fetch");
3889   check_stmt(stmt);
3890 
3891   for (i= 0; i < (int) array_elements(my_bind); i++)
3892   {
3893     my_bind[i].buffer= (void *) &data[i];
3894     my_bind[i].length= &length[i];
3895     my_bind[i].is_null= &is_null[i];
3896   }
3897 
3898   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
3899   my_bind[0].buffer= (void *)&i8_data;
3900 
3901   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
3902   my_bind[1].buffer= (void *)&i16_data;
3903 
3904   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
3905   my_bind[2].buffer= (void *)&i32_data;
3906 
3907   my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
3908   my_bind[3].buffer= (void *)&i64_data;
3909 
3910   my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
3911   my_bind[4].buffer= (void *)&f_data;
3912 
3913   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
3914   my_bind[5].buffer= (void *)&d_data;
3915 
3916   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
3917   my_bind[6].buffer= (void *)&s_data;
3918   my_bind[6].buffer_length= sizeof(s_data);
3919 
3920   rc= mysql_stmt_bind_result(stmt, my_bind);
3921   check_execute(stmt, rc);
3922 
3923   rc= mysql_stmt_execute(stmt);
3924   check_execute(stmt, rc);
3925 
3926   rc= mysql_stmt_store_result(stmt);
3927   check_execute(stmt, rc);
3928 
3929   while (row_count--)
3930   {
3931     rc= mysql_stmt_fetch(stmt);
3932     check_execute(stmt, rc);
3933 
3934     if (!opt_silent)
3935     {
3936       fprintf(stdout, "\n");
3937       fprintf(stdout, "\n tiny     : %ld(%lu)", (ulong) i8_data, length[0]);
3938       fprintf(stdout, "\n short    : %ld(%lu)", (ulong) i16_data, length[1]);
3939       fprintf(stdout, "\n int      : %ld(%lu)", (ulong) i32_data, length[2]);
3940       fprintf(stdout, "\n longlong : %ld(%lu)", (ulong) i64_data, length[3]);
3941       fprintf(stdout, "\n float    : %f(%lu)",  f_data,  length[4]);
3942       fprintf(stdout, "\n double   : %g(%lu)",  d_data,  length[5]);
3943       fprintf(stdout, "\n char     : %s(%lu)",  s_data,  length[6]);
3944     }
3945     rc= 10+row_count;
3946 
3947     /* TINY */
3948     DIE_UNLESS((int) i8_data == rc);
3949     DIE_UNLESS(length[0] == 1);
3950     rc+= 13;
3951 
3952     /* SHORT */
3953     DIE_UNLESS((int) i16_data == rc);
3954     DIE_UNLESS(length[1] == 2);
3955     rc+= 13;
3956 
3957     /* LONG */
3958     DIE_UNLESS((int) i32_data == rc);
3959     DIE_UNLESS(length[2] == 4);
3960     rc+= 13;
3961 
3962     /* LONGLONG */
3963     DIE_UNLESS((int) i64_data == rc);
3964     DIE_UNLESS(length[3] == 8);
3965     rc+= 13;
3966 
3967     /* FLOAT */
3968     DIE_UNLESS((int)f_data == rc);
3969     DIE_UNLESS(length[4] == 4);
3970     rc+= 13;
3971 
3972     /* DOUBLE */
3973     DIE_UNLESS((int)d_data == rc);
3974     DIE_UNLESS(length[5] == 8);
3975     rc+= 13;
3976 
3977     /* CHAR */
3978     {
3979       char buff[20];
3980       long len= sprintf(buff, "%d", rc);
3981       DIE_UNLESS(strcmp(s_data, buff) == 0);
3982       DIE_UNLESS(length[6] == (ulong) len);
3983     }
3984   }
3985   rc= mysql_stmt_fetch(stmt);
3986   DIE_UNLESS(rc == MYSQL_NO_DATA);
3987 
3988   mysql_stmt_close(stmt);
3989 }
3990 
3991 
3992 /* Test fetching of date, time and ts */
3993 
test_fetch_date()3994 static void test_fetch_date()
3995 {
3996   MYSQL_STMT *stmt;
3997   uint       i;
3998   int        rc, year;
3999   char       date[25], my_time[25], ts[25], ts_4[25], ts_6[20], dt[20];
4000   ulong      d_length, t_length, ts_length, ts4_length, ts6_length,
4001              dt_length, y_length;
4002   MYSQL_BIND my_bind[8];
4003   my_bool    is_null[8];
4004   ulong      length[8];
4005 
4006   myheader("test_fetch_date");
4007 
4008   /* Will not work if sql_mode is NO_ZERO_DATE (implicit if TRADITIONAL) */
4009   rc= mysql_query(mysql, "SET SQL_MODE=''");
4010   myquery(rc);
4011 
4012   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
4013   myquery(rc);
4014 
4015   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \
4016                                                         c3 timestamp, \
4017                                                         c4 year, \
4018                                                         c5 datetime, \
4019                                                         c6 timestamp, \
4020                                                         c7 timestamp)");
4021   myquery(rc);
4022 
4023   rc= mysql_query(mysql, "SET SQL_MODE=''");
4024   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \
4025                                                               '12:49:00', \
4026                                                               '2002-01-02 17:46:59', \
4027                                                               2010, \
4028                                                               '2010-07-10', \
4029                                                               '2020', '1999-12-29')");
4030   myquery(rc);
4031 
4032   rc= mysql_commit(mysql);
4033   myquery(rc);
4034 
4035   bzero((char*) my_bind, sizeof(my_bind));
4036   for (i= 0; i < array_elements(my_bind); i++)
4037   {
4038     my_bind[i].is_null= &is_null[i];
4039     my_bind[i].length= &length[i];
4040   }
4041 
4042   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
4043   my_bind[1]= my_bind[2]= my_bind[0];
4044 
4045   my_bind[0].buffer= (void *)&date;
4046   my_bind[0].buffer_length= sizeof(date);
4047   my_bind[0].length= &d_length;
4048 
4049   my_bind[1].buffer= (void *)&my_time;
4050   my_bind[1].buffer_length= sizeof(my_time);
4051   my_bind[1].length= &t_length;
4052 
4053   my_bind[2].buffer= (void *)&ts;
4054   my_bind[2].buffer_length= sizeof(ts);
4055   my_bind[2].length= &ts_length;
4056 
4057   my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4058   my_bind[3].buffer= (void *)&year;
4059   my_bind[3].length= &y_length;
4060 
4061   my_bind[4].buffer_type= MYSQL_TYPE_STRING;
4062   my_bind[4].buffer= (void *)&dt;
4063   my_bind[4].buffer_length= sizeof(dt);
4064   my_bind[4].length= &dt_length;
4065 
4066   my_bind[5].buffer_type= MYSQL_TYPE_STRING;
4067   my_bind[5].buffer= (void *)&ts_4;
4068   my_bind[5].buffer_length= sizeof(ts_4);
4069   my_bind[5].length= &ts4_length;
4070 
4071   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
4072   my_bind[6].buffer= (void *)&ts_6;
4073   my_bind[6].buffer_length= sizeof(ts_6);
4074   my_bind[6].length= &ts6_length;
4075 
4076   rc= my_stmt_result("SELECT * FROM test_bind_result");
4077   DIE_UNLESS(rc == 1);
4078 
4079   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
4080   check_stmt(stmt);
4081 
4082   rc= mysql_stmt_bind_result(stmt, my_bind);
4083   check_execute(stmt, rc);
4084 
4085   rc= mysql_stmt_execute(stmt);
4086   check_execute(stmt, rc);
4087 
4088   ts_4[0]= '\0';
4089   rc= mysql_stmt_fetch(stmt);
4090   check_execute(stmt, rc);
4091 
4092   if (!opt_silent)
4093   {
4094     fprintf(stdout, "\n date   : %s(%lu)", date, d_length);
4095     fprintf(stdout, "\n time   : %s(%lu)", my_time, t_length);
4096     fprintf(stdout, "\n ts     : %s(%lu)", ts, ts_length);
4097     fprintf(stdout, "\n year   : %d(%lu)", year, y_length);
4098     fprintf(stdout, "\n dt     : %s(%lu)", dt,  dt_length);
4099     fprintf(stdout, "\n ts(4)  : %s(%lu)", ts_4, ts4_length);
4100     fprintf(stdout, "\n ts(6)  : %s(%lu)", ts_6, ts6_length);
4101   }
4102 
4103   DIE_UNLESS(strcmp(date, "2002-01-02") == 0);
4104   DIE_UNLESS(d_length == 10);
4105 
4106   DIE_UNLESS(strcmp(my_time, "12:49:00") == 0);
4107   DIE_UNLESS(t_length == 8);
4108 
4109   DIE_UNLESS(strcmp(ts, "2002-01-02 17:46:59") == 0);
4110   DIE_UNLESS(ts_length == 19);
4111 
4112   DIE_UNLESS(year == 2010);
4113   DIE_UNLESS(y_length == 4);
4114 
4115   DIE_UNLESS(strcmp(dt, "2010-07-10 00:00:00") == 0);
4116   DIE_UNLESS(dt_length == 19);
4117 
4118   DIE_UNLESS(strcmp(ts_4, "0000-00-00 00:00:00") == 0);
4119   DIE_UNLESS(ts4_length == strlen("0000-00-00 00:00:00"));
4120 
4121   DIE_UNLESS(strcmp(ts_6, "1999-12-29 00:00:00") == 0);
4122   DIE_UNLESS(ts6_length == 19);
4123 
4124   rc= mysql_stmt_fetch(stmt);
4125   DIE_UNLESS(rc == MYSQL_NO_DATA);
4126 
4127   mysql_stmt_close(stmt);
4128 }
4129 
4130 
4131 /* Test fetching of str to all types */
4132 
test_fetch_str()4133 static void test_fetch_str()
4134 {
4135   int rc;
4136 
4137   myheader("test_fetch_str");
4138 
4139   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4140   myquery(rc);
4141 
4142   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 char(10), \
4143                                                      c2 char(10), \
4144                                                      c3 char(20), \
4145                                                      c4 char(20), \
4146                                                      c5 char(30), \
4147                                                      c6 char(40), \
4148                                                      c7 char(20))");
4149   myquery(rc);
4150 
4151   bind_fetch(3);
4152 }
4153 
4154 
4155 /* Test fetching of long to all types */
4156 
test_fetch_long()4157 static void test_fetch_long()
4158 {
4159   int rc;
4160 
4161   myheader("test_fetch_long");
4162 
4163   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4164   myquery(rc);
4165 
4166   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 int unsigned, \
4167                                                      c2 int unsigned, \
4168                                                      c3 int, \
4169                                                      c4 int, \
4170                                                      c5 int, \
4171                                                      c6 int unsigned, \
4172                                                      c7 int)");
4173   myquery(rc);
4174 
4175   bind_fetch(4);
4176 }
4177 
4178 
4179 /* Test fetching of short to all types */
4180 
test_fetch_short()4181 static void test_fetch_short()
4182 {
4183   int rc;
4184 
4185   myheader("test_fetch_short");
4186 
4187   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4188   myquery(rc);
4189 
4190   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, \
4191                                                      c2 smallint, \
4192                                                      c3 smallint unsigned, \
4193                                                      c4 smallint, \
4194                                                      c5 smallint, \
4195                                                      c6 smallint, \
4196                                                      c7 smallint unsigned)");
4197   myquery(rc);
4198 
4199   bind_fetch(5);
4200 }
4201 
4202 
4203 /* Test fetching of tiny to all types */
4204 
test_fetch_tiny()4205 static void test_fetch_tiny()
4206 {
4207   int rc;
4208 
4209   myheader("test_fetch_tiny");
4210 
4211   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4212   myquery(rc);
4213 
4214   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 tinyint unsigned, \
4215                                                      c2 tinyint, \
4216                                                      c3 tinyint unsigned, \
4217                                                      c4 tinyint, \
4218                                                      c5 tinyint, \
4219                                                      c6 tinyint, \
4220                                                      c7 tinyint unsigned)");
4221   myquery(rc);
4222 
4223   bind_fetch(3);
4224 
4225 }
4226 
4227 
4228 /* Test fetching of longlong to all types */
4229 
test_fetch_bigint()4230 static void test_fetch_bigint()
4231 {
4232   int rc;
4233 
4234   myheader("test_fetch_bigint");
4235 
4236   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4237   myquery(rc);
4238 
4239   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 bigint, \
4240                                                      c2 bigint, \
4241                                                      c3 bigint unsigned, \
4242                                                      c4 bigint unsigned, \
4243                                                      c5 bigint unsigned, \
4244                                                      c6 bigint unsigned, \
4245                                                      c7 bigint unsigned)");
4246   myquery(rc);
4247 
4248   bind_fetch(2);
4249 
4250 }
4251 
4252 
4253 /* Test fetching of float to all types */
4254 
test_fetch_float()4255 static void test_fetch_float()
4256 {
4257   int rc;
4258 
4259   myheader("test_fetch_float");
4260 
4261   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4262   myquery(rc);
4263 
4264   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 float(3), \
4265                                                      c2 float, \
4266                                                      c3 float unsigned, \
4267                                                      c4 float, \
4268                                                      c5 float, \
4269                                                      c6 float, \
4270                                                      c7 float(10) unsigned)");
4271   myquery(rc);
4272 
4273   bind_fetch(2);
4274 
4275 }
4276 
4277 
4278 /* Test fetching of double to all types */
4279 
test_fetch_double()4280 static void test_fetch_double()
4281 {
4282   int rc;
4283 
4284   myheader("test_fetch_double");
4285 
4286   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4287   myquery(rc);
4288 
4289   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 double(5, 2), "
4290                          "c2 double unsigned, c3 double unsigned, "
4291                          "c4 double unsigned, c5 double unsigned, "
4292                          "c6 double unsigned, c7 double unsigned)");
4293   myquery(rc);
4294 
4295   bind_fetch(3);
4296 
4297 }
4298 
4299 
4300 /* Test simple prepare with all possible types */
4301 
test_prepare_ext()4302 static void test_prepare_ext()
4303 {
4304   MYSQL_STMT *stmt;
4305   int        rc;
4306   char       *sql;
4307   int        nData= 1;
4308   char       tData= 1;
4309   short      sData= 10;
4310   longlong   bData= 20;
4311   MYSQL_BIND my_bind[6];
4312   char query[MAX_TEST_QUERY_LENGTH];
4313   myheader("test_prepare_ext");
4314 
4315   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext");
4316   myquery(rc);
4317 
4318   sql= (char *)"CREATE TABLE test_prepare_ext"
4319                "("
4320                " c1  tinyint,"
4321                " c2  smallint,"
4322                " c3  mediumint,"
4323                " c4  int,"
4324                " c5  integer,"
4325                " c6  bigint,"
4326                " c7  float,"
4327                " c8  double,"
4328                " c9  double precision,"
4329                " c10 real,"
4330                " c11 decimal(7, 4),"
4331                " c12 numeric(8, 4),"
4332                " c13 date,"
4333                " c14 datetime,"
4334                " c15 timestamp,"
4335                " c16 time,"
4336                " c17 year,"
4337                " c18 bit,"
4338                " c19 bool,"
4339                " c20 char,"
4340                " c21 char(10),"
4341                " c22 varchar(30),"
4342                " c23 tinyblob,"
4343                " c24 tinytext,"
4344                " c25 blob,"
4345                " c26 text,"
4346                " c27 mediumblob,"
4347                " c28 mediumtext,"
4348                " c29 longblob,"
4349                " c30 longtext,"
4350                " c31 enum('one', 'two', 'three'),"
4351                " c32 set('monday', 'tuesday', 'wednesday'))";
4352 
4353   rc= mysql_query(mysql, sql);
4354   myquery(rc);
4355 
4356   /* insert by prepare - all integers */
4357   strmov(query, (char *)"INSERT INTO test_prepare_ext(c1, c2, c3, c4, c5, c6) VALUES(?, ?, ?, ?, ?, ?)");
4358   stmt= mysql_simple_prepare(mysql, query);
4359   check_stmt(stmt);
4360 
4361   verify_param_count(stmt, 6);
4362 
4363   /* Always bzero all members of bind parameter */
4364   bzero((char*) my_bind, sizeof(my_bind));
4365 
4366   /*tinyint*/
4367   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4368   my_bind[0].buffer= (void *)&tData;
4369 
4370   /*smallint*/
4371   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
4372   my_bind[1].buffer= (void *)&sData;
4373 
4374   /*mediumint*/
4375   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
4376   my_bind[2].buffer= (void *)&nData;
4377 
4378   /*int*/
4379   my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4380   my_bind[3].buffer= (void *)&nData;
4381 
4382   /*integer*/
4383   my_bind[4].buffer_type= MYSQL_TYPE_LONG;
4384   my_bind[4].buffer= (void *)&nData;
4385 
4386   /*bigint*/
4387   my_bind[5].buffer_type= MYSQL_TYPE_LONGLONG;
4388   my_bind[5].buffer= (void *)&bData;
4389 
4390   rc= mysql_stmt_bind_param(stmt, my_bind);
4391   check_execute(stmt, rc);
4392 
4393   /*
4394   *  integer to integer
4395   */
4396   for (nData= 0; nData<10; nData++, tData++, sData++, bData++)
4397   {
4398     rc= mysql_stmt_execute(stmt);
4399     check_execute(stmt, rc);
4400   }
4401   mysql_stmt_close(stmt);
4402 
4403   /* now fetch the results ..*/
4404 
4405   stmt= mysql_simple_prepare(mysql, "SELECT c1, c2, c3, c4, c5, c6 "
4406                                     "FROM test_prepare_ext");
4407   check_stmt(stmt);
4408 
4409   /* get the result */
4410   rc= mysql_stmt_execute(stmt);
4411   check_execute(stmt, rc);
4412 
4413   rc= my_process_stmt_result(stmt);
4414   DIE_UNLESS(nData == rc);
4415 
4416   mysql_stmt_close(stmt);
4417 }
4418 
4419 
4420 /* Test real and alias names */
4421 
test_field_names()4422 static void test_field_names()
4423 {
4424   int        rc;
4425   MYSQL_RES  *result;
4426 
4427   myheader("test_field_names");
4428 
4429   if (!opt_silent)
4430     fprintf(stdout, "\n %d, %d, %d", MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_ENUM);
4431   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names1");
4432   myquery(rc);
4433 
4434   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names2");
4435   myquery(rc);
4436 
4437   rc= mysql_query(mysql, "CREATE TABLE test_field_names1(id int, name varchar(50))");
4438   myquery(rc);
4439 
4440   rc= mysql_query(mysql, "CREATE TABLE test_field_names2(id int, name varchar(50))");
4441   myquery(rc);
4442 
4443   /* with table name included with TRUE column name */
4444   rc= mysql_query(mysql, "SELECT id as 'id-alias' FROM test_field_names1");
4445   myquery(rc);
4446 
4447   result= mysql_use_result(mysql);
4448   mytest(result);
4449 
4450   rc= my_process_result_set(result);
4451   DIE_UNLESS(rc == 0);
4452   mysql_free_result(result);
4453 
4454   /* with table name included with TRUE column name */
4455   rc= mysql_query(mysql, "SELECT t1.id as 'id-alias', test_field_names2.name FROM test_field_names1 t1, test_field_names2");
4456   myquery(rc);
4457 
4458   result= mysql_use_result(mysql);
4459   mytest(result);
4460 
4461   rc= my_process_result_set(result);
4462   DIE_UNLESS(rc == 0);
4463   mysql_free_result(result);
4464 }
4465 
4466 
4467 /* Test warnings */
4468 
test_warnings()4469 static void test_warnings()
4470 {
4471   int        rc;
4472   MYSQL_RES  *result;
4473 
4474   myheader("test_warnings");
4475 
4476   mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4477 
4478   rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4479   myquery(rc);
4480 
4481   if (!opt_silent)
4482     fprintf(stdout, "\n total warnings: %d", mysql_warning_count(mysql));
4483   rc= mysql_query(mysql, "SHOW WARNINGS");
4484   myquery(rc);
4485 
4486   result= mysql_store_result(mysql);
4487   mytest(result);
4488 
4489   rc= my_process_result_set(result);
4490   DIE_UNLESS(rc == 1);
4491   mysql_free_result(result);
4492 }
4493 
4494 
4495 /* Test errors */
4496 
test_errors()4497 static void test_errors()
4498 {
4499   int        rc;
4500   MYSQL_RES  *result;
4501 
4502   myheader("test_errors");
4503 
4504   mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4505 
4506   rc= mysql_query(mysql, "DROP TABLE test_non_exists");
4507   myquery_r(rc);
4508 
4509   rc= mysql_query(mysql, "SHOW ERRORS");
4510   myquery(rc);
4511 
4512   result= mysql_store_result(mysql);
4513   mytest(result);
4514 
4515   (void) my_process_result_set(result);
4516   mysql_free_result(result);
4517 }
4518 
4519 
4520 /* Test simple prepare-insert */
4521 
test_insert()4522 static void test_insert()
4523 {
4524   MYSQL_STMT *stmt;
4525   int        rc;
4526   char       str_data[50];
4527   char       tiny_data;
4528   MYSQL_RES  *result;
4529   MYSQL_BIND my_bind[2];
4530   ulong      length;
4531 
4532   myheader("test_insert");
4533 
4534   rc= mysql_autocommit(mysql, TRUE);
4535   myquery(rc);
4536 
4537   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_insert");
4538   myquery(rc);
4539 
4540   rc= mysql_query(mysql, "CREATE TABLE test_prep_insert(col1 tinyint, \
4541                                 col2 varchar(50))");
4542   myquery(rc);
4543 
4544   /* insert by prepare */
4545   stmt= mysql_simple_prepare(mysql,
4546                              "INSERT INTO test_prep_insert VALUES(?, ?)");
4547   check_stmt(stmt);
4548 
4549   verify_param_count(stmt, 2);
4550 
4551   /*
4552     We need to bzero bind structure because mysql_stmt_bind_param checks all
4553     its members.
4554   */
4555   bzero((char*) my_bind, sizeof(my_bind));
4556 
4557   /* tinyint */
4558   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4559   my_bind[0].buffer= (void *)&tiny_data;
4560 
4561   /* string */
4562   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
4563   my_bind[1].buffer= str_data;
4564   my_bind[1].buffer_length= sizeof(str_data);;
4565   my_bind[1].length= &length;
4566 
4567   rc= mysql_stmt_bind_param(stmt, my_bind);
4568   check_execute(stmt, rc);
4569 
4570   /* now, execute the prepared statement to insert 10 records.. */
4571   for (tiny_data= 0; tiny_data < 3; tiny_data++)
4572   {
4573     length= sprintf(str_data, "MySQL%d", tiny_data);
4574     rc= mysql_stmt_execute(stmt);
4575     check_execute(stmt, rc);
4576   }
4577 
4578   mysql_stmt_close(stmt);
4579 
4580   /* now fetch the results ..*/
4581   rc= mysql_commit(mysql);
4582   myquery(rc);
4583 
4584   /* test the results now, only one row should exist */
4585   rc= mysql_query(mysql, "SELECT * FROM test_prep_insert");
4586   myquery(rc);
4587 
4588   /* get the result */
4589   result= mysql_store_result(mysql);
4590   mytest(result);
4591 
4592   rc= my_process_result_set(result);
4593   DIE_UNLESS((int) tiny_data == rc);
4594   mysql_free_result(result);
4595 
4596 }
4597 
4598 
4599 /* Test simple prepare-resultset info */
4600 
test_prepare_resultset()4601 static void test_prepare_resultset()
4602 {
4603   MYSQL_STMT *stmt;
4604   int        rc;
4605   MYSQL_RES  *result;
4606 
4607   myheader("test_prepare_resultset");
4608 
4609   rc= mysql_autocommit(mysql, TRUE);
4610   myquery(rc);
4611 
4612   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_resultset");
4613   myquery(rc);
4614 
4615   rc= mysql_query(mysql, "CREATE TABLE test_prepare_resultset(id int, \
4616                                 name varchar(50), extra double)");
4617   myquery(rc);
4618 
4619   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_prepare_resultset");
4620   check_stmt(stmt);
4621 
4622   verify_param_count(stmt, 0);
4623 
4624   result= mysql_stmt_result_metadata(stmt);
4625   mytest(result);
4626   my_print_result_metadata(result);
4627   mysql_free_result(result);
4628   mysql_stmt_close(stmt);
4629 }
4630 
4631 
4632 /* Test field flags (verify .NET provider) */
4633 
test_field_flags()4634 static void test_field_flags()
4635 {
4636   int          rc;
4637   MYSQL_RES    *result;
4638   MYSQL_FIELD  *field;
4639   unsigned int i;
4640 
4641 
4642   myheader("test_field_flags");
4643 
4644   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_flags");
4645   myquery(rc);
4646 
4647   rc= mysql_query(mysql, "CREATE TABLE test_field_flags(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, \
4648                                                         id1 int NOT NULL, \
4649                                                         id2 int UNIQUE, \
4650                                                         id3 int, \
4651                                                         id4 int NOT NULL, \
4652                                                         id5 int, \
4653                                                         KEY(id3, id4))");
4654   myquery(rc);
4655 
4656   /* with table name included with TRUE column name */
4657   rc= mysql_query(mysql, "SELECT * FROM test_field_flags");
4658   myquery(rc);
4659 
4660   result= mysql_use_result(mysql);
4661   mytest(result);
4662 
4663   mysql_field_seek(result, 0);
4664   if (!opt_silent)
4665     fputc('\n', stdout);
4666 
4667   for(i= 0; i< mysql_num_fields(result); i++)
4668   {
4669     field= mysql_fetch_field(result);
4670     if (!opt_silent)
4671     {
4672       fprintf(stdout, "\n field:%d", i);
4673       if (field->flags & NOT_NULL_FLAG)
4674         fprintf(stdout, "\n  NOT_NULL_FLAG");
4675       if (field->flags & PRI_KEY_FLAG)
4676         fprintf(stdout, "\n  PRI_KEY_FLAG");
4677       if (field->flags & UNIQUE_KEY_FLAG)
4678         fprintf(stdout, "\n  UNIQUE_KEY_FLAG");
4679       if (field->flags & MULTIPLE_KEY_FLAG)
4680         fprintf(stdout, "\n  MULTIPLE_KEY_FLAG");
4681       if (field->flags & AUTO_INCREMENT_FLAG)
4682         fprintf(stdout, "\n  AUTO_INCREMENT_FLAG");
4683 
4684     }
4685   }
4686   mysql_free_result(result);
4687 }
4688 
4689 
4690 /* Test mysql_stmt_close for open stmts */
4691 
test_stmt_close()4692 static void test_stmt_close()
4693 {
4694   MYSQL *lmysql;
4695   MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x;
4696   MYSQL_BIND  my_bind[1];
4697   MYSQL_RES   *result;
4698   unsigned int  count;
4699   int   rc;
4700   char query[MAX_TEST_QUERY_LENGTH];
4701 
4702   myheader("test_stmt_close");
4703 
4704   if (!opt_silent)
4705     fprintf(stdout, "\n Establishing a test connection ...");
4706   if (!(lmysql= mysql_client_init(NULL)))
4707   {
4708     myerror("mysql_client_init() failed");
4709     exit(1);
4710   }
4711   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
4712                            opt_password, current_db, opt_port,
4713                            opt_unix_socket, 0)))
4714   {
4715     myerror("connection failed");
4716     exit(1);
4717   }
4718   lmysql->reconnect= 1;
4719   if (!opt_silent)
4720     fprintf(stdout, "OK");
4721 
4722 
4723   /* set AUTOCOMMIT to ON*/
4724   mysql_autocommit(lmysql, TRUE);
4725 
4726   rc= mysql_query(lmysql, "SET SQL_MODE = ''");
4727   myquery(rc);
4728 
4729   rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close");
4730   myquery(rc);
4731 
4732   rc= mysql_query(lmysql, "CREATE TABLE test_stmt_close(id int)");
4733   myquery(rc);
4734 
4735   strmov(query, "DO \"nothing\"");
4736   stmt1= mysql_simple_prepare(lmysql, query);
4737   check_stmt(stmt1);
4738 
4739   verify_param_count(stmt1, 0);
4740 
4741   strmov(query, "INSERT INTO test_stmt_close(id) VALUES(?)");
4742   stmt_x= mysql_simple_prepare(mysql, query);
4743   check_stmt(stmt_x);
4744 
4745   verify_param_count(stmt_x, 1);
4746 
4747   strmov(query, "UPDATE test_stmt_close SET id= ? WHERE id= ?");
4748   stmt3= mysql_simple_prepare(lmysql, query);
4749   check_stmt(stmt3);
4750 
4751   verify_param_count(stmt3, 2);
4752 
4753   strmov(query, "SELECT * FROM test_stmt_close WHERE id= ?");
4754   stmt2= mysql_simple_prepare(lmysql, query);
4755   check_stmt(stmt2);
4756 
4757   verify_param_count(stmt2, 1);
4758 
4759   rc= mysql_stmt_close(stmt1);
4760   if (!opt_silent)
4761     fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
4762   DIE_UNLESS(rc == 0);
4763 
4764   /*
4765     Originally we were going to close all statements automatically in
4766     mysql_close(). This proved to not work well - users weren't able to
4767     close statements by hand once mysql_close() had been called.
4768     Now mysql_close() doesn't free any statements, so this test doesn't
4769     serve its original designation any more.
4770     Here we free stmt2 and stmt3 by hand to avoid memory leaks.
4771   */
4772   mysql_stmt_close(stmt2);
4773   mysql_stmt_close(stmt3);
4774   mysql_close(lmysql);
4775 
4776   /*
4777     We need to bzero bind structure because mysql_stmt_bind_param checks all
4778     its members.
4779   */
4780   bzero((char*) my_bind, sizeof(my_bind));
4781 
4782   my_bind[0].buffer= (void *)&count;
4783   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
4784   count= 100;
4785 
4786   rc= mysql_stmt_bind_param(stmt_x, my_bind);
4787   check_execute(stmt_x, rc);
4788 
4789   rc= mysql_stmt_execute(stmt_x);
4790   check_execute(stmt_x, rc);
4791 
4792   verify_st_affected_rows(stmt_x, 1);
4793 
4794   rc= mysql_stmt_close(stmt_x);
4795   if (!opt_silent)
4796     fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
4797   DIE_UNLESS( rc == 0);
4798 
4799   rc= mysql_query(mysql, "SELECT id FROM test_stmt_close");
4800   myquery(rc);
4801 
4802   result= mysql_store_result(mysql);
4803   mytest(result);
4804 
4805   rc= my_process_result_set(result);
4806   DIE_UNLESS(rc == 1);
4807   mysql_free_result(result);
4808 }
4809 
4810 
4811 /* Test simple set variable prepare */
4812 
test_set_variable()4813 static void test_set_variable()
4814 {
4815   MYSQL_STMT *stmt, *stmt1;
4816   int        rc;
4817   int        set_count, def_count, get_count;
4818   ulong      length;
4819   char       var[NAME_LEN+1];
4820   MYSQL_BIND set_bind[1], get_bind[2];
4821 
4822   myheader("test_set_variable");
4823 
4824   mysql_autocommit(mysql, TRUE);
4825 
4826   stmt1= mysql_simple_prepare(mysql, "show variables like 'max_error_count'");
4827   check_stmt(stmt1);
4828 
4829   /*
4830     We need to bzero bind structure because mysql_stmt_bind_param checks all
4831     its members.
4832   */
4833   bzero((char*) get_bind, sizeof(get_bind));
4834 
4835   get_bind[0].buffer_type= MYSQL_TYPE_STRING;
4836   get_bind[0].buffer= (void *)var;
4837   get_bind[0].length= &length;
4838   get_bind[0].buffer_length= (int)NAME_LEN;
4839   length= NAME_LEN;
4840 
4841   get_bind[1].buffer_type= MYSQL_TYPE_LONG;
4842   get_bind[1].buffer= (void *)&get_count;
4843 
4844   rc= mysql_stmt_execute(stmt1);
4845   check_execute(stmt1, rc);
4846 
4847   rc= mysql_stmt_bind_result(stmt1, get_bind);
4848   check_execute(stmt1, rc);
4849 
4850   rc= mysql_stmt_fetch(stmt1);
4851   check_execute(stmt1, rc);
4852 
4853   if (!opt_silent)
4854     fprintf(stdout, "\n max_error_count(default): %d", get_count);
4855   def_count= get_count;
4856 
4857   DIE_UNLESS(strcmp(var, "max_error_count") == 0);
4858   rc= mysql_stmt_fetch(stmt1);
4859   DIE_UNLESS(rc == MYSQL_NO_DATA);
4860 
4861   stmt= mysql_simple_prepare(mysql, "set max_error_count= ?");
4862   check_stmt(stmt);
4863 
4864   bzero((char*) set_bind, sizeof(set_bind));
4865 
4866   set_bind[0].buffer_type= MYSQL_TYPE_LONG;
4867   set_bind[0].buffer= (void *)&set_count;
4868 
4869   rc= mysql_stmt_bind_param(stmt, set_bind);
4870   check_execute(stmt, rc);
4871 
4872   set_count= 31;
4873   rc= mysql_stmt_execute(stmt);
4874   check_execute(stmt, rc);
4875 
4876   mysql_commit(mysql);
4877 
4878   rc= mysql_stmt_execute(stmt1);
4879   check_execute(stmt1, rc);
4880 
4881   rc= mysql_stmt_fetch(stmt1);
4882   check_execute(stmt1, rc);
4883 
4884   if (!opt_silent)
4885     fprintf(stdout, "\n max_error_count         : %d", get_count);
4886   DIE_UNLESS(get_count == set_count);
4887 
4888   rc= mysql_stmt_fetch(stmt1);
4889   DIE_UNLESS(rc == MYSQL_NO_DATA);
4890 
4891   /* restore back to default */
4892   set_count= def_count;
4893   rc= mysql_stmt_execute(stmt);
4894   check_execute(stmt, rc);
4895 
4896   rc= mysql_stmt_execute(stmt1);
4897   check_execute(stmt1, rc);
4898 
4899   rc= mysql_stmt_fetch(stmt1);
4900   check_execute(stmt1, rc);
4901 
4902   if (!opt_silent)
4903     fprintf(stdout, "\n max_error_count(default): %d", get_count);
4904   DIE_UNLESS(get_count == set_count);
4905 
4906   rc= mysql_stmt_fetch(stmt1);
4907   DIE_UNLESS(rc == MYSQL_NO_DATA);
4908 
4909   mysql_stmt_close(stmt);
4910   mysql_stmt_close(stmt1);
4911 }
4912 
4913 /* Test FUNCTION field info / DATE_FORMAT() table_name . */
4914 
test_func_fields()4915 static void test_func_fields()
4916 {
4917   int        rc;
4918   MYSQL_RES  *result;
4919   MYSQL_FIELD *field;
4920 
4921   myheader("test_func_fields");
4922 
4923   rc= mysql_autocommit(mysql, TRUE);
4924   myquery(rc);
4925 
4926   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_dateformat");
4927   myquery(rc);
4928 
4929   rc= mysql_query(mysql, "CREATE TABLE test_dateformat(id int, \
4930                                                        ts timestamp)");
4931   myquery(rc);
4932 
4933   rc= mysql_query(mysql, "INSERT INTO test_dateformat(id) values(10)");
4934   myquery(rc);
4935 
4936   rc= mysql_query(mysql, "SELECT ts FROM test_dateformat");
4937   myquery(rc);
4938 
4939   result= mysql_store_result(mysql);
4940   mytest(result);
4941 
4942   field= mysql_fetch_field(result);
4943   mytest(field);
4944   if (!opt_silent)
4945     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table,
4946             "test_dateformat");
4947   DIE_UNLESS(strcmp(field->table, "test_dateformat") == 0);
4948 
4949   field= mysql_fetch_field(result);
4950   mytest_r(field); /* no more fields */
4951 
4952   mysql_free_result(result);
4953 
4954   /* DATE_FORMAT */
4955   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'venu' FROM test_dateformat");
4956   myquery(rc);
4957 
4958   result= mysql_store_result(mysql);
4959   mytest(result);
4960 
4961   field= mysql_fetch_field(result);
4962   mytest(field);
4963   if (!opt_silent)
4964     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table, "");
4965   DIE_UNLESS(field->table[0] == '\0');
4966 
4967   field= mysql_fetch_field(result);
4968   mytest_r(field); /* no more fields */
4969 
4970   mysql_free_result(result);
4971 
4972   /* FIELD ALIAS TEST */
4973   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y')  AS 'YEAR' FROM test_dateformat");
4974   myquery(rc);
4975 
4976   result= mysql_store_result(mysql);
4977   mytest(result);
4978 
4979   field= mysql_fetch_field(result);
4980   mytest(field);
4981   if (!opt_silent)
4982   {
4983     printf("\n field name: `%s` (expected: `%s`)", field->name, "YEAR");
4984     printf("\n field org name: `%s` (expected: `%s`)", field->org_name, "");
4985   }
4986   DIE_UNLESS(strcmp(field->name, "YEAR") == 0);
4987   DIE_UNLESS(field->org_name[0] == '\0');
4988 
4989   field= mysql_fetch_field(result);
4990   mytest_r(field); /* no more fields */
4991 
4992   mysql_free_result(result);
4993 }
4994 
4995 
4996 /* Multiple stmts .. */
4997 
test_multi_stmt()4998 static void test_multi_stmt()
4999 {
5000 
5001   MYSQL_STMT  *stmt, *stmt1, *stmt2;
5002   int         rc;
5003   uint32      id;
5004   char        name[50];
5005   MYSQL_BIND  my_bind[2];
5006   ulong       length[2];
5007   my_bool     is_null[2];
5008   myheader("test_multi_stmt");
5009 
5010   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_multi_table");
5011   myquery(rc);
5012 
5013   rc= mysql_query(mysql, "CREATE TABLE test_multi_table(id int, name char(20))");
5014   myquery(rc);
5015 
5016   rc= mysql_query(mysql, "INSERT INTO test_multi_table values(10, 'mysql')");
5017   myquery(rc);
5018 
5019   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_multi_table "
5020                                     "WHERE id= ?");
5021   check_stmt(stmt);
5022 
5023   stmt2= mysql_simple_prepare(mysql, "UPDATE test_multi_table "
5024                                      "SET name='updated' WHERE id=10");
5025   check_stmt(stmt2);
5026 
5027   verify_param_count(stmt, 1);
5028 
5029   /*
5030     We need to bzero bind structure because mysql_stmt_bind_param checks all
5031     its members.
5032   */
5033   bzero((char*) my_bind, sizeof(my_bind));
5034 
5035   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5036   my_bind[0].buffer= (void *)&id;
5037   my_bind[0].is_null= &is_null[0];
5038   my_bind[0].length= &length[0];
5039   is_null[0]= 0;
5040   length[0]= 0;
5041 
5042   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5043   my_bind[1].buffer= (void *)name;
5044   my_bind[1].buffer_length= sizeof(name);
5045   my_bind[1].length= &length[1];
5046   my_bind[1].is_null= &is_null[1];
5047 
5048   rc= mysql_stmt_bind_param(stmt, my_bind);
5049   check_execute(stmt, rc);
5050 
5051   rc= mysql_stmt_bind_result(stmt, my_bind);
5052   check_execute(stmt, rc);
5053 
5054   id= 10;
5055   rc= mysql_stmt_execute(stmt);
5056   check_execute(stmt, rc);
5057 
5058   id= 999;
5059   rc= mysql_stmt_fetch(stmt);
5060   check_execute(stmt, rc);
5061 
5062   if (!opt_silent)
5063   {
5064     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5065     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5066   }
5067   DIE_UNLESS(id == 10);
5068   DIE_UNLESS(strcmp(name, "mysql") == 0);
5069 
5070   rc= mysql_stmt_fetch(stmt);
5071   DIE_UNLESS(rc == MYSQL_NO_DATA);
5072 
5073   /* alter the table schema now */
5074   stmt1= mysql_simple_prepare(mysql, "DELETE FROM test_multi_table "
5075                                      "WHERE id= ? AND "
5076                                      "CONVERT(name USING utf8)=?");
5077   check_stmt(stmt1);
5078 
5079   verify_param_count(stmt1, 2);
5080 
5081   rc= mysql_stmt_bind_param(stmt1, my_bind);
5082   check_execute(stmt1, rc);
5083 
5084   rc= mysql_stmt_execute(stmt2);
5085   check_execute(stmt2, rc);
5086 
5087   verify_st_affected_rows(stmt2, 1);
5088 
5089   rc= mysql_stmt_execute(stmt);
5090   check_execute(stmt, rc);
5091 
5092   rc= mysql_stmt_fetch(stmt);
5093   check_execute(stmt, rc);
5094 
5095   if (!opt_silent)
5096   {
5097     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5098     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5099   }
5100   DIE_UNLESS(id == 10);
5101   DIE_UNLESS(strcmp(name, "updated") == 0);
5102 
5103   rc= mysql_stmt_fetch(stmt);
5104   DIE_UNLESS(rc == MYSQL_NO_DATA);
5105 
5106   rc= mysql_stmt_execute(stmt1);
5107   check_execute(stmt1, rc);
5108 
5109   verify_st_affected_rows(stmt1, 1);
5110 
5111   mysql_stmt_close(stmt1);
5112 
5113   rc= mysql_stmt_execute(stmt);
5114   check_execute(stmt, rc);
5115 
5116   rc= mysql_stmt_fetch(stmt);
5117   DIE_UNLESS(rc == MYSQL_NO_DATA);
5118 
5119   rc= my_stmt_result("SELECT * FROM test_multi_table");
5120   DIE_UNLESS(rc == 0);
5121 
5122   mysql_stmt_close(stmt);
5123   mysql_stmt_close(stmt2);
5124 
5125 }
5126 
5127 
5128 /* Test simple sample - manual */
5129 
test_manual_sample()5130 static void test_manual_sample()
5131 {
5132   unsigned int param_count;
5133   MYSQL_STMT   *stmt;
5134   short        small_data;
5135   int          int_data;
5136   int          rc;
5137   char         str_data[50];
5138   ulonglong    affected_rows;
5139   MYSQL_BIND   my_bind[3];
5140   my_bool      is_null;
5141   char query[MAX_TEST_QUERY_LENGTH];
5142 
5143   myheader("test_manual_sample");
5144 
5145   /*
5146     Sample which is incorporated directly in the manual under Prepared
5147     statements section (Example from mysql_stmt_execute()
5148   */
5149 
5150   mysql_autocommit(mysql, 1);
5151   if (mysql_query(mysql, "DROP TABLE IF EXISTS test_table"))
5152   {
5153     fprintf(stderr, "\n drop table failed");
5154     fprintf(stderr, "\n %s", mysql_error(mysql));
5155     exit(1);
5156   }
5157   if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \
5158                                                  col3 smallint, \
5159                                                  col4 timestamp)"))
5160   {
5161     fprintf(stderr, "\n create table failed");
5162     fprintf(stderr, "\n %s", mysql_error(mysql));
5163     exit(1);
5164   }
5165 
5166   /* Prepare a insert query with 3 parameters */
5167   strmov(query, "INSERT INTO test_table(col1, col2, col3) values(?, ?, ?)");
5168   if (!(stmt= mysql_simple_prepare(mysql, query)))
5169   {
5170     fprintf(stderr, "\n prepare, insert failed");
5171     fprintf(stderr, "\n %s", mysql_error(mysql));
5172     exit(1);
5173   }
5174   if (!opt_silent)
5175     fprintf(stdout, "\n prepare, insert successful");
5176 
5177   /* Get the parameter count from the statement */
5178   param_count= mysql_stmt_param_count(stmt);
5179 
5180   if (!opt_silent)
5181     fprintf(stdout, "\n total parameters in insert: %d", param_count);
5182   if (param_count != 3) /* validate parameter count */
5183   {
5184     fprintf(stderr, "\n invalid parameter count returned by MySQL");
5185     exit(1);
5186   }
5187 
5188   /* Bind the data for the parameters */
5189 
5190   /*
5191     We need to bzero bind structure because mysql_stmt_bind_param checks all
5192     its members.
5193   */
5194   bzero((char*) my_bind, sizeof(my_bind));
5195 
5196   /* INTEGER PART */
5197   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5198   my_bind[0].buffer= (void *)&int_data;
5199 
5200   /* STRING PART */
5201   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
5202   my_bind[1].buffer= (void *)str_data;
5203   my_bind[1].buffer_length= sizeof(str_data);
5204 
5205   /* SMALLINT PART */
5206   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
5207   my_bind[2].buffer= (void *)&small_data;
5208   my_bind[2].is_null= &is_null;
5209   is_null= 0;
5210 
5211   /* Bind the buffers */
5212   if (mysql_stmt_bind_param(stmt, my_bind))
5213   {
5214     fprintf(stderr, "\n param bind failed");
5215     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5216     exit(1);
5217   }
5218 
5219   /* Specify the data */
5220   int_data= 10;             /* integer */
5221   strmov(str_data, "MySQL"); /* string  */
5222 
5223   /* INSERT SMALLINT data as NULL */
5224   is_null= 1;
5225 
5226   /* Execute the insert statement - 1*/
5227   if (mysql_stmt_execute(stmt))
5228   {
5229     fprintf(stderr, "\n execute 1 failed");
5230     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5231     exit(1);
5232   }
5233 
5234   /* Get the total rows affected */
5235   affected_rows= mysql_stmt_affected_rows(stmt);
5236 
5237   if (!opt_silent)
5238     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5239   if (affected_rows != 1) /* validate affected rows */
5240   {
5241     fprintf(stderr, "\n invalid affected rows by MySQL");
5242     exit(1);
5243   }
5244 
5245   /* Re-execute the insert, by changing the values */
5246   int_data= 1000;
5247   strmov(str_data, "The most popular open source database");
5248   small_data= 1000;         /* smallint */
5249   is_null= 0;               /* reset */
5250 
5251   /* Execute the insert statement - 2*/
5252   if (mysql_stmt_execute(stmt))
5253   {
5254     fprintf(stderr, "\n execute 2 failed");
5255     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5256     exit(1);
5257   }
5258 
5259   /* Get the total rows affected */
5260   affected_rows= mysql_stmt_affected_rows(stmt);
5261 
5262   if (!opt_silent)
5263     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5264   if (affected_rows != 1) /* validate affected rows */
5265   {
5266     fprintf(stderr, "\n invalid affected rows by MySQL");
5267     exit(1);
5268   }
5269 
5270   /* Close the statement */
5271   if (mysql_stmt_close(stmt))
5272   {
5273     fprintf(stderr, "\n failed while closing the statement");
5274     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5275     exit(1);
5276   }
5277   rc= my_stmt_result("SELECT * FROM test_table");
5278   DIE_UNLESS(rc == 2);
5279 
5280   /* DROP THE TABLE */
5281   if (mysql_query(mysql, "DROP TABLE test_table"))
5282   {
5283     fprintf(stderr, "\n drop table failed");
5284     fprintf(stderr, "\n %s", mysql_error(mysql));
5285     exit(1);
5286   }
5287   if (!opt_silent)
5288     fprintf(stdout, "Success !!!");
5289 }
5290 
5291 
5292 /* Test alter table scenario in the middle of prepare */
5293 
test_prepare_alter()5294 static void test_prepare_alter()
5295 {
5296   MYSQL_STMT  *stmt;
5297   int         rc, id;
5298   MYSQL_BIND  my_bind[1];
5299   my_bool     is_null;
5300 
5301   myheader("test_prepare_alter");
5302 
5303   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_alter");
5304   myquery(rc);
5305 
5306   rc= mysql_query(mysql, "CREATE TABLE test_prep_alter(id int, name char(20))");
5307   myquery(rc);
5308 
5309   rc= mysql_query(mysql, "INSERT INTO test_prep_alter values(10, 'venu'), (20, 'mysql')");
5310   myquery(rc);
5311 
5312   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?, 'monty')");
5313   check_stmt(stmt);
5314 
5315   verify_param_count(stmt, 1);
5316 
5317   /*
5318     We need to bzero bind structure because mysql_stmt_bind_param checks all
5319     its members.
5320   */
5321   bzero((char*) my_bind, sizeof(my_bind));
5322 
5323   is_null= 0;
5324   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
5325   my_bind[0].buffer= (void *)&id;
5326   my_bind[0].is_null= &is_null;
5327 
5328   rc= mysql_stmt_bind_param(stmt, my_bind);
5329   check_execute(stmt, rc);
5330 
5331   id= 30;
5332   rc= mysql_stmt_execute(stmt);
5333   check_execute(stmt, rc);
5334 
5335   if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)"))
5336     exit(1);
5337 
5338   is_null= 1;
5339   rc= mysql_stmt_execute(stmt);
5340   check_execute(stmt, rc);
5341 
5342   rc= my_stmt_result("SELECT * FROM test_prep_alter");
5343   DIE_UNLESS(rc == 4);
5344 
5345   mysql_stmt_close(stmt);
5346 }
5347 
5348 
5349 /* Test the support of multi-statement executions */
5350 
test_multi_statements()5351 static void test_multi_statements()
5352 {
5353   MYSQL *mysql_local;
5354   MYSQL_RES *result;
5355   int    rc;
5356 
5357   const char *query= "\
5358 DROP TABLE IF EXISTS test_multi_tab;\
5359 CREATE TABLE test_multi_tab(id int, name char(20));\
5360 INSERT INTO test_multi_tab(id) VALUES(10), (20);\
5361 INSERT INTO test_multi_tab VALUES(20, 'insert;comma');\
5362 SELECT * FROM test_multi_tab;\
5363 UPDATE test_multi_tab SET name='new;name' WHERE id=20;\
5364 DELETE FROM test_multi_tab WHERE name='new;name';\
5365 SELECT * FROM test_multi_tab;\
5366 DELETE FROM test_multi_tab WHERE id=10;\
5367 SELECT * FROM test_multi_tab;\
5368 DROP TABLE test_multi_tab;\
5369 select 1;\
5370 DROP TABLE IF EXISTS test_multi_tab";
5371   uint count, exp_value;
5372   uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0};
5373 
5374   myheader("test_multi_statements");
5375 
5376   /*
5377     First test that we get an error for multi statements
5378     (Because default connection is not opened with CLIENT_MULTI_STATEMENTS)
5379   */
5380   rc= mysql_query(mysql, query); /* syntax error */
5381   myquery_r(rc);
5382 
5383   rc= mysql_next_result(mysql);
5384   DIE_UNLESS(rc == -1);
5385   rc= mysql_more_results(mysql);
5386   DIE_UNLESS(rc == 0);
5387 
5388   if (!(mysql_local= mysql_client_init(NULL)))
5389   {
5390     fprintf(stdout, "\n mysql_client_init() failed");
5391     exit(1);
5392   }
5393 
5394   /* Create connection that supports multi statements */
5395   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5396                            opt_password, current_db, opt_port,
5397                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5398   {
5399     fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local));
5400     exit(1);
5401   }
5402   mysql_local->reconnect= 1;
5403 
5404   rc= mysql_query(mysql_local, query);
5405   myquery(rc);
5406 
5407   for (count= 0 ; count < array_elements(rows) ; count++)
5408   {
5409     if (!opt_silent)
5410       fprintf(stdout, "\n Query %d: ", count);
5411     if ((result= mysql_store_result(mysql_local)))
5412     {
5413       (void) my_process_result_set(result);
5414       mysql_free_result(result);
5415     }
5416     else if (!opt_silent)
5417       fprintf(stdout, "OK, %ld row(s) affected, %ld warning(s)\n",
5418               (ulong) mysql_affected_rows(mysql_local),
5419               (ulong) mysql_warning_count(mysql_local));
5420 
5421     exp_value= (uint) mysql_affected_rows(mysql_local);
5422     if (rows[count] !=  exp_value)
5423     {
5424       fprintf(stderr, "row %d  had affected rows: %d, should be %d\n",
5425               count, exp_value, rows[count]);
5426       exit(1);
5427     }
5428     if (count != array_elements(rows) -1)
5429     {
5430       if (!(rc= mysql_more_results(mysql_local)))
5431       {
5432         fprintf(stdout,
5433                 "mysql_more_result returned wrong value: %d for row %d\n",
5434                 rc, count);
5435         exit(1);
5436       }
5437       if ((rc= mysql_next_result(mysql_local)))
5438       {
5439         exp_value= mysql_errno(mysql_local);
5440 
5441         exit(1);
5442       }
5443     }
5444     else
5445     {
5446       rc= mysql_more_results(mysql_local);
5447       DIE_UNLESS(rc == 0);
5448       rc= mysql_next_result(mysql_local);
5449       DIE_UNLESS(rc == -1);
5450     }
5451   }
5452 
5453   /* check that errors abort multi statements */
5454 
5455   rc= mysql_query(mysql_local, "select 1+1+a;select 1+1");
5456   myquery_r(rc);
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   rc= mysql_query(mysql_local, "select 1+1;select 1+1+a;select 1");
5463   myquery(rc);
5464   result= mysql_store_result(mysql_local);
5465   mytest(result);
5466   mysql_free_result(result);
5467   rc= mysql_more_results(mysql_local);
5468   DIE_UNLESS(rc == 1);
5469   rc= mysql_next_result(mysql_local);
5470   DIE_UNLESS(rc > 0);
5471 
5472   /*
5473     Ensure that we can now do a simple query (this checks that the server is
5474     not trying to send us the results for the last 'select 1'
5475   */
5476   rc= mysql_query(mysql_local, "select 1+1+1");
5477   myquery(rc);
5478   result= mysql_store_result(mysql_local);
5479   mytest(result);
5480   (void) my_process_result_set(result);
5481   mysql_free_result(result);
5482 
5483   /*
5484     Check if errors in one of the queries handled properly.
5485   */
5486   rc= mysql_query(mysql_local, "select 1; select * from not_existing_table");
5487   myquery(rc);
5488   result= mysql_store_result(mysql_local);
5489   mysql_free_result(result);
5490 
5491   rc= mysql_next_result(mysql_local);
5492   DIE_UNLESS(rc > 0);
5493 
5494   rc= mysql_next_result(mysql_local);
5495   DIE_UNLESS(rc < 0);
5496 
5497   mysql_close(mysql_local);
5498 }
5499 
5500 
5501 /*
5502   Check that Prepared statement cannot contain several
5503   SQL statements
5504 */
5505 
test_prepare_multi_statements()5506 static void test_prepare_multi_statements()
5507 {
5508   MYSQL *mysql_local;
5509   MYSQL_STMT *stmt;
5510   char query[MAX_TEST_QUERY_LENGTH];
5511   myheader("test_prepare_multi_statements");
5512 
5513   if (!(mysql_local= mysql_client_init(NULL)))
5514   {
5515     fprintf(stderr, "\n mysql_client_init() failed");
5516     exit(1);
5517   }
5518 
5519   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5520                            opt_password, current_db, opt_port,
5521                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5522   {
5523     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
5524     exit(1);
5525   }
5526   mysql_local->reconnect= 1;
5527   strmov(query, "select 1; select 'another value'");
5528   stmt= mysql_simple_prepare(mysql_local, query);
5529   check_stmt_r(stmt);
5530   mysql_close(mysql_local);
5531 }
5532 
5533 
5534 /* Test simple bind store result */
5535 
test_store_result()5536 static void test_store_result()
5537 {
5538   MYSQL_STMT *stmt;
5539   int        rc;
5540   int32      nData;
5541   char       szData[100];
5542   MYSQL_BIND my_bind[2];
5543   ulong      length, length1;
5544   my_bool    is_null[2];
5545 
5546   myheader("test_store_result");
5547 
5548   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5549   myquery(rc);
5550 
5551   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5552   myquery(rc);
5553 
5554   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5555   myquery(rc);
5556 
5557   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5558   myquery(rc);
5559 
5560   rc= mysql_commit(mysql);
5561   myquery(rc);
5562 
5563   /* fetch */
5564   bzero((char*) my_bind, sizeof(my_bind));
5565   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5566   my_bind[0].buffer= (void *) &nData;       /* integer data */
5567   my_bind[0].length= &length;
5568   my_bind[0].is_null= &is_null[0];
5569 
5570   length= 0;
5571   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5572   my_bind[1].buffer= szData;                /* string data */
5573   my_bind[1].buffer_length= sizeof(szData);
5574   my_bind[1].length= &length1;
5575   my_bind[1].is_null= &is_null[1];
5576   length1= 0;
5577 
5578   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5579   check_stmt(stmt);
5580 
5581   rc= mysql_stmt_bind_result(stmt, my_bind);
5582   check_execute(stmt, rc);
5583 
5584   rc= mysql_stmt_execute(stmt);
5585   check_execute(stmt, rc);
5586 
5587   rc= mysql_stmt_store_result(stmt);
5588   check_execute(stmt, rc);
5589 
5590   rc= mysql_stmt_fetch(stmt);
5591   check_execute(stmt, rc);
5592 
5593   if (!opt_silent)
5594     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5595   DIE_UNLESS(nData == 10);
5596   DIE_UNLESS(strcmp(szData, "venu") == 0);
5597   DIE_UNLESS(length1 == 4);
5598 
5599   rc= mysql_stmt_fetch(stmt);
5600   check_execute(stmt, rc);
5601 
5602   if (!opt_silent)
5603     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5604   DIE_UNLESS(nData == 20);
5605   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5606   DIE_UNLESS(length1 == 5);
5607 
5608   length= 99;
5609   rc= mysql_stmt_fetch(stmt);
5610   check_execute(stmt, rc);
5611 
5612   if (!opt_silent && is_null[0])
5613     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5614   DIE_UNLESS(is_null[0]);
5615   DIE_UNLESS(strcmp(szData, "monty") == 0);
5616   DIE_UNLESS(length1 == 5);
5617 
5618   rc= mysql_stmt_fetch(stmt);
5619   DIE_UNLESS(rc == MYSQL_NO_DATA);
5620 
5621   rc= mysql_stmt_execute(stmt);
5622   check_execute(stmt, rc);
5623 
5624   rc= mysql_stmt_store_result(stmt);
5625   check_execute(stmt, rc);
5626 
5627   rc= mysql_stmt_fetch(stmt);
5628   check_execute(stmt, rc);
5629 
5630   if (!opt_silent)
5631     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5632   DIE_UNLESS(nData == 10);
5633   DIE_UNLESS(strcmp(szData, "venu") == 0);
5634   DIE_UNLESS(length1 == 4);
5635 
5636   rc= mysql_stmt_fetch(stmt);
5637   check_execute(stmt, rc);
5638 
5639   if (!opt_silent)
5640     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5641   DIE_UNLESS(nData == 20);
5642   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5643   DIE_UNLESS(length1 == 5);
5644 
5645   length= 99;
5646   rc= mysql_stmt_fetch(stmt);
5647   check_execute(stmt, rc);
5648 
5649   if (!opt_silent && is_null[0])
5650     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5651   DIE_UNLESS(is_null[0]);
5652   DIE_UNLESS(strcmp(szData, "monty") == 0);
5653   DIE_UNLESS(length1 == 5);
5654 
5655   rc= mysql_stmt_fetch(stmt);
5656   DIE_UNLESS(rc == MYSQL_NO_DATA);
5657 
5658   mysql_stmt_close(stmt);
5659 }
5660 
5661 
5662 /* Test simple bind store result */
5663 
test_store_result1()5664 static void test_store_result1()
5665 {
5666   MYSQL_STMT *stmt;
5667   int        rc;
5668 
5669   myheader("test_store_result1");
5670 
5671   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5672   myquery(rc);
5673 
5674   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5675   myquery(rc);
5676 
5677   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5678   myquery(rc);
5679 
5680   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5681   myquery(rc);
5682 
5683   rc= mysql_commit(mysql);
5684   myquery(rc);
5685 
5686   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5687   check_stmt(stmt);
5688 
5689   rc= mysql_stmt_execute(stmt);
5690   check_execute(stmt, rc);
5691 
5692   rc= mysql_stmt_store_result(stmt);
5693   check_execute(stmt, rc);
5694 
5695   rc= 0;
5696   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5697     rc++;
5698   if (!opt_silent)
5699     fprintf(stdout, "\n total rows: %d", rc);
5700   DIE_UNLESS(rc == 3);
5701 
5702   rc= mysql_stmt_execute(stmt);
5703   check_execute(stmt, rc);
5704 
5705   rc= mysql_stmt_store_result(stmt);
5706   check_execute(stmt, rc);
5707 
5708   rc= 0;
5709   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5710     rc++;
5711   if (!opt_silent)
5712     fprintf(stdout, "\n total rows: %d", rc);
5713   DIE_UNLESS(rc == 3);
5714 
5715   mysql_stmt_close(stmt);
5716 }
5717 
5718 
5719 /* Another test for bind and store result */
5720 
test_store_result2()5721 static void test_store_result2()
5722 {
5723   MYSQL_STMT *stmt;
5724   int        rc;
5725   int        nData;
5726   ulong      length;
5727   MYSQL_BIND my_bind[1];
5728   char query[MAX_TEST_QUERY_LENGTH];
5729 
5730   myheader("test_store_result2");
5731 
5732   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5733   myquery(rc);
5734 
5735   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5736   myquery(rc);
5737 
5738   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5739   myquery(rc);
5740 
5741   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5742   myquery(rc);
5743 
5744   rc= mysql_commit(mysql);
5745   myquery(rc);
5746 
5747   /*
5748     We need to bzero bind structure because mysql_stmt_bind_param checks all
5749     its members.
5750   */
5751   bzero((char*) my_bind, sizeof(my_bind));
5752 
5753   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5754   my_bind[0].buffer= (void *) &nData;      /* integer data */
5755   my_bind[0].length= &length;
5756   my_bind[0].is_null= 0;
5757 
5758   strmov((char *)query , "SELECT col1 FROM test_store_result where col1= ?");
5759   stmt= mysql_simple_prepare(mysql, query);
5760   check_stmt(stmt);
5761 
5762   rc= mysql_stmt_bind_param(stmt, my_bind);
5763   check_execute(stmt, rc);
5764 
5765   rc= mysql_stmt_bind_result(stmt, my_bind);
5766   check_execute(stmt, rc);
5767 
5768   nData= 10; length= 0;
5769   rc= mysql_stmt_execute(stmt);
5770   check_execute(stmt, rc);
5771 
5772   nData= 0;
5773   rc= mysql_stmt_store_result(stmt);
5774   check_execute(stmt, rc);
5775 
5776   rc= mysql_stmt_fetch(stmt);
5777   check_execute(stmt, rc);
5778 
5779   if (!opt_silent)
5780     fprintf(stdout, "\n row 1: %d", nData);
5781   DIE_UNLESS(nData == 10);
5782 
5783   rc= mysql_stmt_fetch(stmt);
5784   DIE_UNLESS(rc == MYSQL_NO_DATA);
5785 
5786   nData= 20;
5787   rc= mysql_stmt_execute(stmt);
5788   check_execute(stmt, rc);
5789 
5790   nData= 0;
5791   rc= mysql_stmt_store_result(stmt);
5792   check_execute(stmt, rc);
5793 
5794   rc= mysql_stmt_fetch(stmt);
5795   check_execute(stmt, rc);
5796 
5797   if (!opt_silent)
5798     fprintf(stdout, "\n row 1: %d", nData);
5799   DIE_UNLESS(nData == 20);
5800 
5801   rc= mysql_stmt_fetch(stmt);
5802   DIE_UNLESS(rc == MYSQL_NO_DATA);
5803   mysql_stmt_close(stmt);
5804 }
5805 
5806 
5807 /* Test simple subselect prepare */
5808 
test_subselect()5809 static void test_subselect()
5810 {
5811 
5812   MYSQL_STMT *stmt;
5813   int        rc, id;
5814   MYSQL_BIND my_bind[1];
5815   DBUG_ENTER("test_subselect");
5816 
5817   myheader("test_subselect");
5818 
5819   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub1");
5820   myquery(rc);
5821 
5822   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub2");
5823   myquery(rc);
5824 
5825   rc= mysql_query(mysql, "CREATE TABLE test_sub1(id int)");
5826   myquery(rc);
5827 
5828   rc= mysql_query(mysql, "CREATE TABLE test_sub2(id int, id1 int)");
5829   myquery(rc);
5830 
5831   rc= mysql_query(mysql, "INSERT INTO test_sub1 values(2)");
5832   myquery(rc);
5833 
5834   rc= mysql_query(mysql, "INSERT INTO test_sub2 VALUES(1, 7), (2, 7)");
5835   myquery(rc);
5836 
5837   rc= mysql_commit(mysql);
5838   myquery(rc);
5839 
5840   /* fetch */
5841   /*
5842     We need to bzero bind structure because mysql_stmt_bind_param checks all
5843     its members.
5844   */
5845   bzero((char*) my_bind, sizeof(my_bind));
5846 
5847   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5848   my_bind[0].buffer= (void *) &id;
5849   my_bind[0].length= 0;
5850   my_bind[0].is_null= 0;
5851 
5852   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id= ?");
5853   check_stmt(stmt);
5854 
5855   rc= mysql_stmt_bind_param(stmt, my_bind);
5856   check_execute(stmt, rc);
5857 
5858   id= 2;
5859   rc= mysql_stmt_execute(stmt);
5860   check_execute(stmt, rc);
5861 
5862   verify_st_affected_rows(stmt, 1);
5863 
5864   id= 9;
5865   rc= mysql_stmt_execute(stmt);
5866   check_execute(stmt, rc);
5867 
5868   verify_st_affected_rows(stmt, 0);
5869 
5870   mysql_stmt_close(stmt);
5871 
5872   rc= my_stmt_result("SELECT * FROM test_sub2");
5873   DIE_UNLESS(rc == 3);
5874 
5875   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
5876                      "from test_sub2 WHERE id1= 8)");
5877   DIE_UNLESS(rc == 1);
5878   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
5879                      "from test_sub2 WHERE id1= 7)");
5880   DIE_UNLESS(rc == 1);
5881 
5882   stmt= mysql_simple_prepare(mysql, ("SELECT ROW(1, 7) IN (select id, id1 "
5883                                      "from test_sub2 WHERE id1= ?)"));
5884   check_stmt(stmt);
5885 
5886   rc= mysql_stmt_bind_param(stmt, my_bind);
5887   check_execute(stmt, rc);
5888 
5889   rc= mysql_stmt_bind_result(stmt, my_bind);
5890   check_execute(stmt, rc);
5891 
5892   id= 7;
5893   rc= mysql_stmt_execute(stmt);
5894   check_execute(stmt, rc);
5895 
5896   rc= mysql_stmt_fetch(stmt);
5897   check_execute(stmt, rc);
5898 
5899   if (!opt_silent)
5900     fprintf(stdout, "\n row 1: %d", id);
5901   DIE_UNLESS(id == 1);
5902 
5903   rc= mysql_stmt_fetch(stmt);
5904   DIE_UNLESS(rc == MYSQL_NO_DATA);
5905 
5906   id= 8;
5907   rc= mysql_stmt_execute(stmt);
5908   check_execute(stmt, rc);
5909 
5910   rc= mysql_stmt_fetch(stmt);
5911   check_execute(stmt, rc);
5912 
5913   if (!opt_silent)
5914     fprintf(stdout, "\n row 1: %d", id);
5915   DIE_UNLESS(id == 0);
5916 
5917   rc= mysql_stmt_fetch(stmt);
5918   DIE_UNLESS(rc == MYSQL_NO_DATA);
5919 
5920   mysql_stmt_close(stmt);
5921   DBUG_VOID_RETURN;
5922 }
5923 
5924 
5925 /*
5926   Generalized conversion routine to handle DATE, TIME and DATETIME
5927   conversion using MYSQL_TIME structure
5928 */
5929 
test_bind_date_conv(uint row_count)5930 static void test_bind_date_conv(uint row_count)
5931 {
5932   MYSQL_STMT   *stmt= 0;
5933   uint         rc, i, count= row_count;
5934   ulong        length[4];
5935   MYSQL_BIND   my_bind[4];
5936   my_bool      is_null[4]= {0};
5937   MYSQL_TIME   tm[4];
5938   ulong        second_part;
5939   uint         year, month, day, hour, minute, sec;
5940 
5941   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_date VALUES(?, ?, ?, ?)");
5942   check_stmt(stmt);
5943 
5944   verify_param_count(stmt, 4);
5945 
5946   /*
5947     We need to bzero bind structure because mysql_stmt_bind_param checks all
5948     its members.
5949   */
5950   bzero((char*) my_bind, sizeof(my_bind));
5951 
5952   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
5953   my_bind[1].buffer_type= MYSQL_TYPE_TIME;
5954   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
5955   my_bind[3].buffer_type= MYSQL_TYPE_DATE;
5956 
5957   for (i= 0; i < (int) array_elements(my_bind); i++)
5958   {
5959     my_bind[i].buffer= (void *) &tm[i];
5960     my_bind[i].is_null= &is_null[i];
5961     my_bind[i].length= &length[i];
5962     my_bind[i].buffer_length= 30;
5963     length[i]= 20;
5964   }
5965 
5966   second_part= 0;
5967 
5968   year= 2000;
5969   month= 01;
5970   day= 10;
5971 
5972   hour= 11;
5973   minute= 16;
5974   sec= 20;
5975 
5976   rc= mysql_stmt_bind_param(stmt, my_bind);
5977   check_execute(stmt, rc);
5978 
5979   for (count= 0; count < row_count; count++)
5980   {
5981     for (i= 0; i < (int) array_elements(my_bind); i++)
5982     {
5983       tm[i].neg= 0;
5984       tm[i].second_part= second_part+count;
5985       if (my_bind[i].buffer_type != MYSQL_TYPE_TIME)
5986       {
5987         tm[i].year= year+count;
5988         tm[i].month= month+count;
5989         tm[i].day= day+count;
5990       }
5991       else
5992         tm[i].year= tm[i].month= tm[i].day= 0;
5993       if (my_bind[i].buffer_type != MYSQL_TYPE_DATE)
5994       {
5995         tm[i].hour= hour+count;
5996         tm[i].minute= minute+count;
5997         tm[i].second= sec+count;
5998       }
5999       else
6000         tm[i].hour= tm[i].minute= tm[i].second= 0;
6001     }
6002     rc= mysql_stmt_execute(stmt);
6003     check_execute(stmt, rc);
6004   }
6005 
6006   rc= mysql_commit(mysql);
6007   myquery(rc);
6008 
6009   mysql_stmt_close(stmt);
6010 
6011   rc= my_stmt_result("SELECT * FROM test_date");
6012   DIE_UNLESS(row_count == rc);
6013 
6014   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_date");
6015   check_stmt(stmt);
6016 
6017   rc= mysql_stmt_bind_result(stmt, my_bind);
6018   check_execute(stmt, rc);
6019 
6020   rc= mysql_stmt_execute(stmt);
6021   check_execute(stmt, rc);
6022 
6023   rc= mysql_stmt_store_result(stmt);
6024   check_execute(stmt, rc);
6025 
6026   for (count= 0; count < row_count; count++)
6027   {
6028     rc= mysql_stmt_fetch(stmt);
6029     DIE_UNLESS(rc == 0 || rc == MYSQL_DATA_TRUNCATED);
6030 
6031     if (!opt_silent)
6032       fprintf(stdout, "\n");
6033     for (i= 0; i < array_elements(my_bind); i++)
6034     {
6035       if (!opt_silent)
6036         fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d %02d:%02d:%02d.%02lu",
6037                 i, tm[i].year, tm[i].month, tm[i].day,
6038                 tm[i].hour, tm[i].minute, tm[i].second,
6039                 tm[i].second_part);
6040       DIE_UNLESS(tm[i].year == 0 || tm[i].year == year+count);
6041       DIE_UNLESS(tm[i].month == 0 || tm[i].month == month+count);
6042       DIE_UNLESS(tm[i].day == 0 || tm[i].day == day+count);
6043 
6044       DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count);
6045       DIE_UNLESS(tm[i].minute == 0 || tm[i].minute == minute+count);
6046       DIE_UNLESS(tm[i].second == 0 || tm[i].second == sec+count);
6047       DIE_UNLESS(tm[i].second_part == 0 ||
6048                  tm[i].second_part == second_part+count);
6049     }
6050   }
6051   rc= mysql_stmt_fetch(stmt);
6052   DIE_UNLESS(rc == MYSQL_NO_DATA);
6053 
6054   mysql_stmt_close(stmt);
6055 }
6056 
6057 
6058 /* Test DATE, TIME, DATETIME and TS with MYSQL_TIME conversion */
6059 
test_date()6060 static void test_date()
6061 {
6062   int        rc;
6063 
6064   myheader("test_date");
6065 
6066   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6067   myquery(rc);
6068 
6069   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6070                                                  c2 TIME, \
6071                                                  c3 DATETIME, \
6072                                                  c4 DATE)");
6073 
6074   myquery(rc);
6075 
6076   test_bind_date_conv(5);
6077 }
6078 
6079 
6080 /* Test all time types to DATE and DATE to all types */
6081 
test_date_date()6082 static void test_date_date()
6083 {
6084   int        rc;
6085 
6086   myheader("test_date_date");
6087 
6088   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6089   myquery(rc);
6090 
6091   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 DATE, \
6092                                                  c2 DATE, \
6093                                                  c3 DATE, \
6094                                                  c4 DATE)");
6095 
6096   myquery(rc);
6097 
6098   test_bind_date_conv(3);
6099 }
6100 
6101 
6102 /* Test all time types to TIME and TIME to all types */
6103 
test_date_time()6104 static void test_date_time()
6105 {
6106   int        rc;
6107 
6108   myheader("test_date_time");
6109 
6110   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6111   myquery(rc);
6112 
6113   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIME, \
6114                                                  c2 TIME, \
6115                                                  c3 TIME, \
6116                                                  c4 TIME)");
6117 
6118   myquery(rc);
6119 
6120   test_bind_date_conv(3);
6121 }
6122 
6123 
6124 /* Test all time types to TIMESTAMP and TIMESTAMP to all types */
6125 
test_date_ts()6126 static void test_date_ts()
6127 {
6128   int        rc;
6129 
6130   myheader("test_date_ts");
6131 
6132   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6133   myquery(rc);
6134 
6135   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6136                                                  c2 TIMESTAMP, \
6137                                                  c3 TIMESTAMP, \
6138                                                  c4 TIMESTAMP)");
6139 
6140   myquery(rc);
6141 
6142   test_bind_date_conv(2);
6143 }
6144 
6145 
6146 /* Test all time types to DATETIME and DATETIME to all types */
6147 
test_date_dt()6148 static void test_date_dt()
6149 {
6150   int rc;
6151 
6152   myheader("test_date_dt");
6153 
6154   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6155   myquery(rc);
6156 
6157   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 datetime, "
6158                          " c2 datetime, c3 datetime, c4 date)");
6159   myquery(rc);
6160 
6161   test_bind_date_conv(2);
6162 }
6163 
6164 
6165 /* Misc tests to keep pure coverage happy */
6166 
test_pure_coverage()6167 static void test_pure_coverage()
6168 {
6169   MYSQL_STMT *stmt;
6170   MYSQL_BIND my_bind[1];
6171   int        rc;
6172   ulong      length;
6173 
6174   myheader("test_pure_coverage");
6175 
6176   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_pure");
6177   myquery(rc);
6178 
6179   rc= mysql_query(mysql, "CREATE TABLE test_pure(c1 int, c2 varchar(20))");
6180   myquery(rc);
6181 
6182   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c67788) values(10)");
6183   check_stmt_r(stmt);
6184 
6185   /* Query without params and result should allow to bind 0 arrays */
6186   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(10)");
6187   check_stmt(stmt);
6188 
6189   rc= mysql_stmt_bind_param(stmt, (MYSQL_BIND*)0);
6190   check_execute(stmt, rc);
6191 
6192   rc= mysql_stmt_execute(stmt);
6193   check_execute(stmt, rc);
6194 
6195   rc= mysql_stmt_bind_result(stmt, (MYSQL_BIND*)0);
6196   DIE_UNLESS(rc == 1);
6197 
6198   mysql_stmt_close(stmt);
6199 
6200   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(?)");
6201   check_stmt(stmt);
6202 
6203   /*
6204     We need to bzero bind structure because mysql_stmt_bind_param checks all
6205     its members.
6206   */
6207   bzero((char*) my_bind, sizeof(my_bind));
6208 
6209   my_bind[0].length= &length;
6210   my_bind[0].is_null= 0;
6211   my_bind[0].buffer_length= 0;
6212 
6213   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6214   rc= mysql_stmt_bind_param(stmt, my_bind);
6215   check_execute_r(stmt, rc); /* unsupported buffer type */
6216 
6217   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6218   rc= mysql_stmt_bind_param(stmt, my_bind);
6219   check_execute(stmt, rc);
6220 
6221   rc= mysql_stmt_store_result(stmt);
6222   check_execute(stmt, rc);
6223 
6224   mysql_stmt_close(stmt);
6225 
6226   stmt= mysql_simple_prepare(mysql, "select * from test_pure");
6227   check_execute(stmt, rc);
6228 
6229   rc= mysql_stmt_execute(stmt);
6230   check_execute(stmt, rc);
6231 
6232   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6233   rc= mysql_stmt_bind_result(stmt, my_bind);
6234   check_execute_r(stmt, rc); /* unsupported buffer type */
6235 
6236   rc= mysql_stmt_store_result(stmt);
6237   DIE_UNLESS(rc);
6238 
6239   rc= mysql_stmt_store_result(stmt);
6240   DIE_UNLESS(rc); /* Old error must be reset first */
6241 
6242   mysql_stmt_close(stmt);
6243 
6244   mysql_query(mysql, "DROP TABLE test_pure");
6245 }
6246 
6247 
6248 /* Test for string buffer fetch */
6249 
test_buffers()6250 static void test_buffers()
6251 {
6252   MYSQL_STMT *stmt;
6253   MYSQL_BIND my_bind[1];
6254   int        rc;
6255   ulong      length;
6256   my_bool    is_null;
6257   char       buffer[20];
6258 
6259   myheader("test_buffers");
6260 
6261   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_buffer");
6262   myquery(rc);
6263 
6264   rc= mysql_query(mysql, "CREATE TABLE test_buffer(str varchar(20))");
6265   myquery(rc);
6266 
6267   rc= mysql_query(mysql, "insert into test_buffer values('MySQL')\
6268                           , ('Database'), ('Open-Source'), ('Popular')");
6269   myquery(rc);
6270 
6271   stmt= mysql_simple_prepare(mysql, "select str from test_buffer");
6272   check_stmt(stmt);
6273 
6274   rc= mysql_stmt_execute(stmt);
6275   check_execute(stmt, rc);
6276 
6277   bzero(buffer, sizeof(buffer));              /* Avoid overruns in printf() */
6278 
6279   bzero((char*) my_bind, sizeof(my_bind));
6280   my_bind[0].length= &length;
6281   my_bind[0].is_null= &is_null;
6282   my_bind[0].buffer_length= 1;
6283   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6284   my_bind[0].buffer= (void *)buffer;
6285   my_bind[0].error= &my_bind[0].error_value;
6286 
6287   rc= mysql_stmt_bind_result(stmt, my_bind);
6288   check_execute(stmt, rc);
6289 
6290   rc= mysql_stmt_store_result(stmt);
6291   check_execute(stmt, rc);
6292 
6293   buffer[1]= 'X';
6294   rc= mysql_stmt_fetch(stmt);
6295   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6296   DIE_UNLESS(my_bind[0].error_value);
6297   if (!opt_silent)
6298     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6299   DIE_UNLESS(buffer[0] == 'M');
6300   DIE_UNLESS(buffer[1] == 'X');
6301   DIE_UNLESS(length == 5);
6302 
6303   my_bind[0].buffer_length= 8;
6304   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6305   check_execute(stmt, rc);
6306 
6307   rc= mysql_stmt_fetch(stmt);
6308   check_execute(stmt, rc);
6309   if (!opt_silent)
6310     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6311   DIE_UNLESS(strncmp(buffer, "Database", 8) == 0);
6312   DIE_UNLESS(length == 8);
6313 
6314   my_bind[0].buffer_length= 12;
6315   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6316   check_execute(stmt, rc);
6317 
6318   rc= mysql_stmt_fetch(stmt);
6319   check_execute(stmt, rc);
6320   if (!opt_silent)
6321     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6322   DIE_UNLESS(strcmp(buffer, "Open-Source") == 0);
6323   DIE_UNLESS(length == 11);
6324 
6325   my_bind[0].buffer_length= 6;
6326   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6327   check_execute(stmt, rc);
6328 
6329   rc= mysql_stmt_fetch(stmt);
6330   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6331   DIE_UNLESS(my_bind[0].error_value);
6332   if (!opt_silent)
6333     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6334   DIE_UNLESS(strncmp(buffer, "Popula", 6) == 0);
6335   DIE_UNLESS(length == 7);
6336 
6337   mysql_stmt_close(stmt);
6338 }
6339 
6340 
6341 /* Test the direct query execution in the middle of open stmts */
6342 
test_open_direct()6343 static void test_open_direct()
6344 {
6345   MYSQL_STMT  *stmt;
6346   MYSQL_RES   *result;
6347   int         rc;
6348 
6349   myheader("test_open_direct");
6350 
6351   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_open_direct");
6352   myquery(rc);
6353 
6354   rc= mysql_query(mysql, "CREATE TABLE test_open_direct(id int, name char(6))");
6355   myquery(rc);
6356 
6357   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_open_direct values(10, 'mysql')");
6358   check_stmt(stmt);
6359 
6360   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6361   myquery(rc);
6362 
6363   result= mysql_store_result(mysql);
6364   mytest(result);
6365 
6366   rc= my_process_result_set(result);
6367   DIE_UNLESS(rc == 0);
6368   mysql_free_result(result);
6369 
6370   rc= mysql_stmt_execute(stmt);
6371   check_execute(stmt, rc);
6372 
6373   verify_st_affected_rows(stmt, 1);
6374 
6375   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6376   myquery(rc);
6377 
6378   result= mysql_store_result(mysql);
6379   mytest(result);
6380 
6381   rc= my_process_result_set(result);
6382   DIE_UNLESS(rc == 1);
6383   mysql_free_result(result);
6384 
6385   rc= mysql_stmt_execute(stmt);
6386   check_execute(stmt, rc);
6387 
6388   verify_st_affected_rows(stmt, 1);
6389 
6390   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6391   myquery(rc);
6392 
6393   result= mysql_store_result(mysql);
6394   mytest(result);
6395 
6396   rc= my_process_result_set(result);
6397   DIE_UNLESS(rc == 2);
6398   mysql_free_result(result);
6399 
6400   mysql_stmt_close(stmt);
6401 
6402   /* run a direct query in the middle of a fetch */
6403   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6404   check_stmt(stmt);
6405 
6406   rc= mysql_stmt_execute(stmt);
6407   check_execute(stmt, rc);
6408 
6409   rc= mysql_stmt_fetch(stmt);
6410   check_execute(stmt, rc);
6411 
6412   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6413   myquery_r(rc);
6414 
6415   rc= mysql_stmt_close(stmt);
6416   check_execute(stmt, rc);
6417 
6418   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6419   myquery(rc);
6420 
6421   /* run a direct query with store result */
6422   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6423   check_stmt(stmt);
6424 
6425   rc= mysql_stmt_execute(stmt);
6426   check_execute(stmt, rc);
6427 
6428   rc= mysql_stmt_store_result(stmt);
6429   check_execute(stmt, rc);
6430 
6431   rc= mysql_stmt_fetch(stmt);
6432   check_execute(stmt, rc);
6433 
6434   rc= mysql_query(mysql, "drop table test_open_direct");
6435   myquery(rc);
6436 
6437   rc= mysql_stmt_close(stmt);
6438   check_execute(stmt, rc);
6439 }
6440 
6441 
6442 /* Test fetch without prior bound buffers */
6443 
test_fetch_nobuffs()6444 static void test_fetch_nobuffs()
6445 {
6446   MYSQL_STMT *stmt;
6447   MYSQL_BIND my_bind[4];
6448   char       str[4][50];
6449   int        rc;
6450 
6451   myheader("test_fetch_nobuffs");
6452 
6453   stmt= mysql_simple_prepare(mysql, "SELECT DATABASE(), CURRENT_USER(), \
6454                               CURRENT_DATE(), CURRENT_TIME()");
6455   check_stmt(stmt);
6456 
6457   rc= mysql_stmt_execute(stmt);
6458   check_execute(stmt, rc);
6459 
6460   rc= 0;
6461   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6462     rc++;
6463 
6464   if (!opt_silent)
6465     fprintf(stdout, "\n total rows        : %d", rc);
6466   DIE_UNLESS(rc == 1);
6467 
6468   bzero((char*) my_bind, sizeof(MYSQL_BIND));
6469   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6470   my_bind[0].buffer= (void *)str[0];
6471   my_bind[0].buffer_length= sizeof(str[0]);
6472   my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0];
6473   my_bind[1].buffer= (void *)str[1];
6474   my_bind[2].buffer= (void *)str[2];
6475   my_bind[3].buffer= (void *)str[3];
6476 
6477   rc= mysql_stmt_bind_result(stmt, my_bind);
6478   check_execute(stmt, rc);
6479 
6480   rc= mysql_stmt_execute(stmt);
6481   check_execute(stmt, rc);
6482 
6483   rc= 0;
6484   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6485   {
6486     rc++;
6487     if (!opt_silent)
6488     {
6489       fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
6490       fprintf(stdout, "\n CURRENT_USER()    : %s", str[1]);
6491       fprintf(stdout, "\n CURRENT_DATE()    : %s", str[2]);
6492       fprintf(stdout, "\n CURRENT_TIME()    : %s", str[3]);
6493     }
6494   }
6495   if (!opt_silent)
6496     fprintf(stdout, "\n total rows        : %d", rc);
6497   DIE_UNLESS(rc == 1);
6498 
6499   mysql_stmt_close(stmt);
6500 }
6501 
6502 
6503 /* Test a misc bug */
6504 
test_ushort_bug()6505 static void test_ushort_bug()
6506 {
6507   MYSQL_STMT *stmt;
6508   MYSQL_BIND my_bind[4];
6509   ushort     short_value;
6510   uint32     long_value;
6511   ulong      s_length, l_length, ll_length, t_length;
6512   ulonglong  longlong_value;
6513   int        rc;
6514   uchar      tiny_value;
6515   char       llbuf[22];
6516   myheader("test_ushort_bug");
6517 
6518   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ushort");
6519   myquery(rc);
6520 
6521   rc= mysql_query(mysql, "CREATE TABLE test_ushort(a smallint unsigned, \
6522                                                   b smallint unsigned, \
6523                                                   c smallint unsigned, \
6524                                                   d smallint unsigned)");
6525   myquery(rc);
6526 
6527   rc= mysql_query(mysql,
6528                   "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)");
6529   myquery(rc);
6530 
6531 
6532   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ushort");
6533   check_stmt(stmt);
6534 
6535   rc= mysql_stmt_execute(stmt);
6536   check_execute(stmt, rc);
6537 
6538   bzero((char*) my_bind, sizeof(my_bind));
6539   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6540   my_bind[0].buffer= (void *)&short_value;
6541   my_bind[0].is_unsigned= TRUE;
6542   my_bind[0].length= &s_length;
6543 
6544   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6545   my_bind[1].buffer= (void *)&long_value;
6546   my_bind[1].length= &l_length;
6547 
6548   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6549   my_bind[2].buffer= (void *)&longlong_value;
6550   my_bind[2].length= &ll_length;
6551 
6552   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6553   my_bind[3].buffer= (void *)&tiny_value;
6554   my_bind[3].is_unsigned= TRUE;
6555   my_bind[3].length= &t_length;
6556 
6557   rc= mysql_stmt_bind_result(stmt, my_bind);
6558   check_execute(stmt, rc);
6559 
6560   rc= mysql_stmt_fetch(stmt);
6561   check_execute(stmt, rc);
6562 
6563   if (!opt_silent)
6564   {
6565     fprintf(stdout, "\n ushort   : %d (%ld)", short_value, s_length);
6566     fprintf(stdout, "\n ulong    : %lu (%ld)", (ulong) long_value, l_length);
6567     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6568             ll_length);
6569     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, t_length);
6570   }
6571 
6572   DIE_UNLESS(short_value == 35999);
6573   DIE_UNLESS(s_length == 2);
6574 
6575   DIE_UNLESS(long_value == 35999);
6576   DIE_UNLESS(l_length == 4);
6577 
6578   DIE_UNLESS(longlong_value == 35999);
6579   DIE_UNLESS(ll_length == 8);
6580 
6581   DIE_UNLESS(tiny_value == 200);
6582   DIE_UNLESS(t_length == 1);
6583 
6584   rc= mysql_stmt_fetch(stmt);
6585   DIE_UNLESS(rc == MYSQL_NO_DATA);
6586 
6587   mysql_stmt_close(stmt);
6588 }
6589 
6590 
6591 /* Test a misc smallint-signed conversion bug */
6592 
test_sshort_bug()6593 static void test_sshort_bug()
6594 {
6595   MYSQL_STMT *stmt;
6596   MYSQL_BIND my_bind[4];
6597   short      short_value;
6598   int32      long_value;
6599   ulong      s_length, l_length, ll_length, t_length;
6600   ulonglong  longlong_value;
6601   int        rc;
6602   uchar      tiny_value;
6603   char       llbuf[22];
6604 
6605   myheader("test_sshort_bug");
6606 
6607   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sshort");
6608   myquery(rc);
6609 
6610   rc= mysql_query(mysql, "CREATE TABLE test_sshort(a smallint signed, \
6611                                                   b smallint signed, \
6612                                                   c smallint unsigned, \
6613                                                   d smallint unsigned)");
6614   myquery(rc);
6615 
6616   rc= mysql_query(mysql, "INSERT INTO test_sshort VALUES(-5999, -5999, 35999, 200)");
6617   myquery(rc);
6618 
6619 
6620   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_sshort");
6621   check_stmt(stmt);
6622 
6623   rc= mysql_stmt_execute(stmt);
6624   check_execute(stmt, rc);
6625 
6626   bzero((char*) my_bind, sizeof(my_bind));
6627   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6628   my_bind[0].buffer= (void *)&short_value;
6629   my_bind[0].length= &s_length;
6630 
6631   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6632   my_bind[1].buffer= (void *)&long_value;
6633   my_bind[1].length= &l_length;
6634 
6635   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6636   my_bind[2].buffer= (void *)&longlong_value;
6637   my_bind[2].length= &ll_length;
6638 
6639   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6640   my_bind[3].buffer= (void *)&tiny_value;
6641   my_bind[3].is_unsigned= TRUE;
6642   my_bind[3].length= &t_length;
6643 
6644   rc= mysql_stmt_bind_result(stmt, my_bind);
6645   check_execute(stmt, rc);
6646 
6647   rc= mysql_stmt_fetch(stmt);
6648   check_execute(stmt, rc);
6649 
6650   if (!opt_silent)
6651   {
6652     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, s_length);
6653     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, l_length);
6654     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6655             ll_length);
6656     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, t_length);
6657   }
6658 
6659   DIE_UNLESS(short_value == -5999);
6660   DIE_UNLESS(s_length == 2);
6661 
6662   DIE_UNLESS(long_value == -5999);
6663   DIE_UNLESS(l_length == 4);
6664 
6665   DIE_UNLESS(longlong_value == 35999);
6666   DIE_UNLESS(ll_length == 8);
6667 
6668   DIE_UNLESS(tiny_value == 200);
6669   DIE_UNLESS(t_length == 1);
6670 
6671   rc= mysql_stmt_fetch(stmt);
6672   DIE_UNLESS(rc == MYSQL_NO_DATA);
6673 
6674   mysql_stmt_close(stmt);
6675 }
6676 
6677 
6678 /* Test a misc tinyint-signed conversion bug */
6679 
test_stiny_bug()6680 static void test_stiny_bug()
6681 {
6682   MYSQL_STMT *stmt;
6683   MYSQL_BIND my_bind[4];
6684   short      short_value;
6685   int32      long_value;
6686   ulong      s_length, l_length, ll_length, t_length;
6687   ulonglong  longlong_value;
6688   int        rc;
6689   uchar      tiny_value;
6690   char       llbuf[22];
6691 
6692   myheader("test_stiny_bug");
6693 
6694   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_stiny");
6695   myquery(rc);
6696 
6697   rc= mysql_query(mysql, "CREATE TABLE test_stiny(a tinyint signed, \
6698                                                   b tinyint signed, \
6699                                                   c tinyint unsigned, \
6700                                                   d tinyint unsigned)");
6701   myquery(rc);
6702 
6703   rc= mysql_query(mysql, "INSERT INTO test_stiny VALUES(-128, -127, 255, 0)");
6704   myquery(rc);
6705 
6706 
6707   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_stiny");
6708   check_stmt(stmt);
6709 
6710   rc= mysql_stmt_execute(stmt);
6711   check_execute(stmt, rc);
6712 
6713   bzero((char*) my_bind, sizeof(my_bind));
6714   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6715   my_bind[0].buffer= (void *)&short_value;
6716   my_bind[0].length= &s_length;
6717 
6718   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6719   my_bind[1].buffer= (void *)&long_value;
6720   my_bind[1].length= &l_length;
6721 
6722   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6723   my_bind[2].buffer= (void *)&longlong_value;
6724   my_bind[2].length= &ll_length;
6725 
6726   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6727   my_bind[3].buffer= (void *)&tiny_value;
6728   my_bind[3].length= &t_length;
6729 
6730   rc= mysql_stmt_bind_result(stmt, my_bind);
6731   check_execute(stmt, rc);
6732 
6733   rc= mysql_stmt_fetch(stmt);
6734   check_execute(stmt, rc);
6735 
6736   if (!opt_silent)
6737   {
6738     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, s_length);
6739     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, l_length);
6740     fprintf(stdout, "\n longlong : %s  (%ld)", llstr(longlong_value, llbuf),
6741             ll_length);
6742     fprintf(stdout, "\n tinyint  : %d    (%ld)", tiny_value, t_length);
6743   }
6744 
6745   DIE_UNLESS(short_value == -128);
6746   DIE_UNLESS(s_length == 2);
6747 
6748   DIE_UNLESS(long_value == -127);
6749   DIE_UNLESS(l_length == 4);
6750 
6751   DIE_UNLESS(longlong_value == 255);
6752   DIE_UNLESS(ll_length == 8);
6753 
6754   DIE_UNLESS(tiny_value == 0);
6755   DIE_UNLESS(t_length == 1);
6756 
6757   rc= mysql_stmt_fetch(stmt);
6758   DIE_UNLESS(rc == MYSQL_NO_DATA);
6759 
6760   mysql_stmt_close(stmt);
6761 }
6762 
6763 
6764 /* Test misc field information, bug: #74 */
6765 
test_field_misc()6766 static void test_field_misc()
6767 {
6768   MYSQL_STMT  *stmt;
6769   MYSQL_RES   *result;
6770   int         rc;
6771 
6772   myheader("test_field_misc");
6773 
6774   rc= mysql_query(mysql, "SELECT @@autocommit");
6775   myquery(rc);
6776 
6777   result= mysql_store_result(mysql);
6778   mytest(result);
6779 
6780   rc= my_process_result_set(result);
6781   DIE_UNLESS(rc == 1);
6782 
6783   verify_prepare_field(result, 0,
6784                        "@@autocommit", "",  /* field and its org name */
6785                        MYSQL_TYPE_LONGLONG, /* field type */
6786                        "", "",              /* table and its org name */
6787                        "", 1, 0);           /* db name, length(its bool flag)*/
6788 
6789   mysql_free_result(result);
6790 
6791   stmt= mysql_simple_prepare(mysql, "SELECT @@autocommit");
6792   check_stmt(stmt);
6793 
6794   rc= mysql_stmt_execute(stmt);
6795   check_execute(stmt, rc);
6796 
6797   result= mysql_stmt_result_metadata(stmt);
6798   mytest(result);
6799 
6800   rc= my_process_stmt_result(stmt);
6801   DIE_UNLESS(rc == 1);
6802 
6803   verify_prepare_field(result, 0,
6804                        "@@autocommit", "",  /* field and its org name */
6805                        MYSQL_TYPE_LONGLONG, /* field type */
6806                        "", "",              /* table and its org name */
6807                        "", 1, 0);           /* db name, length(its bool flag)*/
6808 
6809   mysql_free_result(result);
6810   mysql_stmt_close(stmt);
6811 
6812   stmt= mysql_simple_prepare(mysql, "SELECT @@max_error_count");
6813   check_stmt(stmt);
6814 
6815   result= mysql_stmt_result_metadata(stmt);
6816   mytest(result);
6817 
6818   rc= mysql_stmt_execute(stmt);
6819   check_execute(stmt, rc);
6820 
6821   rc= my_process_stmt_result(stmt);
6822   DIE_UNLESS(rc == 1);
6823 
6824   verify_prepare_field(result, 0,
6825                        "@@max_error_count", "",   /* field and its org name */
6826                        MYSQL_TYPE_LONGLONG, /* field type */
6827                        "", "",              /* table and its org name */
6828                        /* db name, length */
6829                        "", MY_INT64_NUM_DECIMAL_DIGITS , 0);
6830 
6831   mysql_free_result(result);
6832   mysql_stmt_close(stmt);
6833 
6834   stmt= mysql_simple_prepare(mysql, "SELECT @@max_allowed_packet");
6835   check_stmt(stmt);
6836 
6837   result= mysql_stmt_result_metadata(stmt);
6838   mytest(result);
6839 
6840   rc= mysql_stmt_execute(stmt);
6841   check_execute(stmt, rc);
6842 
6843   DIE_UNLESS(1 == my_process_stmt_result(stmt));
6844 
6845   verify_prepare_field(result, 0,
6846                        "@@max_allowed_packet", "", /* field and its org name */
6847                        MYSQL_TYPE_LONGLONG, /* field type */
6848                        "", "",              /* table and its org name */
6849                        /* db name, length */
6850                        "", MY_INT64_NUM_DECIMAL_DIGITS, 0);
6851 
6852   mysql_free_result(result);
6853   mysql_stmt_close(stmt);
6854 
6855   stmt= mysql_simple_prepare(mysql, "SELECT @@sql_warnings");
6856   check_stmt(stmt);
6857 
6858   result= mysql_stmt_result_metadata(stmt);
6859   mytest(result);
6860 
6861   rc= mysql_stmt_execute(stmt);
6862   check_execute(stmt, rc);
6863 
6864   rc= my_process_stmt_result(stmt);
6865   DIE_UNLESS(rc == 1);
6866 
6867   verify_prepare_field(result, 0,
6868                        "@@sql_warnings", "",  /* field and its org name */
6869                        MYSQL_TYPE_LONGLONG,   /* field type */
6870                        "", "",                /* table and its org name */
6871                        "", 1, 0);             /* db name, length */
6872 
6873   mysql_free_result(result);
6874   mysql_stmt_close(stmt);
6875 }
6876 
6877 
6878 /*
6879   Test SET OPTION feature with prepare stmts
6880   bug #85 (reported by mark@mysql.com)
6881 */
6882 
test_set_option()6883 static void test_set_option()
6884 {
6885   MYSQL_STMT *stmt;
6886   MYSQL_RES  *result;
6887   int        rc;
6888 
6889   myheader("test_set_option");
6890 
6891   mysql_autocommit(mysql, TRUE);
6892 
6893   /* LIMIT the rows count to 2 */
6894   rc= mysql_query(mysql, "SET OPTION SQL_SELECT_LIMIT= 2");
6895   myquery(rc);
6896 
6897   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_limit");
6898   myquery(rc);
6899 
6900   rc= mysql_query(mysql, "CREATE TABLE test_limit(a tinyint)");
6901   myquery(rc);
6902 
6903   rc= mysql_query(mysql, "INSERT INTO test_limit VALUES(10), (20), (30), (40)");
6904   myquery(rc);
6905 
6906   if (!opt_silent)
6907     fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)");
6908   rc= mysql_query(mysql, "SELECT * FROM test_limit");
6909   myquery(rc);
6910 
6911   result= mysql_store_result(mysql);
6912   mytest(result);
6913 
6914   rc= my_process_result_set(result);
6915   DIE_UNLESS(rc == 2);
6916 
6917   mysql_free_result(result);
6918 
6919   if (!opt_silent)
6920     fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)");
6921   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
6922   check_stmt(stmt);
6923 
6924   rc= mysql_stmt_execute(stmt);
6925   check_execute(stmt, rc);
6926 
6927   rc= my_process_stmt_result(stmt);
6928   DIE_UNLESS(rc == 2);
6929 
6930   mysql_stmt_close(stmt);
6931 
6932   /* RESET the LIMIT the rows count to 0 */
6933   if (!opt_silent)
6934     fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)");
6935   rc= mysql_query(mysql, "SET OPTION SQL_SELECT_LIMIT=DEFAULT");
6936   myquery(rc);
6937 
6938   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
6939   check_stmt(stmt);
6940 
6941   rc= mysql_stmt_execute(stmt);
6942   check_execute(stmt, rc);
6943 
6944   rc= my_process_stmt_result(stmt);
6945   DIE_UNLESS(rc == 4);
6946 
6947   mysql_stmt_close(stmt);
6948 }
6949 
6950 
6951 /*
6952   Test a misc GRANT option
6953   bug #89 (reported by mark@mysql.com)
6954 */
6955 
6956 #ifndef EMBEDDED_LIBRARY
test_prepare_grant()6957 static void test_prepare_grant()
6958 {
6959   int rc;
6960   char query[MAX_TEST_QUERY_LENGTH];
6961 
6962   myheader("test_prepare_grant");
6963 
6964   mysql_autocommit(mysql, TRUE);
6965 
6966   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_grant");
6967   myquery(rc);
6968 
6969   rc= mysql_query(mysql, "CREATE TABLE test_grant(a tinyint primary key auto_increment)");
6970   myquery(rc);
6971 
6972   strxmov(query, "GRANT INSERT, UPDATE, SELECT ON ", current_db,
6973                 ".test_grant TO 'test_grant'@",
6974                 opt_host ? opt_host : "'localhost'", NullS);
6975 
6976   if (mysql_query(mysql, query))
6977   {
6978     myerror("GRANT failed");
6979 
6980     /*
6981        If server started with --skip-grant-tables, skip this test, else
6982        exit to indicate an error
6983 
6984        ER_UNKNOWN_COM_ERROR= 1047
6985      */
6986     if (mysql_errno(mysql) != 1047)
6987       exit(1);
6988   }
6989   else
6990   {
6991     MYSQL *org_mysql= mysql, *lmysql;
6992     MYSQL_STMT *stmt;
6993 
6994     if (!opt_silent)
6995       fprintf(stdout, "\n Establishing a test connection ...");
6996     if (!(lmysql= mysql_client_init(NULL)))
6997     {
6998       myerror("mysql_client_init() failed");
6999       exit(1);
7000     }
7001     if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
7002                              "", current_db, opt_port,
7003                              opt_unix_socket, 0)))
7004     {
7005       myerror("connection failed");
7006       mysql_close(lmysql);
7007       exit(1);
7008     }
7009     lmysql->reconnect= 1;
7010     if (!opt_silent)
7011       fprintf(stdout, "OK");
7012 
7013     mysql= lmysql;
7014     rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)");
7015     myquery(rc);
7016 
7017     rc= mysql_query(mysql, "INSERT INTO test_grant(a) VALUES(NULL)");
7018     myquery(rc);
7019 
7020     execute_prepare_query("INSERT INTO test_grant(a) VALUES(NULL)", 1);
7021     execute_prepare_query("INSERT INTO test_grant VALUES(NULL)", 1);
7022     execute_prepare_query("UPDATE test_grant SET a=9 WHERE a=1", 1);
7023     rc= my_stmt_result("SELECT a FROM test_grant");
7024     DIE_UNLESS(rc == 4);
7025 
7026     /* Both DELETE expected to fail as user does not have DELETE privs */
7027 
7028     rc= mysql_query(mysql, "DELETE FROM test_grant");
7029     myquery_r(rc);
7030 
7031     stmt= mysql_simple_prepare(mysql, "DELETE FROM test_grant");
7032     check_stmt_r(stmt);
7033 
7034     rc= my_stmt_result("SELECT * FROM test_grant");
7035     DIE_UNLESS(rc == 4);
7036 
7037     mysql_close(lmysql);
7038     mysql= org_mysql;
7039 
7040     rc= mysql_query(mysql, "delete from mysql.user where User='test_grant'");
7041     myquery(rc);
7042     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7043 
7044     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_grant'");
7045     myquery(rc);
7046     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7047 
7048   }
7049 }
7050 #endif /* EMBEDDED_LIBRARY */
7051 
7052 /*
7053   Test a crash when invalid/corrupted .frm is used in the
7054   SHOW TABLE STATUS
7055   bug #93 (reported by serg@mysql.com).
7056 */
7057 
test_frm_bug()7058 static void test_frm_bug()
7059 {
7060   MYSQL_STMT *stmt;
7061   MYSQL_BIND my_bind[2];
7062   MYSQL_RES  *result;
7063   MYSQL_ROW  row;
7064   FILE       *test_file;
7065   char       data_dir[FN_REFLEN];
7066   char       test_frm[FN_REFLEN];
7067   int        rc;
7068 
7069   myheader("test_frm_bug");
7070 
7071   mysql_autocommit(mysql, TRUE);
7072 
7073   rc= mysql_query(mysql, "drop table if exists test_frm_bug");
7074   myquery(rc);
7075 
7076   rc= mysql_query(mysql, "flush tables");
7077   myquery(rc);
7078 
7079   stmt= mysql_simple_prepare(mysql, "show variables like 'datadir'");
7080   check_stmt(stmt);
7081 
7082   rc= mysql_stmt_execute(stmt);
7083   check_execute(stmt, rc);
7084 
7085   bzero((char*) my_bind, sizeof(my_bind));
7086   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
7087   my_bind[0].buffer= data_dir;
7088   my_bind[0].buffer_length= FN_REFLEN;
7089   my_bind[1]= my_bind[0];
7090 
7091   rc= mysql_stmt_bind_result(stmt, my_bind);
7092   check_execute(stmt, rc);
7093 
7094   rc= mysql_stmt_fetch(stmt);
7095   check_execute(stmt, rc);
7096 
7097   if (!opt_silent)
7098     fprintf(stdout, "\n data directory: %s", data_dir);
7099 
7100   rc= mysql_stmt_fetch(stmt);
7101   DIE_UNLESS(rc == MYSQL_NO_DATA);
7102 
7103   strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS);
7104 
7105   if (!opt_silent)
7106     fprintf(stdout, "\n test_frm: %s", test_frm);
7107 
7108   if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
7109   {
7110     fprintf(stdout, "\n ERROR: my_fopen failed for '%s'", test_frm);
7111     fprintf(stdout, "\n test cancelled");
7112     exit(1);
7113   }
7114   if (!opt_silent)
7115     fprintf(test_file, "this is a junk file for test");
7116 
7117   rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'");
7118   myquery(rc);
7119 
7120   result= mysql_store_result(mysql);
7121   mytest(result);/* It can't be NULL */
7122 
7123   rc= my_process_result_set(result);
7124   DIE_UNLESS(rc == 1);
7125 
7126   mysql_data_seek(result, 0);
7127 
7128   row= mysql_fetch_row(result);
7129   mytest(row);
7130 
7131   if (!opt_silent)
7132     fprintf(stdout, "\n Comment: %s", row[17]);
7133   DIE_UNLESS(row[17] != 0);
7134 
7135   mysql_free_result(result);
7136   mysql_stmt_close(stmt);
7137 
7138   my_fclose(test_file, MYF(0));
7139   mysql_query(mysql, "drop table if exists test_frm_bug");
7140 }
7141 
7142 
7143 /* Test DECIMAL conversion */
7144 
test_decimal_bug()7145 static void test_decimal_bug()
7146 {
7147   MYSQL_STMT *stmt;
7148   MYSQL_BIND my_bind[1];
7149   char       data[30];
7150   int        rc;
7151   my_bool    is_null;
7152 
7153   myheader("test_decimal_bug");
7154 
7155   mysql_autocommit(mysql, TRUE);
7156 
7157   rc= mysql_query(mysql, "drop table if exists test_decimal_bug");
7158   myquery(rc);
7159 
7160   rc= mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10, 2))");
7161   myquery(rc);
7162 
7163   rc= mysql_query(mysql, "insert into test_decimal_bug value(8), (10.22), (5.61)");
7164   myquery(rc);
7165 
7166   stmt= mysql_simple_prepare(mysql, "select c1 from test_decimal_bug where c1= ?");
7167   check_stmt(stmt);
7168 
7169   /*
7170     We need to bzero bind structure because mysql_stmt_bind_param checks all
7171     its members.
7172   */
7173   bzero((char*) my_bind, sizeof(my_bind));
7174 
7175   my_bind[0].buffer_type= MYSQL_TYPE_NEWDECIMAL;
7176   my_bind[0].buffer= (void *)data;
7177   my_bind[0].buffer_length= 25;
7178   my_bind[0].is_null= &is_null;
7179 
7180   is_null= 0;
7181   rc= mysql_stmt_bind_param(stmt, my_bind);
7182   check_execute(stmt, rc);
7183 
7184   strmov(data, "8.0");
7185   rc= mysql_stmt_execute(stmt);
7186   check_execute(stmt, rc);
7187 
7188   data[0]= 0;
7189   rc= mysql_stmt_bind_result(stmt, my_bind);
7190   check_execute(stmt, rc);
7191 
7192   rc= mysql_stmt_fetch(stmt);
7193   check_execute(stmt, rc);
7194 
7195   if (!opt_silent)
7196     fprintf(stdout, "\n data: %s", data);
7197   DIE_UNLESS(strcmp(data, "8.00") == 0);
7198 
7199   rc= mysql_stmt_fetch(stmt);
7200   DIE_UNLESS(rc == MYSQL_NO_DATA);
7201 
7202   strmov(data, "5.61");
7203   rc= mysql_stmt_execute(stmt);
7204   check_execute(stmt, rc);
7205 
7206   data[0]= 0;
7207   rc= mysql_stmt_bind_result(stmt, my_bind);
7208   check_execute(stmt, rc);
7209 
7210   rc= mysql_stmt_fetch(stmt);
7211   check_execute(stmt, rc);
7212 
7213   if (!opt_silent)
7214     fprintf(stdout, "\n data: %s", data);
7215   DIE_UNLESS(strcmp(data, "5.61") == 0);
7216 
7217   rc= mysql_stmt_fetch(stmt);
7218   DIE_UNLESS(rc == MYSQL_NO_DATA);
7219 
7220   is_null= 1;
7221   rc= mysql_stmt_execute(stmt);
7222   check_execute(stmt, rc);
7223 
7224   rc= mysql_stmt_fetch(stmt);
7225   DIE_UNLESS(rc == MYSQL_NO_DATA);
7226 
7227   strmov(data, "10.22"); is_null= 0;
7228   rc= mysql_stmt_execute(stmt);
7229   check_execute(stmt, rc);
7230 
7231   data[0]= 0;
7232   rc= mysql_stmt_bind_result(stmt, my_bind);
7233   check_execute(stmt, rc);
7234 
7235   rc= mysql_stmt_fetch(stmt);
7236   check_execute(stmt, rc);
7237 
7238   if (!opt_silent)
7239     fprintf(stdout, "\n data: %s", data);
7240   DIE_UNLESS(strcmp(data, "10.22") == 0);
7241 
7242   rc= mysql_stmt_fetch(stmt);
7243   DIE_UNLESS(rc == MYSQL_NO_DATA);
7244 
7245   mysql_stmt_close(stmt);
7246 }
7247 
7248 
7249 /* Test EXPLAIN bug (#115, reported by mark@mysql.com & georg@php.net). */
7250 
test_explain_bug()7251 static void test_explain_bug()
7252 {
7253   MYSQL_STMT *stmt;
7254   MYSQL_RES  *result;
7255   int        rc;
7256 
7257   myheader("test_explain_bug");
7258 
7259   mysql_autocommit(mysql, TRUE);
7260 
7261   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_explain");
7262   myquery(rc);
7263 
7264   rc= mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))");
7265   myquery(rc);
7266 
7267   stmt= mysql_simple_prepare(mysql, "explain test_explain");
7268   check_stmt(stmt);
7269 
7270   rc= mysql_stmt_execute(stmt);
7271   check_execute(stmt, rc);
7272 
7273   rc= my_process_stmt_result(stmt);
7274   DIE_UNLESS(rc == 2);
7275 
7276   result= mysql_stmt_result_metadata(stmt);
7277   mytest(result);
7278 
7279   if (!opt_silent)
7280     fprintf(stdout, "\n total fields in the result: %d",
7281             mysql_num_fields(result));
7282   DIE_UNLESS(6 == mysql_num_fields(result));
7283 
7284   verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
7285                        mysql_get_server_version(mysql) <= 50000 ?
7286                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7287                        0, 0, "information_schema", 64, 0);
7288 
7289   verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
7290                        0, 0, "information_schema", 0, 0);
7291 
7292   verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
7293                        mysql_get_server_version(mysql) <= 50000 ?
7294                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7295                        0, 0, "information_schema", 3, 0);
7296 
7297   verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
7298                        mysql_get_server_version(mysql) <= 50000 ?
7299                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7300                        0, 0, "information_schema", 3, 0);
7301 
7302   if ( mysql_get_server_version(mysql) >= 50027 )
7303   {
7304     /*  The patch for bug#23037 changes column type of DEAULT to blob */
7305     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7306                          MYSQL_TYPE_BLOB, 0, 0, "information_schema", 0, 0);
7307   }
7308   else
7309   {
7310     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7311                          mysql_get_server_version(mysql) >= 50027 ?
7312                          MYSQL_TYPE_BLOB :
7313                          mysql_get_server_version(mysql) <= 50000 ?
7314                          MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7315                          0, 0, "information_schema",
7316                          mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
7317   }
7318 
7319   verify_prepare_field(result, 5, "Extra", "EXTRA",
7320                        mysql_get_server_version(mysql) <= 50000 ?
7321                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7322                        0, 0, "information_schema", 27, 0);
7323 
7324   mysql_free_result(result);
7325   mysql_stmt_close(stmt);
7326 
7327   stmt= mysql_simple_prepare(mysql, "explain select id, name FROM test_explain");
7328   check_stmt(stmt);
7329 
7330   rc= mysql_stmt_execute(stmt);
7331   check_execute(stmt, rc);
7332 
7333   rc= my_process_stmt_result(stmt);
7334   DIE_UNLESS(rc == 1);
7335 
7336   result= mysql_stmt_result_metadata(stmt);
7337   mytest(result);
7338 
7339   if (!opt_silent)
7340     fprintf(stdout, "\n total fields in the result: %d",
7341             mysql_num_fields(result));
7342   DIE_UNLESS(10 == mysql_num_fields(result));
7343 
7344   verify_prepare_field(result, 0, "id", "", MYSQL_TYPE_LONGLONG,
7345                        "", "", "", 3, 0);
7346 
7347   verify_prepare_field(result, 1, "select_type", "", MYSQL_TYPE_VAR_STRING,
7348                        "", "", "", 19, 0);
7349 
7350   verify_prepare_field(result, 2, "table", "", MYSQL_TYPE_VAR_STRING,
7351                        "", "", "", NAME_CHAR_LEN, 0);
7352 
7353   verify_prepare_field(result, 3, "type", "", MYSQL_TYPE_VAR_STRING,
7354                        "", "", "", 10, 0);
7355 
7356   verify_prepare_field(result, 4, "possible_keys", "", MYSQL_TYPE_VAR_STRING,
7357                        "", "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7358 
7359   verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
7360                        "", "", "", NAME_CHAR_LEN, 0);
7361 
7362   if (mysql_get_server_version(mysql) <= 50000)
7363   {
7364     verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG, "",
7365                          "", "", 3, 0);
7366   }
7367   else
7368   {
7369     verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
7370                          "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7371   }
7372 
7373   verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
7374                        "", "", "", NAME_CHAR_LEN*16, 0);
7375 
7376   verify_prepare_field(result, 8, "rows", "", MYSQL_TYPE_LONGLONG,
7377                        "", "", "", 10, 0);
7378 
7379   verify_prepare_field(result, 9, "Extra", "", MYSQL_TYPE_VAR_STRING,
7380                        "", "", "", 255, 0);
7381 
7382   mysql_free_result(result);
7383   mysql_stmt_close(stmt);
7384 }
7385 
7386 #ifdef NOT_YET_WORKING
7387 
7388 /*
7389   Test math functions.
7390   Bug #148 (reported by salle@mysql.com).
7391 */
7392 
7393 #define myerrno(n) check_errcode(n)
7394 
check_errcode(const unsigned int err)7395 static void check_errcode(const unsigned int err)
7396 {
7397   if (!opt_silent || mysql_errno(mysql) != err)
7398   {
7399     if (mysql->server_version)
7400       fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
7401     else
7402       fprintf(stdout, "\n [MySQL]");
7403     fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
7404   }
7405   DIE_UNLESS(mysql_errno(mysql) == err);
7406 }
7407 
7408 
test_drop_temp()7409 static void test_drop_temp()
7410 {
7411   int rc;
7412 
7413   myheader("test_drop_temp");
7414 
7415   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS test_drop_temp_db");
7416   myquery(rc);
7417 
7418   rc= mysql_query(mysql, "CREATE DATABASE test_drop_temp_db");
7419   myquery(rc);
7420 
7421   rc= mysql_query(mysql, "CREATE TABLE test_drop_temp_db.t1(c1 int, c2 char(1))");
7422   myquery(rc);
7423 
7424   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7425   myquery(rc);
7426 
7427   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7428   myquery(rc);
7429 
7430   strxmov(query, "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@",
7431                 opt_host ? opt_host : "localhost", NullS);
7432 
7433   if (mysql_query(mysql, query))
7434   {
7435     myerror("GRANT failed");
7436 
7437     /*
7438        If server started with --skip-grant-tables, skip this test, else
7439        exit to indicate an error
7440 
7441        ER_UNKNOWN_COM_ERROR= 1047
7442      */
7443     if (mysql_errno(mysql) != 1047)
7444       exit(1);
7445   }
7446   else
7447   {
7448     MYSQL *org_mysql= mysql, *lmysql;
7449 
7450     if (!opt_silent)
7451       fprintf(stdout, "\n Establishing a test connection ...");
7452     if (!(lmysql= mysql_client_init(NULL)))
7453     {
7454       myerror("mysql_client_init() failed");
7455       exit(1);
7456     }
7457 
7458     rc= mysql_query(mysql, "flush privileges");
7459     myquery(rc);
7460 
7461     if (!(mysql_real_connect(lmysql, opt_host ? opt_host : "localhost", "test_temp",
7462                              "", "test_drop_temp_db", opt_port,
7463                              opt_unix_socket, 0)))
7464     {
7465       mysql= lmysql;
7466       myerror("connection failed");
7467       mysql_close(lmysql);
7468       exit(1);
7469     }
7470     lmysql->reconnect= 1;
7471     if (!opt_silent)
7472       fprintf(stdout, "OK");
7473 
7474     mysql= lmysql;
7475     rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')");
7476     myerrno((uint)1142);
7477 
7478     rc= mysql_query(mysql, "DROP TABLE t1");
7479     myerrno((uint)1142);
7480 
7481     mysql= org_mysql;
7482     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t1(c1 int)");
7483     myquery(rc);
7484 
7485     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t2 LIKE test_drop_temp_db.t1");
7486     myquery(rc);
7487 
7488     mysql= lmysql;
7489 
7490     rc= mysql_query(mysql, "DROP TABLE t1, t2");
7491     myquery_r(rc);
7492 
7493     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t1");
7494     myquery_r(rc);
7495 
7496     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t2");
7497     myquery_r(rc);
7498 
7499     mysql_close(lmysql);
7500     mysql= org_mysql;
7501 
7502     rc= mysql_query(mysql, "drop database test_drop_temp_db");
7503     myquery(rc);
7504     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7505 
7506     rc= mysql_query(mysql, "delete from mysql.user where User='test_temp'");
7507     myquery(rc);
7508     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7509 
7510 
7511     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_temp'");
7512     myquery(rc);
7513     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7514   }
7515 }
7516 #endif
7517 
7518 
7519 /* Test warnings for cuted rows */
7520 
test_cuted_rows()7521 static void test_cuted_rows()
7522 {
7523   int        rc, count;
7524   MYSQL_RES  *result;
7525 
7526   myheader("test_cuted_rows");
7527 
7528   mysql_query(mysql, "DROP TABLE if exists t1");
7529   mysql_query(mysql, "DROP TABLE if exists t2");
7530 
7531   rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)");
7532   myquery(rc);
7533 
7534   rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)");
7535   myquery(rc);
7536 
7537   rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)");
7538   myquery(rc);
7539 
7540   count= mysql_warning_count(mysql);
7541   if (!opt_silent)
7542     fprintf(stdout, "\n total warnings: %d", count);
7543   DIE_UNLESS(count == 0);
7544 
7545   rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
7546   myquery(rc);
7547 
7548   count= mysql_warning_count(mysql);
7549   if (!opt_silent)
7550     fprintf(stdout, "\n total warnings: %d", count);
7551   DIE_UNLESS(count == 2);
7552 
7553   rc= mysql_query(mysql, "SHOW WARNINGS");
7554   myquery(rc);
7555 
7556   result= mysql_store_result(mysql);
7557   mytest(result);
7558 
7559   rc= my_process_result_set(result);
7560   DIE_UNLESS(rc == 2);
7561   mysql_free_result(result);
7562 
7563   rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)");
7564   myquery(rc);
7565 
7566   count= mysql_warning_count(mysql);
7567   if (!opt_silent)
7568     fprintf(stdout, "\n total warnings: %d", count);
7569   DIE_UNLESS(count == 2);
7570 
7571   rc= mysql_query(mysql, "SHOW WARNINGS");
7572   myquery(rc);
7573 
7574   result= mysql_store_result(mysql);
7575   mytest(result);
7576 
7577   rc= my_process_result_set(result);
7578   DIE_UNLESS(rc == 2);
7579   mysql_free_result(result);
7580 }
7581 
7582 
7583 /* Test update/binary logs */
7584 
test_logs()7585 static void test_logs()
7586 {
7587   MYSQL_STMT *stmt;
7588   MYSQL_BIND my_bind[2];
7589   char       data[255];
7590   ulong      length;
7591   int        rc;
7592   short      id;
7593 
7594   myheader("test_logs");
7595 
7596 
7597   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs");
7598   myquery(rc);
7599 
7600   rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))");
7601   myquery(rc);
7602 
7603   strmov((char *)data, "INSERT INTO test_logs VALUES(?, ?)");
7604   stmt= mysql_simple_prepare(mysql, data);
7605   check_stmt(stmt);
7606 
7607   /*
7608     We need to bzero bind structure because mysql_stmt_bind_param checks all
7609     its members.
7610   */
7611   bzero((char*) my_bind, sizeof(my_bind));
7612 
7613   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
7614   my_bind[0].buffer= (void *)&id;
7615 
7616   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
7617   my_bind[1].buffer= (void *)&data;
7618   my_bind[1].buffer_length= 255;
7619   my_bind[1].length= &length;
7620 
7621   id= 9876;
7622   length= (ulong)(strmov((char *)data, "MySQL - Open Source Database")- data);
7623 
7624   rc= mysql_stmt_bind_param(stmt, my_bind);
7625   check_execute(stmt, rc);
7626 
7627   rc= mysql_stmt_execute(stmt);
7628   check_execute(stmt, rc);
7629 
7630   strmov((char *)data, "'");
7631   length= 1;
7632 
7633   rc= mysql_stmt_execute(stmt);
7634   check_execute(stmt, rc);
7635 
7636   strmov((char *)data, "\"");
7637   length= 1;
7638 
7639   rc= mysql_stmt_execute(stmt);
7640   check_execute(stmt, rc);
7641 
7642   length= (ulong)(strmov((char *)data, "my\'sql\'")-data);
7643   rc= mysql_stmt_execute(stmt);
7644   check_execute(stmt, rc);
7645 
7646   length= (ulong)(strmov((char *)data, "my\"sql\"")-data);
7647   rc= mysql_stmt_execute(stmt);
7648   check_execute(stmt, rc);
7649 
7650   mysql_stmt_close(stmt);
7651 
7652   strmov((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')");
7653   stmt= mysql_simple_prepare(mysql, data);
7654   check_stmt(stmt);
7655 
7656   rc= mysql_stmt_execute(stmt);
7657   check_execute(stmt, rc);
7658 
7659   rc= mysql_stmt_execute(stmt);
7660   check_execute(stmt, rc);
7661 
7662   mysql_stmt_close(stmt);
7663 
7664   strmov((char *)data, "SELECT * FROM test_logs WHERE id=?");
7665   stmt= mysql_simple_prepare(mysql, data);
7666   check_stmt(stmt);
7667 
7668   rc= mysql_stmt_bind_param(stmt, my_bind);
7669   check_execute(stmt, rc);
7670 
7671   rc= mysql_stmt_execute(stmt);
7672   check_execute(stmt, rc);
7673 
7674   my_bind[1].buffer_length= 255;
7675   rc= mysql_stmt_bind_result(stmt, my_bind);
7676   check_execute(stmt, rc);
7677 
7678   rc= mysql_stmt_fetch(stmt);
7679   check_execute(stmt, rc);
7680 
7681   if (!opt_silent)
7682   {
7683     fprintf(stdout, "id    : %d\n", id);
7684     fprintf(stdout, "name  : %s(%ld)\n", data, length);
7685   }
7686 
7687   DIE_UNLESS(id == 9876);
7688   DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */
7689   DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1);
7690 
7691   rc= mysql_stmt_fetch(stmt);
7692   check_execute(stmt, rc);
7693 
7694   if (!opt_silent)
7695     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7696 
7697   DIE_UNLESS(length == 1);
7698   DIE_UNLESS(strcmp(data, "'") == 0);
7699 
7700   rc= mysql_stmt_fetch(stmt);
7701   check_execute(stmt, rc);
7702 
7703   if (!opt_silent)
7704     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7705 
7706   DIE_UNLESS(length == 1);
7707   DIE_UNLESS(strcmp(data, "\"") == 0);
7708 
7709   rc= mysql_stmt_fetch(stmt);
7710   check_execute(stmt, rc);
7711 
7712   if (!opt_silent)
7713     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7714 
7715   DIE_UNLESS(length == 7);
7716   DIE_UNLESS(strcmp(data, "my\'sql\'") == 0);
7717 
7718   rc= mysql_stmt_fetch(stmt);
7719   check_execute(stmt, rc);
7720 
7721   if (!opt_silent)
7722     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7723 
7724   DIE_UNLESS(length == 7);
7725   /*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */
7726 
7727   rc= mysql_stmt_fetch(stmt);
7728   DIE_UNLESS(rc == MYSQL_NO_DATA);
7729 
7730   mysql_stmt_close(stmt);
7731 
7732   rc= mysql_query(mysql, "DROP TABLE test_logs");
7733   myquery(rc);
7734 }
7735 
7736 
7737 /* Test 'n' statements create and close */
7738 
test_nstmts()7739 static void test_nstmts()
7740 {
7741   MYSQL_STMT  *stmt;
7742   char        query[255];
7743   int         rc;
7744   static uint i, total_stmts= 2000;
7745   MYSQL_BIND  my_bind[1];
7746 
7747   myheader("test_nstmts");
7748 
7749   mysql_autocommit(mysql, TRUE);
7750 
7751   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_nstmts");
7752   myquery(rc);
7753 
7754   rc= mysql_query(mysql, "CREATE TABLE test_nstmts(id int)");
7755   myquery(rc);
7756 
7757   /*
7758     We need to bzero bind structure because mysql_stmt_bind_param checks all
7759     its members.
7760   */
7761   bzero((char*) my_bind, sizeof(my_bind));
7762 
7763   my_bind[0].buffer= (void *)&i;
7764   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
7765 
7766   for (i= 0; i < total_stmts; i++)
7767   {
7768     if (!opt_silent)
7769       fprintf(stdout, "\r stmt: %d", i);
7770 
7771     strmov(query, "insert into test_nstmts values(?)");
7772     stmt= mysql_simple_prepare(mysql, query);
7773     check_stmt(stmt);
7774 
7775     rc= mysql_stmt_bind_param(stmt, my_bind);
7776     check_execute(stmt, rc);
7777 
7778     rc= mysql_stmt_execute(stmt);
7779     check_execute(stmt, rc);
7780 
7781     mysql_stmt_close(stmt);
7782   }
7783 
7784   stmt= mysql_simple_prepare(mysql, " select count(*) from test_nstmts");
7785   check_stmt(stmt);
7786 
7787   rc= mysql_stmt_execute(stmt);
7788   check_execute(stmt, rc);
7789 
7790   i= 0;
7791   rc= mysql_stmt_bind_result(stmt, my_bind);
7792   check_execute(stmt, rc);
7793 
7794   rc= mysql_stmt_fetch(stmt);
7795   check_execute(stmt, rc);
7796   if (!opt_silent)
7797     fprintf(stdout, "\n total rows: %d", i);
7798   DIE_UNLESS( i == total_stmts);
7799 
7800   rc= mysql_stmt_fetch(stmt);
7801   DIE_UNLESS(rc == MYSQL_NO_DATA);
7802 
7803   mysql_stmt_close(stmt);
7804 
7805   rc= mysql_query(mysql, "DROP TABLE test_nstmts");
7806   myquery(rc);
7807 }
7808 
7809 
7810 /* Test stmt seek() functions */
7811 
test_fetch_seek()7812 static void test_fetch_seek()
7813 {
7814   MYSQL_STMT *stmt;
7815   MYSQL_BIND my_bind[3];
7816   MYSQL_ROW_OFFSET row;
7817   int        rc;
7818   int32      c1;
7819   char       c2[11], c3[20];
7820 
7821   myheader("test_fetch_seek");
7822   rc= mysql_query(mysql, "drop table if exists t1");
7823 
7824   myquery(rc);
7825 
7826   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
7827   myquery(rc);
7828 
7829   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
7830   myquery(rc);
7831 
7832   stmt= mysql_simple_prepare(mysql, "select * from t1");
7833   check_stmt(stmt);
7834 
7835   bzero((char*) my_bind, sizeof(my_bind));
7836   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
7837   my_bind[0].buffer= (void *)&c1;
7838 
7839   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
7840   my_bind[1].buffer= (void *)c2;
7841   my_bind[1].buffer_length= sizeof(c2);
7842 
7843   my_bind[2]= my_bind[1];
7844   my_bind[2].buffer= (void *)c3;
7845   my_bind[2].buffer_length= sizeof(c3);
7846 
7847   rc= mysql_stmt_execute(stmt);
7848   check_execute(stmt, rc);
7849 
7850   rc= mysql_stmt_bind_result(stmt, my_bind);
7851   check_execute(stmt, rc);
7852 
7853   rc= mysql_stmt_store_result(stmt);
7854   check_execute(stmt, rc);
7855 
7856   rc= mysql_stmt_fetch(stmt);
7857   check_execute(stmt, rc);
7858 
7859   if (!opt_silent)
7860     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
7861 
7862   row= mysql_stmt_row_tell(stmt);
7863 
7864   row= mysql_stmt_row_seek(stmt, row);
7865 
7866   rc= mysql_stmt_fetch(stmt);
7867   check_execute(stmt, rc);
7868 
7869   if (!opt_silent)
7870     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
7871 
7872   row= mysql_stmt_row_seek(stmt, row);
7873 
7874   rc= mysql_stmt_fetch(stmt);
7875   check_execute(stmt, rc);
7876 
7877   if (!opt_silent)
7878     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
7879 
7880   mysql_stmt_data_seek(stmt, 0);
7881 
7882   rc= mysql_stmt_fetch(stmt);
7883   check_execute(stmt, rc);
7884 
7885   if (!opt_silent)
7886     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
7887 
7888   rc= mysql_stmt_fetch(stmt);
7889   check_execute(stmt, rc);
7890 
7891   rc= mysql_stmt_fetch(stmt);
7892   check_execute(stmt, rc);
7893 
7894   rc= mysql_stmt_fetch(stmt);
7895   check_execute(stmt, rc);
7896 
7897   rc= mysql_stmt_fetch(stmt);
7898   DIE_UNLESS(rc == MYSQL_NO_DATA);
7899 
7900   mysql_stmt_close(stmt);
7901   myquery(mysql_query(mysql, "drop table t1"));
7902 }
7903 
7904 
7905 /* Test mysql_stmt_fetch_column() with offset */
7906 
test_fetch_offset()7907 static void test_fetch_offset()
7908 {
7909   MYSQL_STMT *stmt;
7910   MYSQL_BIND my_bind[1];
7911   char       data[11];
7912   ulong      length;
7913   int        rc;
7914   my_bool    is_null;
7915 
7916 
7917   myheader("test_fetch_offset");
7918 
7919   rc= mysql_query(mysql, "drop table if exists t1");
7920   myquery(rc);
7921 
7922   rc= mysql_query(mysql, "create table t1(a char(10))");
7923   myquery(rc);
7924 
7925   rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)");
7926   myquery(rc);
7927 
7928   stmt= mysql_simple_prepare(mysql, "select * from t1");
7929   check_stmt(stmt);
7930 
7931   bzero((char*) my_bind, sizeof(my_bind));
7932   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
7933   my_bind[0].buffer= (void *)data;
7934   my_bind[0].buffer_length= 11;
7935   my_bind[0].is_null= &is_null;
7936   my_bind[0].length= &length;
7937 
7938   rc= mysql_stmt_execute(stmt);
7939   check_execute(stmt, rc);
7940 
7941   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
7942   check_execute_r(stmt, rc);
7943 
7944   rc= mysql_stmt_execute(stmt);
7945   check_execute(stmt, rc);
7946 
7947   rc= mysql_stmt_bind_result(stmt, my_bind);
7948   check_execute(stmt, rc);
7949 
7950   rc= mysql_stmt_store_result(stmt);
7951   check_execute(stmt, rc);
7952 
7953   rc= mysql_stmt_fetch(stmt);
7954   check_execute(stmt, rc);
7955 
7956   data[0]= '\0';
7957   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
7958   check_execute(stmt, rc);
7959   if (!opt_silent)
7960     fprintf(stdout, "\n col 1: %s (%ld)", data, length);
7961   DIE_UNLESS(strncmp(data, "abcd", 4) == 0 && length == 10);
7962 
7963   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5);
7964   check_execute(stmt, rc);
7965   if (!opt_silent)
7966     fprintf(stdout, "\n col 1: %s (%ld)", data, length);
7967   DIE_UNLESS(strncmp(data, "fg", 2) == 0 && length == 10);
7968 
7969   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9);
7970   check_execute(stmt, rc);
7971   if (!opt_silent)
7972     fprintf(stdout, "\n col 0: %s (%ld)", data, length);
7973   DIE_UNLESS(strncmp(data, "j", 1) == 0 && length == 10);
7974 
7975   rc= mysql_stmt_fetch(stmt);
7976   check_execute(stmt, rc);
7977 
7978   is_null= 0;
7979 
7980   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
7981   check_execute(stmt, rc);
7982 
7983   DIE_UNLESS(is_null == 1);
7984 
7985   rc= mysql_stmt_fetch(stmt);
7986   DIE_UNLESS(rc == MYSQL_NO_DATA);
7987 
7988   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
7989   check_execute_r(stmt, rc);
7990 
7991   mysql_stmt_close(stmt);
7992 
7993   myquery(mysql_query(mysql, "drop table t1"));
7994 }
7995 
7996 
7997 /* Test mysql_stmt_fetch_column() */
7998 
test_fetch_column()7999 static void test_fetch_column()
8000 {
8001   MYSQL_STMT *stmt;
8002   MYSQL_BIND my_bind[2];
8003   char       c2[20], bc2[20];
8004   ulong      l1, l2, bl1, bl2;
8005   int        rc, c1, bc1;
8006 
8007   myheader("test_fetch_column");
8008 
8009   rc= mysql_query(mysql, "drop table if exists t1");
8010   myquery(rc);
8011 
8012   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
8013   myquery(rc);
8014 
8015   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
8016   myquery(rc);
8017 
8018   stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc");
8019   check_stmt(stmt);
8020 
8021   bzero((char*) my_bind, sizeof(my_bind));
8022   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8023   my_bind[0].buffer= (void *)&bc1;
8024   my_bind[0].buffer_length= 0;
8025   my_bind[0].is_null= 0;
8026   my_bind[0].length= &bl1;
8027   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8028   my_bind[1].buffer= (void *)bc2;
8029   my_bind[1].buffer_length= 7;
8030   my_bind[1].is_null= 0;
8031   my_bind[1].length= &bl2;
8032 
8033   rc= mysql_stmt_execute(stmt);
8034   check_execute(stmt, rc);
8035 
8036   rc= mysql_stmt_bind_result(stmt, my_bind);
8037   check_execute(stmt, rc);
8038 
8039   rc= mysql_stmt_store_result(stmt);
8040   check_execute(stmt, rc);
8041 
8042   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */
8043   check_execute_r(stmt, rc);
8044 
8045   rc= mysql_stmt_fetch(stmt);
8046   check_execute(stmt, rc);
8047 
8048   if (!opt_silent)
8049     fprintf(stdout, "\n row 0: %d, %s", bc1, bc2);
8050 
8051   c2[0]= '\0'; l2= 0;
8052   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8053   my_bind[0].buffer= (void *)c2;
8054   my_bind[0].buffer_length= 7;
8055   my_bind[0].is_null= 0;
8056   my_bind[0].length= &l2;
8057 
8058   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8059   check_execute(stmt, rc);
8060   if (!opt_silent)
8061     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8062   DIE_UNLESS(strncmp(c2, "venu", 4) == 0 && l2 == 4);
8063 
8064   c2[0]= '\0'; l2= 0;
8065   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8066   check_execute(stmt, rc);
8067   if (!opt_silent)
8068     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8069   DIE_UNLESS(strcmp(c2, "venu") == 0 && l2 == 4);
8070 
8071   c1= 0;
8072   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8073   my_bind[0].buffer= (void *)&c1;
8074   my_bind[0].buffer_length= 0;
8075   my_bind[0].is_null= 0;
8076   my_bind[0].length= &l1;
8077 
8078   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8079   check_execute(stmt, rc);
8080   if (!opt_silent)
8081     fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
8082   DIE_UNLESS(c1 == 1 && l1 == 4);
8083 
8084   rc= mysql_stmt_fetch(stmt);
8085   check_execute(stmt, rc);
8086 
8087   if (!opt_silent)
8088     fprintf(stdout, "\n row 1: %d, %s", bc1, bc2);
8089 
8090   c2[0]= '\0'; l2= 0;
8091   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8092   my_bind[0].buffer= (void *)c2;
8093   my_bind[0].buffer_length= 7;
8094   my_bind[0].is_null= 0;
8095   my_bind[0].length= &l2;
8096 
8097   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8098   check_execute(stmt, rc);
8099   if (!opt_silent)
8100     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8101   DIE_UNLESS(strncmp(c2, "mysq", 4) == 0 && l2 == 5);
8102 
8103   c2[0]= '\0'; l2= 0;
8104   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8105   check_execute(stmt, rc);
8106   if (!opt_silent)
8107     fprintf(stdout, "\n col 1: %si(%ld)", c2, l2);
8108   DIE_UNLESS(strcmp(c2, "mysql") == 0 && l2 == 5);
8109 
8110   c1= 0;
8111   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8112   my_bind[0].buffer= (void *)&c1;
8113   my_bind[0].buffer_length= 0;
8114   my_bind[0].is_null= 0;
8115   my_bind[0].length= &l1;
8116 
8117   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8118   check_execute(stmt, rc);
8119   if (!opt_silent)
8120     fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
8121   DIE_UNLESS(c1 == 2 && l1 == 4);
8122 
8123   rc= mysql_stmt_fetch(stmt);
8124   DIE_UNLESS(rc == MYSQL_NO_DATA);
8125 
8126   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8127   check_execute_r(stmt, rc);
8128 
8129   mysql_stmt_close(stmt);
8130   myquery(mysql_query(mysql, "drop table t1"));
8131 }
8132 
8133 
8134 /* Test mysql_list_fields() */
8135 
test_list_fields()8136 static void test_list_fields()
8137 {
8138   MYSQL_RES *result;
8139   int rc;
8140   myheader("test_list_fields");
8141 
8142   rc= mysql_query(mysql, "drop table if exists t1");
8143   myquery(rc);
8144 
8145   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10) default 'mysql')");
8146   myquery(rc);
8147 
8148   result= mysql_list_fields(mysql, "t1", NULL);
8149   mytest(result);
8150 
8151   rc= my_process_result_set(result);
8152   DIE_UNLESS(rc == 0);
8153 
8154   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_LONG,
8155                        "t1", "t1",
8156                        current_db, 11, "0");
8157 
8158   verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_STRING,
8159                        "t1", "t1",
8160                        current_db, 10, "mysql");
8161 
8162   mysql_free_result(result);
8163   myquery(mysql_query(mysql, "drop table t1"));
8164 }
8165 
8166 
test_bug19671()8167 static void test_bug19671()
8168 {
8169   MYSQL_RES *result;
8170   int rc;
8171   myheader("test_bug19671");
8172 
8173   mysql_query(mysql, "set sql_mode=''");
8174   rc= mysql_query(mysql, "drop table if exists t1");
8175   myquery(rc);
8176 
8177   rc= mysql_query(mysql, "drop view if exists v1");
8178   myquery(rc);
8179 
8180   rc= mysql_query(mysql, "create table t1(f1 int)");
8181   myquery(rc);
8182 
8183   rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
8184   myquery(rc);
8185 
8186   result= mysql_list_fields(mysql, "v1", NULL);
8187   mytest(result);
8188 
8189   rc= my_process_result_set(result);
8190   DIE_UNLESS(rc == 0);
8191 
8192   verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
8193                        "v1", "v1", current_db, 11, "0");
8194 
8195   mysql_free_result(result);
8196   myquery(mysql_query(mysql, "drop view v1"));
8197   myquery(mysql_query(mysql, "drop table t1"));
8198 }
8199 
8200 
8201 /* Test a memory ovverun bug */
8202 
test_mem_overun()8203 static void test_mem_overun()
8204 {
8205   char       buffer[10000], field[10];
8206   MYSQL_STMT *stmt;
8207   MYSQL_RES  *field_res;
8208   int        rc, i, length;
8209 
8210   myheader("test_mem_overun");
8211 
8212   /*
8213     Test a memory ovverun bug when a table had 1000 fields with
8214     a row of data
8215   */
8216   rc= mysql_query(mysql, "drop table if exists t_mem_overun");
8217   myquery(rc);
8218 
8219   strxmov(buffer, "create table t_mem_overun(", NullS);
8220   for (i= 0; i < 1000; i++)
8221   {
8222     sprintf(field, "c%d int", i);
8223     strxmov(buffer, buffer, field, ", ", NullS);
8224   }
8225   length= strlen(buffer);
8226   buffer[length-2]= ')';
8227   buffer[--length]= '\0';
8228 
8229   rc= mysql_real_query(mysql, buffer, length);
8230   myquery(rc);
8231 
8232   strxmov(buffer, "insert into t_mem_overun values(", NullS);
8233   for (i= 0; i < 1000; i++)
8234   {
8235     strxmov(buffer, buffer, "1, ", NullS);
8236   }
8237   length= strlen(buffer);
8238   buffer[length-2]= ')';
8239   buffer[--length]= '\0';
8240 
8241   rc= mysql_real_query(mysql, buffer, length);
8242   myquery(rc);
8243 
8244   rc= mysql_query(mysql, "select * from t_mem_overun");
8245   myquery(rc);
8246 
8247   rc= my_process_result(mysql);
8248   DIE_UNLESS(rc == 1);
8249 
8250   stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun");
8251   check_stmt(stmt);
8252 
8253   rc= mysql_stmt_execute(stmt);
8254   check_execute(stmt, rc);
8255 
8256   field_res= mysql_stmt_result_metadata(stmt);
8257   mytest(field_res);
8258 
8259   if (!opt_silent)
8260     fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
8261   DIE_UNLESS( 1000 == mysql_num_fields(field_res));
8262 
8263   rc= mysql_stmt_store_result(stmt);
8264   check_execute(stmt, rc);
8265 
8266   rc= mysql_stmt_fetch(stmt);
8267   check_execute(stmt, rc);
8268 
8269   rc= mysql_stmt_fetch(stmt);
8270   DIE_UNLESS(rc == MYSQL_NO_DATA);
8271 
8272   mysql_free_result(field_res);
8273 
8274   mysql_stmt_close(stmt);
8275 }
8276 
8277 
8278 /* Test mysql_stmt_free_result() */
8279 
test_free_result()8280 static void test_free_result()
8281 {
8282   MYSQL_STMT *stmt;
8283   MYSQL_BIND my_bind[1];
8284   char       c2[5];
8285   ulong      bl1, l2;
8286   int        rc, c1, bc1;
8287 
8288   myheader("test_free_result");
8289 
8290   rc= mysql_query(mysql, "drop table if exists test_free_result");
8291   myquery(rc);
8292 
8293   rc= mysql_query(mysql, "create table test_free_result("
8294                          "c1 int primary key auto_increment)");
8295   myquery(rc);
8296 
8297   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8298   myquery(rc);
8299 
8300   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8301   check_stmt(stmt);
8302 
8303   bzero((char*) my_bind, sizeof(my_bind));
8304   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8305   my_bind[0].buffer= (void *)&bc1;
8306   my_bind[0].length= &bl1;
8307 
8308   rc= mysql_stmt_execute(stmt);
8309   check_execute(stmt, rc);
8310 
8311   rc= mysql_stmt_bind_result(stmt, my_bind);
8312   check_execute(stmt, rc);
8313 
8314   rc= mysql_stmt_fetch(stmt);
8315   check_execute(stmt, rc);
8316 
8317   c2[0]= '\0'; l2= 0;
8318   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8319   my_bind[0].buffer= (void *)c2;
8320   my_bind[0].buffer_length= 7;
8321   my_bind[0].is_null= 0;
8322   my_bind[0].length= &l2;
8323 
8324   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8325   check_execute(stmt, rc);
8326   if (!opt_silent)
8327     fprintf(stdout, "\n col 0: %s(%ld)", c2, l2);
8328   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8329 
8330   rc= mysql_stmt_fetch(stmt);
8331   check_execute(stmt, rc);
8332 
8333   c1= 0, l2= 0;
8334   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8335   my_bind[0].buffer= (void *)&c1;
8336   my_bind[0].buffer_length= 0;
8337   my_bind[0].is_null= 0;
8338   my_bind[0].length= &l2;
8339 
8340   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8341   check_execute(stmt, rc);
8342   if (!opt_silent)
8343     fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8344   DIE_UNLESS(c1 == 2 && l2 == 4);
8345 
8346   rc= mysql_query(mysql, "drop table test_free_result");
8347   myquery_r(rc); /* error should be, COMMANDS OUT OF SYNC */
8348 
8349   rc= mysql_stmt_free_result(stmt);
8350   check_execute(stmt, rc);
8351 
8352   rc= mysql_query(mysql, "drop table test_free_result");
8353   myquery(rc);  /* should be successful */
8354 
8355   mysql_stmt_close(stmt);
8356 }
8357 
8358 
8359 /* Test mysql_stmt_store_result() */
8360 
test_free_store_result()8361 static void test_free_store_result()
8362 {
8363   MYSQL_STMT *stmt;
8364   MYSQL_BIND my_bind[1];
8365   char       c2[5];
8366   ulong      bl1, l2;
8367   int        rc, c1, bc1;
8368 
8369   myheader("test_free_store_result");
8370 
8371   rc= mysql_query(mysql, "drop table if exists test_free_result");
8372   myquery(rc);
8373 
8374   rc= mysql_query(mysql, "create table test_free_result(c1 int primary key auto_increment)");
8375   myquery(rc);
8376 
8377   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8378   myquery(rc);
8379 
8380   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8381   check_stmt(stmt);
8382 
8383   bzero((char*) my_bind, sizeof(my_bind));
8384   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8385   my_bind[0].buffer= (void *)&bc1;
8386   my_bind[0].buffer_length= 0;
8387   my_bind[0].is_null= 0;
8388   my_bind[0].length= &bl1;
8389 
8390   rc= mysql_stmt_execute(stmt);
8391   check_execute(stmt, rc);
8392 
8393   rc= mysql_stmt_bind_result(stmt, my_bind);
8394   check_execute(stmt, rc);
8395 
8396   rc= mysql_stmt_store_result(stmt);
8397   check_execute(stmt, rc);
8398 
8399   rc= mysql_stmt_fetch(stmt);
8400   check_execute(stmt, rc);
8401 
8402   c2[0]= '\0'; l2= 0;
8403   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8404   my_bind[0].buffer= (void *)c2;
8405   my_bind[0].buffer_length= 7;
8406   my_bind[0].is_null= 0;
8407   my_bind[0].length= &l2;
8408 
8409   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8410   check_execute(stmt, rc);
8411   if (!opt_silent)
8412     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8413   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8414 
8415   rc= mysql_stmt_fetch(stmt);
8416   check_execute(stmt, rc);
8417 
8418   c1= 0, l2= 0;
8419   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8420   my_bind[0].buffer= (void *)&c1;
8421   my_bind[0].buffer_length= 0;
8422   my_bind[0].is_null= 0;
8423   my_bind[0].length= &l2;
8424 
8425   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8426   check_execute(stmt, rc);
8427   if (!opt_silent)
8428     fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8429   DIE_UNLESS(c1 == 2 && l2 == 4);
8430 
8431   rc= mysql_stmt_free_result(stmt);
8432   check_execute(stmt, rc);
8433 
8434   rc= mysql_query(mysql, "drop table test_free_result");
8435   myquery(rc);
8436 
8437   mysql_stmt_close(stmt);
8438 }
8439 
8440 
8441 /* Test SQLmode */
8442 
test_sqlmode()8443 static void test_sqlmode()
8444 {
8445   MYSQL_STMT *stmt;
8446   MYSQL_BIND my_bind[2];
8447   char       c1[5], c2[5];
8448   int        rc;
8449   char query[MAX_TEST_QUERY_LENGTH];
8450 
8451   myheader("test_sqlmode");
8452 
8453   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping");
8454   myquery(rc);
8455 
8456   rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))");
8457   myquery(rc);
8458 
8459   /* PIPES_AS_CONCAT */
8460   strmov(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
8461   if (!opt_silent)
8462     fprintf(stdout, "\n With %s", query);
8463   rc= mysql_query(mysql, query);
8464   myquery(rc);
8465 
8466   strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8467   if (!opt_silent)
8468     fprintf(stdout, "\n  query: %s", query);
8469   stmt= mysql_simple_prepare(mysql, query);
8470   check_stmt(stmt);
8471 
8472   if (!opt_silent)
8473     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8474 
8475   /*
8476     We need to bzero bind structure because mysql_stmt_bind_param checks all
8477     its members.
8478   */
8479   bzero((char*) my_bind, sizeof(my_bind));
8480 
8481   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8482   my_bind[0].buffer= (void *)c1;
8483   my_bind[0].buffer_length= 2;
8484 
8485   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8486   my_bind[1].buffer= (void *)c2;
8487   my_bind[1].buffer_length= 3;
8488 
8489   rc= mysql_stmt_bind_param(stmt, my_bind);
8490   check_execute(stmt, rc);
8491 
8492   strmov(c1, "My"); strmov(c2, "SQL");
8493   rc= mysql_stmt_execute(stmt);
8494   check_execute(stmt, rc);
8495   mysql_stmt_close(stmt);
8496 
8497   verify_col_data("test_piping", "name", "MySQL");
8498 
8499   rc= mysql_query(mysql, "DELETE FROM test_piping");
8500   myquery(rc);
8501 
8502   strmov(query, "SELECT connection_id    ()");
8503   if (!opt_silent)
8504     fprintf(stdout, "\n  query: %s", query);
8505   stmt= mysql_simple_prepare(mysql, query);
8506   check_stmt(stmt);
8507   mysql_stmt_close(stmt);
8508 
8509   /* ANSI */
8510   strmov(query, "SET SQL_MODE= \"ANSI\"");
8511   if (!opt_silent)
8512     fprintf(stdout, "\n With %s", query);
8513   rc= mysql_query(mysql, query);
8514   myquery(rc);
8515 
8516   strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8517   if (!opt_silent)
8518     fprintf(stdout, "\n  query: %s", query);
8519   stmt= mysql_simple_prepare(mysql, query);
8520   check_stmt(stmt);
8521   if (!opt_silent)
8522     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8523 
8524   rc= mysql_stmt_bind_param(stmt, my_bind);
8525   check_execute(stmt, rc);
8526 
8527   strmov(c1, "My"); strmov(c2, "SQL");
8528   rc= mysql_stmt_execute(stmt);
8529   check_execute(stmt, rc);
8530 
8531   mysql_stmt_close(stmt);
8532   verify_col_data("test_piping", "name", "MySQL");
8533 
8534   /* ANSI mode spaces ... */
8535   strmov(query, "SELECT connection_id    ()");
8536   if (!opt_silent)
8537     fprintf(stdout, "\n  query: %s", query);
8538   stmt= mysql_simple_prepare(mysql, query);
8539   check_stmt(stmt);
8540 
8541   rc= mysql_stmt_execute(stmt);
8542   check_execute(stmt, rc);
8543 
8544   rc= mysql_stmt_fetch(stmt);
8545   check_execute(stmt, rc);
8546 
8547   rc= mysql_stmt_fetch(stmt);
8548   DIE_UNLESS(rc == MYSQL_NO_DATA);
8549   if (!opt_silent)
8550     fprintf(stdout, "\n  returned 1 row\n");
8551 
8552   mysql_stmt_close(stmt);
8553 
8554   /* IGNORE SPACE MODE */
8555   strmov(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
8556   if (!opt_silent)
8557     fprintf(stdout, "\n With %s", query);
8558   rc= mysql_query(mysql, query);
8559   myquery(rc);
8560 
8561   strmov(query, "SELECT connection_id    ()");
8562   if (!opt_silent)
8563     fprintf(stdout, "\n  query: %s", query);
8564   stmt= mysql_simple_prepare(mysql, query);
8565   check_stmt(stmt);
8566 
8567   rc= mysql_stmt_execute(stmt);
8568   check_execute(stmt, rc);
8569 
8570   rc= mysql_stmt_fetch(stmt);
8571   check_execute(stmt, rc);
8572 
8573   rc= mysql_stmt_fetch(stmt);
8574   DIE_UNLESS(rc == MYSQL_NO_DATA);
8575   if (!opt_silent)
8576     fprintf(stdout, "\n  returned 1 row");
8577 
8578   mysql_stmt_close(stmt);
8579 }
8580 
8581 
8582 /* Test for timestamp handling */
8583 
test_ts()8584 static void test_ts()
8585 {
8586   MYSQL_STMT *stmt;
8587   MYSQL_BIND my_bind[6];
8588   MYSQL_TIME ts;
8589   MYSQL_RES  *prep_res;
8590   char       strts[30];
8591   ulong      length;
8592   int        rc, field_count;
8593   char       name;
8594   char query[MAX_TEST_QUERY_LENGTH];
8595   const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
8596                             "SELECT a, b, c FROM test_ts WHERE %c=?",
8597                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
8598   myheader("test_ts");
8599 
8600   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts");
8601   myquery(rc);
8602 
8603   rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)");
8604   myquery(rc);
8605 
8606   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)");
8607   check_stmt(stmt);
8608 
8609   ts.year= 2003;
8610   ts.month= 07;
8611   ts.day= 12;
8612   ts.hour= 21;
8613   ts.minute= 07;
8614   ts.second= 46;
8615   ts.second_part= 0;
8616   length= (long)(strmov(strts, "2003-07-12 21:07:46") - strts);
8617 
8618   /*
8619     We need to bzero bind structure because mysql_stmt_bind_param checks all
8620     its members.
8621   */
8622   bzero((char*) my_bind, sizeof(my_bind));
8623 
8624   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
8625   my_bind[0].buffer= (void *)&ts;
8626   my_bind[0].buffer_length= sizeof(ts);
8627 
8628   my_bind[2]= my_bind[1]= my_bind[0];
8629 
8630   my_bind[3].buffer_type= MYSQL_TYPE_STRING;
8631   my_bind[3].buffer= (void *)strts;
8632   my_bind[3].buffer_length= sizeof(strts);
8633   my_bind[3].length= &length;
8634 
8635   my_bind[5]= my_bind[4]= my_bind[3];
8636 
8637   rc= mysql_stmt_bind_param(stmt, my_bind);
8638   check_execute(stmt, rc);
8639 
8640   rc= mysql_stmt_execute(stmt);
8641   check_execute(stmt, rc);
8642 
8643   mysql_stmt_close(stmt);
8644 
8645   verify_col_data("test_ts", "a", "2003-07-12");
8646   verify_col_data("test_ts", "b", "21:07:46");
8647   verify_col_data("test_ts", "c", "2003-07-12 21:07:46");
8648 
8649   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts");
8650   check_stmt(stmt);
8651 
8652   prep_res= mysql_stmt_result_metadata(stmt);
8653   mytest(prep_res);
8654 
8655   rc= mysql_stmt_execute(stmt);
8656   check_execute(stmt, rc);
8657 
8658   rc= my_process_stmt_result(stmt);
8659   DIE_UNLESS(rc == 2);
8660   field_count= mysql_num_fields(prep_res);
8661 
8662   mysql_free_result(prep_res);
8663   mysql_stmt_close(stmt);
8664 
8665   for (name= 'a'; field_count--; name++)
8666   {
8667     int row_count= 0;
8668 
8669     sprintf(query, queries[field_count], name);
8670 
8671     if (!opt_silent)
8672       fprintf(stdout, "\n  %s", query);
8673     stmt= mysql_simple_prepare(mysql, query);
8674     check_stmt(stmt);
8675 
8676     rc= mysql_stmt_bind_param(stmt, my_bind);
8677     check_execute(stmt, rc);
8678 
8679     rc= mysql_stmt_execute(stmt);
8680     check_execute(stmt, rc);
8681 
8682     while (mysql_stmt_fetch(stmt) == 0)
8683       row_count++;
8684 
8685     if (!opt_silent)
8686       fprintf(stdout, "\n   returned '%d' rows", row_count);
8687     DIE_UNLESS(row_count == 2);
8688     mysql_stmt_close(stmt);
8689   }
8690 }
8691 
8692 
8693 /* Test for bug #1500. */
8694 
test_bug1500()8695 static void test_bug1500()
8696 {
8697   MYSQL_STMT *stmt;
8698   MYSQL_BIND my_bind[3];
8699   int        rc;
8700   int32 int_data[3]= {2, 3, 4};
8701   const char *data;
8702 
8703   myheader("test_bug1500");
8704 
8705   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
8706   myquery(rc);
8707 
8708   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (i INT)");
8709   myquery(rc);
8710 
8711   rc= mysql_query(mysql, "INSERT INTO test_bg1500 VALUES (1), (2)");
8712   myquery(rc);
8713 
8714   rc= mysql_commit(mysql);
8715   myquery(rc);
8716 
8717   stmt= mysql_simple_prepare(mysql, "SELECT i FROM test_bg1500 WHERE i IN (?, ?, ?)");
8718   check_stmt(stmt);
8719   verify_param_count(stmt, 3);
8720 
8721   /*
8722     We need to bzero bind structure because mysql_stmt_bind_param checks all
8723     its members.
8724   */
8725   bzero((char*) my_bind, sizeof(my_bind));
8726 
8727   my_bind[0].buffer= (void *)int_data;
8728   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8729   my_bind[2]= my_bind[1]= my_bind[0];
8730   my_bind[1].buffer= (void *)(int_data + 1);
8731   my_bind[2].buffer= (void *)(int_data + 2);
8732 
8733   rc= mysql_stmt_bind_param(stmt, my_bind);
8734   check_execute(stmt, rc);
8735 
8736   rc= mysql_stmt_execute(stmt);
8737   check_execute(stmt, rc);
8738 
8739   rc= my_process_stmt_result(stmt);
8740   DIE_UNLESS(rc == 1);
8741 
8742   mysql_stmt_close(stmt);
8743 
8744   rc= mysql_query(mysql, "DROP TABLE test_bg1500");
8745   myquery(rc);
8746 
8747   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM");
8748   myquery(rc);
8749 
8750   rc= mysql_query(mysql,
8751         "INSERT INTO test_bg1500 VALUES ('Gravedigger'), ('Greed'), ('Hollow Dogs')");
8752   myquery(rc);
8753 
8754   rc= mysql_commit(mysql);
8755   myquery(rc);
8756 
8757   stmt= mysql_simple_prepare(mysql,
8758           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)");
8759   check_stmt(stmt);
8760 
8761   verify_param_count(stmt, 1);
8762 
8763   data= "Dogs";
8764   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8765   my_bind[0].buffer= (void *) data;
8766   my_bind[0].buffer_length= strlen(data);
8767   my_bind[0].is_null= 0;
8768   my_bind[0].length= 0;
8769 
8770   rc= mysql_stmt_bind_param(stmt, my_bind);
8771   check_execute(stmt, rc);
8772 
8773   rc= mysql_stmt_execute(stmt);
8774   check_execute(stmt, rc);
8775 
8776   rc= my_process_stmt_result(stmt);
8777   DIE_UNLESS(rc == 1);
8778 
8779   mysql_stmt_close(stmt);
8780 
8781   /* This should work too */
8782   stmt= mysql_simple_prepare(mysql,
8783           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?, 'digger'))");
8784   check_stmt(stmt);
8785 
8786   verify_param_count(stmt, 1);
8787 
8788   data= "Grave";
8789   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8790   my_bind[0].buffer= (void *) data;
8791   my_bind[0].buffer_length= strlen(data);
8792 
8793   rc= mysql_stmt_bind_param(stmt, my_bind);
8794   check_execute(stmt, rc);
8795 
8796   rc= mysql_stmt_execute(stmt);
8797   check_execute(stmt, rc);
8798 
8799   rc= my_process_stmt_result(stmt);
8800   DIE_UNLESS(rc == 1);
8801 
8802   mysql_stmt_close(stmt);
8803 }
8804 
8805 
test_bug1946()8806 static void test_bug1946()
8807 {
8808   MYSQL_STMT *stmt;
8809   int rc;
8810   const char *query= "INSERT INTO prepare_command VALUES (?)";
8811 
8812   myheader("test_bug1946");
8813 
8814   rc= mysql_query(mysql, "DROP TABLE IF EXISTS prepare_command");
8815   myquery(rc);
8816 
8817   rc= mysql_query(mysql, "CREATE TABLE prepare_command(ID INT)");
8818   myquery(rc);
8819 
8820   stmt= mysql_simple_prepare(mysql, query);
8821   check_stmt(stmt);
8822   rc= mysql_real_query(mysql, query, strlen(query));
8823   DIE_UNLESS(rc != 0);
8824   if (!opt_silent)
8825     fprintf(stdout, "Got error (as expected):\n");
8826   myerror(NULL);
8827 
8828   mysql_stmt_close(stmt);
8829   rc= mysql_query(mysql, "DROP TABLE prepare_command");
8830 }
8831 
8832 
test_parse_error_and_bad_length()8833 static void test_parse_error_and_bad_length()
8834 {
8835   MYSQL_STMT *stmt;
8836   int rc;
8837 
8838   /* check that we get 4 syntax errors over the 4 calls */
8839   myheader("test_parse_error_and_bad_length");
8840 
8841   rc= mysql_query(mysql, "SHOW DATABAAAA");
8842   DIE_UNLESS(rc);
8843   if (!opt_silent)
8844     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
8845   rc= mysql_real_query(mysql, "SHOW DATABASES", 100);
8846   DIE_UNLESS(rc);
8847   if (!opt_silent)
8848     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
8849 
8850   stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA");
8851   DIE_UNLESS(!stmt);
8852   if (!opt_silent)
8853     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
8854   stmt= mysql_stmt_init(mysql);
8855   DIE_UNLESS(stmt);
8856   rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 100);
8857   DIE_UNLESS(rc != 0);
8858   if (!opt_silent)
8859     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
8860   mysql_stmt_close(stmt);
8861 }
8862 
8863 
test_bug2247()8864 static void test_bug2247()
8865 {
8866   MYSQL_STMT *stmt;
8867   MYSQL_RES *res;
8868   int rc;
8869   int i;
8870   const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)";
8871   const char *insert= "INSERT INTO bug2247 VALUES (NULL)";
8872   const char *SELECT= "SELECT id FROM bug2247";
8873   const char *update= "UPDATE bug2247 SET id=id+10";
8874   const char *drop= "DROP TABLE IF EXISTS bug2247";
8875   ulonglong exp_count;
8876   enum { NUM_ROWS= 5 };
8877 
8878   myheader("test_bug2247");
8879 
8880   if (!opt_silent)
8881     fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
8882                   "mysql_query ... ");
8883   /* create table and insert few rows */
8884   rc= mysql_query(mysql, drop);
8885   myquery(rc);
8886 
8887   rc= mysql_query(mysql, create);
8888   myquery(rc);
8889 
8890   stmt= mysql_simple_prepare(mysql, insert);
8891   check_stmt(stmt);
8892   for (i= 0; i < NUM_ROWS; ++i)
8893   {
8894     rc= mysql_stmt_execute(stmt);
8895     check_execute(stmt, rc);
8896   }
8897   exp_count= mysql_stmt_affected_rows(stmt);
8898   DIE_UNLESS(exp_count == 1);
8899 
8900   rc= mysql_query(mysql, SELECT);
8901   myquery(rc);
8902   /*
8903     mysql_store_result overwrites mysql->affected_rows. Check that
8904     mysql_stmt_affected_rows() returns the same value, whereas
8905     mysql_affected_rows() value is correct.
8906   */
8907   res= mysql_store_result(mysql);
8908   mytest(res);
8909 
8910   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
8911   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
8912 
8913   rc= mysql_query(mysql, update);
8914   myquery(rc);
8915   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
8916   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
8917 
8918   mysql_free_result(res);
8919   mysql_stmt_close(stmt);
8920 
8921   /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */
8922   stmt= mysql_simple_prepare(mysql, SELECT);
8923   check_stmt(stmt);
8924 
8925   rc= mysql_stmt_execute(stmt);
8926   check_execute(stmt, rc);
8927   rc= mysql_stmt_store_result(stmt);
8928   check_execute(stmt, rc);
8929   exp_count= mysql_stmt_affected_rows(stmt);
8930   DIE_UNLESS(exp_count == NUM_ROWS);
8931 
8932   rc= mysql_query(mysql, insert);
8933   myquery(rc);
8934   DIE_UNLESS(mysql_affected_rows(mysql) == 1);
8935   DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count);
8936 
8937   mysql_stmt_close(stmt);
8938   if (!opt_silent)
8939     fprintf(stdout, "OK");
8940 }
8941 
8942 
test_subqueries()8943 static void test_subqueries()
8944 {
8945   MYSQL_STMT *stmt;
8946   int rc, i;
8947   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";
8948 
8949   myheader("test_subqueries");
8950 
8951   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
8952   myquery(rc);
8953 
8954   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
8955   myquery(rc);
8956 
8957   rc= mysql_query(mysql,
8958                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
8959   myquery(rc);
8960 
8961   rc= mysql_query(mysql, "create table t2 select * from t1;");
8962   myquery(rc);
8963 
8964   stmt= mysql_simple_prepare(mysql, query);
8965   check_stmt(stmt);
8966   for (i= 0; i < 3; i++)
8967   {
8968     rc= mysql_stmt_execute(stmt);
8969     check_execute(stmt, rc);
8970     rc= my_process_stmt_result(stmt);
8971     DIE_UNLESS(rc == 5);
8972   }
8973   mysql_stmt_close(stmt);
8974 
8975   rc= mysql_query(mysql, "DROP TABLE t1, t2");
8976   myquery(rc);
8977 }
8978 
8979 
test_bad_union()8980 static void test_bad_union()
8981 {
8982   MYSQL_STMT *stmt;
8983   const char *query= "SELECT 1, 2 union SELECT 1";
8984 
8985   myheader("test_bad_union");
8986 
8987   stmt= mysql_simple_prepare(mysql, query);
8988   DIE_UNLESS(stmt == 0);
8989   myerror(NULL);
8990 }
8991 
8992 
test_distinct()8993 static void test_distinct()
8994 {
8995   MYSQL_STMT *stmt;
8996   int rc, i;
8997   const char *query=
8998     "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a";
8999 
9000   myheader("test_distinct");
9001 
9002   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9003   myquery(rc);
9004 
9005   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9006   myquery(rc);
9007 
9008   rc= mysql_query(mysql,
9009                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), \
9010 (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);");
9011   myquery(rc);
9012 
9013   for (i= 0; i < 3; i++)
9014   {
9015     stmt= mysql_simple_prepare(mysql, query);
9016     check_stmt(stmt);
9017     rc= mysql_stmt_execute(stmt);
9018     check_execute(stmt, rc);
9019     rc= my_process_stmt_result(stmt);
9020     DIE_UNLESS(rc == 5);
9021     mysql_stmt_close(stmt);
9022   }
9023 
9024   rc= mysql_query(mysql, "DROP TABLE t1");
9025   myquery(rc);
9026 }
9027 
9028 
9029 /*
9030   Test for bug#2248 "mysql_fetch without prior mysql_stmt_execute hangs"
9031 */
9032 
test_bug2248()9033 static void test_bug2248()
9034 {
9035   MYSQL_STMT *stmt;
9036   int rc;
9037   const char *query1= "SELECT DATABASE()";
9038   const char *query2= "INSERT INTO test_bug2248 VALUES (10)";
9039 
9040   myheader("test_bug2248");
9041 
9042   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248");
9043   myquery(rc);
9044 
9045   rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)");
9046   myquery(rc);
9047 
9048   stmt= mysql_simple_prepare(mysql, query1);
9049   check_stmt(stmt);
9050 
9051   /* This should not hang */
9052   rc= mysql_stmt_fetch(stmt);
9053   check_execute_r(stmt, rc);
9054 
9055   /* And this too */
9056   rc= mysql_stmt_store_result(stmt);
9057   check_execute_r(stmt, rc);
9058 
9059   mysql_stmt_close(stmt);
9060 
9061   stmt= mysql_simple_prepare(mysql, query2);
9062   check_stmt(stmt);
9063 
9064   rc= mysql_stmt_execute(stmt);
9065   check_execute(stmt, rc);
9066 
9067   /* This too should not hang but should return proper error */
9068   rc= mysql_stmt_fetch(stmt);
9069   DIE_UNLESS(rc == 1);
9070 
9071   /* This too should not hang but should not bark */
9072   rc= mysql_stmt_store_result(stmt);
9073   check_execute(stmt, rc);
9074 
9075   /* This should return proper error */
9076   rc= mysql_stmt_fetch(stmt);
9077   check_execute_r(stmt, rc);
9078   DIE_UNLESS(rc == 1);
9079 
9080   mysql_stmt_close(stmt);
9081 
9082   rc= mysql_query(mysql, "DROP TABLE test_bug2248");
9083   myquery(rc);
9084 }
9085 
9086 
test_subqueries_ref()9087 static void test_subqueries_ref()
9088 {
9089   MYSQL_STMT *stmt;
9090   int rc, i;
9091   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)";
9092 
9093   myheader("test_subqueries_ref");
9094 
9095   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9096   myquery(rc);
9097 
9098   rc= mysql_query(mysql, "CREATE TABLE t1 (a int);");
9099   myquery(rc);
9100 
9101   rc= mysql_query(mysql,
9102                   "insert into t1 values (1), (2), (3), (4), (5);");
9103   myquery(rc);
9104 
9105   stmt= mysql_simple_prepare(mysql, query);
9106   check_stmt(stmt);
9107   for (i= 0; i < 3; i++)
9108   {
9109     rc= mysql_stmt_execute(stmt);
9110     check_execute(stmt, rc);
9111     rc= my_process_stmt_result(stmt);
9112     DIE_UNLESS(rc == 1);
9113   }
9114   mysql_stmt_close(stmt);
9115 
9116   rc= mysql_query(mysql, "DROP TABLE t1");
9117   myquery(rc);
9118 }
9119 
9120 
test_union()9121 static void test_union()
9122 {
9123   MYSQL_STMT *stmt;
9124   int rc;
9125 
9126   myheader("test_union");
9127 
9128   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9129   myquery(rc);
9130 
9131   rc= mysql_query(mysql,
9132                   "CREATE TABLE t1 "
9133                   "(id INTEGER NOT NULL PRIMARY KEY, "
9134                   " name VARCHAR(20) NOT NULL)");
9135   myquery(rc);
9136   rc= mysql_query(mysql,
9137                   "INSERT INTO t1 (id, name) VALUES "
9138                   "(2, 'Ja'), (3, 'Ede'), "
9139                   "(4, 'Haag'), (5, 'Kabul'), "
9140                   "(6, 'Almere'), (7, 'Utrecht'), "
9141                   "(8, 'Qandahar'), (9, 'Amsterdam'), "
9142                   "(10, 'Amersfoort'), (11, 'Constantine')");
9143   myquery(rc);
9144   rc= mysql_query(mysql,
9145                   "CREATE TABLE t2 "
9146                   "(id INTEGER NOT NULL PRIMARY KEY, "
9147                   " name VARCHAR(20) NOT NULL)");
9148   myquery(rc);
9149   rc= mysql_query(mysql,
9150                   "INSERT INTO t2 (id, name) VALUES "
9151                   "(4, 'Guam'), (5, 'Aruba'), "
9152                   "(6, 'Angola'), (7, 'Albania'), "
9153                   "(8, 'Anguilla'), (9, 'Argentina'), "
9154                   "(10, 'Azerbaijan'), (11, 'Afghanistan'), "
9155                   "(12, 'Burkina Faso'), (13, 'Faroe Islands')");
9156   myquery(rc);
9157 
9158   stmt= mysql_simple_prepare(mysql,
9159                              "SELECT t1.name FROM t1 UNION "
9160                              "SELECT t2.name FROM t2");
9161   check_stmt(stmt);
9162 
9163   rc= mysql_stmt_execute(stmt);
9164   check_execute(stmt, rc);
9165   rc= my_process_stmt_result(stmt);
9166   DIE_UNLESS(rc == 20);
9167   mysql_stmt_close(stmt);
9168 
9169   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9170   myquery(rc);
9171 }
9172 
9173 
test_bug3117()9174 static void test_bug3117()
9175 {
9176   MYSQL_STMT *stmt;
9177   MYSQL_BIND buffer;
9178   longlong lii;
9179   ulong length;
9180   my_bool is_null;
9181   int rc;
9182 
9183   myheader("test_bug3117");
9184 
9185   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9186   myquery(rc);
9187 
9188   rc= mysql_query(mysql, "CREATE TABLE t1 (id int auto_increment primary key)");
9189   myquery(rc);
9190 
9191   stmt= mysql_simple_prepare(mysql, "SELECT LAST_INSERT_ID()");
9192   check_stmt(stmt);
9193 
9194   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9195   myquery(rc);
9196 
9197   rc= mysql_stmt_execute(stmt);
9198   check_execute(stmt, rc);
9199 
9200   bzero((char*) &buffer, sizeof(buffer));
9201   buffer.buffer_type= MYSQL_TYPE_LONGLONG;
9202   buffer.buffer_length= sizeof(lii);
9203   buffer.buffer= (void *)&lii;
9204   buffer.length= &length;
9205   buffer.is_null= &is_null;
9206 
9207   rc= mysql_stmt_bind_result(stmt, &buffer);
9208   check_execute(stmt, rc);
9209 
9210   rc= mysql_stmt_store_result(stmt);
9211   check_execute(stmt, rc);
9212 
9213   rc= mysql_stmt_fetch(stmt);
9214   check_execute(stmt, rc);
9215 
9216   DIE_UNLESS(is_null == 0 && lii == 1);
9217   if (!opt_silent)
9218     fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
9219 
9220   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9221   myquery(rc);
9222 
9223   rc= mysql_stmt_execute(stmt);
9224   check_execute(stmt, rc);
9225 
9226   rc= mysql_stmt_fetch(stmt);
9227   check_execute(stmt, rc);
9228 
9229   DIE_UNLESS(is_null == 0 && lii == 2);
9230   if (!opt_silent)
9231     fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
9232 
9233   mysql_stmt_close(stmt);
9234 
9235   rc= mysql_query(mysql, "DROP TABLE t1");
9236   myquery(rc);
9237 }
9238 
9239 
test_join()9240 static void test_join()
9241 {
9242   MYSQL_STMT *stmt;
9243   int rc, i, j;
9244   const char *query[]= {"SELECT * FROM t2 join t1 on (t1.a=t2.a)",
9245                         "SELECT * FROM t2 natural join t1",
9246                         "SELECT * FROM t2 join t1 using(a)",
9247                         "SELECT * FROM t2 left join t1 on(t1.a=t2.a)",
9248                         "SELECT * FROM t2 natural left join t1",
9249                         "SELECT * FROM t2 left join t1 using(a)",
9250                         "SELECT * FROM t2 right join t1 on(t1.a=t2.a)",
9251                         "SELECT * FROM t2 natural right join t1",
9252                         "SELECT * FROM t2 right join t1 using(a)"};
9253 
9254   myheader("test_join");
9255 
9256   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9257   myquery(rc);
9258 
9259   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9260   myquery(rc);
9261 
9262   rc= mysql_query(mysql,
9263                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9264   myquery(rc);
9265 
9266   rc= mysql_query(mysql, "CREATE TABLE t2 (a int , c int);");
9267   myquery(rc);
9268 
9269   rc= mysql_query(mysql,
9270                   "insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9271   myquery(rc);
9272 
9273   for (j= 0; j < 9; j++)
9274   {
9275     stmt= mysql_simple_prepare(mysql, query[j]);
9276     check_stmt(stmt);
9277     for (i= 0; i < 3; i++)
9278     {
9279       rc= mysql_stmt_execute(stmt);
9280       check_execute(stmt, rc);
9281       rc= my_process_stmt_result(stmt);
9282       DIE_UNLESS(rc == 5);
9283     }
9284     mysql_stmt_close(stmt);
9285   }
9286 
9287   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9288   myquery(rc);
9289 }
9290 
9291 
test_selecttmp()9292 static void test_selecttmp()
9293 {
9294   MYSQL_STMT *stmt;
9295   int rc, i;
9296   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";
9297 
9298   myheader("test_select_tmp");
9299 
9300   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3");
9301   myquery(rc);
9302 
9303   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9304   myquery(rc);
9305 
9306   rc= mysql_query(mysql, "create table t2 (a int, b int);");
9307   myquery(rc);
9308 
9309   rc= mysql_query(mysql, "create table t3 (a int, b int);");
9310   myquery(rc);
9311 
9312   rc= mysql_query(mysql,
9313                   "insert into t1 values (0, 100), (1, 2), (1, 3), (2, 2), (2, 7), \
9314 (2, -1), (3, 10);");
9315   myquery(rc);
9316   rc= mysql_query(mysql,
9317                   "insert into t2 values (0, 0), (1, 1), (2, 1), (3, 1), (4, 1);");
9318   myquery(rc);
9319   rc= mysql_query(mysql,
9320                   "insert into t3 values (3, 3), (2, 2), (1, 1);");
9321   myquery(rc);
9322 
9323   stmt= mysql_simple_prepare(mysql, query);
9324   check_stmt(stmt);
9325   for (i= 0; i < 3; i++)
9326   {
9327     rc= mysql_stmt_execute(stmt);
9328     check_execute(stmt, rc);
9329     rc= my_process_stmt_result(stmt);
9330     DIE_UNLESS(rc == 3);
9331   }
9332   mysql_stmt_close(stmt);
9333 
9334   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3");
9335   myquery(rc);
9336 }
9337 
9338 
test_create_drop()9339 static void test_create_drop()
9340 {
9341   MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select;
9342   char *query;
9343   int rc, i;
9344   myheader("test_table_manipulation");
9345 
9346   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9347   myquery(rc);
9348 
9349   rc= mysql_query(mysql, "create table t2 (a int);");
9350   myquery(rc);
9351 
9352   rc= mysql_query(mysql, "create table t1 (a int);");
9353   myquery(rc);
9354 
9355   rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);");
9356   myquery(rc);
9357 
9358   query= (char*)"create table t1 (a int)";
9359   stmt_create= mysql_simple_prepare(mysql, query);
9360   check_stmt(stmt_create);
9361 
9362   query= (char*)"drop table t1";
9363   stmt_drop= mysql_simple_prepare(mysql, query);
9364   check_stmt(stmt_drop);
9365 
9366   query= (char*)"select a in (select a from t2) from t1";
9367   stmt_select= mysql_simple_prepare(mysql, query);
9368   check_stmt(stmt_select);
9369 
9370   rc= mysql_query(mysql, "DROP TABLE t1");
9371   myquery(rc);
9372 
9373   query= (char*)"create table t1 select a from t2";
9374   stmt_create_select= mysql_simple_prepare(mysql, query);
9375   check_stmt(stmt_create_select);
9376 
9377   for (i= 0; i < 3; i++)
9378   {
9379     rc= mysql_stmt_execute(stmt_create);
9380     check_execute(stmt_create, rc);
9381     if (!opt_silent)
9382       fprintf(stdout, "created %i\n", i);
9383 
9384     rc= mysql_stmt_execute(stmt_select);
9385     check_execute(stmt_select, rc);
9386     rc= my_process_stmt_result(stmt_select);
9387     DIE_UNLESS(rc == 0);
9388 
9389     rc= mysql_stmt_execute(stmt_drop);
9390     check_execute(stmt_drop, rc);
9391     if (!opt_silent)
9392       fprintf(stdout, "dropped %i\n", i);
9393 
9394     rc= mysql_stmt_execute(stmt_create_select);
9395     check_execute(stmt_create, rc);
9396     if (!opt_silent)
9397       fprintf(stdout, "created select %i\n", i);
9398 
9399     rc= mysql_stmt_execute(stmt_select);
9400     check_execute(stmt_select, rc);
9401     rc= my_process_stmt_result(stmt_select);
9402     DIE_UNLESS(rc == 3);
9403 
9404     rc= mysql_stmt_execute(stmt_drop);
9405     check_execute(stmt_drop, rc);
9406     if (!opt_silent)
9407       fprintf(stdout, "dropped %i\n", i);
9408   }
9409 
9410   mysql_stmt_close(stmt_create);
9411   mysql_stmt_close(stmt_drop);
9412   mysql_stmt_close(stmt_select);
9413   mysql_stmt_close(stmt_create_select);
9414 
9415   rc= mysql_query(mysql, "DROP TABLE t2");
9416   myquery(rc);
9417 }
9418 
9419 
test_rename()9420 static void test_rename()
9421 {
9422   MYSQL_STMT *stmt;
9423   const char *query= "rename table t1 to t2, t3 to t4";
9424   int rc;
9425   myheader("test_table_rename");
9426 
9427   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
9428   myquery(rc);
9429 
9430   stmt= mysql_simple_prepare(mysql, query);
9431   check_stmt(stmt);
9432 
9433   rc= mysql_query(mysql, "create table t1 (a int)");
9434   myquery(rc);
9435 
9436   rc= mysql_stmt_execute(stmt);
9437   check_execute_r(stmt, rc);
9438   if (!opt_silent)
9439     fprintf(stdout, "rename without t3\n");
9440 
9441   rc= mysql_query(mysql, "create table t3 (a int)");
9442   myquery(rc);
9443 
9444   rc= mysql_stmt_execute(stmt);
9445   check_execute(stmt, rc);
9446   if (!opt_silent)
9447     fprintf(stdout, "rename with t3\n");
9448 
9449   rc= mysql_stmt_execute(stmt);
9450   check_execute_r(stmt, rc);
9451   if (!opt_silent)
9452     fprintf(stdout, "rename renamed\n");
9453 
9454   rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3");
9455   myquery(rc);
9456 
9457   rc= mysql_stmt_execute(stmt);
9458   check_execute(stmt, rc);
9459   if (!opt_silent)
9460     fprintf(stdout, "rename reverted\n");
9461 
9462   mysql_stmt_close(stmt);
9463 
9464   rc= mysql_query(mysql, "DROP TABLE t2, t4");
9465   myquery(rc);
9466 }
9467 
9468 
test_do_set()9469 static void test_do_set()
9470 {
9471   MYSQL_STMT *stmt_do, *stmt_set;
9472   char *query;
9473   int rc, i;
9474   myheader("test_do_set");
9475 
9476   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9477   myquery(rc);
9478 
9479   rc= mysql_query(mysql, "create table t1 (a int)");
9480   myquery(rc);
9481 
9482   query= (char*)"do @var:=(1 in (select * from t1))";
9483   stmt_do= mysql_simple_prepare(mysql, query);
9484   check_stmt(stmt_do);
9485 
9486   query= (char*)"set @var=(1 in (select * from t1))";
9487   stmt_set= mysql_simple_prepare(mysql, query);
9488   check_stmt(stmt_set);
9489 
9490   for (i= 0; i < 3; i++)
9491   {
9492     rc= mysql_stmt_execute(stmt_do);
9493     check_execute(stmt_do, rc);
9494     if (!opt_silent)
9495       fprintf(stdout, "do %i\n", i);
9496     rc= mysql_stmt_execute(stmt_set);
9497     check_execute(stmt_set, rc);
9498     if (!opt_silent)
9499       fprintf(stdout, "set %i\n", i);
9500   }
9501 
9502   mysql_stmt_close(stmt_do);
9503   mysql_stmt_close(stmt_set);
9504 }
9505 
9506 
test_multi()9507 static void test_multi()
9508 {
9509   MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2;
9510   char *query;
9511   MYSQL_BIND my_bind[1];
9512   int rc, i;
9513   int32 param= 1;
9514   ulong length= 1;
9515   myheader("test_multi");
9516 
9517   /*
9518     We need to bzero bind structure because mysql_stmt_bind_param checks all
9519     its members.
9520   */
9521   bzero((char*) my_bind, sizeof(my_bind));
9522 
9523   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9524   my_bind[0].buffer= (void *)&param;
9525   my_bind[0].length= &length;
9526 
9527   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9528   myquery(rc);
9529 
9530   rc= mysql_query(mysql, "create table t1 (a int, b int)");
9531   myquery(rc);
9532 
9533   rc= mysql_query(mysql, "create table t2 (a int, b int)");
9534   myquery(rc);
9535 
9536   rc= mysql_query(mysql, "insert into t1 values (3, 3), (2, 2), (1, 1)");
9537   myquery(rc);
9538 
9539   rc= mysql_query(mysql, "insert into t2 values (3, 3), (2, 2), (1, 1)");
9540   myquery(rc);
9541 
9542   query= (char*)"delete t1, t2 from t1, t2 where t1.a=t2.a and t1.b=10";
9543   stmt_delete= mysql_simple_prepare(mysql, query);
9544   check_stmt(stmt_delete);
9545 
9546   query= (char*)"update t1, t2 set t1.b=10, t2.b=10 where t1.a=t2.a and t1.b=?";
9547   stmt_update= mysql_simple_prepare(mysql, query);
9548   check_stmt(stmt_update);
9549 
9550   query= (char*)"select * from t1";
9551   stmt_select1= mysql_simple_prepare(mysql, query);
9552   check_stmt(stmt_select1);
9553 
9554   query= (char*)"select * from t2";
9555   stmt_select2= mysql_simple_prepare(mysql, query);
9556   check_stmt(stmt_select2);
9557 
9558   for(i= 0; i < 3; i++)
9559   {
9560     rc= mysql_stmt_bind_param(stmt_update, my_bind);
9561     check_execute(stmt_update, rc);
9562 
9563     rc= mysql_stmt_execute(stmt_update);
9564     check_execute(stmt_update, rc);
9565     if (!opt_silent)
9566       fprintf(stdout, "update %ld\n", (long) param);
9567 
9568     rc= mysql_stmt_execute(stmt_delete);
9569     check_execute(stmt_delete, rc);
9570     if (!opt_silent)
9571       fprintf(stdout, "delete %ld\n", (long) param);
9572 
9573     rc= mysql_stmt_execute(stmt_select1);
9574     check_execute(stmt_select1, rc);
9575     rc= my_process_stmt_result(stmt_select1);
9576     DIE_UNLESS(rc == 3-param);
9577 
9578     rc= mysql_stmt_execute(stmt_select2);
9579     check_execute(stmt_select2, rc);
9580     rc= my_process_stmt_result(stmt_select2);
9581     DIE_UNLESS(rc == 3-param);
9582 
9583     param++;
9584   }
9585 
9586   mysql_stmt_close(stmt_delete);
9587   mysql_stmt_close(stmt_update);
9588   mysql_stmt_close(stmt_select1);
9589   mysql_stmt_close(stmt_select2);
9590   rc= mysql_query(mysql, "drop table t1, t2");
9591   myquery(rc);
9592 }
9593 
9594 
test_insert_select()9595 static void test_insert_select()
9596 {
9597   MYSQL_STMT *stmt_insert, *stmt_select;
9598   char *query;
9599   int rc;
9600   uint i;
9601   myheader("test_insert_select");
9602 
9603   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9604   myquery(rc);
9605 
9606   rc= mysql_query(mysql, "create table t1 (a int)");
9607   myquery(rc);
9608 
9609   rc= mysql_query(mysql, "create table t2 (a int)");
9610   myquery(rc);
9611 
9612   rc= mysql_query(mysql, "insert into t2 values (1)");
9613   myquery(rc);
9614 
9615   query= (char*)"insert into t1 select a from t2";
9616   stmt_insert= mysql_simple_prepare(mysql, query);
9617   check_stmt(stmt_insert);
9618 
9619   query= (char*)"select * from t1";
9620   stmt_select= mysql_simple_prepare(mysql, query);
9621   check_stmt(stmt_select);
9622 
9623   for(i= 0; i < 3; i++)
9624   {
9625     rc= mysql_stmt_execute(stmt_insert);
9626     check_execute(stmt_insert, rc);
9627     if (!opt_silent)
9628       fprintf(stdout, "insert %u\n", i);
9629 
9630     rc= mysql_stmt_execute(stmt_select);
9631     check_execute(stmt_select, rc);
9632     rc= my_process_stmt_result(stmt_select);
9633     DIE_UNLESS(rc == (int)(i+1));
9634   }
9635 
9636   mysql_stmt_close(stmt_insert);
9637   mysql_stmt_close(stmt_select);
9638   rc= mysql_query(mysql, "drop table t1, t2");
9639   myquery(rc);
9640 }
9641 
9642 
test_bind_nagative()9643 static void test_bind_nagative()
9644 {
9645   MYSQL_STMT *stmt_insert;
9646   char *query;
9647   int rc;
9648   MYSQL_BIND      my_bind[1];
9649   int32           my_val= 0;
9650   ulong           my_length= 0L;
9651   my_bool         my_null= FALSE;
9652   myheader("test_insert_select");
9653 
9654   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9655   myquery(rc);
9656 
9657   rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)");
9658   myquery(rc);
9659 
9660   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)");
9661   myquery(rc);
9662 
9663   query= (char*)"INSERT INTO t1 VALUES (?)";
9664   stmt_insert= mysql_simple_prepare(mysql, query);
9665   check_stmt(stmt_insert);
9666 
9667   /* bind parameters */
9668   bzero((char*) my_bind, sizeof(my_bind));
9669 
9670   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9671   my_bind[0].buffer= (void *)&my_val;
9672   my_bind[0].length= &my_length;
9673   my_bind[0].is_null= (char*)&my_null;
9674 
9675   rc= mysql_stmt_bind_param(stmt_insert, my_bind);
9676   check_execute(stmt_insert, rc);
9677 
9678   my_val= -1;
9679   rc= mysql_stmt_execute(stmt_insert);
9680   check_execute(stmt_insert, rc);
9681 
9682   mysql_stmt_close(stmt_insert);
9683   rc= mysql_query(mysql, "drop table t1");
9684   myquery(rc);
9685 }
9686 
9687 
test_derived()9688 static void test_derived()
9689 {
9690   MYSQL_STMT *stmt;
9691   int rc, i;
9692   MYSQL_BIND      my_bind[1];
9693   int32           my_val= 0;
9694   ulong           my_length= 0L;
9695   my_bool         my_null= FALSE;
9696   const char *query=
9697     "select count(1) from (select f.id from t1 f where f.id=?) as x";
9698 
9699   myheader("test_derived");
9700 
9701   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9702   myquery(rc);
9703 
9704   rc= mysql_query(mysql, "create table t1 (id  int(8), primary key (id)) \
9705 ENGINE=InnoDB DEFAULT CHARSET=utf8");
9706   myquery(rc);
9707 
9708   rc= mysql_query(mysql, "insert into t1 values (1)");
9709   myquery(rc);
9710 
9711   stmt= mysql_simple_prepare(mysql, query);
9712   check_stmt(stmt);
9713   /*
9714     We need to bzero bind structure because mysql_stmt_bind_param checks all
9715     its members.
9716   */
9717   bzero((char*) my_bind, sizeof(my_bind));
9718 
9719   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9720   my_bind[0].buffer= (void *)&my_val;
9721   my_bind[0].length= &my_length;
9722   my_bind[0].is_null= (char*)&my_null;
9723   my_val= 1;
9724   rc= mysql_stmt_bind_param(stmt, my_bind);
9725   check_execute(stmt, rc);
9726 
9727   for (i= 0; i < 3; i++)
9728   {
9729     rc= mysql_stmt_execute(stmt);
9730     check_execute(stmt, rc);
9731     rc= my_process_stmt_result(stmt);
9732     DIE_UNLESS(rc == 1);
9733   }
9734   mysql_stmt_close(stmt);
9735 
9736   rc= mysql_query(mysql, "DROP TABLE t1");
9737   myquery(rc);
9738 }
9739 
9740 
test_xjoin()9741 static void test_xjoin()
9742 {
9743   MYSQL_STMT *stmt;
9744   int rc, i;
9745   const char *query=
9746     "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";
9747 
9748   myheader("test_xjoin");
9749 
9750   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
9751   myquery(rc);
9752 
9753   rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
9754   myquery(rc);
9755 
9756   rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
9757   myquery(rc);
9758 
9759   rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
9760   myquery(rc);
9761 
9762   rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
9763   myquery(rc);
9764 
9765   rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)");
9766   myquery(rc);
9767 
9768   rc= mysql_query(mysql, "insert into t1 values (1, 1, 'aaa'), (2, null, 'bbb')");
9769   myquery(rc);
9770 
9771   rc= mysql_query(mysql, "insert into t2 values (1, 2, 'ccc')");
9772   myquery(rc);
9773 
9774   rc= mysql_query(mysql, "insert into t4 values (1, 'Name1'), (2, null)");
9775   myquery(rc);
9776 
9777   stmt= mysql_simple_prepare(mysql, query);
9778   check_stmt(stmt);
9779 
9780   for (i= 0; i < 3; i++)
9781   {
9782     rc= mysql_stmt_execute(stmt);
9783     check_execute(stmt, rc);
9784     rc= my_process_stmt_result(stmt);
9785     DIE_UNLESS(rc == 1);
9786   }
9787   mysql_stmt_close(stmt);
9788 
9789   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3, t4");
9790   myquery(rc);
9791 }
9792 
9793 
test_bug3035()9794 static void test_bug3035()
9795 {
9796   MYSQL_STMT *stmt;
9797   int rc;
9798   MYSQL_BIND bind_array[12], *my_bind= bind_array, *bind_end= my_bind + 12;
9799   int8 int8_val;
9800   uint8 uint8_val;
9801   int16 int16_val;
9802   uint16 uint16_val;
9803   int32 int32_val;
9804   uint32 uint32_val;
9805   longlong int64_val;
9806   ulonglong uint64_val;
9807   double double_val, udouble_val, double_tmp;
9808   char longlong_as_string[22], ulonglong_as_string[22];
9809 
9810   /* mins and maxes */
9811   const int8 int8_min= -128;
9812   const int8 int8_max= 127;
9813   const uint8 uint8_min= 0;
9814   const uint8 uint8_max= 255;
9815 
9816   const int16 int16_min= -32768;
9817   const int16 int16_max= 32767;
9818   const uint16 uint16_min= 0;
9819   const uint16 uint16_max= 65535;
9820 
9821   const int32 int32_max= 2147483647L;
9822   const int32 int32_min= -int32_max - 1;
9823   const uint32 uint32_min= 0;
9824   const uint32 uint32_max= 4294967295U;
9825 
9826   /* it might not work okay everyplace */
9827   const longlong int64_max= LL(9223372036854775807);
9828   const longlong int64_min= -int64_max - 1;
9829 
9830   const ulonglong uint64_min= 0U;
9831   const ulonglong uint64_max= ULL(18446744073709551615);
9832 
9833   const char *stmt_text;
9834 
9835   myheader("test_bug3035");
9836 
9837   stmt_text= "DROP TABLE IF EXISTS t1";
9838   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
9839   myquery(rc);
9840 
9841   stmt_text= "CREATE TABLE t1 (i8 TINYINT, ui8 TINYINT UNSIGNED, "
9842                               "i16 SMALLINT, ui16 SMALLINT UNSIGNED, "
9843                               "i32 INT, ui32 INT UNSIGNED, "
9844                               "i64 BIGINT, ui64 BIGINT UNSIGNED, "
9845                               "id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT)";
9846   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
9847   myquery(rc);
9848 
9849   bzero((char*) bind_array, sizeof(bind_array));
9850 
9851   for (my_bind= bind_array; my_bind < bind_end; my_bind++)
9852     my_bind->error= &my_bind->error_value;
9853 
9854   bind_array[0].buffer_type= MYSQL_TYPE_TINY;
9855   bind_array[0].buffer= (void *) &int8_val;
9856 
9857   bind_array[1].buffer_type= MYSQL_TYPE_TINY;
9858   bind_array[1].buffer= (void *) &uint8_val;
9859   bind_array[1].is_unsigned= 1;
9860 
9861   bind_array[2].buffer_type= MYSQL_TYPE_SHORT;
9862   bind_array[2].buffer= (void *) &int16_val;
9863 
9864   bind_array[3].buffer_type= MYSQL_TYPE_SHORT;
9865   bind_array[3].buffer= (void *) &uint16_val;
9866   bind_array[3].is_unsigned= 1;
9867 
9868   bind_array[4].buffer_type= MYSQL_TYPE_LONG;
9869   bind_array[4].buffer= (void *) &int32_val;
9870 
9871   bind_array[5].buffer_type= MYSQL_TYPE_LONG;
9872   bind_array[5].buffer= (void *) &uint32_val;
9873   bind_array[5].is_unsigned= 1;
9874 
9875   bind_array[6].buffer_type= MYSQL_TYPE_LONGLONG;
9876   bind_array[6].buffer= (void *) &int64_val;
9877 
9878   bind_array[7].buffer_type= MYSQL_TYPE_LONGLONG;
9879   bind_array[7].buffer= (void *) &uint64_val;
9880   bind_array[7].is_unsigned= 1;
9881 
9882   stmt= mysql_stmt_init(mysql);
9883   check_stmt(stmt);
9884 
9885   stmt_text= "INSERT INTO t1 (i8, ui8, i16, ui16, i32, ui32, i64, ui64) "
9886                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
9887   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
9888   check_execute(stmt, rc);
9889 
9890   mysql_stmt_bind_param(stmt, bind_array);
9891 
9892   int8_val= int8_min;
9893   uint8_val= uint8_min;
9894   int16_val= int16_min;
9895   uint16_val= uint16_min;
9896   int32_val= int32_min;
9897   uint32_val= uint32_min;
9898   int64_val= int64_min;
9899   uint64_val= uint64_min;
9900 
9901   rc= mysql_stmt_execute(stmt);
9902   check_execute(stmt, rc);
9903 
9904   int8_val= int8_max;
9905   uint8_val= uint8_max;
9906   int16_val= int16_max;
9907   uint16_val= uint16_max;
9908   int32_val= int32_max;
9909   uint32_val= uint32_max;
9910   int64_val= int64_max;
9911   uint64_val= uint64_max;
9912 
9913   rc= mysql_stmt_execute(stmt);
9914   check_execute(stmt, rc);
9915 
9916   stmt_text= "SELECT i8, ui8, i16, ui16, i32, ui32, i64, ui64, ui64, "
9917              "cast(ui64 as signed), ui64, cast(ui64 as signed)"
9918              "FROM t1 ORDER BY id ASC";
9919 
9920   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
9921   check_execute(stmt, rc);
9922 
9923   rc= mysql_stmt_execute(stmt);
9924   check_execute(stmt, rc);
9925 
9926   bind_array[8].buffer_type= MYSQL_TYPE_DOUBLE;
9927   bind_array[8].buffer= (void *) &udouble_val;
9928 
9929   bind_array[9].buffer_type= MYSQL_TYPE_DOUBLE;
9930   bind_array[9].buffer= (void *) &double_val;
9931 
9932   bind_array[10].buffer_type= MYSQL_TYPE_STRING;
9933   bind_array[10].buffer= (void *) &ulonglong_as_string;
9934   bind_array[10].buffer_length= sizeof(ulonglong_as_string);
9935 
9936   bind_array[11].buffer_type= MYSQL_TYPE_STRING;
9937   bind_array[11].buffer= (void *) &longlong_as_string;
9938   bind_array[11].buffer_length= sizeof(longlong_as_string);
9939 
9940   mysql_stmt_bind_result(stmt, bind_array);
9941 
9942   rc= mysql_stmt_fetch(stmt);
9943   check_execute(stmt, rc);
9944 
9945   DIE_UNLESS(int8_val == int8_min);
9946   DIE_UNLESS(uint8_val == uint8_min);
9947   DIE_UNLESS(int16_val == int16_min);
9948   DIE_UNLESS(uint16_val == uint16_min);
9949   DIE_UNLESS(int32_val == int32_min);
9950   DIE_UNLESS(uint32_val == uint32_min);
9951   DIE_UNLESS(int64_val == int64_min);
9952   DIE_UNLESS(uint64_val == uint64_min);
9953   DIE_UNLESS(double_val == (longlong) uint64_min);
9954   double_tmp= ulonglong2double(uint64_val);
9955   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
9956   DIE_UNLESS(!strcmp(longlong_as_string, "0"));
9957   DIE_UNLESS(!strcmp(ulonglong_as_string, "0"));
9958 
9959   rc= mysql_stmt_fetch(stmt);
9960 
9961   if (!opt_silent)
9962   {
9963     printf("Truncation mask: ");
9964     for (my_bind= bind_array; my_bind < bind_end; my_bind++)
9965       printf("%d", (int) my_bind->error_value);
9966     printf("\n");
9967   }
9968   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0);
9969 
9970   DIE_UNLESS(int8_val == int8_max);
9971   DIE_UNLESS(uint8_val == uint8_max);
9972   DIE_UNLESS(int16_val == int16_max);
9973   DIE_UNLESS(uint16_val == uint16_max);
9974   DIE_UNLESS(int32_val == int32_max);
9975   DIE_UNLESS(uint32_val == uint32_max);
9976   DIE_UNLESS(int64_val == int64_max);
9977   DIE_UNLESS(uint64_val == uint64_max);
9978   DIE_UNLESS(double_val == (longlong) uint64_val);
9979   double_tmp= ulonglong2double(uint64_val);
9980   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
9981   DIE_UNLESS(!strcmp(longlong_as_string, "-1"));
9982   DIE_UNLESS(!strcmp(ulonglong_as_string, "18446744073709551615"));
9983 
9984   rc= mysql_stmt_fetch(stmt);
9985   DIE_UNLESS(rc == MYSQL_NO_DATA);
9986 
9987   mysql_stmt_close(stmt);
9988 
9989   stmt_text= "DROP TABLE t1";
9990   mysql_real_query(mysql, stmt_text, strlen(stmt_text));
9991 }
9992 
9993 
test_union2()9994 static void test_union2()
9995 {
9996   MYSQL_STMT *stmt;
9997   int rc, i;
9998 
9999   myheader("test_union2");
10000 
10001   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10002   myquery(rc);
10003 
10004   rc= mysql_query(mysql, "CREATE TABLE t1(col1 INT, \
10005                                          col2 VARCHAR(40),      \
10006                                          col3 SMALLINT, \
10007                                          col4 TIMESTAMP)");
10008   myquery(rc);
10009 
10010   stmt= mysql_simple_prepare(mysql,
10011                              "select col1 FROM t1 where col1=1 union distinct "
10012                              "select col1 FROM t1 where col1=2");
10013   check_stmt(stmt);
10014 
10015   for (i= 0; i < 3; i++)
10016   {
10017     rc= mysql_stmt_execute(stmt);
10018     check_execute(stmt, rc);
10019     rc= my_process_stmt_result(stmt);
10020     DIE_UNLESS(rc == 0);
10021   }
10022 
10023   mysql_stmt_close(stmt);
10024 
10025   rc= mysql_query(mysql, "DROP TABLE t1");
10026   myquery(rc);
10027 }
10028 
10029 
10030 /*
10031   This tests for various mysql_stmt_send_long_data bugs described in #1664
10032 */
10033 
test_bug1664()10034 static void test_bug1664()
10035 {
10036     MYSQL_STMT *stmt;
10037     int        rc, int_data;
10038     const char *data;
10039     const char *str_data= "Simple string";
10040     MYSQL_BIND my_bind[2];
10041     const char *query= "INSERT INTO test_long_data(col2, col1) VALUES(?, ?)";
10042 
10043     myheader("test_bug1664");
10044 
10045     rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
10046     myquery(rc);
10047 
10048     rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, col2 long varchar)");
10049     myquery(rc);
10050 
10051     stmt= mysql_stmt_init(mysql);
10052     check_stmt(stmt);
10053     rc= mysql_stmt_prepare(stmt, query, strlen(query));
10054     check_execute(stmt, rc);
10055 
10056     verify_param_count(stmt, 2);
10057 
10058     bzero((char*) my_bind, sizeof(my_bind));
10059 
10060     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10061     my_bind[0].buffer= (void *)str_data;
10062     my_bind[0].buffer_length= strlen(str_data);
10063 
10064     my_bind[1].buffer= (void *)&int_data;
10065     my_bind[1].buffer_type= MYSQL_TYPE_LONG;
10066 
10067     rc= mysql_stmt_bind_param(stmt, my_bind);
10068     check_execute(stmt, rc);
10069 
10070     int_data= 1;
10071 
10072     /*
10073       Let us supply empty long_data. This should work and should
10074       not break following execution.
10075     */
10076     data= "";
10077     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10078     check_execute(stmt, rc);
10079 
10080     rc= mysql_stmt_execute(stmt);
10081     check_execute(stmt, rc);
10082 
10083     verify_col_data("test_long_data", "col1", "1");
10084     verify_col_data("test_long_data", "col2", "");
10085 
10086     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10087     myquery(rc);
10088 
10089     /* This should pass OK */
10090     data= (char *)"Data";
10091     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10092     check_execute(stmt, rc);
10093 
10094     rc= mysql_stmt_execute(stmt);
10095     check_execute(stmt, rc);
10096 
10097     verify_col_data("test_long_data", "col1", "1");
10098     verify_col_data("test_long_data", "col2", "Data");
10099 
10100     /* clean up */
10101     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10102     myquery(rc);
10103 
10104     /*
10105       Now we are changing int parameter and don't do anything
10106       with first parameter. Second mysql_stmt_execute() should run
10107       OK treating this first parameter as string parameter.
10108     */
10109 
10110     int_data= 2;
10111     /* execute */
10112     rc= mysql_stmt_execute(stmt);
10113     check_execute(stmt, rc);
10114 
10115     verify_col_data("test_long_data", "col1", "2");
10116     verify_col_data("test_long_data", "col2", str_data);
10117 
10118     /* clean up */
10119     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10120     myquery(rc);
10121 
10122     /*
10123       Now we are sending other long data. It should not be
10124       concatened to previous.
10125     */
10126 
10127     data= (char *)"SomeOtherData";
10128     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10129     check_execute(stmt, rc);
10130 
10131     rc= mysql_stmt_execute(stmt);
10132     check_execute(stmt, rc);
10133 
10134     verify_col_data("test_long_data", "col1", "2");
10135     verify_col_data("test_long_data", "col2", "SomeOtherData");
10136 
10137     mysql_stmt_close(stmt);
10138 
10139     /* clean up */
10140     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10141     myquery(rc);
10142 
10143     /* Now let us test how mysql_stmt_reset works. */
10144     stmt= mysql_stmt_init(mysql);
10145     check_stmt(stmt);
10146     rc= mysql_stmt_prepare(stmt, query, strlen(query));
10147     check_execute(stmt, rc);
10148     rc= mysql_stmt_bind_param(stmt, my_bind);
10149     check_execute(stmt, rc);
10150 
10151     data= (char *)"SomeData";
10152     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10153     check_execute(stmt, rc);
10154 
10155     rc= mysql_stmt_reset(stmt);
10156     check_execute(stmt, rc);
10157 
10158     rc= mysql_stmt_execute(stmt);
10159     check_execute(stmt, rc);
10160 
10161     verify_col_data("test_long_data", "col1", "2");
10162     verify_col_data("test_long_data", "col2", str_data);
10163 
10164     mysql_stmt_close(stmt);
10165 
10166     /* Final clean up */
10167     rc= mysql_query(mysql, "DROP TABLE test_long_data");
10168     myquery(rc);
10169 }
10170 
10171 
test_order_param()10172 static void test_order_param()
10173 {
10174   MYSQL_STMT *stmt;
10175   int rc;
10176 
10177   myheader("test_order_param");
10178 
10179   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10180   myquery(rc);
10181 
10182   rc= mysql_query(mysql, "CREATE TABLE t1(a INT, b char(10))");
10183   myquery(rc);
10184 
10185   stmt= mysql_simple_prepare(mysql,
10186                              "select sum(a) + 200, 1 from t1 "
10187                              " union distinct "
10188                              "select sum(a) + 200, 1 from t1 group by b ");
10189   check_stmt(stmt);
10190   mysql_stmt_close(stmt);
10191 
10192   stmt= mysql_simple_prepare(mysql,
10193                              "select sum(a) + 200, ? from t1 group by b "
10194                              " union distinct "
10195                              "select sum(a) + 200, 1 from t1 group by b ");
10196   check_stmt(stmt);
10197   mysql_stmt_close(stmt);
10198 
10199   stmt= mysql_simple_prepare(mysql,
10200                              "select sum(a) + 200, ? from t1 "
10201                              " union distinct "
10202                              "select sum(a) + 200, 1 from t1 group by b ");
10203   check_stmt(stmt);
10204   mysql_stmt_close(stmt);
10205 
10206   rc= mysql_query(mysql, "DROP TABLE t1");
10207   myquery(rc);
10208 }
10209 
10210 
test_union_param()10211 static void test_union_param()
10212 {
10213   MYSQL_STMT *stmt;
10214   char *query;
10215   int rc, i;
10216   MYSQL_BIND      my_bind[2];
10217   char            my_val[4];
10218   ulong           my_length= 3L;
10219   my_bool         my_null= FALSE;
10220   myheader("test_union_param");
10221 
10222   strmov(my_val, "abc");
10223 
10224   query= (char*)"select ? as my_col union distinct select ?";
10225   stmt= mysql_simple_prepare(mysql, query);
10226   check_stmt(stmt);
10227 
10228   /*
10229     We need to bzero bind structure because mysql_stmt_bind_param checks all
10230     its members.
10231   */
10232   bzero((char*) my_bind, sizeof(my_bind));
10233 
10234   /* bind parameters */
10235   my_bind[0].buffer_type=    MYSQL_TYPE_STRING;
10236   my_bind[0].buffer=         (char*) &my_val;
10237   my_bind[0].buffer_length=  4;
10238   my_bind[0].length=         &my_length;
10239   my_bind[0].is_null=        (char*)&my_null;
10240   my_bind[1].buffer_type=    MYSQL_TYPE_STRING;
10241   my_bind[1].buffer=         (char*) &my_val;
10242   my_bind[1].buffer_length=  4;
10243   my_bind[1].length=         &my_length;
10244   my_bind[1].is_null=        (char*)&my_null;
10245 
10246   rc= mysql_stmt_bind_param(stmt, my_bind);
10247   check_execute(stmt, rc);
10248 
10249   for (i= 0; i < 3; i++)
10250   {
10251     rc= mysql_stmt_execute(stmt);
10252     check_execute(stmt, rc);
10253     rc= my_process_stmt_result(stmt);
10254     DIE_UNLESS(rc == 1);
10255   }
10256 
10257   mysql_stmt_close(stmt);
10258 }
10259 
10260 
test_ps_i18n()10261 static void test_ps_i18n()
10262 {
10263   MYSQL_STMT *stmt;
10264   int rc;
10265   const char *stmt_text;
10266   MYSQL_BIND bind_array[2];
10267 
10268   /* Represented as numbers to keep UTF8 tools from clobbering them. */
10269   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
10270   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
10271   char buf1[16], buf2[16];
10272   ulong buf1_len, buf2_len;
10273 
10274 
10275   myheader("test_ps_i18n");
10276 
10277   stmt_text= "DROP TABLE IF EXISTS t1";
10278   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10279   myquery(rc);
10280 
10281   /*
10282     Create table with binary columns, set session character set to cp1251,
10283     client character set to koi8, and make sure that there is conversion
10284     on insert and no conversion on select
10285   */
10286 
10287   stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
10288 
10289   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10290   myquery(rc);
10291 
10292   stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
10293                  "CHARACTER_SET_CONNECTION=cp1251, "
10294                  "CHARACTER_SET_RESULTS=koi8r";
10295 
10296   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10297   myquery(rc);
10298 
10299   bzero((char*) bind_array, sizeof(bind_array));
10300 
10301   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10302   bind_array[0].buffer= (void *) koi8;
10303   bind_array[0].buffer_length= strlen(koi8);
10304 
10305   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10306   bind_array[1].buffer= (void *) koi8;
10307   bind_array[1].buffer_length= strlen(koi8);
10308 
10309   stmt= mysql_stmt_init(mysql);
10310   check_stmt(stmt);
10311 
10312   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10313 
10314   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10315   check_execute(stmt, rc);
10316 
10317   mysql_stmt_bind_param(stmt, bind_array);
10318 
10319   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10320 
10321   rc= mysql_stmt_execute(stmt);
10322   check_execute(stmt, rc);
10323 
10324   stmt_text= "SELECT c1, c2 FROM t1";
10325 
10326   /* c1 and c2 are binary so no conversion will be done on select */
10327   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10328   check_execute(stmt, rc);
10329 
10330   rc= mysql_stmt_execute(stmt);
10331   check_execute(stmt, rc);
10332 
10333   bind_array[0].buffer= buf1;
10334   bind_array[0].buffer_length= sizeof(buf1);
10335   bind_array[0].length= &buf1_len;
10336 
10337   bind_array[1].buffer= buf2;
10338   bind_array[1].buffer_length= sizeof(buf2);
10339   bind_array[1].length= &buf2_len;
10340 
10341   mysql_stmt_bind_result(stmt, bind_array);
10342 
10343   rc= mysql_stmt_fetch(stmt);
10344   check_execute(stmt, rc);
10345 
10346   DIE_UNLESS(buf1_len == strlen(cp1251));
10347   DIE_UNLESS(buf2_len == strlen(cp1251));
10348   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
10349   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
10350 
10351   rc= mysql_stmt_fetch(stmt);
10352   DIE_UNLESS(rc == MYSQL_NO_DATA);
10353 
10354   stmt_text= "DROP TABLE IF EXISTS t1";
10355   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10356   myquery(rc);
10357 
10358   /*
10359     Now create table with two cp1251 columns, set client character
10360     set to koi8 and supply columns of one row as string and another as
10361     binary data. Binary data must not be converted on insert, and both
10362     columns must be converted to client character set on select.
10363   */
10364 
10365   stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
10366                               "c2 VARCHAR(255) CHARACTER SET cp1251)";
10367 
10368   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10369   myquery(rc);
10370 
10371   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10372 
10373   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10374   check_execute(stmt, rc);
10375 
10376   /* this data must be converted */
10377   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10378   bind_array[0].buffer= (void *) koi8;
10379   bind_array[0].buffer_length= strlen(koi8);
10380 
10381   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10382   bind_array[1].buffer= (void *) koi8;
10383   bind_array[1].buffer_length= strlen(koi8);
10384 
10385   mysql_stmt_bind_param(stmt, bind_array);
10386 
10387   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10388 
10389   rc= mysql_stmt_execute(stmt);
10390   check_execute(stmt, rc);
10391 
10392   /* this data must not be converted */
10393   bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
10394   bind_array[0].buffer= (void *) cp1251;
10395   bind_array[0].buffer_length= strlen(cp1251);
10396 
10397   bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
10398   bind_array[1].buffer= (void *) cp1251;
10399   bind_array[1].buffer_length= strlen(cp1251);
10400 
10401   mysql_stmt_bind_param(stmt, bind_array);
10402 
10403   mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251));
10404 
10405   rc= mysql_stmt_execute(stmt);
10406   check_execute(stmt, rc);
10407 
10408   /* Fetch data and verify that rows are in koi8 */
10409 
10410   stmt_text= "SELECT c1, c2 FROM t1";
10411 
10412   /* c1 and c2 are binary so no conversion will be done on select */
10413   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10414   check_execute(stmt, rc);
10415 
10416   rc= mysql_stmt_execute(stmt);
10417   check_execute(stmt, rc);
10418 
10419   bind_array[0].buffer= buf1;
10420   bind_array[0].buffer_length= sizeof(buf1);
10421   bind_array[0].length= &buf1_len;
10422 
10423   bind_array[1].buffer= buf2;
10424   bind_array[1].buffer_length= sizeof(buf2);
10425   bind_array[1].length= &buf2_len;
10426 
10427   mysql_stmt_bind_result(stmt, bind_array);
10428 
10429   while ((rc= mysql_stmt_fetch(stmt)) == 0)
10430   {
10431     DIE_UNLESS(buf1_len == strlen(koi8));
10432     DIE_UNLESS(buf2_len == strlen(koi8));
10433     DIE_UNLESS(!memcmp(buf1, koi8, buf1_len));
10434     DIE_UNLESS(!memcmp(buf2, koi8, buf1_len));
10435   }
10436   DIE_UNLESS(rc == MYSQL_NO_DATA);
10437   mysql_stmt_close(stmt);
10438 
10439   stmt_text= "DROP TABLE t1";
10440   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10441   myquery(rc);
10442   stmt_text= "SET NAMES DEFAULT";
10443   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10444   myquery(rc);
10445 }
10446 
10447 
test_bug3796()10448 static void test_bug3796()
10449 {
10450   MYSQL_STMT *stmt;
10451   MYSQL_BIND my_bind[1];
10452   const char *concat_arg0= "concat_with_";
10453   enum { OUT_BUFF_SIZE= 30 };
10454   char out_buff[OUT_BUFF_SIZE];
10455   char canonical_buff[OUT_BUFF_SIZE];
10456   ulong out_length;
10457   const char *stmt_text;
10458   int rc;
10459 
10460   myheader("test_bug3796");
10461 
10462   /* Create and fill test table */
10463   stmt_text= "DROP TABLE IF EXISTS t1";
10464   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10465   myquery(rc);
10466 
10467   stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))";
10468   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10469   myquery(rc);
10470 
10471   stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')";
10472   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10473   myquery(rc);
10474 
10475   /* Create statement handle and prepare it with select */
10476   stmt= mysql_stmt_init(mysql);
10477   stmt_text= "SELECT concat(?, b) FROM t1";
10478 
10479   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10480   check_execute(stmt, rc);
10481 
10482   /* Bind input buffers */
10483   bzero((char*) my_bind, sizeof(my_bind));
10484 
10485   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10486   my_bind[0].buffer= (void *) concat_arg0;
10487   my_bind[0].buffer_length= strlen(concat_arg0);
10488 
10489   mysql_stmt_bind_param(stmt, my_bind);
10490 
10491   /* Execute the select statement */
10492   rc= mysql_stmt_execute(stmt);
10493   check_execute(stmt, rc);
10494 
10495   my_bind[0].buffer= (void *) out_buff;
10496   my_bind[0].buffer_length= OUT_BUFF_SIZE;
10497   my_bind[0].length= &out_length;
10498 
10499   mysql_stmt_bind_result(stmt, my_bind);
10500 
10501   rc= mysql_stmt_fetch(stmt);
10502   if (!opt_silent)
10503     printf("Concat result: '%s'\n", out_buff);
10504   check_execute(stmt, rc);
10505   strmov(canonical_buff, concat_arg0);
10506   strcat(canonical_buff, "ONE");
10507   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10508          strncmp(out_buff, canonical_buff, out_length) == 0);
10509 
10510   rc= mysql_stmt_fetch(stmt);
10511   check_execute(stmt, rc);
10512   strmov(canonical_buff + strlen(concat_arg0), "TWO");
10513   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10514          strncmp(out_buff, canonical_buff, out_length) == 0);
10515   if (!opt_silent)
10516     printf("Concat result: '%s'\n", out_buff);
10517 
10518   rc= mysql_stmt_fetch(stmt);
10519   DIE_UNLESS(rc == MYSQL_NO_DATA);
10520 
10521   mysql_stmt_close(stmt);
10522 
10523   stmt_text= "DROP TABLE IF EXISTS t1";
10524   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10525   myquery(rc);
10526 }
10527 
10528 
test_bug4026()10529 static void test_bug4026()
10530 {
10531   MYSQL_STMT *stmt;
10532   MYSQL_BIND my_bind[2];
10533   MYSQL_TIME time_in, time_out;
10534   MYSQL_TIME datetime_in, datetime_out;
10535   const char *stmt_text;
10536   int rc;
10537 
10538   myheader("test_bug4026");
10539 
10540   /* Check that microseconds are inserted and selected successfully */
10541 
10542   /* Create a statement handle and prepare it with select */
10543   stmt= mysql_stmt_init(mysql);
10544   stmt_text= "SELECT ?, ?";
10545 
10546   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10547   check_execute(stmt, rc);
10548 
10549   /* Bind input buffers */
10550   bzero((char*) my_bind, sizeof(my_bind));
10551   bzero((char*) &time_in, sizeof(time_in));
10552   bzero((char*) &time_out, sizeof(time_out));
10553   bzero((char*) &datetime_in, sizeof(datetime_in));
10554   bzero((char*) &datetime_out, sizeof(datetime_out));
10555 
10556   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
10557   my_bind[0].buffer= (void *) &time_in;
10558   my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
10559   my_bind[1].buffer= (void *) &datetime_in;
10560 
10561   time_in.hour= 23;
10562   time_in.minute= 59;
10563   time_in.second= 59;
10564   time_in.second_part= 123456;
10565   /*
10566     This is not necessary, just to make DIE_UNLESS below work: this field
10567     is filled in when time is received from server
10568   */
10569   time_in.time_type= MYSQL_TIMESTAMP_TIME;
10570 
10571   datetime_in= time_in;
10572   datetime_in.year= 2003;
10573   datetime_in.month= 12;
10574   datetime_in.day= 31;
10575   datetime_in.time_type= MYSQL_TIMESTAMP_DATETIME;
10576 
10577   mysql_stmt_bind_param(stmt, my_bind);
10578 
10579   /* Execute the select statement */
10580   rc= mysql_stmt_execute(stmt);
10581   check_execute(stmt, rc);
10582 
10583   my_bind[0].buffer= (void *) &time_out;
10584   my_bind[1].buffer= (void *) &datetime_out;
10585 
10586   mysql_stmt_bind_result(stmt, my_bind);
10587 
10588   rc= mysql_stmt_fetch(stmt);
10589   DIE_UNLESS(rc == 0);
10590   if (!opt_silent)
10591   {
10592     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
10593            time_out.second_part);
10594     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
10595            datetime_out.day, datetime_out.hour,
10596            datetime_out.minute, datetime_out.second,
10597            datetime_out.second_part);
10598   }
10599   DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0);
10600   DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0);
10601   mysql_stmt_close(stmt);
10602 }
10603 
10604 
test_bug4079()10605 static void test_bug4079()
10606 {
10607   MYSQL_STMT *stmt;
10608   MYSQL_BIND my_bind[1];
10609   const char *stmt_text;
10610   uint32 res;
10611   int rc;
10612 
10613   myheader("test_bug4079");
10614 
10615   /* Create and fill table */
10616   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10617   mysql_query(mysql, "CREATE TABLE t1 (a int)");
10618   mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2)");
10619 
10620   /* Prepare erroneous statement */
10621   stmt= mysql_stmt_init(mysql);
10622   stmt_text= "SELECT 1 < (SELECT a FROM t1)";
10623 
10624   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10625   check_execute(stmt, rc);
10626 
10627   /* Execute the select statement */
10628   rc= mysql_stmt_execute(stmt);
10629   check_execute(stmt, rc);
10630 
10631   /* Bind input buffers */
10632   bzero((char*) my_bind, sizeof(my_bind));
10633 
10634   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10635   my_bind[0].buffer= (void *) &res;
10636 
10637   mysql_stmt_bind_result(stmt, my_bind);
10638 
10639   rc= mysql_stmt_fetch(stmt);
10640   DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA);
10641   if (!opt_silent)
10642     printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
10643            mysql_stmt_error(stmt));
10644   /* buggy version of libmysql hanged up here */
10645   mysql_stmt_close(stmt);
10646 }
10647 
10648 
test_bug4236()10649 static void test_bug4236()
10650 {
10651   MYSQL_STMT *stmt;
10652   const char *stmt_text;
10653   int rc;
10654   MYSQL_STMT backup;
10655 
10656   myheader("test_bug4236");
10657 
10658   stmt= mysql_stmt_init(mysql);
10659 
10660   /* mysql_stmt_execute() of statement with statement id= 0 crashed server */
10661   stmt_text= "SELECT 1";
10662   /* We need to prepare statement to pass by possible check in libmysql */
10663   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10664   check_execute(stmt, rc);
10665   /* Hack to check that server works OK if statement wasn't found */
10666   backup.stmt_id= stmt->stmt_id;
10667   stmt->stmt_id= 0;
10668   rc= mysql_stmt_execute(stmt);
10669   DIE_UNLESS(rc);
10670   /* Restore original statement id to be able to reprepare it */
10671   stmt->stmt_id= backup.stmt_id;
10672 
10673   mysql_stmt_close(stmt);
10674 }
10675 
10676 
test_bug4030()10677 static void test_bug4030()
10678 {
10679   MYSQL_STMT *stmt;
10680   MYSQL_BIND my_bind[3];
10681   MYSQL_TIME time_canonical, time_out;
10682   MYSQL_TIME date_canonical, date_out;
10683   MYSQL_TIME datetime_canonical, datetime_out;
10684   const char *stmt_text;
10685   int rc;
10686 
10687   myheader("test_bug4030");
10688 
10689   /* Check that microseconds are inserted and selected successfully */
10690 
10691   /* Execute a query with time values in prepared mode */
10692   stmt= mysql_stmt_init(mysql);
10693   stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
10694              "'2003-12-31 23:59:59.123456'";
10695   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10696   check_execute(stmt, rc);
10697   rc= mysql_stmt_execute(stmt);
10698   check_execute(stmt, rc);
10699 
10700   /* Bind output buffers */
10701   bzero((char*) my_bind, sizeof(my_bind));
10702   bzero((char*) &time_canonical, sizeof(time_canonical));
10703   bzero((char*) &time_out, sizeof(time_out));
10704   bzero((char*) &date_canonical, sizeof(date_canonical));
10705   bzero((char*) &date_out, sizeof(date_out));
10706   bzero((char*) &datetime_canonical, sizeof(datetime_canonical));
10707   bzero((char*) &datetime_out, sizeof(datetime_out));
10708 
10709   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
10710   my_bind[0].buffer= (void *) &time_out;
10711   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
10712   my_bind[1].buffer= (void *) &date_out;
10713   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
10714   my_bind[2].buffer= (void *) &datetime_out;
10715 
10716   time_canonical.hour= 23;
10717   time_canonical.minute= 59;
10718   time_canonical.second= 59;
10719   time_canonical.second_part= 123456;
10720   time_canonical.time_type= MYSQL_TIMESTAMP_TIME;
10721 
10722   date_canonical.year= 2003;
10723   date_canonical.month= 12;
10724   date_canonical.day= 31;
10725   date_canonical.time_type= MYSQL_TIMESTAMP_DATE;
10726 
10727   datetime_canonical= time_canonical;
10728   datetime_canonical.year= 2003;
10729   datetime_canonical.month= 12;
10730   datetime_canonical.day= 31;
10731   datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME;
10732 
10733   mysql_stmt_bind_result(stmt, my_bind);
10734 
10735   rc= mysql_stmt_fetch(stmt);
10736   DIE_UNLESS(rc == 0);
10737   if (!opt_silent)
10738   {
10739     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
10740            time_out.second_part);
10741     printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
10742     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
10743            datetime_out.day, datetime_out.hour,
10744            datetime_out.minute, datetime_out.second,
10745            datetime_out.second_part);
10746   }
10747   DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
10748   DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
10749   DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
10750   mysql_stmt_close(stmt);
10751 }
10752 
test_view()10753 static void test_view()
10754 {
10755   MYSQL_STMT *stmt;
10756   int rc, i;
10757   MYSQL_BIND      my_bind[1];
10758   char            str_data[50];
10759   ulong           length = 0L;
10760   long            is_null = 0L;
10761   const char *query=
10762     "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
10763 
10764   myheader("test_view");
10765 
10766   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
10767   myquery(rc);
10768 
10769   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
10770   myquery(rc);
10771   rc= mysql_query(mysql,"CREATE TABLE t1 ("
10772                         " SERVERGRP varchar(20) NOT NULL default '', "
10773                         " DBINSTANCE varchar(20) NOT NULL default '', "
10774                         " PRIMARY KEY  (SERVERGRP)) "
10775                         " CHARSET=latin1 collate=latin1_bin");
10776   myquery(rc);
10777   rc= mysql_query(mysql,"CREATE TABLE t2 ("
10778                         " SERVERNAME varchar(20) NOT NULL, "
10779                         " SERVERGRP varchar(20) NOT NULL, "
10780                         " PRIMARY KEY (SERVERNAME)) "
10781                         " CHARSET=latin1 COLLATE latin1_bin");
10782   myquery(rc);
10783   rc= mysql_query(mysql,
10784                   "CREATE TABLE t3 ("
10785                   " SERVERGRP varchar(20) BINARY NOT NULL, "
10786                   " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
10787                   " ACTSTATE char(1) NOT NULL , "
10788                   " LOCAL_NAME varchar(30) NOT NULL, "
10789                   " CHG_DATE varchar(8) NOT NULL default '00000000', "
10790                   " CHG_TIME varchar(6) NOT NULL default '000000', "
10791                   " MXUSER varchar(12) NOT NULL default '', "
10792                   " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
10793                   " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
10794   myquery(rc);
10795   rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
10796                   " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
10797                   " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
10798                   " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
10799                   " ((T0002.SERVERGRP = T0001.SERVERGRP) and"
10800                   " (T0002.SERVERGRP = T0003.SERVERGRP)"
10801                   " and (T0003.MAPSTATE = _latin1'A') and"
10802                   " (T0003.ACTSTATE = _latin1' '))");
10803   myquery(rc);
10804 
10805   stmt= mysql_stmt_init(mysql);
10806   rc= mysql_stmt_prepare(stmt, query, strlen(query));
10807   check_execute(stmt, rc);
10808 
10809   strmov(str_data, "TEST");
10810   bzero((char*) my_bind, sizeof(my_bind));
10811   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10812   my_bind[0].buffer= (char *)&str_data;
10813   my_bind[0].buffer_length= 50;
10814   my_bind[0].length= &length;
10815   length= 4;
10816   my_bind[0].is_null= (char*)&is_null;
10817   rc= mysql_stmt_bind_param(stmt, my_bind);
10818   check_execute(stmt,rc);
10819 
10820   for (i= 0; i < 3; i++)
10821   {
10822     rc= mysql_stmt_execute(stmt);
10823     check_execute(stmt, rc);
10824     rc= my_process_stmt_result(stmt);
10825     DIE_UNLESS(1 == rc);
10826   }
10827   mysql_stmt_close(stmt);
10828 
10829   rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
10830   myquery(rc);
10831   rc= mysql_query(mysql, "DROP VIEW v1");
10832   myquery(rc);
10833 }
10834 
10835 
test_view_where()10836 static void test_view_where()
10837 {
10838   MYSQL_STMT *stmt;
10839   int rc, i;
10840   const char *query=
10841     "select v1.c,v2.c from v1, v2";
10842 
10843   myheader("test_view_where");
10844 
10845   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2");
10846   myquery(rc);
10847 
10848   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1");
10849   myquery(rc);
10850   rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)");
10851   myquery(rc);
10852   rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)");
10853   myquery(rc);
10854   rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3");
10855   myquery(rc);
10856   rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3");
10857   myquery(rc);
10858 
10859   stmt= mysql_stmt_init(mysql);
10860   rc= mysql_stmt_prepare(stmt, query, strlen(query));
10861   check_execute(stmt, rc);
10862 
10863   for (i= 0; i < 3; i++)
10864   {
10865     rc= mysql_stmt_execute(stmt);
10866     check_execute(stmt, rc);
10867     rc= my_process_stmt_result(stmt);
10868     DIE_UNLESS(4 == rc);
10869   }
10870   mysql_stmt_close(stmt);
10871 
10872   rc= mysql_query(mysql, "DROP TABLE t1");
10873   myquery(rc);
10874   rc= mysql_query(mysql, "DROP VIEW v1, v2");
10875   myquery(rc);
10876 }
10877 
10878 
test_view_2where()10879 static void test_view_2where()
10880 {
10881   MYSQL_STMT *stmt;
10882   int rc, i;
10883   MYSQL_BIND      my_bind[8];
10884   char            parms[8][100];
10885   ulong           length[8];
10886   const char *query=
10887     "select relid, report, handle, log_group, username, variant, type, "
10888     "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
10889     "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
10890     "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";
10891 
10892   myheader("test_view_2where");
10893 
10894   rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
10895   myquery(rc);
10896   rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
10897   myquery(rc);
10898   rc= mysql_query(mysql,
10899                   "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
10900                   " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
10901                   " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
10902                   " USERNAME varchar(12) NOT NULL,"
10903                   " VARIANT varchar(12) NOT NULL,"
10904                   " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
10905                   " VERSION varchar(6) NOT NULL default '000000',"
10906                   " ERFDAT varchar(8) NOT NULL default '00000000',"
10907                   " ERFTIME varchar(6) NOT NULL default '000000',"
10908                   " ERFNAME varchar(12) NOT NULL,"
10909                   " AEDAT varchar(8) NOT NULL default '00000000',"
10910                   " AETIME varchar(6) NOT NULL default '000000',"
10911                   " AENAME varchar(12) NOT NULL,"
10912                   " DEPENDVARS varchar(10) NOT NULL,"
10913                   " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
10914                   " CLUSTD blob,"
10915                   " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
10916                                 "USERNAME, VARIANT, TYPE, SRTF2))"
10917                  " CHARSET=latin1 COLLATE latin1_bin");
10918   myquery(rc);
10919   rc= mysql_query(mysql,
10920                   "CREATE VIEW V_LTDX AS select T0001.MANDT AS "
10921                   " MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
10922                   " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
10923                   " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
10924                   " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
10925                   " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
10926                   " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
10927                   " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
10928                   " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
10929                   " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
10930   myquery(rc);
10931   bzero((char*) my_bind, sizeof(my_bind));
10932   for (i=0; i < 8; i++) {
10933     strmov(parms[i], "1");
10934     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
10935     my_bind[i].buffer = (char *)&parms[i];
10936     my_bind[i].buffer_length = 100;
10937     my_bind[i].is_null = 0;
10938     my_bind[i].length = &length[i];
10939     length[i] = 1;
10940   }
10941   stmt= mysql_stmt_init(mysql);
10942   rc= mysql_stmt_prepare(stmt, query, strlen(query));
10943   check_execute(stmt, rc);
10944 
10945   rc= mysql_stmt_bind_param(stmt, my_bind);
10946   check_execute(stmt,rc);
10947 
10948   rc= mysql_stmt_execute(stmt);
10949   check_execute(stmt, rc);
10950   rc= my_process_stmt_result(stmt);
10951   DIE_UNLESS(0 == rc);
10952 
10953   mysql_stmt_close(stmt);
10954 
10955   rc= mysql_query(mysql, "DROP VIEW V_LTDX");
10956   myquery(rc);
10957   rc= mysql_query(mysql, "DROP TABLE LTDX");
10958   myquery(rc);
10959 }
10960 
10961 
test_view_star()10962 static void test_view_star()
10963 {
10964   MYSQL_STMT *stmt;
10965   int rc, i;
10966   MYSQL_BIND      my_bind[8];
10967   char            parms[8][100];
10968   ulong           length[8];
10969   const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)";
10970 
10971   myheader("test_view_star");
10972 
10973   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1");
10974   myquery(rc);
10975   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1");
10976   myquery(rc);
10977   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
10978   myquery(rc);
10979   rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1");
10980   myquery(rc);
10981   bzero((char*) my_bind, sizeof(my_bind));
10982   for (i= 0; i < 2; i++) {
10983     sprintf((char *)&parms[i], "%d", i);
10984     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
10985     my_bind[i].buffer = (char *)&parms[i];
10986     my_bind[i].buffer_length = 100;
10987     my_bind[i].is_null = 0;
10988     my_bind[i].length = &length[i];
10989     length[i] = 1;
10990   }
10991 
10992   stmt= mysql_stmt_init(mysql);
10993   rc= mysql_stmt_prepare(stmt, query, strlen(query));
10994   check_execute(stmt, rc);
10995 
10996   rc= mysql_stmt_bind_param(stmt, my_bind);
10997   check_execute(stmt,rc);
10998 
10999   for (i= 0; i < 3; i++)
11000   {
11001     rc= mysql_stmt_execute(stmt);
11002     check_execute(stmt, rc);
11003     rc= my_process_stmt_result(stmt);
11004     DIE_UNLESS(0 == rc);
11005   }
11006 
11007   mysql_stmt_close(stmt);
11008 
11009   rc= mysql_query(mysql, "DROP TABLE t1");
11010   myquery(rc);
11011   rc= mysql_query(mysql, "DROP VIEW vt1");
11012   myquery(rc);
11013 }
11014 
11015 
test_view_insert()11016 static void test_view_insert()
11017 {
11018   MYSQL_STMT *insert_stmt, *select_stmt;
11019   int rc, i;
11020   MYSQL_BIND      my_bind[1];
11021   int             my_val = 0;
11022   ulong           my_length = 0L;
11023   long            my_null = 0L;
11024   const char *query=
11025     "insert into v1 values (?)";
11026 
11027   myheader("test_view_insert");
11028 
11029   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11030   myquery(rc);
11031   rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1");
11032   myquery(rc);
11033 
11034   rc= mysql_query(mysql,"create table t1 (a int, primary key (a))");
11035   myquery(rc);
11036 
11037   rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1");
11038   myquery(rc);
11039 
11040   insert_stmt= mysql_stmt_init(mysql);
11041   rc= mysql_stmt_prepare(insert_stmt, query, strlen(query));
11042   check_execute(insert_stmt, rc);
11043   query= "select * from t1";
11044   select_stmt= mysql_stmt_init(mysql);
11045   rc= mysql_stmt_prepare(select_stmt, query, strlen(query));
11046   check_execute(select_stmt, rc);
11047 
11048   bzero((char*) my_bind, sizeof(my_bind));
11049   my_bind[0].buffer_type = MYSQL_TYPE_LONG;
11050   my_bind[0].buffer = (char *)&my_val;
11051   my_bind[0].length = &my_length;
11052   my_bind[0].is_null = (char*)&my_null;
11053   rc= mysql_stmt_bind_param(insert_stmt, my_bind);
11054   check_execute(insert_stmt, rc);
11055 
11056   for (i= 0; i < 3; i++)
11057   {
11058     int rowcount= 0;
11059     my_val= i;
11060 
11061     rc= mysql_stmt_execute(insert_stmt);
11062     check_execute(insert_stmt, rc);
11063 
11064     rc= mysql_stmt_execute(select_stmt);
11065     check_execute(select_stmt, rc);
11066     rowcount= (int)my_process_stmt_result(select_stmt);
11067     DIE_UNLESS((i+1) == rowcount);
11068   }
11069   mysql_stmt_close(insert_stmt);
11070   mysql_stmt_close(select_stmt);
11071 
11072   rc= mysql_query(mysql, "DROP VIEW v1");
11073   myquery(rc);
11074   rc= mysql_query(mysql, "DROP TABLE t1");
11075   myquery(rc);
11076 }
11077 
11078 
test_left_join_view()11079 static void test_left_join_view()
11080 {
11081   MYSQL_STMT *stmt;
11082   int rc, i;
11083   const char *query=
11084     "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);";
11085 
11086   myheader("test_left_join_view");
11087 
11088   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11089   myquery(rc);
11090 
11091   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1");
11092   myquery(rc);
11093   rc= mysql_query(mysql,"CREATE TABLE t1 (a int)");
11094   myquery(rc);
11095   rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)");
11096   myquery(rc);
11097   rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1");
11098   myquery(rc);
11099   stmt= mysql_stmt_init(mysql);
11100   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11101   check_execute(stmt, rc);
11102 
11103   for (i= 0; i < 3; i++)
11104   {
11105     rc= mysql_stmt_execute(stmt);
11106     check_execute(stmt, rc);
11107     rc= my_process_stmt_result(stmt);
11108     DIE_UNLESS(3 == rc);
11109   }
11110   mysql_stmt_close(stmt);
11111 
11112   rc= mysql_query(mysql, "DROP VIEW v1");
11113   myquery(rc);
11114   rc= mysql_query(mysql, "DROP TABLE t1");
11115   myquery(rc);
11116 }
11117 
11118 
test_view_insert_fields()11119 static void test_view_insert_fields()
11120 {
11121   MYSQL_STMT	*stmt;
11122   char		parm[11][1000];
11123   ulong         l[11];
11124   int		rc, i;
11125   MYSQL_BIND	my_bind[11];
11126   const char    *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";
11127 
11128   myheader("test_view_insert_fields");
11129 
11130   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
11131   myquery(rc);
11132   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
11133   myquery(rc);
11134   rc= mysql_query(mysql,
11135                   "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
11136                   "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
11137                   "K4N4 varchar(4) NOT NULL default '0000',"
11138                   "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
11139                   "F3N5 varchar(5) NOT NULL default '00000',"
11140                   "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
11141                   "F6N4 varchar(4) NOT NULL default '0000',"
11142                   "F7F8 double NOT NULL default '0',"
11143                   "F8F8 double NOT NULL default '0',"
11144                   "F9D8 decimal(8,2) NOT NULL default '0.00',"
11145                   "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
11146                   "CHARSET=latin1 COLLATE latin1_bin");
11147   myquery(rc);
11148   rc= mysql_query(mysql,
11149                   "CREATE VIEW v1 AS select sql_no_cache "
11150                   " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
11151                   " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
11152                   " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
11153                   " from t1 T0001");
11154 
11155   bzero((char*) my_bind, sizeof(my_bind));
11156   for (i= 0; i < 11; i++)
11157   {
11158     l[i]= 20;
11159     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
11160     my_bind[i].is_null= 0;
11161     my_bind[i].buffer= (char *)&parm[i];
11162 
11163     strmov(parm[i], "1");
11164     my_bind[i].buffer_length= 2;
11165     my_bind[i].length= &l[i];
11166   }
11167   stmt= mysql_stmt_init(mysql);
11168   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11169   check_execute(stmt, rc);
11170   rc= mysql_stmt_bind_param(stmt, my_bind);
11171   check_execute(stmt, rc);
11172 
11173   rc= mysql_stmt_execute(stmt);
11174   check_execute(stmt, rc);
11175   mysql_stmt_close(stmt);
11176 
11177   query= "select * from t1";
11178   stmt= mysql_stmt_init(mysql);
11179   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11180   check_execute(stmt, rc);
11181   rc= mysql_stmt_execute(stmt);
11182   check_execute(stmt, rc);
11183   rc= my_process_stmt_result(stmt);
11184   DIE_UNLESS(1 == rc);
11185 
11186   mysql_stmt_close(stmt);
11187   rc= mysql_query(mysql, "DROP VIEW v1");
11188   myquery(rc);
11189   rc= mysql_query(mysql, "DROP TABLE t1");
11190   myquery(rc);
11191 
11192 }
11193 
test_bug5126()11194 static void test_bug5126()
11195 {
11196   MYSQL_STMT *stmt;
11197   MYSQL_BIND my_bind[2];
11198   int32 c1, c2;
11199   const char *stmt_text;
11200   int rc;
11201 
11202   myheader("test_bug5126");
11203 
11204   stmt_text= "DROP TABLE IF EXISTS t1";
11205   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11206   myquery(rc);
11207 
11208   stmt_text= "CREATE TABLE t1 (a mediumint, b int)";
11209   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11210   myquery(rc);
11211 
11212   stmt_text= "INSERT INTO t1 VALUES (8386608, 1)";
11213   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11214   myquery(rc);
11215 
11216   stmt= mysql_stmt_init(mysql);
11217   stmt_text= "SELECT a, b FROM t1";
11218   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11219   check_execute(stmt, rc);
11220   rc= mysql_stmt_execute(stmt);
11221   check_execute(stmt, rc);
11222 
11223   /* Bind output buffers */
11224   bzero((char*) my_bind, sizeof(my_bind));
11225 
11226   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11227   my_bind[0].buffer= &c1;
11228   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
11229   my_bind[1].buffer= &c2;
11230 
11231   mysql_stmt_bind_result(stmt, my_bind);
11232 
11233   rc= mysql_stmt_fetch(stmt);
11234   DIE_UNLESS(rc == 0);
11235   DIE_UNLESS(c1 == 8386608 && c2 == 1);
11236   if (!opt_silent)
11237     printf("%ld, %ld\n", (long) c1, (long) c2);
11238   mysql_stmt_close(stmt);
11239 }
11240 
11241 
test_bug4231()11242 static void test_bug4231()
11243 {
11244   MYSQL_STMT *stmt;
11245   MYSQL_BIND my_bind[2];
11246   MYSQL_TIME tm[2];
11247   const char *stmt_text;
11248   int rc;
11249 
11250   myheader("test_bug4231");
11251 
11252   stmt_text= "DROP TABLE IF EXISTS t1";
11253   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11254   myquery(rc);
11255 
11256   stmt_text= "CREATE TABLE t1 (a int)";
11257   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11258   myquery(rc);
11259 
11260   stmt_text= "INSERT INTO t1 VALUES (1)";
11261   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11262   myquery(rc);
11263 
11264   stmt= mysql_stmt_init(mysql);
11265   stmt_text= "SELECT a FROM t1 WHERE ? = ?";
11266   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11267   check_execute(stmt, rc);
11268 
11269   /* Bind input buffers */
11270   bzero((char*) my_bind, sizeof(my_bind));
11271   bzero((char*) tm, sizeof(tm));
11272 
11273   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
11274   my_bind[0].buffer= &tm[0];
11275   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11276   my_bind[1].buffer= &tm[1];
11277 
11278   mysql_stmt_bind_param(stmt, my_bind);
11279   check_execute(stmt, rc);
11280 
11281   /*
11282     First set server-side params to some non-zero non-equal values:
11283     then we will check that they are not used when client sends
11284     new (zero) times.
11285   */
11286   tm[0].time_type = MYSQL_TIMESTAMP_DATE;
11287   tm[0].year = 2000;
11288   tm[0].month = 1;
11289   tm[0].day = 1;
11290   tm[1]= tm[0];
11291   --tm[1].year;                                 /* tm[0] != tm[1] */
11292 
11293   rc= mysql_stmt_execute(stmt);
11294   check_execute(stmt, rc);
11295 
11296   rc= mysql_stmt_fetch(stmt);
11297 
11298   /* binds are unequal, no rows should be returned */
11299   DIE_UNLESS(rc == MYSQL_NO_DATA);
11300 
11301   /* Set one of the dates to zero */
11302   tm[0].year= tm[0].month= tm[0].day= 0;
11303   tm[1]= tm[0];
11304   mysql_stmt_execute(stmt);
11305   rc= mysql_stmt_fetch(stmt);
11306   DIE_UNLESS(rc == 0);
11307 
11308   mysql_stmt_close(stmt);
11309   stmt_text= "DROP TABLE t1";
11310   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11311   myquery(rc);
11312 }
11313 
11314 
test_bug5399()11315 static void test_bug5399()
11316 {
11317   /*
11318     Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
11319     statement id hash in the server uses binary collation.
11320   */
11321 #define NUM_OF_USED_STMT 97
11322   MYSQL_STMT *stmt_list[NUM_OF_USED_STMT];
11323   MYSQL_STMT **stmt;
11324   MYSQL_BIND my_bind[1];
11325   char buff[600];
11326   int rc;
11327   int32 no;
11328 
11329   myheader("test_bug5399");
11330 
11331   bzero((char*) my_bind, sizeof(my_bind));
11332   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11333   my_bind[0].buffer= &no;
11334 
11335   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11336   {
11337     sprintf(buff, "select %d", (int) (stmt - stmt_list));
11338     *stmt= mysql_stmt_init(mysql);
11339     rc= mysql_stmt_prepare(*stmt, buff, strlen(buff));
11340     check_execute(*stmt, rc);
11341     mysql_stmt_bind_result(*stmt, my_bind);
11342   }
11343   if (!opt_silent)
11344     printf("%d statements prepared.\n", NUM_OF_USED_STMT);
11345 
11346   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11347   {
11348     rc= mysql_stmt_execute(*stmt);
11349     check_execute(*stmt, rc);
11350     rc= mysql_stmt_store_result(*stmt);
11351     check_execute(*stmt, rc);
11352     rc= mysql_stmt_fetch(*stmt);
11353     DIE_UNLESS(rc == 0);
11354     DIE_UNLESS((int32) (stmt - stmt_list) == no);
11355   }
11356 
11357   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11358     mysql_stmt_close(*stmt);
11359 #undef NUM_OF_USED_STMT
11360 }
11361 
11362 
test_bug5194()11363 static void test_bug5194()
11364 {
11365   MYSQL_STMT *stmt;
11366   MYSQL_BIND *my_bind;
11367   char *query;
11368   char *param_str;
11369   int param_str_length;
11370   const char *stmt_text;
11371   int rc;
11372   float float_array[250] =
11373   {
11374     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11375     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11376     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11377     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11378     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11379     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11380     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11381     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11382     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11383     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11384     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11385     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11386     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11387     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11388     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11389     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11390     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11391     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11392     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11393     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11394     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11395     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11396     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11397     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11398     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25
11399   };
11400   float *fa_ptr= float_array;
11401   /* Number of columns per row */
11402   const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array);
11403   /* Number of rows per bulk insert to start with */
11404   const int MIN_ROWS_PER_INSERT= 262;
11405   /* Max number of rows per bulk insert to end with */
11406   const int MAX_ROWS_PER_INSERT= 300;
11407   const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT;
11408   const char *query_template= "insert into t1 values %s";
11409   const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */
11410   const int uint16_max= 65535;
11411   int nrows, i;
11412 
11413   myheader("test_bug5194");
11414 
11415   stmt_text= "drop table if exists t1";
11416   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11417 
11418   stmt_text= "create table if not exists t1"
11419    "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, "
11420    "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, "
11421    "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, "
11422    "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, "
11423    "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, "
11424    "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, "
11425    "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, "
11426    "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, "
11427    "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, "
11428    "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, "
11429    "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, "
11430    "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, "
11431    "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, "
11432    "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, "
11433    "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, "
11434    "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, "
11435    "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, "
11436    "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, "
11437    "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, "
11438    "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, "
11439    "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, "
11440    "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, "
11441    "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, "
11442    "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, "
11443    "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, "
11444    "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, "
11445    "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, "
11446    "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, "
11447    "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, "
11448    "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, "
11449    "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, "
11450    "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, "
11451    "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, "
11452    "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, "
11453    "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, "
11454    "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, "
11455    "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, "
11456    "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, "
11457    "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, "
11458    "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, "
11459    "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, "
11460    "c247 float, c248 float, c249 float, c250 float)";
11461   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11462   myquery(rc);
11463 
11464   my_bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11465   query= (char*) malloc(strlen(query_template) +
11466                         MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
11467   param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
11468 
11469   if (my_bind == 0 || query == 0 || param_str == 0)
11470   {
11471     fprintf(stderr, "Can't allocate enough memory for query structs\n");
11472     if (my_bind)
11473       free(my_bind);
11474     if (query)
11475       free(query);
11476     if (param_str)
11477       free(param_str);
11478     return;
11479   }
11480 
11481   stmt= mysql_stmt_init(mysql);
11482 
11483   /* setup a template for one row of parameters */
11484   sprintf(param_str, "(");
11485   for (i= 1; i < COLUMN_COUNT; ++i)
11486     strcat(param_str, "?, ");
11487   strcat(param_str, "?)");
11488   param_str_length= strlen(param_str);
11489 
11490   /* setup bind array */
11491   bzero((char*) my_bind, MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11492   for (i= 0; i < MAX_PARAM_COUNT; ++i)
11493   {
11494     my_bind[i].buffer_type= MYSQL_TYPE_FLOAT;
11495     my_bind[i].buffer= fa_ptr;
11496     if (++fa_ptr == float_array + COLUMN_COUNT)
11497       fa_ptr= float_array;
11498   }
11499 
11500   /*
11501     Test each number of rows per bulk insert, so that we can see where
11502     MySQL fails.
11503   */
11504   for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows)
11505   {
11506     char *query_ptr;
11507     /* Create statement text for current number of rows */
11508     sprintf(query, query_template, param_str);
11509     query_ptr= query + strlen(query);
11510     for (i= 1; i < nrows; ++i)
11511     {
11512       memcpy(query_ptr, ", ", 2);
11513       query_ptr+= 2;
11514       memcpy(query_ptr, param_str, param_str_length);
11515       query_ptr+= param_str_length;
11516     }
11517     *query_ptr= '\0';
11518 
11519     rc= mysql_stmt_prepare(stmt, query, query_ptr - query);
11520     if (rc && nrows * COLUMN_COUNT > uint16_max)
11521     {
11522       if (!opt_silent)
11523         printf("Failed to prepare a statement with %d placeholders "
11524                "(as expected).\n", nrows * COLUMN_COUNT);
11525       break;
11526     }
11527     else
11528       check_execute(stmt, rc);
11529 
11530     if (!opt_silent)
11531       printf("Insert: query length= %d, row count= %d, param count= %lu\n",
11532              (int) strlen(query), nrows, mysql_stmt_param_count(stmt));
11533 
11534     /* bind the parameter array and execute the query */
11535     rc= mysql_stmt_bind_param(stmt, my_bind);
11536     check_execute(stmt, rc);
11537 
11538     rc= mysql_stmt_execute(stmt);
11539     check_execute(stmt, rc);
11540     mysql_stmt_reset(stmt);
11541   }
11542 
11543   mysql_stmt_close(stmt);
11544   free(my_bind);
11545   free(query);
11546   free(param_str);
11547   stmt_text= "drop table t1";
11548   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11549   myquery(rc);
11550 }
11551 
11552 
test_bug5315()11553 static void test_bug5315()
11554 {
11555   MYSQL_STMT *stmt;
11556   const char *stmt_text;
11557   int rc;
11558 
11559   myheader("test_bug5315");
11560 
11561   stmt_text= "SELECT 1";
11562   stmt= mysql_stmt_init(mysql);
11563   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11564   DIE_UNLESS(rc == 0);
11565   if (!opt_silent)
11566     printf("Excuting mysql_change_user\n");
11567   mysql_change_user(mysql, opt_user, opt_password, current_db);
11568   if (!opt_silent)
11569     printf("Excuting mysql_stmt_execute\n");
11570   rc= mysql_stmt_execute(stmt);
11571   DIE_UNLESS(rc != 0);
11572   if (rc)
11573   {
11574     if (!opt_silent)
11575       printf("Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
11576   }
11577   /* check that connection is OK */
11578   if (!opt_silent)
11579     printf("Excuting mysql_stmt_close\n");
11580   mysql_stmt_close(stmt);
11581   if (!opt_silent)
11582     printf("Excuting mysql_stmt_init\n");
11583   stmt= mysql_stmt_init(mysql);
11584   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11585   DIE_UNLESS(rc == 0);
11586   rc= mysql_stmt_execute(stmt);
11587   DIE_UNLESS(rc == 0);
11588   mysql_stmt_close(stmt);
11589 }
11590 
11591 
test_bug6049()11592 static void test_bug6049()
11593 {
11594   MYSQL_STMT *stmt;
11595   MYSQL_BIND my_bind[1];
11596   MYSQL_RES *res;
11597   MYSQL_ROW row;
11598   const char *stmt_text;
11599   char buffer[30];
11600   ulong length;
11601   int rc;
11602 
11603   myheader("test_bug6049");
11604 
11605   stmt_text= "SELECT MAKETIME(-25, 12, 12)";
11606 
11607   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11608   myquery(rc);
11609   res= mysql_store_result(mysql);
11610   row= mysql_fetch_row(res);
11611 
11612   stmt= mysql_stmt_init(mysql);
11613   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11614   check_execute(stmt, rc);
11615   rc= mysql_stmt_execute(stmt);
11616   check_execute(stmt, rc);
11617 
11618   bzero((char*) my_bind, sizeof(my_bind));
11619   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
11620   my_bind[0].buffer         = &buffer;
11621   my_bind[0].buffer_length  = sizeof(buffer);
11622   my_bind[0].length         = &length;
11623 
11624   mysql_stmt_bind_result(stmt, my_bind);
11625   rc= mysql_stmt_fetch(stmt);
11626   DIE_UNLESS(rc == 0);
11627 
11628   if (!opt_silent)
11629   {
11630     printf("Result from query: %s\n", row[0]);
11631     printf("Result from prepared statement: %s\n", (char*) buffer);
11632   }
11633 
11634   DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);
11635 
11636   mysql_free_result(res);
11637   mysql_stmt_close(stmt);
11638 }
11639 
11640 
test_bug6058()11641 static void test_bug6058()
11642 {
11643   MYSQL_STMT *stmt;
11644   MYSQL_BIND my_bind[1];
11645   MYSQL_RES *res;
11646   MYSQL_ROW row;
11647   const char *stmt_text;
11648   char buffer[30];
11649   ulong length;
11650   int rc;
11651 
11652   myheader("test_bug6058");
11653 
11654   rc= mysql_query(mysql, "SET SQL_MODE=''");
11655   myquery(rc);
11656 
11657   stmt_text= "SELECT CAST('0000-00-00' AS DATE)";
11658 
11659   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11660   myquery(rc);
11661   res= mysql_store_result(mysql);
11662   row= mysql_fetch_row(res);
11663 
11664   stmt= mysql_stmt_init(mysql);
11665   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11666   check_execute(stmt, rc);
11667   rc= mysql_stmt_execute(stmt);
11668   check_execute(stmt, rc);
11669 
11670   bzero((char*) my_bind, sizeof(my_bind));
11671   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
11672   my_bind[0].buffer         = &buffer;
11673   my_bind[0].buffer_length  = sizeof(buffer);
11674   my_bind[0].length         = &length;
11675 
11676   mysql_stmt_bind_result(stmt, my_bind);
11677   rc= mysql_stmt_fetch(stmt);
11678   DIE_UNLESS(rc == 0);
11679 
11680   if (!opt_silent)
11681   {
11682     printf("Result from query: %s\n", row[0]);
11683     printf("Result from prepared statement: %s\n", buffer);
11684   }
11685 
11686   DIE_UNLESS(strcmp(row[0], buffer) == 0);
11687 
11688   mysql_free_result(res);
11689   mysql_stmt_close(stmt);
11690 }
11691 
11692 
test_bug6059()11693 static void test_bug6059()
11694 {
11695   MYSQL_STMT *stmt;
11696   const char *stmt_text;
11697 
11698   myheader("test_bug6059");
11699 
11700   stmt_text= "SELECT 'foo' INTO OUTFILE 'x.3'";
11701 
11702   stmt= mysql_stmt_init(mysql);
11703   (void) mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11704   DIE_UNLESS(mysql_stmt_field_count(stmt) == 0);
11705   mysql_stmt_close(stmt);
11706 }
11707 
11708 
test_bug6046()11709 static void test_bug6046()
11710 {
11711   MYSQL_STMT *stmt;
11712   const char *stmt_text;
11713   int rc;
11714   short b= 1;
11715   MYSQL_BIND my_bind[1];
11716 
11717   myheader("test_bug6046");
11718 
11719   stmt_text= "DROP TABLE IF EXISTS t1";
11720   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11721   myquery(rc);
11722   stmt_text= "CREATE TABLE t1 (a int, b int)";
11723   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11724   myquery(rc);
11725   stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)";
11726   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11727   myquery(rc);
11728 
11729   stmt= mysql_stmt_init(mysql);
11730 
11731   stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 "
11732              "WHERE t1.b > ? ORDER BY t1.a";
11733 
11734   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11735   check_execute(stmt, rc);
11736 
11737   b= 1;
11738   bzero((char*) my_bind, sizeof(my_bind));
11739   my_bind[0].buffer= &b;
11740   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
11741 
11742   mysql_stmt_bind_param(stmt, my_bind);
11743 
11744   rc= mysql_stmt_execute(stmt);
11745   check_execute(stmt, rc);
11746   mysql_stmt_store_result(stmt);
11747 
11748   rc= mysql_stmt_execute(stmt);
11749   check_execute(stmt, rc);
11750 
11751   mysql_stmt_close(stmt);
11752 }
11753 
11754 
11755 
test_basic_cursors()11756 static void test_basic_cursors()
11757 {
11758   const char *basic_tables[]=
11759   {
11760     "DROP TABLE IF EXISTS t1, t2",
11761 
11762     "CREATE TABLE t1 "
11763     "(id INTEGER NOT NULL PRIMARY KEY, "
11764     " name VARCHAR(20) NOT NULL)",
11765 
11766     "INSERT INTO t1 (id, name) VALUES "
11767     "  (2, 'Ja'), (3, 'Ede'), "
11768     "  (4, 'Haag'), (5, 'Kabul'), "
11769     "  (6, 'Almere'), (7, 'Utrecht'), "
11770     "  (8, 'Qandahar'), (9, 'Amsterdam'), "
11771     "  (10, 'Amersfoort'), (11, 'Constantine')",
11772 
11773     "CREATE TABLE t2 "
11774     "(id INTEGER NOT NULL PRIMARY KEY, "
11775     " name VARCHAR(20) NOT NULL)",
11776 
11777     "INSERT INTO t2 (id, name) VALUES "
11778     "  (4, 'Guam'), (5, 'Aruba'), "
11779     "  (6, 'Angola'), (7, 'Albania'), "
11780     "  (8, 'Anguilla'), (9, 'Argentina'), "
11781     "  (10, 'Azerbaijan'), (11, 'Afghanistan'), "
11782     "  (12, 'Burkina Faso'), (13, 'Faroe Islands')"
11783   };
11784   const char *queries[]=
11785   {
11786     "SELECT * FROM t1",
11787     "SELECT * FROM t2"
11788   };
11789 
11790   DBUG_ENTER("test_basic_cursors");
11791   myheader("test_basic_cursors");
11792 
11793   fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
11794 
11795   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
11796   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
11797   DBUG_VOID_RETURN;
11798 }
11799 
11800 
test_cursors_with_union()11801 static void test_cursors_with_union()
11802 {
11803   const char *queries[]=
11804   {
11805     "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2",
11806     "SELECT t1.id FROM t1 WHERE t1.id < 5"
11807   };
11808   myheader("test_cursors_with_union");
11809   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
11810   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
11811 }
11812 
11813 
test_cursors_with_procedure()11814 static void test_cursors_with_procedure()
11815 {
11816   const char *queries[]=
11817   {
11818     "SELECT * FROM t1 procedure analyse()"
11819   };
11820   myheader("test_cursors_with_procedure");
11821   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
11822   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
11823 }
11824 
11825 
11826 /*
11827   Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
11828   should not crash server and should not hang in case of errors.
11829 
11830   Since those functions can't be seen in modern API (unless client library
11831   was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro.
11832 */
test_bug6081()11833 static void test_bug6081()
11834 {
11835   int rc;
11836   myheader("test_bug6081");
11837 
11838   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
11839                      (ulong)strlen(current_db), 0);
11840   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
11841   {
11842     myerror(NULL);                                   /* purecov: inspected */
11843     die(__FILE__, __LINE__, "COM_DROP_DB failed");   /* purecov: inspected */
11844   }
11845   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
11846                      (ulong)strlen(current_db), 0);
11847   myquery_r(rc);
11848   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
11849                      (ulong)strlen(current_db), 0);
11850   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
11851   {
11852     myerror(NULL);                                   /* purecov: inspected */
11853     die(__FILE__, __LINE__, "COM_CREATE_DB failed"); /* purecov: inspected */
11854   }
11855   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
11856                      (ulong)strlen(current_db), 0);
11857   myquery_r(rc);
11858   rc= mysql_select_db(mysql, current_db);
11859   myquery(rc);
11860 }
11861 
11862 
test_bug6096()11863 static void test_bug6096()
11864 {
11865   MYSQL_STMT *stmt;
11866   MYSQL_RES *query_result, *stmt_metadata;
11867   const char *stmt_text;
11868   MYSQL_BIND my_bind[12];
11869   MYSQL_FIELD *query_field_list, *stmt_field_list;
11870   ulong query_field_count, stmt_field_count;
11871   int rc;
11872   my_bool update_max_length= TRUE;
11873   uint i;
11874 
11875   myheader("test_bug6096");
11876 
11877   stmt_text= "drop table if exists t1";
11878   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11879   myquery(rc);
11880 
11881   mysql_query(mysql, "set sql_mode=''");
11882   stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, "
11883                              " c_mediumint mediumint, c_int int, "
11884                              " c_bigint bigint, c_float float, "
11885                              " c_double double, c_varchar varchar(20), "
11886                              " c_char char(20), c_time time, c_date date, "
11887                              " c_datetime datetime)";
11888   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11889   myquery(rc);
11890   stmt_text= "insert into t1  values (-100, -20000, 30000000, 4, 8, 1.0, "
11891                                      "2.0, 'abc', 'def', now(), now(), now())";
11892   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11893   myquery(rc);
11894 
11895   stmt_text= "select * from t1";
11896 
11897   /* Run select in prepared and non-prepared mode and compare metadata */
11898   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11899   myquery(rc);
11900   query_result= mysql_store_result(mysql);
11901   query_field_list= mysql_fetch_fields(query_result);
11902   query_field_count= mysql_num_fields(query_result);
11903 
11904   stmt= mysql_stmt_init(mysql);
11905   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11906   check_execute(stmt, rc);
11907   rc= mysql_stmt_execute(stmt);
11908   check_execute(stmt, rc);
11909   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
11910                       (void*) &update_max_length);
11911   mysql_stmt_store_result(stmt);
11912   stmt_metadata= mysql_stmt_result_metadata(stmt);
11913   stmt_field_list= mysql_fetch_fields(stmt_metadata);
11914   stmt_field_count= mysql_num_fields(stmt_metadata);
11915   DIE_UNLESS(stmt_field_count == query_field_count);
11916 
11917   /* Print out and check the metadata */
11918 
11919   if (!opt_silent)
11920   {
11921     printf(" ------------------------------------------------------------\n");
11922     printf("             |                     Metadata \n");
11923     printf(" ------------------------------------------------------------\n");
11924     printf("             |         Query          |   Prepared statement \n");
11925     printf(" ------------------------------------------------------------\n");
11926     printf(" field name  |  length   | max_length |  length   |  max_length\n");
11927     printf(" ------------------------------------------------------------\n");
11928 
11929     for (i= 0; i < query_field_count; ++i)
11930     {
11931       MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
11932       printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
11933              f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
11934       DIE_UNLESS(f1->length == f2->length);
11935     }
11936     printf(" ---------------------------------------------------------------\n");
11937   }
11938 
11939   /* Bind and fetch the data */
11940 
11941   bzero((char*) my_bind, sizeof(my_bind));
11942   for (i= 0; i < stmt_field_count; ++i)
11943   {
11944     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
11945     my_bind[i].buffer_length= stmt_field_list[i].max_length + 1;
11946     my_bind[i].buffer= malloc(my_bind[i].buffer_length);
11947   }
11948   mysql_stmt_bind_result(stmt, my_bind);
11949   rc= mysql_stmt_fetch(stmt);
11950   check_execute(stmt, rc);
11951   rc= mysql_stmt_fetch(stmt);
11952   DIE_UNLESS(rc == MYSQL_NO_DATA);
11953 
11954   /* Clean up */
11955 
11956   for (i= 0; i < stmt_field_count; ++i)
11957     free(my_bind[i].buffer);
11958   mysql_stmt_close(stmt);
11959   mysql_free_result(query_result);
11960   mysql_free_result(stmt_metadata);
11961   stmt_text= "drop table t1";
11962   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11963   myquery(rc);
11964 }
11965 
11966 
11967 /*
11968   Test of basic checks that are performed in server for components
11969   of MYSQL_TIME parameters.
11970 */
11971 
test_datetime_ranges()11972 static void test_datetime_ranges()
11973 {
11974   const char *stmt_text;
11975   int rc, i;
11976   MYSQL_STMT *stmt;
11977   MYSQL_BIND my_bind[6];
11978   MYSQL_TIME tm[6];
11979 
11980   myheader("test_datetime_ranges");
11981 
11982   stmt_text= "drop table if exists t1";
11983   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11984   myquery(rc);
11985 
11986   stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
11987                               "hour datetime, min datetime, sec datetime)";
11988   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11989   myquery(rc);
11990 
11991   stmt= mysql_simple_prepare(mysql,
11992                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
11993   check_stmt(stmt);
11994   verify_param_count(stmt, 6);
11995 
11996   bzero((char*) my_bind, sizeof(my_bind));
11997   for (i= 0; i < 6; i++)
11998   {
11999     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12000     my_bind[i].buffer= &tm[i];
12001   }
12002   rc= mysql_stmt_bind_param(stmt, my_bind);
12003   check_execute(stmt, rc);
12004 
12005   tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
12006   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12007   tm[0].second_part= 0; tm[0].neg= 0;
12008 
12009   tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12010   tm[0].year= 10000;  tm[1].month= 13; tm[2].day= 32;
12011   tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;
12012 
12013   rc= mysql_stmt_execute(stmt);
12014   check_execute(stmt, rc);
12015   my_process_warnings(mysql, 12);
12016 
12017   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12018   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12019   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12020   verify_col_data("t1", "hour", "0000-00-00 00:00:00");
12021   verify_col_data("t1", "min", "0000-00-00 00:00:00");
12022   verify_col_data("t1", "sec", "0000-00-00 00:00:00");
12023 
12024   mysql_stmt_close(stmt);
12025 
12026   stmt_text= "delete from t1";
12027   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12028   myquery(rc);
12029 
12030   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
12031                                     "VALUES (?, ?, ?)");
12032   check_stmt(stmt);
12033   verify_param_count(stmt, 3);
12034 
12035   /*
12036     We reuse contents of bind and tm arrays left from previous part of test.
12037   */
12038   for (i= 0; i < 3; i++)
12039     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12040 
12041   rc= mysql_stmt_bind_param(stmt, my_bind);
12042   check_execute(stmt, rc);
12043 
12044   rc= mysql_stmt_execute(stmt);
12045   check_execute(stmt, rc);
12046   my_process_warnings(mysql, 6);
12047 
12048   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12049   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12050   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12051 
12052   mysql_stmt_close(stmt);
12053 
12054   stmt_text= "drop table t1";
12055   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12056   myquery(rc);
12057 
12058   stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
12059   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12060   myquery(rc);
12061 
12062   stmt= mysql_simple_prepare(mysql,
12063                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
12064   check_stmt(stmt);
12065   verify_param_count(stmt, 5);
12066 
12067   /*
12068     Again we reuse what we can from previous part of test.
12069   */
12070   for (i= 0; i < 5; i++)
12071     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12072 
12073   rc= mysql_stmt_bind_param(stmt, my_bind);
12074   check_execute(stmt, rc);
12075 
12076   tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
12077   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12078   tm[0].second_part= 0; tm[0].neg= 0;
12079 
12080   tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12081   tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;
12082 
12083   rc= mysql_stmt_execute(stmt);
12084   check_execute(stmt, rc);
12085   my_process_warnings(mysql, 2);
12086 
12087   verify_col_data("t1", "day_ovfl", "838:59:59");
12088   verify_col_data("t1", "day", "828:30:30");
12089   verify_col_data("t1", "hour", "270:30:30");
12090   verify_col_data("t1", "min", "00:00:00");
12091   verify_col_data("t1", "sec", "00:00:00");
12092 
12093   mysql_stmt_close(stmt);
12094 
12095   stmt_text= "drop table t1";
12096   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12097   myquery(rc);
12098 }
12099 
12100 
test_bug4172()12101 static void test_bug4172()
12102 {
12103   MYSQL_STMT *stmt;
12104   MYSQL_BIND my_bind[3];
12105   const char *stmt_text;
12106   MYSQL_RES *res;
12107   MYSQL_ROW row;
12108   int rc;
12109   char f[100], d[100], e[100];
12110   ulong f_len, d_len, e_len;
12111 
12112   myheader("test_bug4172");
12113 
12114   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
12115   mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))");
12116   mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, "
12117                                             "123456.1234)");
12118 
12119   stmt= mysql_stmt_init(mysql);
12120   stmt_text= "SELECT f, d, e FROM t1";
12121 
12122   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12123   check_execute(stmt, rc);
12124   rc= mysql_stmt_execute(stmt);
12125   check_execute(stmt, rc);
12126 
12127   bzero((char*) my_bind, sizeof(my_bind));
12128   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12129   my_bind[0].buffer= f;
12130   my_bind[0].buffer_length= sizeof(f);
12131   my_bind[0].length= &f_len;
12132   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
12133   my_bind[1].buffer= d;
12134   my_bind[1].buffer_length= sizeof(d);
12135   my_bind[1].length= &d_len;
12136   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
12137   my_bind[2].buffer= e;
12138   my_bind[2].buffer_length= sizeof(e);
12139   my_bind[2].length= &e_len;
12140 
12141   mysql_stmt_bind_result(stmt, my_bind);
12142 
12143   mysql_stmt_store_result(stmt);
12144   rc= mysql_stmt_fetch(stmt);
12145   check_execute(stmt, rc);
12146 
12147   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12148   myquery(rc);
12149   res= mysql_store_result(mysql);
12150   row= mysql_fetch_row(res);
12151 
12152   if (!opt_silent)
12153   {
12154     printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n",
12155            f, d, e);
12156     printf("Text protocol:   float=%s, double=%s, decimal(10,4)=%s\n",
12157            row[0], row[1], row[2]);
12158   }
12159   DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]));
12160 
12161   mysql_free_result(res);
12162   mysql_stmt_close(stmt);
12163 }
12164 
12165 
test_conversion()12166 static void test_conversion()
12167 {
12168   MYSQL_STMT *stmt;
12169   const char *stmt_text;
12170   int rc;
12171   MYSQL_BIND my_bind[1];
12172   char buff[4];
12173   ulong length;
12174 
12175   myheader("test_conversion");
12176 
12177   stmt_text= "DROP TABLE IF EXISTS t1";
12178   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12179   myquery(rc);
12180   stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
12181   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12182   myquery(rc);
12183   stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
12184              " character_set_results=latin1";
12185   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12186   myquery(rc);
12187 
12188   stmt= mysql_stmt_init(mysql);
12189 
12190   stmt_text= "INSERT INTO t1 (a) VALUES (?)";
12191   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12192   check_execute(stmt, rc);
12193 
12194   bzero((char*) my_bind, sizeof(my_bind));
12195   my_bind[0].buffer= buff;
12196   my_bind[0].length= &length;
12197   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12198 
12199   mysql_stmt_bind_param(stmt, my_bind);
12200 
12201   buff[0]= (uchar) 0xC3;
12202   buff[1]= (uchar) 0xA0;
12203   length= 2;
12204 
12205   rc= mysql_stmt_execute(stmt);
12206   check_execute(stmt, rc);
12207 
12208   stmt_text= "SELECT a FROM t1";
12209   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12210   check_execute(stmt, rc);
12211   rc= mysql_stmt_execute(stmt);
12212   check_execute(stmt, rc);
12213 
12214   my_bind[0].buffer_length= sizeof(buff);
12215   mysql_stmt_bind_result(stmt, my_bind);
12216 
12217   rc= mysql_stmt_fetch(stmt);
12218   DIE_UNLESS(rc == 0);
12219   DIE_UNLESS(length == 1);
12220   DIE_UNLESS((uchar) buff[0] == 0xE0);
12221   rc= mysql_stmt_fetch(stmt);
12222   DIE_UNLESS(rc == MYSQL_NO_DATA);
12223 
12224   mysql_stmt_close(stmt);
12225   stmt_text= "DROP TABLE t1";
12226   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12227   myquery(rc);
12228   stmt_text= "SET NAMES DEFAULT";
12229   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12230   myquery(rc);
12231 }
12232 
test_rewind(void)12233 static void test_rewind(void)
12234 {
12235   MYSQL_STMT *stmt;
12236   MYSQL_BIND my_bind;
12237   int rc = 0;
12238   const char *stmt_text;
12239   long unsigned int length=4, Data=0;
12240   my_bool isnull=0;
12241 
12242   myheader("test_rewind");
12243 
12244   stmt_text= "CREATE TABLE t1 (a int)";
12245   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12246   myquery(rc);
12247   stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)";
12248   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12249   myquery(rc);
12250 
12251   stmt= mysql_stmt_init(mysql);
12252 
12253   stmt_text= "SELECT * FROM t1";
12254   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12255   check_execute(stmt, rc);
12256 
12257   bzero((char*) &my_bind, sizeof(MYSQL_BIND));
12258   my_bind.buffer_type= MYSQL_TYPE_LONG;
12259   my_bind.buffer= (void *)&Data; /* this buffer won't be altered */
12260   my_bind.length= &length;
12261   my_bind.is_null= &isnull;
12262 
12263   rc= mysql_stmt_execute(stmt);
12264   check_execute(stmt, rc);
12265 
12266   rc= mysql_stmt_store_result(stmt);
12267   DIE_UNLESS(rc == 0);
12268 
12269   rc= mysql_stmt_bind_result(stmt, &my_bind);
12270   DIE_UNLESS(rc == 0);
12271 
12272   /* retreive all result sets till we are at the end */
12273   while(!mysql_stmt_fetch(stmt))
12274     if (!opt_silent)
12275       printf("fetched result:%ld\n", Data);
12276 
12277   DIE_UNLESS(rc != MYSQL_NO_DATA);
12278 
12279   /* seek to the first row */
12280   mysql_stmt_data_seek(stmt, 0);
12281 
12282   /* now we should be able to fetch the results again */
12283   /* but mysql_stmt_fetch returns MYSQL_NO_DATA */
12284   while(!(rc= mysql_stmt_fetch(stmt)))
12285     if (!opt_silent)
12286       printf("fetched result after seek:%ld\n", Data);
12287 
12288   DIE_UNLESS(rc == MYSQL_NO_DATA);
12289 
12290   stmt_text= "DROP TABLE t1";
12291   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12292   myquery(rc);
12293   rc= mysql_stmt_free_result(stmt);
12294   rc= mysql_stmt_close(stmt);
12295 }
12296 
12297 
test_truncation()12298 static void test_truncation()
12299 {
12300   MYSQL_STMT *stmt;
12301   const char *stmt_text;
12302   int rc;
12303   uint bind_count;
12304   MYSQL_BIND *bind_array, *my_bind;
12305 
12306   myheader("test_truncation");
12307 
12308   /* Prepare the test table */
12309   rc= mysql_query(mysql, "drop table if exists t1");
12310   myquery(rc);
12311 
12312   stmt_text= "create table t1 ("
12313              "i8 tinyint, ui8 tinyint unsigned, "
12314              "i16 smallint, i16_1 smallint, "
12315              "ui16 smallint unsigned, i32 int, i32_1 int, "
12316              "d double, d_1 double, ch char(30), ch_1 char(30), "
12317              "tx text, tx_1 text, ch_2 char(30) "
12318              ")";
12319   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12320   myquery(rc);
12321 
12322   {
12323     const char insert_text[]=
12324              "insert into t1 VALUES ("
12325              "-10, "                            /* i8 */
12326              "200, "                            /* ui8 */
12327              "32000, "                          /* i16 */
12328              "-32767, "                         /* i16_1 */
12329              "64000, "                          /* ui16 */
12330              "1073741824, "                     /* i32 */
12331              "1073741825, "                     /* i32_1 */
12332              "123.456, "                        /* d */
12333              "-12345678910, "                   /* d_1 */
12334              "'111111111111111111111111111111',"/* ch */
12335              "'abcdef', "                       /* ch_1 */
12336              "'12345 	      ', "              /* tx */
12337              "'12345.67 	      ', "      /* tx_1 */
12338              "'12345.67abc'"                    /* ch_2 */
12339              ")";
12340     rc= mysql_real_query(mysql, insert_text, strlen(insert_text));
12341     myquery(rc);
12342   }
12343 
12344   stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, "
12345              "       i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, "
12346              "       d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, "
12347              "       tx_1 c17, ch_2 c18 "
12348              "from t1";
12349 
12350   stmt= mysql_stmt_init(mysql);
12351   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12352   check_execute(stmt, rc);
12353   rc= mysql_stmt_execute(stmt);
12354   check_execute(stmt, rc);
12355   bind_count= (uint) mysql_stmt_field_count(stmt);
12356 
12357   /*************** Fill in the bind structure and bind it **************/
12358   bind_array= malloc(sizeof(MYSQL_BIND) * bind_count);
12359   bzero((char*) bind_array, sizeof(MYSQL_BIND) * bind_count);
12360   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12361     my_bind->error= &my_bind->error_value;
12362   my_bind= bind_array;
12363 
12364   my_bind->buffer= malloc(sizeof(uint8));
12365   my_bind->buffer_type= MYSQL_TYPE_TINY;
12366   my_bind->is_unsigned= TRUE;
12367 
12368   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12369   my_bind->buffer= malloc(sizeof(uint32));
12370   my_bind->buffer_type= MYSQL_TYPE_LONG;
12371   my_bind->is_unsigned= TRUE;
12372 
12373   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12374   my_bind->buffer= malloc(sizeof(int8));
12375   my_bind->buffer_type= MYSQL_TYPE_TINY;
12376 
12377   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12378   my_bind->buffer= malloc(sizeof(uint16));
12379   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12380   my_bind->is_unsigned= TRUE;
12381 
12382   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12383   my_bind->buffer= malloc(sizeof(int16));
12384   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12385 
12386   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12387   my_bind->buffer= malloc(sizeof(uint16));
12388   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12389   my_bind->is_unsigned= TRUE;
12390 
12391   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12392   my_bind->buffer= malloc(sizeof(int8));
12393   my_bind->buffer_type= MYSQL_TYPE_TINY;
12394   my_bind->is_unsigned= TRUE;
12395 
12396   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12397   my_bind->buffer= malloc(sizeof(float));
12398   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12399 
12400   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12401   my_bind->buffer= malloc(sizeof(float));
12402   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12403 
12404   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12405   my_bind->buffer= malloc(sizeof(double));
12406   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12407 
12408   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12409   my_bind->buffer= malloc(sizeof(longlong));
12410   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12411 
12412   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12413   my_bind->buffer= malloc(sizeof(ulonglong));
12414   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12415   my_bind->is_unsigned= TRUE;
12416 
12417   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12418   my_bind->buffer= malloc(sizeof(longlong));
12419   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12420 
12421   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12422   my_bind->buffer= malloc(sizeof(longlong));
12423   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12424 
12425   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12426   my_bind->buffer= malloc(sizeof(longlong));
12427   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12428 
12429   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12430   my_bind->buffer= malloc(sizeof(longlong));
12431   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12432 
12433   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12434   my_bind->buffer= malloc(sizeof(double));
12435   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12436 
12437   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12438   my_bind->buffer= malloc(sizeof(double));
12439   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12440 
12441   rc= mysql_stmt_bind_result(stmt, bind_array);
12442   check_execute(stmt, rc);
12443   rc= mysql_stmt_fetch(stmt);
12444   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12445 
12446   /*************** Verify truncation results ***************************/
12447   my_bind= bind_array;
12448 
12449   /* signed tiny -> tiny */
12450   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == -10);
12451 
12452   /* signed tiny -> uint32 */
12453   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12454   DIE_UNLESS(*my_bind->error && * (int32*) my_bind->buffer == -10);
12455 
12456   /* unsigned tiny -> tiny */
12457   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12458   DIE_UNLESS(*my_bind->error && * (uint8*) my_bind->buffer == 200);
12459 
12460   /* short -> ushort */
12461   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12462   DIE_UNLESS(*my_bind->error && * (int16*) my_bind->buffer == -32767);
12463 
12464   /* ushort -> short */
12465   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12466   DIE_UNLESS(*my_bind->error && * (uint16*) my_bind->buffer == 64000);
12467 
12468   /* short -> ushort (no truncation, data is in the range of target type) */
12469   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12470   DIE_UNLESS(! *my_bind->error && * (uint16*) my_bind->buffer == 32000);
12471 
12472   /* ushort -> utiny */
12473   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12474   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == 0);
12475 
12476   /* int -> float: no truncation, the number is a power of two */
12477   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12478   DIE_UNLESS(! *my_bind->error && * (float*) my_bind->buffer == 1073741824);
12479 
12480   /* int -> float: truncation, not enough bits in float */
12481   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12482   DIE_UNLESS(*my_bind->error);
12483 
12484   /* int -> double: no truncation */
12485   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12486   DIE_UNLESS(! *my_bind->error && * (double*) my_bind->buffer == 1073741825);
12487 
12488   /* double -> longlong: fractional part is lost */
12489   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12490 
12491   /* double -> ulonglong, negative fp number to unsigned integer */
12492   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12493   /* Value in the buffer is not defined: don't test it */
12494   DIE_UNLESS(*my_bind->error);
12495 
12496   /* double -> longlong, negative fp number to signed integer: no loss */
12497   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12498   DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == LL(-12345678910));
12499 
12500   /* big numeric string -> number */
12501   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12502   DIE_UNLESS(*my_bind->error);
12503 
12504   /* junk string -> number */
12505   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12506   DIE_UNLESS(*my_bind->error && *(longlong*) my_bind->buffer == 0);
12507 
12508   /* string with trailing spaces -> number */
12509   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12510   DIE_UNLESS(! *my_bind->error && *(longlong*) my_bind->buffer == 12345);
12511 
12512   /* string with trailing spaces -> double */
12513   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12514   DIE_UNLESS(! *my_bind->error && *(double*) my_bind->buffer == 12345.67);
12515 
12516   /* string with trailing junk -> double */
12517   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12518   /*
12519     XXX: There must be a truncation error: but it's not the way the server
12520     behaves, so let's leave it for now.
12521   */
12522   DIE_UNLESS(*(double*) my_bind->buffer == 12345.67);
12523   /*
12524     TODO: string -> double,  double -> time, double -> string (truncation
12525           errors are not supported here yet)
12526           longlong -> time/date/datetime
12527           date -> time, date -> timestamp, date -> number
12528           time -> string, time -> date, time -> timestamp,
12529           number -> date string -> date
12530   */
12531   /*************** Cleanup *********************************************/
12532 
12533   mysql_stmt_close(stmt);
12534 
12535   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12536     free(my_bind->buffer);
12537   free(bind_array);
12538 
12539   rc= mysql_query(mysql, "drop table t1");
12540   myquery(rc);
12541 }
12542 
test_truncation_option()12543 static void test_truncation_option()
12544 {
12545   MYSQL_STMT *stmt;
12546   const char *stmt_text;
12547   int rc;
12548   uint8 buf;
12549   my_bool option= 0;
12550   my_bool error;
12551   MYSQL_BIND my_bind;
12552 
12553   myheader("test_truncation_option");
12554 
12555   /* Prepare the test table */
12556   stmt_text= "select -1";
12557 
12558   stmt= mysql_stmt_init(mysql);
12559   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12560   check_execute(stmt, rc);
12561   rc= mysql_stmt_execute(stmt);
12562   check_execute(stmt, rc);
12563 
12564   bzero((char*) &my_bind, sizeof(my_bind));
12565 
12566   my_bind.buffer= (void*) &buf;
12567   my_bind.buffer_type= MYSQL_TYPE_TINY;
12568   my_bind.is_unsigned= TRUE;
12569   my_bind.error= &error;
12570 
12571   rc= mysql_stmt_bind_result(stmt, &my_bind);
12572   check_execute(stmt, rc);
12573   rc= mysql_stmt_fetch(stmt);
12574   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12575   DIE_UNLESS(error);
12576   rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
12577   myquery(rc);
12578   /* need to rebind for the new setting to take effect */
12579   rc= mysql_stmt_bind_result(stmt, &my_bind);
12580   check_execute(stmt, rc);
12581   rc= mysql_stmt_execute(stmt);
12582   check_execute(stmt, rc);
12583   rc= mysql_stmt_fetch(stmt);
12584   check_execute(stmt, rc);
12585   /* The only change is rc - error pointers are still filled in */
12586   DIE_UNLESS(error == 1);
12587   /* restore back the defaults */
12588   option= 1;
12589   mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
12590 
12591   mysql_stmt_close(stmt);
12592 }
12593 
12594 
12595 /* Bug#6761 - mysql_list_fields doesn't work */
12596 
test_bug6761(void)12597 static void test_bug6761(void)
12598 {
12599   const char *stmt_text;
12600   MYSQL_RES *res;
12601   int rc;
12602   myheader("test_bug6761");
12603 
12604   stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
12605   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12606   myquery(rc);
12607 
12608   res= mysql_list_fields(mysql, "t1", "%");
12609   DIE_UNLESS(res && mysql_num_fields(res) == 3);
12610   mysql_free_result(res);
12611 
12612   stmt_text= "DROP TABLE t1";
12613   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12614   myquery(rc);
12615 }
12616 
12617 
12618 /* Bug#8330 - mysql_stmt_execute crashes (libmysql) */
12619 
test_bug8330()12620 static void test_bug8330()
12621 {
12622   const char *stmt_text;
12623   MYSQL_STMT *stmt[2];
12624   int i, rc;
12625   const char *query= "select a,b from t1 where a=?";
12626   MYSQL_BIND my_bind[2];
12627   long lval[2];
12628 
12629   myheader("test_bug8330");
12630 
12631   stmt_text= "drop table if exists t1";
12632   /* in case some previos test failed */
12633   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12634   myquery(rc);
12635   stmt_text= "create table t1 (a int, b int)";
12636   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12637   myquery(rc);
12638 
12639   bzero((char*) my_bind, sizeof(my_bind));
12640   for (i=0; i < 2; i++)
12641   {
12642     stmt[i]= mysql_stmt_init(mysql);
12643     rc= mysql_stmt_prepare(stmt[i], query, strlen(query));
12644     check_execute(stmt[i], rc);
12645 
12646     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
12647     my_bind[i].buffer= (void*) &lval[i];
12648     my_bind[i].is_null= 0;
12649     mysql_stmt_bind_param(stmt[i], &my_bind[i]);
12650   }
12651 
12652   rc= mysql_stmt_execute(stmt[0]);
12653   check_execute(stmt[0], rc);
12654 
12655   rc= mysql_stmt_execute(stmt[1]);
12656   DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
12657   rc= mysql_stmt_execute(stmt[0]);
12658   check_execute(stmt[0], rc);
12659 
12660   mysql_stmt_close(stmt[0]);
12661   mysql_stmt_close(stmt[1]);
12662 
12663   stmt_text= "drop table t1";
12664   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12665   myquery(rc);
12666 }
12667 
12668 
12669 /* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */
12670 
test_bug7990()12671 static void test_bug7990()
12672 {
12673   MYSQL_STMT *stmt;
12674   int rc;
12675   myheader("test_bug7990");
12676 
12677   stmt= mysql_stmt_init(mysql);
12678   rc= mysql_stmt_prepare(stmt, "foo", 3);
12679   /*
12680     XXX: the fact that we store errno both in STMT and in
12681     MYSQL is not documented and is subject to change in 5.0
12682   */
12683   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql));
12684   mysql_stmt_close(stmt);
12685   DIE_UNLESS(!mysql_errno(mysql));
12686 }
12687 
12688 /*
12689   Bug #15518 - Reusing a stmt that has failed during prepare
12690   does not clear error
12691 */
12692 
test_bug15518()12693 static void test_bug15518()
12694 {
12695   MYSQL_STMT *stmt;
12696   MYSQL* mysql1;
12697   int rc;
12698   myheader("test_bug15518");
12699 
12700   mysql1= mysql_client_init(NULL);
12701 
12702   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
12703                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
12704                           CLIENT_MULTI_STATEMENTS))
12705   {
12706     fprintf(stderr, "Failed to connect to the database\n");
12707     DIE_UNLESS(0);
12708   }
12709 
12710   stmt= mysql_stmt_init(mysql1);
12711 
12712   /*
12713     The prepare of foo should fail with errno 1064 since
12714     it's not a valid query
12715   */
12716   rc= mysql_stmt_prepare(stmt, "foo", 3);
12717   if (!opt_silent)
12718     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
12719             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
12720   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
12721 
12722   /*
12723     Use the same stmt and reprepare with another query that
12724     suceeds
12725   */
12726   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
12727   if (!opt_silent)
12728     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
12729             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
12730   DIE_UNLESS(!rc || mysql_stmt_errno(stmt) || mysql_errno(mysql1));
12731 
12732   mysql_stmt_close(stmt);
12733   DIE_UNLESS(!mysql_errno(mysql1));
12734 
12735   /*
12736     part2, when connection to server has been closed
12737     after first prepare
12738   */
12739   stmt= mysql_stmt_init(mysql1);
12740   rc= mysql_stmt_prepare(stmt, "foo", 3);
12741   if (!opt_silent)
12742     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
12743             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
12744   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
12745 
12746   /* Close connection to server */
12747   mysql_close(mysql1);
12748 
12749   /*
12750     Use the same stmt and reprepare with another query that
12751     suceeds. The prepare should fail with error 2013 since
12752     connection to server has been closed.
12753   */
12754   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
12755   if (!opt_silent)
12756     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d\n",
12757             rc, mysql_stmt_errno(stmt));
12758   DIE_UNLESS(rc && mysql_stmt_errno(stmt));
12759 
12760   mysql_stmt_close(stmt);
12761 }
12762 
12763 
disable_query_logs()12764 static void disable_query_logs()
12765 {
12766   int rc;
12767   rc= mysql_query(mysql, "set @@global.general_log=off");
12768   myquery(rc);
12769   rc= mysql_query(mysql, "set @@global.slow_query_log=off");
12770   myquery(rc);
12771 }
12772 
12773 
enable_query_logs(int truncate)12774 static void enable_query_logs(int truncate)
12775 {
12776   int rc;
12777 
12778   rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
12779   myquery(rc);
12780 
12781   rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log");
12782   myquery(rc);
12783 
12784   rc= mysql_query(mysql, "set @@global.general_log=on");
12785   myquery(rc);
12786 
12787   rc= mysql_query(mysql, "set @@global.slow_query_log=on");
12788   myquery(rc);
12789 
12790 
12791   if (truncate)
12792   {
12793     rc= mysql_query(mysql, "truncate mysql.general_log");
12794     myquery(rc);
12795 
12796     rc= mysql_query(mysql, "truncate mysql.slow_log");
12797     myquery(rc);
12798   }
12799 }
12800 
12801 
restore_query_logs()12802 static void restore_query_logs()
12803 {
12804   int rc;
12805   rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
12806   myquery(rc);
12807 
12808   rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log");
12809   myquery(rc);
12810 }
12811 
12812 
test_view_sp_list_fields()12813 static void test_view_sp_list_fields()
12814 {
12815   int		rc;
12816   MYSQL_RES     *res;
12817 
12818   myheader("test_view_sp_list_fields");
12819 
12820   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
12821   myquery(rc);
12822   rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
12823   myquery(rc);
12824   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
12825   myquery(rc);
12826   rc= mysql_query(mysql, "create function f1 () returns int return 5");
12827   myquery(rc);
12828   rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
12829   myquery(rc);
12830   rc= mysql_query(mysql, "create table t2 (s1 int);");
12831   myquery(rc);
12832   rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
12833 count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
12834 from t2);");
12835   myquery(rc);
12836   res= mysql_list_fields(mysql, "v1", NullS);
12837   DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0);
12838   rc= mysql_query(mysql, "DROP FUNCTION f1");
12839   myquery(rc);
12840   rc= mysql_query(mysql, "DROP VIEW v1");
12841   myquery(rc);
12842   rc= mysql_query(mysql, "DROP TABLE t1, t2");
12843   mysql_free_result(res);
12844   myquery(rc);
12845 
12846 }
12847 
12848 
12849 /*
12850  Test mysql_real_escape_string() with gbk charset
12851 
12852  The important part is that 0x27 (') is the second-byte in a invalid
12853  two-byte GBK character here. But 0xbf5c is a valid GBK character, so
12854  it needs to be escaped as 0x5cbf27
12855 */
12856 #define TEST_BUG8378_IN  "\xef\xbb\xbf\x27\xbf\x10"
12857 #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
12858 
test_bug8378()12859 static void test_bug8378()
12860 {
12861 #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
12862   MYSQL *lmysql;
12863   char out[9]; /* strlen(TEST_BUG8378)*2+1 */
12864   char buf[256];
12865   int len, rc;
12866 
12867   myheader("test_bug8378");
12868 
12869   if (!opt_silent)
12870     fprintf(stdout, "\n Establishing a test connection ...");
12871   if (!(lmysql= mysql_client_init(NULL)))
12872   {
12873     myerror("mysql_client_init() failed");
12874     exit(1);
12875   }
12876   if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
12877   {
12878     myerror("mysql_options() failed");
12879     exit(1);
12880   }
12881   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
12882                            opt_password, current_db, opt_port,
12883                            opt_unix_socket, 0)))
12884   {
12885     myerror("connection failed");
12886     exit(1);
12887   }
12888   if (!opt_silent)
12889     fprintf(stdout, "OK");
12890 
12891   rc= mysql_query(lmysql, "SET SQL_MODE=''");
12892   myquery(rc);
12893 
12894   len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4);
12895 
12896   /* No escaping should have actually happened. */
12897   DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
12898 
12899   sprintf(buf, "SELECT '%s'", out);
12900 
12901   rc=mysql_real_query(lmysql, buf, strlen(buf));
12902   myquery(rc);
12903 
12904   mysql_close(lmysql);
12905 #endif
12906 }
12907 
12908 
test_bug8722()12909 static void test_bug8722()
12910 {
12911   MYSQL_STMT *stmt;
12912   int rc;
12913   const char *stmt_text;
12914 
12915   myheader("test_bug8722");
12916   /* Prepare test data */
12917   stmt_text= "drop table if exists t1, v1";
12918   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12919   myquery(rc);
12920   stmt_text= "CREATE TABLE t1 (c1 varchar(10), c2 varchar(10), c3 varchar(10),"
12921                              " c4 varchar(10), c5 varchar(10), c6 varchar(10),"
12922                              " c7 varchar(10), c8 varchar(10), c9 varchar(10),"
12923                              "c10 varchar(10))";
12924   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12925   myquery(rc);
12926   stmt_text= "INSERT INTO t1 VALUES (1,2,3,4,5,6,7,8,9,10)";
12927   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12928   myquery(rc);
12929   stmt_text= "CREATE VIEW v1 AS SELECT * FROM t1";
12930   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12931   myquery(rc);
12932   /* Note: if you uncomment following block everything works fine */
12933 /*
12934   rc= mysql_query(mysql, "sellect * from v1");
12935   myquery(rc);
12936   mysql_free_result(mysql_store_result(mysql));
12937 */
12938 
12939   stmt= mysql_stmt_init(mysql);
12940   stmt_text= "select * from v1";
12941   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12942   check_execute(stmt, rc);
12943   mysql_stmt_close(stmt);
12944   stmt_text= "drop table if exists t1, v1";
12945   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12946   myquery(rc);
12947 }
12948 
12949 
open_cursor(const char * query)12950 MYSQL_STMT *open_cursor(const char *query)
12951 {
12952   int rc;
12953   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
12954 
12955   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
12956   rc= mysql_stmt_prepare(stmt, query, strlen(query));
12957   check_execute(stmt, rc);
12958 
12959   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
12960   return stmt;
12961 }
12962 
12963 
test_bug8880()12964 static void test_bug8880()
12965 {
12966   MYSQL_STMT *stmt_list[2], **stmt;
12967   MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
12968   int rc;
12969 
12970   myheader("test_bug8880");
12971 
12972   mysql_query(mysql, "drop table if exists t1");
12973   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
12974   rc= mysql_query(mysql, "insert into t1 values (1,1)");
12975   myquery(rc);                                  /* one check is enough */
12976   /*
12977     when inserting 2 rows everything works well
12978     mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
12979   */
12980   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
12981     *stmt= open_cursor("select a from t1");
12982   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
12983   {
12984     rc= mysql_stmt_execute(*stmt);
12985     check_execute(*stmt, rc);
12986   }
12987   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
12988     mysql_stmt_close(*stmt);
12989 }
12990 
12991 
test_bug9159()12992 static void test_bug9159()
12993 {
12994   MYSQL_STMT *stmt;
12995   int rc;
12996   const char *stmt_text= "select a, b from t1";
12997   const unsigned long type= CURSOR_TYPE_READ_ONLY;
12998 
12999   myheader("test_bug9159");
13000 
13001   mysql_query(mysql, "drop table if exists t1");
13002   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13003   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13004   myquery(rc);
13005 
13006   stmt= mysql_stmt_init(mysql);
13007   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13008   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
13009 
13010   mysql_stmt_execute(stmt);
13011   mysql_stmt_close(stmt);
13012   rc= mysql_query(mysql, "drop table if exists t1");
13013   myquery(rc);
13014 }
13015 
13016 
13017 /* Crash when opening a cursor to a query with DISTICNT and no key */
13018 
test_bug9520()13019 static void test_bug9520()
13020 {
13021   MYSQL_STMT *stmt;
13022   MYSQL_BIND my_bind[1];
13023   char a[6];
13024   ulong a_len;
13025   int rc, row_count= 0;
13026 
13027   myheader("test_bug9520");
13028 
13029   mysql_query(mysql, "drop table if exists t1");
13030   mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
13031                      " primary key (a, b, c))");
13032   rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
13033                   " ('a', 'b', 'c'), ('k', 'l', 'm')");
13034   myquery(rc);
13035 
13036   stmt= open_cursor("select distinct b from t1");
13037 
13038   /*
13039     Not crashes with:
13040     stmt= open_cursor("select distinct a from t1");
13041   */
13042 
13043   rc= mysql_stmt_execute(stmt);
13044   check_execute(stmt, rc);
13045 
13046   bzero((char*) my_bind, sizeof(my_bind));
13047   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13048   my_bind[0].buffer= (char*) a;
13049   my_bind[0].buffer_length= sizeof(a);
13050   my_bind[0].length= &a_len;
13051 
13052   mysql_stmt_bind_result(stmt, my_bind);
13053 
13054   while (!(rc= mysql_stmt_fetch(stmt)))
13055     row_count++;
13056 
13057   DIE_UNLESS(rc == MYSQL_NO_DATA);
13058 
13059   if (!opt_silent)
13060     printf("Fetched %d rows\n", row_count);
13061   DBUG_ASSERT(row_count == 3);
13062 
13063   mysql_stmt_close(stmt);
13064 
13065   rc= mysql_query(mysql, "drop table t1");
13066   myquery(rc);
13067 }
13068 
13069 
13070 /*
13071   We can't have more than one cursor open for a prepared statement.
13072   Test re-executions of a PS with cursor; mysql_stmt_reset must close
13073   the cursor attached to the statement, if there is one.
13074 */
13075 
test_bug9478()13076 static void test_bug9478()
13077 {
13078   MYSQL_STMT *stmt;
13079   MYSQL_BIND my_bind[1];
13080   char a[6];
13081   ulong a_len;
13082   int rc, i;
13083   DBUG_ENTER("test_bug9478");
13084 
13085   myheader("test_bug9478");
13086 
13087   mysql_query(mysql, "drop table if exists t1");
13088   mysql_query(mysql, "create table t1 (id integer not null primary key, "
13089                      " name varchar(20) not null)");
13090   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13091                          " (1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13092   myquery(rc);
13093 
13094   stmt= open_cursor("select name from t1 where id=2");
13095 
13096   bzero((char*) my_bind, sizeof(my_bind));
13097   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13098   my_bind[0].buffer= (char*) a;
13099   my_bind[0].buffer_length= sizeof(a);
13100   my_bind[0].length= &a_len;
13101   mysql_stmt_bind_result(stmt, my_bind);
13102 
13103   for (i= 0; i < 5; i++)
13104   {
13105     rc= mysql_stmt_execute(stmt);
13106     check_execute(stmt, rc);
13107     rc= mysql_stmt_fetch(stmt);
13108     check_execute(stmt, rc);
13109     if (!opt_silent && i == 0)
13110       printf("Fetched row: %s\n", a);
13111 
13112     /*
13113       The query above is a one-row result set. Therefore, there is no
13114       cursor associated with it, as the server won't bother with opening
13115       a cursor for a one-row result set. The first row was read from the
13116       server in the fetch above. But there is eof packet pending in the
13117       network. mysql_stmt_execute will flush the packet and successfully
13118       execute the statement.
13119     */
13120 
13121     rc= mysql_stmt_execute(stmt);
13122     check_execute(stmt, rc);
13123 
13124     rc= mysql_stmt_fetch(stmt);
13125     check_execute(stmt, rc);
13126     if (!opt_silent && i == 0)
13127       printf("Fetched row: %s\n", a);
13128     rc= mysql_stmt_fetch(stmt);
13129     DIE_UNLESS(rc == MYSQL_NO_DATA);
13130 
13131     {
13132       char buff[8];
13133       /* Fill in the fetch packet */
13134       int4store(buff, stmt->stmt_id);
13135       buff[4]= 1;                               /* prefetch rows */
13136       rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
13137                                                (uchar*) buff,
13138                                                sizeof(buff), 0,0,1,NULL) ||
13139            (*mysql->methods->read_query_result)(mysql));
13140       DIE_UNLESS(rc);
13141       if (!opt_silent && i == 0)
13142         printf("Got error (as expected): %s\n", mysql_error(mysql));
13143     }
13144 
13145     rc= mysql_stmt_execute(stmt);
13146     check_execute(stmt, rc);
13147 
13148     rc= mysql_stmt_fetch(stmt);
13149     check_execute(stmt, rc);
13150     if (!opt_silent && i == 0)
13151       printf("Fetched row: %s\n", a);
13152 
13153     rc= mysql_stmt_reset(stmt);
13154     check_execute(stmt, rc);
13155     rc= mysql_stmt_fetch(stmt);
13156     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13157     if (!opt_silent && i == 0)
13158       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13159   }
13160   rc= mysql_stmt_close(stmt);
13161   DIE_UNLESS(rc == 0);
13162 
13163   /* Test the case with a server side cursor */
13164   stmt= open_cursor("select name from t1");
13165 
13166   mysql_stmt_bind_result(stmt, my_bind);
13167 
13168   for (i= 0; i < 5; i++)
13169   {
13170     DBUG_PRINT("loop",("i: %d", i));
13171     rc= mysql_stmt_execute(stmt);
13172     check_execute(stmt, rc);
13173     rc= mysql_stmt_fetch(stmt);
13174     check_execute(stmt, rc);
13175     if (!opt_silent && i == 0)
13176       printf("Fetched row: %s\n", a);
13177     rc= mysql_stmt_execute(stmt);
13178     check_execute(stmt, rc);
13179 
13180     while (! (rc= mysql_stmt_fetch(stmt)))
13181     {
13182       if (!opt_silent && i == 0)
13183         printf("Fetched row: %s\n", a);
13184     }
13185     DIE_UNLESS(rc == MYSQL_NO_DATA);
13186 
13187     rc= mysql_stmt_execute(stmt);
13188     check_execute(stmt, rc);
13189 
13190     rc= mysql_stmt_fetch(stmt);
13191     check_execute(stmt, rc);
13192     if (!opt_silent && i == 0)
13193       printf("Fetched row: %s\n", a);
13194 
13195     rc= mysql_stmt_reset(stmt);
13196     check_execute(stmt, rc);
13197     rc= mysql_stmt_fetch(stmt);
13198     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13199     if (!opt_silent && i == 0)
13200       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13201   }
13202 
13203   rc= mysql_stmt_close(stmt);
13204   DIE_UNLESS(rc == 0);
13205 
13206   rc= mysql_query(mysql, "drop table t1");
13207   myquery(rc);
13208   DBUG_VOID_RETURN;
13209 }
13210 
13211 
13212 /*
13213   Error message is returned for unsupported features.
13214   Test also cursors with non-default PREFETCH_ROWS
13215 */
13216 
test_bug9643()13217 static void test_bug9643()
13218 {
13219   MYSQL_STMT *stmt;
13220   MYSQL_BIND my_bind[1];
13221   int32 a;
13222   int rc;
13223   const char *stmt_text;
13224   int num_rows= 0;
13225   ulong type;
13226   ulong prefetch_rows= 5;
13227 
13228   myheader("test_bug9643");
13229 
13230   mysql_query(mysql, "drop table if exists t1");
13231   mysql_query(mysql, "create table t1 (id integer not null primary key)");
13232   rc= mysql_query(mysql, "insert into t1 (id) values "
13233                          " (1), (2), (3), (4), (5), (6), (7), (8), (9)");
13234   myquery(rc);
13235 
13236   stmt= mysql_stmt_init(mysql);
13237   /* Not implemented in 5.0 */
13238   type= (ulong) CURSOR_TYPE_SCROLLABLE;
13239   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13240   DIE_UNLESS(rc);
13241   if (! opt_silent)
13242     printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13243 
13244   type= (ulong) CURSOR_TYPE_READ_ONLY;
13245   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13246   check_execute(stmt, rc);
13247   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
13248                           (void*) &prefetch_rows);
13249   check_execute(stmt, rc);
13250   stmt_text= "select * from t1";
13251   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13252   check_execute(stmt, rc);
13253 
13254   bzero((char*) my_bind, sizeof(my_bind));
13255   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13256   my_bind[0].buffer= (void*) &a;
13257   my_bind[0].buffer_length= sizeof(a);
13258   mysql_stmt_bind_result(stmt, my_bind);
13259 
13260   rc= mysql_stmt_execute(stmt);
13261   check_execute(stmt, rc);
13262 
13263   while ((rc= mysql_stmt_fetch(stmt)) == 0)
13264     ++num_rows;
13265   DIE_UNLESS(num_rows == 9);
13266 
13267   rc= mysql_stmt_close(stmt);
13268   DIE_UNLESS(rc == 0);
13269 
13270   rc= mysql_query(mysql, "drop table t1");
13271   myquery(rc);
13272 }
13273 
13274 /*
13275   Bug#11111: fetch from view returns wrong data
13276 */
13277 
test_bug11111()13278 static void test_bug11111()
13279 {
13280   MYSQL_STMT    *stmt;
13281   MYSQL_BIND    my_bind[2];
13282   char          buf[2][20];
13283   ulong         len[2];
13284   int i;
13285   int rc;
13286   const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
13287 
13288   myheader("test_bug11111");
13289 
13290   rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
13291   myquery(rc);
13292   rc= mysql_query(mysql, "drop view if exists t1, t2, v1");
13293   myquery(rc);
13294   rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)");
13295   myquery(rc);
13296   rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)");
13297   myquery(rc);
13298   rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1");
13299   myquery(rc);
13300   rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)");
13301   myquery(rc);
13302   rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
13303   myquery(rc);
13304 
13305   stmt= mysql_stmt_init(mysql);
13306 
13307   mysql_stmt_prepare(stmt, query, strlen(query));
13308   mysql_stmt_execute(stmt);
13309 
13310   bzero((char*) my_bind, sizeof(my_bind));
13311   for (i=0; i < 2; i++)
13312   {
13313     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
13314     my_bind[i].buffer= (uchar* *)&buf[i];
13315     my_bind[i].buffer_length= 20;
13316     my_bind[i].length= &len[i];
13317   }
13318 
13319   rc= mysql_stmt_bind_result(stmt, my_bind);
13320   check_execute(stmt, rc);
13321 
13322   rc= mysql_stmt_fetch(stmt);
13323   check_execute(stmt, rc);
13324   if (!opt_silent)
13325     printf("return: %s", buf[1]);
13326   DIE_UNLESS(!strcmp(buf[1],"1"));
13327   mysql_stmt_close(stmt);
13328   rc= mysql_query(mysql, "drop view v1");
13329   myquery(rc);
13330   rc= mysql_query(mysql, "drop table t1, t2");
13331   myquery(rc);
13332 }
13333 
13334 /*
13335   Check that proper cleanups are done for prepared statement when
13336   fetching thorugh a cursor.
13337 */
13338 
test_bug10729()13339 static void test_bug10729()
13340 {
13341   MYSQL_STMT *stmt;
13342   MYSQL_BIND my_bind[1];
13343   char a[21];
13344   int rc;
13345   const char *stmt_text;
13346   int i= 0;
13347   const char *name_array[3]= { "aaa", "bbb", "ccc" };
13348   ulong type;
13349 
13350   myheader("test_bug10729");
13351 
13352   mysql_query(mysql, "drop table if exists t1");
13353   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13354                                       "name VARCHAR(20) NOT NULL)");
13355   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13356                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13357   myquery(rc);
13358 
13359   stmt= mysql_stmt_init(mysql);
13360 
13361   type= (ulong) CURSOR_TYPE_READ_ONLY;
13362   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13363   check_execute(stmt, rc);
13364   stmt_text= "select name from t1";
13365   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13366   check_execute(stmt, rc);
13367 
13368   bzero((char*) my_bind, sizeof(my_bind));
13369   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13370   my_bind[0].buffer= (void*) a;
13371   my_bind[0].buffer_length= sizeof(a);
13372   mysql_stmt_bind_result(stmt, my_bind);
13373 
13374   for (i= 0; i < 3; i++)
13375   {
13376     int row_no= 0;
13377     rc= mysql_stmt_execute(stmt);
13378     check_execute(stmt, rc);
13379     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13380     {
13381       DIE_UNLESS(strcmp(a, name_array[row_no]) == 0);
13382       if (!opt_silent)
13383         printf("%d: %s\n", row_no, a);
13384       ++row_no;
13385     }
13386     DIE_UNLESS(rc == MYSQL_NO_DATA);
13387   }
13388   rc= mysql_stmt_close(stmt);
13389   DIE_UNLESS(rc == 0);
13390 
13391   rc= mysql_query(mysql, "drop table t1");
13392   myquery(rc);
13393 }
13394 
13395 
13396 /*
13397   Check that mysql_next_result works properly in case when one of
13398   the statements used in a multi-statement query is erroneous
13399 */
13400 
test_bug9992()13401 static void test_bug9992()
13402 {
13403   MYSQL *mysql1;
13404   MYSQL_RES* res ;
13405   int   rc;
13406 
13407   myheader("test_bug9992");
13408 
13409   if (!opt_silent)
13410     printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
13411 
13412   mysql1= mysql_client_init(NULL);
13413 
13414   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13415                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13416                           CLIENT_MULTI_STATEMENTS))
13417   {
13418     fprintf(stderr, "Failed to connect to the database\n");
13419     DIE_UNLESS(0);
13420   }
13421 
13422 
13423   /* Sic: SHOW DATABASE is incorrect syntax. */
13424   rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;");
13425 
13426   if (rc)
13427   {
13428     fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1));
13429     DIE_UNLESS(0);
13430   }
13431 
13432   if (!opt_silent)
13433     printf("Testing mysql_store_result/mysql_next_result..\n");
13434 
13435   res= mysql_store_result(mysql1);
13436   DIE_UNLESS(res);
13437   mysql_free_result(res);
13438   rc= mysql_next_result(mysql1);
13439   DIE_UNLESS(rc == 1);                         /* Got errors, as expected */
13440 
13441   if (!opt_silent)
13442     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
13443             mysql_errno(mysql1), mysql_error(mysql1));
13444 
13445   mysql_close(mysql1);
13446 }
13447 
13448 /* Bug#10736: cursors and subqueries, memroot management */
13449 
test_bug10736()13450 static void test_bug10736()
13451 {
13452   MYSQL_STMT *stmt;
13453   MYSQL_BIND my_bind[1];
13454   char a[21];
13455   int rc;
13456   const char *stmt_text;
13457   int i= 0;
13458   ulong type;
13459 
13460   myheader("test_bug10736");
13461 
13462   mysql_query(mysql, "drop table if exists t1");
13463   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13464                                       "name VARCHAR(20) NOT NULL)");
13465   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13466                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13467   myquery(rc);
13468 
13469   stmt= mysql_stmt_init(mysql);
13470 
13471   type= (ulong) CURSOR_TYPE_READ_ONLY;
13472   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13473   check_execute(stmt, rc);
13474   stmt_text= "select name from t1 where name=(select name from t1 where id=2)";
13475   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13476   check_execute(stmt, rc);
13477 
13478   bzero((char*) my_bind, sizeof(my_bind));
13479   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13480   my_bind[0].buffer= (void*) a;
13481   my_bind[0].buffer_length= sizeof(a);
13482   mysql_stmt_bind_result(stmt, my_bind);
13483 
13484   for (i= 0; i < 3; i++)
13485   {
13486     int row_no= 0;
13487     rc= mysql_stmt_execute(stmt);
13488     check_execute(stmt, rc);
13489     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13490     {
13491       if (!opt_silent)
13492         printf("%d: %s\n", row_no, a);
13493       ++row_no;
13494     }
13495     DIE_UNLESS(rc == MYSQL_NO_DATA);
13496   }
13497   rc= mysql_stmt_close(stmt);
13498   DIE_UNLESS(rc == 0);
13499 
13500   rc= mysql_query(mysql, "drop table t1");
13501   myquery(rc);
13502 }
13503 
13504 /* Bug#10794: cursors, packets out of order */
13505 
test_bug10794()13506 static void test_bug10794()
13507 {
13508   MYSQL_STMT *stmt, *stmt1;
13509   MYSQL_BIND my_bind[2];
13510   char a[21];
13511   int id_val;
13512   ulong a_len;
13513   int rc;
13514   const char *stmt_text;
13515   int i= 0;
13516   ulong type;
13517 
13518   myheader("test_bug10794");
13519 
13520   mysql_query(mysql, "drop table if exists t1");
13521   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13522                                       "name varchar(20) not null)");
13523   stmt= mysql_stmt_init(mysql);
13524   stmt_text= "insert into t1 (id, name) values (?, ?)";
13525   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13526   check_execute(stmt, rc);
13527   bzero((char*) my_bind, sizeof(my_bind));
13528   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13529   my_bind[0].buffer= (void*) &id_val;
13530   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
13531   my_bind[1].buffer= (void*) a;
13532   my_bind[1].length= &a_len;
13533   rc= mysql_stmt_bind_param(stmt, my_bind);
13534   check_execute(stmt, rc);
13535   for (i= 0; i < 42; i++)
13536   {
13537     id_val= (i+1)*10;
13538     sprintf(a, "a%d", i);
13539     a_len= strlen(a); /* safety against broken sprintf */
13540     rc= mysql_stmt_execute(stmt);
13541     check_execute(stmt, rc);
13542   }
13543   stmt_text= "select name from t1";
13544   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13545   type= (ulong) CURSOR_TYPE_READ_ONLY;
13546   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13547   stmt1= mysql_stmt_init(mysql);
13548   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13549   bzero((char*) my_bind, sizeof(my_bind));
13550   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13551   my_bind[0].buffer= (void*) a;
13552   my_bind[0].buffer_length= sizeof(a);
13553   my_bind[0].length= &a_len;
13554   rc= mysql_stmt_bind_result(stmt, my_bind);
13555   check_execute(stmt, rc);
13556   rc= mysql_stmt_execute(stmt);
13557   check_execute(stmt, rc);
13558   rc= mysql_stmt_fetch(stmt);
13559   check_execute(stmt, rc);
13560   if (!opt_silent)
13561     printf("Fetched row from stmt: %s\n", a);
13562   /* Don't optimize: an attribute of the original test case */
13563   mysql_stmt_free_result(stmt);
13564   mysql_stmt_reset(stmt);
13565   stmt_text= "select name from t1 where id=10";
13566   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
13567   check_execute(stmt1, rc);
13568   rc= mysql_stmt_bind_result(stmt1, my_bind);
13569   check_execute(stmt1, rc);
13570   rc= mysql_stmt_execute(stmt1);
13571   while (1)
13572   {
13573     rc= mysql_stmt_fetch(stmt1);
13574     if (rc == MYSQL_NO_DATA)
13575     {
13576       if (!opt_silent)
13577         printf("End of data in stmt1\n");
13578       break;
13579     }
13580     check_execute(stmt1, rc);
13581     if (!opt_silent)
13582       printf("Fetched row from stmt1: %s\n", a);
13583   }
13584   mysql_stmt_close(stmt);
13585   mysql_stmt_close(stmt1);
13586 
13587   rc= mysql_query(mysql, "drop table t1");
13588   myquery(rc);
13589 }
13590 
13591 
13592 /* Bug#11172: cursors, crash on a fetch from a datetime column */
13593 
test_bug11172()13594 static void test_bug11172()
13595 {
13596   MYSQL_STMT *stmt;
13597   MYSQL_BIND bind_in[1], bind_out[2];
13598   MYSQL_TIME hired;
13599   int rc;
13600   const char *stmt_text;
13601   int i= 0, id;
13602   ulong type;
13603 
13604   myheader("test_bug11172");
13605 
13606   mysql_query(mysql, "drop table if exists t1");
13607   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13608                                       "hired date not null)");
13609   rc= mysql_query(mysql,
13610                   "insert into t1 (id, hired) values (1, '1933-08-24'), "
13611                   "(2, '1965-01-01'), (3, '1949-08-17'), (4, '1945-07-07'), "
13612                   "(5, '1941-05-15'), (6, '1978-09-15'), (7, '1936-03-28')");
13613   myquery(rc);
13614   stmt= mysql_stmt_init(mysql);
13615   stmt_text= "SELECT id, hired FROM t1 WHERE hired=?";
13616   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13617   check_execute(stmt, rc);
13618 
13619   type= (ulong) CURSOR_TYPE_READ_ONLY;
13620   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13621 
13622   bzero((char*) bind_in, sizeof(bind_in));
13623   bzero((char*) bind_out, sizeof(bind_out));
13624   bzero((char*) &hired, sizeof(hired));
13625   hired.year= 1965;
13626   hired.month= 1;
13627   hired.day= 1;
13628   bind_in[0].buffer_type= MYSQL_TYPE_DATE;
13629   bind_in[0].buffer= (void*) &hired;
13630   bind_in[0].buffer_length= sizeof(hired);
13631   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
13632   bind_out[0].buffer= (void*) &id;
13633   bind_out[1]= bind_in[0];
13634 
13635   for (i= 0; i < 3; i++)
13636   {
13637     rc= mysql_stmt_bind_param(stmt, bind_in);
13638     check_execute(stmt, rc);
13639     rc= mysql_stmt_bind_result(stmt, bind_out);
13640     check_execute(stmt, rc);
13641     rc= mysql_stmt_execute(stmt);
13642     check_execute(stmt, rc);
13643     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13644     {
13645       if (!opt_silent)
13646         printf("fetched data %d:%d-%d-%d\n", id,
13647                hired.year, hired.month, hired.day);
13648     }
13649     DIE_UNLESS(rc == MYSQL_NO_DATA);
13650     if (!mysql_stmt_free_result(stmt))
13651       mysql_stmt_reset(stmt);
13652   }
13653   mysql_stmt_close(stmt);
13654   mysql_rollback(mysql);
13655   mysql_rollback(mysql);
13656 
13657   rc= mysql_query(mysql, "drop table t1");
13658   myquery(rc);
13659 }
13660 
13661 
13662 /* Bug#11656: cursors, crash on a fetch from a query with distinct. */
13663 
test_bug11656()13664 static void test_bug11656()
13665 {
13666   MYSQL_STMT *stmt;
13667   MYSQL_BIND my_bind[2];
13668   int rc;
13669   const char *stmt_text;
13670   char buf[2][20];
13671   int i= 0;
13672   ulong type;
13673 
13674   myheader("test_bug11656");
13675 
13676   mysql_query(mysql, "drop table if exists t1");
13677 
13678   rc= mysql_query(mysql, "create table t1 ("
13679                   "server varchar(40) not null, "
13680                   "test_kind varchar(1) not null, "
13681                   "test_id varchar(30) not null , "
13682                   "primary key (server,test_kind,test_id))");
13683   myquery(rc);
13684 
13685   stmt_text= "select distinct test_kind, test_id from t1 "
13686              "where server in (?, ?)";
13687   stmt= mysql_stmt_init(mysql);
13688   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13689   check_execute(stmt, rc);
13690   type= (ulong) CURSOR_TYPE_READ_ONLY;
13691   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13692 
13693   bzero((char*) my_bind, sizeof(my_bind));
13694   strmov(buf[0], "pcint502_MY2");
13695   strmov(buf[1], "*");
13696   for (i=0; i < 2; i++)
13697   {
13698     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
13699     my_bind[i].buffer= (uchar* *)&buf[i];
13700     my_bind[i].buffer_length= strlen(buf[i]);
13701   }
13702   mysql_stmt_bind_param(stmt, my_bind);
13703 
13704   rc= mysql_stmt_execute(stmt);
13705   check_execute(stmt, rc);
13706 
13707   rc= mysql_stmt_fetch(stmt);
13708   DIE_UNLESS(rc == MYSQL_NO_DATA);
13709 
13710   mysql_stmt_close(stmt);
13711   rc= mysql_query(mysql, "drop table t1");
13712   myquery(rc);
13713 }
13714 
13715 
13716 /*
13717   Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
13718   and mysql_real_escape_string() does the right thing as a result.
13719 */
13720 
test_bug10214()13721 static void test_bug10214()
13722 {
13723   int   len;
13724   char  out[8];
13725 
13726   myheader("test_bug10214");
13727 
13728   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
13729 
13730   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
13731   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
13732 
13733   mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
13734   DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
13735 
13736   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
13737   DIE_UNLESS(memcmp(out, "a''b\\c", len) == 0);
13738 
13739   mysql_query(mysql, "set sql_mode=''");
13740 }
13741 
test_client_character_set()13742 static void test_client_character_set()
13743 {
13744   MY_CHARSET_INFO cs;
13745   char *csname= (char*) "utf8";
13746   char *csdefault= (char*)mysql_character_set_name(mysql);
13747   int rc;
13748 
13749   myheader("test_client_character_set");
13750 
13751   rc= mysql_set_character_set(mysql, csname);
13752   DIE_UNLESS(rc == 0);
13753 
13754   mysql_get_character_set_info(mysql, &cs);
13755   DIE_UNLESS(!strcmp(cs.csname, "utf8"));
13756   DIE_UNLESS(!strcmp(cs.name, "utf8_general_ci"));
13757   /* Restore the default character set */
13758   rc= mysql_set_character_set(mysql, csdefault);
13759   myquery(rc);
13760 }
13761 
13762 /* Test correct max length for MEDIUMTEXT and LONGTEXT columns */
13763 
test_bug9735()13764 static void test_bug9735()
13765 {
13766   MYSQL_RES *res;
13767   int rc;
13768 
13769   myheader("test_bug9735");
13770 
13771   rc= mysql_query(mysql, "drop table if exists t1");
13772   myquery(rc);
13773   rc= mysql_query(mysql, "create table t1 (a mediumtext, b longtext) "
13774                          "character set latin1");
13775   myquery(rc);
13776   rc= mysql_query(mysql, "select * from t1");
13777   myquery(rc);
13778   res= mysql_store_result(mysql);
13779   verify_prepare_field(res, 0, "a", "a", MYSQL_TYPE_BLOB,
13780                        "t1", "t1", current_db, (1U << 24)-1, 0);
13781   verify_prepare_field(res, 1, "b", "b", MYSQL_TYPE_BLOB,
13782                        "t1", "t1", current_db, ~0U, 0);
13783   mysql_free_result(res);
13784   rc= mysql_query(mysql, "drop table t1");
13785   myquery(rc);
13786 }
13787 
13788 
13789 /* Bug#11183 "mysql_stmt_reset() doesn't reset information about error" */
13790 
test_bug11183()13791 static void test_bug11183()
13792 {
13793   int rc;
13794   MYSQL_STMT *stmt;
13795   char bug_statement[]= "insert into t1 values (1)";
13796 
13797   myheader("test_bug11183");
13798 
13799   mysql_query(mysql, "drop table t1 if exists");
13800   mysql_query(mysql, "create table t1 (a int)");
13801 
13802   stmt= mysql_stmt_init(mysql);
13803   DIE_UNLESS(stmt != 0);
13804 
13805   rc= mysql_stmt_prepare(stmt, bug_statement, strlen(bug_statement));
13806   check_execute(stmt, rc);
13807 
13808   rc= mysql_query(mysql, "drop table t1");
13809   myquery(rc);
13810 
13811   /* Trying to execute statement that should fail on execute stage */
13812   rc= mysql_stmt_execute(stmt);
13813   DIE_UNLESS(rc);
13814 
13815   mysql_stmt_reset(stmt);
13816   DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
13817 
13818   mysql_query(mysql, "create table t1 (a int)");
13819 
13820   /* Trying to execute statement that should pass ok */
13821   if (mysql_stmt_execute(stmt))
13822   {
13823     mysql_stmt_reset(stmt);
13824     DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
13825   }
13826 
13827   mysql_stmt_close(stmt);
13828 
13829   rc= mysql_query(mysql, "drop table t1");
13830   myquery(rc);
13831 }
13832 
test_bug11037()13833 static void test_bug11037()
13834 {
13835   MYSQL_STMT *stmt;
13836   int rc;
13837   const char *stmt_text;
13838 
13839   myheader("test_bug11037");
13840 
13841   mysql_query(mysql, "drop table if exists t1");
13842 
13843   rc= mysql_query(mysql, "create table t1 (id int not null)");
13844   myquery(rc);
13845 
13846   rc= mysql_query(mysql, "insert into t1 values (1)");
13847   myquery(rc);
13848 
13849   stmt_text= "select id FROM t1";
13850   stmt= mysql_stmt_init(mysql);
13851   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13852 
13853   /* expected error */
13854   rc = mysql_stmt_fetch(stmt);
13855   DIE_UNLESS(rc==1);
13856   if (!opt_silent)
13857     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
13858             mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
13859 
13860   rc= mysql_stmt_execute(stmt);
13861   check_execute(stmt, rc);
13862 
13863   rc= mysql_stmt_fetch(stmt);
13864   DIE_UNLESS(rc==0);
13865 
13866   rc= mysql_stmt_fetch(stmt);
13867   DIE_UNLESS(rc==MYSQL_NO_DATA);
13868 
13869   rc= mysql_stmt_fetch(stmt);
13870   DIE_UNLESS(rc==MYSQL_NO_DATA);
13871 
13872   mysql_stmt_close(stmt);
13873   rc= mysql_query(mysql, "drop table t1");
13874   myquery(rc);
13875 }
13876 
13877 /* Bug#10760: cursors, crash in a fetch after rollback. */
13878 
test_bug10760()13879 static void test_bug10760()
13880 {
13881   MYSQL_STMT *stmt;
13882   MYSQL_BIND my_bind[1];
13883   int rc;
13884   const char *stmt_text;
13885   char id_buf[20];
13886   ulong id_len;
13887   int i= 0;
13888   ulong type;
13889 
13890   myheader("test_bug10760");
13891 
13892   mysql_query(mysql, "drop table if exists t1, t2");
13893 
13894   /* create tables */
13895   rc= mysql_query(mysql, "create table t1 (id integer not null primary key)"
13896                          " engine=MyISAM");
13897   myquery(rc);
13898   for (; i < 42; ++i)
13899   {
13900     char buf[100];
13901     sprintf(buf, "insert into t1 (id) values (%d)", i+1);
13902     rc= mysql_query(mysql, buf);
13903     myquery(rc);
13904   }
13905   mysql_autocommit(mysql, FALSE);
13906   /* create statement */
13907   stmt= mysql_stmt_init(mysql);
13908   type= (ulong) CURSOR_TYPE_READ_ONLY;
13909   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13910 
13911   /*
13912     1: check that a deadlock within the same connection
13913     is resolved and an error is returned. The deadlock is modelled
13914     as follows:
13915     con1: open cursor for select * from t1;
13916     con1: insert into t1 (id) values (1)
13917   */
13918   stmt_text= "select id from t1 order by 1";
13919   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13920   check_execute(stmt, rc);
13921   rc= mysql_stmt_execute(stmt);
13922   check_execute(stmt, rc);
13923   rc= mysql_query(mysql, "update t1 set id=id+100");
13924   /*
13925     If cursors are not materialized, the update will return an error;
13926     we mainly test that it won't deadlock.
13927   */
13928   if (rc && !opt_silent)
13929     printf("Got error (as expected): %s\n", mysql_error(mysql));
13930   /*
13931     2: check that MyISAM tables used in cursors survive
13932     COMMIT/ROLLBACK.
13933   */
13934   rc= mysql_rollback(mysql);                  /* should not close the cursor */
13935   myquery(rc);
13936   rc= mysql_stmt_fetch(stmt);
13937   check_execute(stmt, rc);
13938 
13939   /*
13940     3: check that cursors to InnoDB tables are closed (for now) by
13941     COMMIT/ROLLBACK.
13942   */
13943   if (! have_innodb)
13944   {
13945     if (!opt_silent)
13946       printf("Testing that cursors are closed at COMMIT/ROLLBACK requires "
13947              "InnoDB.\n");
13948   }
13949   else
13950   {
13951     stmt_text= "select id from t1 order by 1";
13952     rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13953     check_execute(stmt, rc);
13954 
13955     rc= mysql_query(mysql, "alter table t1 engine=InnoDB");
13956     myquery(rc);
13957 
13958     bzero(my_bind, sizeof(my_bind));
13959     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13960     my_bind[0].buffer= (void*) id_buf;
13961     my_bind[0].buffer_length= sizeof(id_buf);
13962     my_bind[0].length= &id_len;
13963     check_execute(stmt, rc);
13964     mysql_stmt_bind_result(stmt, my_bind);
13965 
13966     rc= mysql_stmt_execute(stmt);
13967     rc= mysql_stmt_fetch(stmt);
13968     DIE_UNLESS(rc == 0);
13969     if (!opt_silent)
13970       printf("Fetched row %s\n", id_buf);
13971     rc= mysql_rollback(mysql);                  /* should close the cursor */
13972     myquery(rc);
13973 #if 0
13974     rc= mysql_stmt_fetch(stmt);
13975     DIE_UNLESS(rc);
13976     if (!opt_silent)
13977       printf("Got error (as expected): %s\n", mysql_error(mysql));
13978 #endif
13979   }
13980 
13981   mysql_stmt_close(stmt);
13982   rc= mysql_query(mysql, "drop table t1");
13983   myquery(rc);
13984   mysql_autocommit(mysql, TRUE);                /* restore default */
13985 }
13986 
test_bug12001()13987 static void test_bug12001()
13988 {
13989   MYSQL *mysql_local;
13990   MYSQL_RES *result;
13991   const char *query= "DROP TABLE IF EXISTS test_table;"
13992                      "CREATE TABLE test_table(id INT);"
13993                      "INSERT INTO test_table VALUES(10);"
13994                      "UPDATE test_table SET id=20 WHERE id=10;"
13995                      "SELECT * FROM test_table;"
13996                      "INSERT INTO non_existent_table VALUES(11);";
13997   int rc, res;
13998 
13999   myheader("test_bug12001");
14000 
14001   if (!(mysql_local= mysql_client_init(NULL)))
14002   {
14003     fprintf(stdout, "\n mysql_client_init() failed");
14004     exit(1);
14005   }
14006 
14007   /* Create connection that supports multi statements */
14008   if (!mysql_real_connect(mysql_local, opt_host, opt_user,
14009                           opt_password, current_db, opt_port,
14010                           opt_unix_socket, CLIENT_MULTI_STATEMENTS))
14011   {
14012     fprintf(stdout, "\n mysql_real_connect() failed");
14013     exit(1);
14014   }
14015 
14016   rc= mysql_query(mysql_local, query);
14017   myquery(rc);
14018 
14019   do
14020   {
14021     if (mysql_field_count(mysql_local) &&
14022         (result= mysql_use_result(mysql_local)))
14023     {
14024       mysql_free_result(result);
14025     }
14026   }
14027   while (!(res= mysql_next_result(mysql_local)));
14028 
14029   rc= mysql_query(mysql_local, "DROP TABLE IF EXISTS test_table");
14030   myquery(rc);
14031 
14032   mysql_close(mysql_local);
14033   DIE_UNLESS(res==1);
14034 }
14035 
14036 
14037 /* Bug#11909: wrong metadata if fetching from two cursors */
14038 
test_bug11909()14039 static void test_bug11909()
14040 {
14041   MYSQL_STMT *stmt1, *stmt2;
14042   MYSQL_BIND my_bind[7];
14043   int rc;
14044   char firstname[20], midinit[20], lastname[20], workdept[20];
14045   ulong firstname_len, midinit_len, lastname_len, workdept_len;
14046   uint32 empno;
14047   double salary;
14048   float bonus;
14049   const char *stmt_text;
14050 
14051   myheader("test_bug11909");
14052 
14053   stmt_text= "drop table if exists t1";
14054   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14055   myquery(rc);
14056 
14057   stmt_text= "create table t1 ("
14058     "  empno int(11) not null, firstname varchar(20) not null,"
14059     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14060     "  workdept varchar(6) not null, salary double not null,"
14061     "  bonus float not null, primary key (empno)"
14062     ") default charset=latin1 collate=latin1_bin";
14063   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14064   myquery(rc);
14065 
14066   stmt_text= "insert into t1 values "
14067     "(10, 'CHRISTINE', 'I', 'HAAS',     'A00', 52750, 1000), "
14068     "(20, 'MICHAEL',   'L', 'THOMPSON', 'B01', 41250, 800),"
14069     "(30, 'SALLY',     'A', 'KWAN',     'C01', 38250, 800),"
14070     "(50, 'JOHN',      'B', 'GEYER',    'E01', 40175, 800), "
14071     "(60, 'IRVING',    'F', 'STERN',    'D11', 32250, 500)";
14072   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14073   myquery(rc);
14074 
14075   /* ****** Begin of trace ****** */
14076 
14077   stmt1= open_cursor("SELECT empno, firstname, midinit, lastname,"
14078                      "workdept, salary, bonus FROM t1");
14079 
14080   bzero(my_bind, sizeof(my_bind));
14081   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14082   my_bind[0].buffer= (void*) &empno;
14083 
14084   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14085   my_bind[1].buffer= (void*) firstname;
14086   my_bind[1].buffer_length= sizeof(firstname);
14087   my_bind[1].length= &firstname_len;
14088 
14089   my_bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;
14090   my_bind[2].buffer= (void*) midinit;
14091   my_bind[2].buffer_length= sizeof(midinit);
14092   my_bind[2].length= &midinit_len;
14093 
14094   my_bind[3].buffer_type= MYSQL_TYPE_VAR_STRING;
14095   my_bind[3].buffer= (void*) lastname;
14096   my_bind[3].buffer_length= sizeof(lastname);
14097   my_bind[3].length= &lastname_len;
14098 
14099   my_bind[4].buffer_type= MYSQL_TYPE_VAR_STRING;
14100   my_bind[4].buffer= (void*) workdept;
14101   my_bind[4].buffer_length= sizeof(workdept);
14102   my_bind[4].length= &workdept_len;
14103 
14104   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
14105   my_bind[5].buffer= (void*) &salary;
14106 
14107   my_bind[6].buffer_type= MYSQL_TYPE_FLOAT;
14108   my_bind[6].buffer= (void*) &bonus;
14109   rc= mysql_stmt_bind_result(stmt1, my_bind);
14110   check_execute(stmt1, rc);
14111 
14112   rc= mysql_stmt_execute(stmt1);
14113   check_execute(stmt1, rc);
14114 
14115   rc= mysql_stmt_fetch(stmt1);
14116   DIE_UNLESS(rc == 0);
14117   DIE_UNLESS(empno == 10);
14118   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14119   DIE_UNLESS(strcmp(midinit, "I") == 0);
14120   DIE_UNLESS(strcmp(lastname, "HAAS") == 0);
14121   DIE_UNLESS(strcmp(workdept, "A00") == 0);
14122   DIE_UNLESS(salary == (double) 52750.0);
14123   DIE_UNLESS(bonus == (float) 1000.0);
14124 
14125   stmt2= open_cursor("SELECT empno, firstname FROM t1");
14126   rc= mysql_stmt_bind_result(stmt2, my_bind);
14127   check_execute(stmt2, rc);
14128 
14129   rc= mysql_stmt_execute(stmt2);
14130   check_execute(stmt2, rc);
14131 
14132   rc= mysql_stmt_fetch(stmt2);
14133   DIE_UNLESS(rc == 0);
14134 
14135   DIE_UNLESS(empno == 10);
14136   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14137 
14138   rc= mysql_stmt_reset(stmt2);
14139   check_execute(stmt2, rc);
14140 
14141   /* ERROR: next statement should return 0 */
14142 
14143   rc= mysql_stmt_fetch(stmt1);
14144   DIE_UNLESS(rc == 0);
14145 
14146   mysql_stmt_close(stmt1);
14147   mysql_stmt_close(stmt2);
14148   rc= mysql_rollback(mysql);
14149   myquery(rc);
14150 
14151   rc= mysql_query(mysql, "drop table t1");
14152   myquery(rc);
14153 }
14154 
14155 /* Cursors: opening a cursor to a compilicated query with ORDER BY */
14156 
test_bug11901()14157 static void test_bug11901()
14158 {
14159   MYSQL_STMT *stmt;
14160   MYSQL_BIND my_bind[2];
14161   int rc;
14162   char workdept[20];
14163   ulong workdept_len;
14164   uint32 empno;
14165   const char *stmt_text;
14166 
14167   myheader("test_bug11901");
14168 
14169   stmt_text= "drop table if exists t1, t2";
14170   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14171   myquery(rc);
14172 
14173   stmt_text= "create table t1 ("
14174     "  empno int(11) not null, firstname varchar(20) not null,"
14175     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14176     "  workdept varchar(6) not null, salary double not null,"
14177     "  bonus float not null, primary key (empno), "
14178     " unique key (workdept, empno) "
14179     ") default charset=latin1 collate=latin1_bin";
14180   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14181   myquery(rc);
14182 
14183   stmt_text= "insert into t1 values "
14184      "(10,  'CHRISTINE', 'I', 'HAAS',      'A00', 52750, 1000),"
14185      "(20,  'MICHAEL',   'L', 'THOMPSON',  'B01', 41250, 800), "
14186      "(30,  'SALLY',     'A', 'KWAN',      'C01', 38250, 800), "
14187      "(50,  'JOHN',      'B', 'GEYER',     'E01', 40175, 800), "
14188      "(60,  'IRVING',    'F', 'STERN',     'D11', 32250, 500), "
14189      "(70,  'EVA',       'D', 'PULASKI',   'D21', 36170, 700), "
14190      "(90,  'EILEEN',    'W', 'HENDERSON', 'E11', 29750, 600), "
14191      "(100, 'THEODORE',  'Q', 'SPENSER',   'E21', 26150, 500), "
14192      "(110, 'VINCENZO',  'G', 'LUCCHESSI', 'A00', 46500, 900), "
14193      "(120, 'SEAN',      '',  'O\\'CONNELL', 'A00', 29250, 600), "
14194      "(130, 'DOLORES',   'M', 'QUINTANA',  'C01', 23800, 500), "
14195      "(140, 'HEATHER',   'A', 'NICHOLLS',  'C01', 28420, 600), "
14196      "(150, 'BRUCE',     '',  'ADAMSON',   'D11', 25280, 500), "
14197      "(160, 'ELIZABETH', 'R', 'PIANKA',    'D11', 22250, 400), "
14198      "(170, 'MASATOSHI', 'J', 'YOSHIMURA', 'D11', 24680, 500), "
14199      "(180, 'MARILYN',   'S', 'SCOUTTEN',  'D11', 21340, 500), "
14200      "(190, 'JAMES',     'H', 'WALKER',    'D11', 20450, 400), "
14201      "(200, 'DAVID',     '',  'BROWN',     'D11', 27740, 600), "
14202      "(210, 'WILLIAM',   'T', 'JONES',     'D11', 18270, 400), "
14203      "(220, 'JENNIFER',  'K', 'LUTZ',      'D11', 29840, 600), "
14204      "(230, 'JAMES',     'J', 'JEFFERSON', 'D21', 22180, 400), "
14205      "(240, 'SALVATORE', 'M', 'MARINO',    'D21', 28760, 600), "
14206      "(250, 'DANIEL',    'S', 'SMITH',     'D21', 19180, 400), "
14207      "(260, 'SYBIL',     'P', 'JOHNSON',   'D21', 17250, 300), "
14208      "(270, 'MARIA',     'L', 'PEREZ',     'D21', 27380, 500), "
14209      "(280, 'ETHEL',     'R', 'SCHNEIDER', 'E11', 26250, 500), "
14210      "(290, 'JOHN',      'R', 'PARKER',    'E11', 15340, 300), "
14211      "(300, 'PHILIP',    'X', 'SMITH',     'E11', 17750, 400), "
14212      "(310, 'MAUDE',     'F', 'SETRIGHT',  'E11', 15900, 300), "
14213      "(320, 'RAMLAL',    'V', 'MEHTA',     'E21', 19950, 400), "
14214      "(330, 'WING',      '',  'LEE',       'E21', 25370, 500), "
14215      "(340, 'JASON',     'R', 'GOUNOT',    'E21', 23840, 500)";
14216 
14217   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14218   myquery(rc);
14219 
14220   stmt_text= "create table t2 ("
14221     " deptno varchar(6) not null, deptname varchar(20) not null,"
14222     " mgrno int(11) not null, location varchar(20) not null,"
14223     " admrdept varchar(6) not null, refcntd int(11) not null,"
14224     " refcntu int(11) not null, primary key (deptno)"
14225     ") default charset=latin1 collate=latin1_bin";
14226   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14227   myquery(rc);
14228 
14229   stmt_text= "insert into t2 values "
14230     "('A00', 'SPIFFY COMPUTER SERV', 10, '', 'A00', 0, 0), "
14231     "('B01', 'PLANNING',             20, '', 'A00', 0, 0), "
14232     "('C01', 'INFORMATION CENTER',   30, '', 'A00', 0, 0), "
14233     "('D01', 'DEVELOPMENT CENTER',   0,  '', 'A00', 0, 0),"
14234     "('D11', 'MANUFACTURING SYSTEM', 60, '', 'D01', 0, 0), "
14235     "('D21', 'ADMINISTRATION SYSTE', 70, '', 'D01', 0, 0), "
14236     "('E01', 'SUPPORT SERVICES',     50, '', 'A00', 0, 0), "
14237     "('E11', 'OPERATIONS',           90, '', 'E01', 0, 0), "
14238     "('E21', 'SOFTWARE SUPPORT',     100,'', 'E01', 0, 0)";
14239   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14240   myquery(rc);
14241 
14242   /* ****** Begin of trace ****** */
14243 
14244   stmt= open_cursor("select t1.empno, t1.workdept "
14245                     "from (t1 left join t2 on t2.deptno = t1.workdept) "
14246                     "where t2.deptno in "
14247                     "   (select t2.deptno "
14248                     "    from (t1 left join t2 on t2.deptno = t1.workdept) "
14249                     "    where t1.empno = ?) "
14250                     "order by 1");
14251   bzero(my_bind, sizeof(my_bind));
14252 
14253   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14254   my_bind[0].buffer= &empno;
14255   rc= mysql_stmt_bind_param(stmt, my_bind);
14256   check_execute(stmt, rc);
14257 
14258   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14259   my_bind[1].buffer= (void*) workdept;
14260   my_bind[1].buffer_length= sizeof(workdept);
14261   my_bind[1].length= &workdept_len;
14262 
14263   rc= mysql_stmt_bind_result(stmt, my_bind);
14264   check_execute(stmt, rc);
14265 
14266   empno= 10;
14267   /* ERROR: next statement causes a server crash */
14268   rc= mysql_stmt_execute(stmt);
14269   check_execute(stmt, rc);
14270 
14271   mysql_stmt_close(stmt);
14272 
14273   rc= mysql_query(mysql, "drop table t1, t2");
14274   myquery(rc);
14275 }
14276 
14277 /* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */
14278 
test_bug11904()14279 static void test_bug11904()
14280 {
14281   MYSQL_STMT *stmt1;
14282   int rc;
14283   const char *stmt_text;
14284   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
14285   MYSQL_BIND my_bind[2];
14286   int country_id=0;
14287   char row_data[11]= {0};
14288 
14289   myheader("test_bug11904");
14290 
14291   /* create tables */
14292   rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b");
14293   myquery(rc);
14294   rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))");
14295   myquery(rc);
14296 
14297   rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv'),"
14298                           " (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg'),"
14299                           " (3,'berlin'), (3, 'frankfurt')");
14300 
14301   myquery(rc);
14302   mysql_commit(mysql);
14303   /* create statement */
14304   stmt1= mysql_stmt_init(mysql);
14305   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14306 
14307   stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id";
14308 
14309   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14310   check_execute(stmt1, rc);
14311 
14312   memset(my_bind, 0, sizeof(my_bind));
14313   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14314   my_bind[0].buffer=& country_id;
14315   my_bind[0].buffer_length= 0;
14316   my_bind[0].length= 0;
14317 
14318   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14319   my_bind[1].buffer=& row_data;
14320   my_bind[1].buffer_length= sizeof(row_data) - 1;
14321   my_bind[1].length= 0;
14322 
14323   rc= mysql_stmt_bind_result(stmt1, my_bind);
14324   check_execute(stmt1, rc);
14325 
14326   rc= mysql_stmt_execute(stmt1);
14327   check_execute(stmt1, rc);
14328 
14329   rc= mysql_stmt_fetch(stmt1);
14330   check_execute(stmt1, rc);
14331   DIE_UNLESS(country_id == 1);
14332   DIE_UNLESS(memcmp(row_data, "plovdiv", 7) == 0);
14333 
14334   rc= mysql_stmt_fetch(stmt1);
14335   check_execute(stmt1, rc);
14336   DIE_UNLESS(country_id == 2);
14337   DIE_UNLESS(memcmp(row_data, "LA", 2) == 0);
14338 
14339   rc= mysql_stmt_fetch(stmt1);
14340   check_execute(stmt1, rc);
14341   DIE_UNLESS(country_id == 3);
14342   DIE_UNLESS(memcmp(row_data, "berlin", 6) == 0);
14343 
14344   rc= mysql_stmt_close(stmt1);
14345   check_execute(stmt1, rc);
14346 
14347   rc= mysql_query(mysql, "drop table bug11904b");
14348   myquery(rc);
14349 }
14350 
14351 
14352 /* Bug#12243: multiple cursors, crash in a fetch after commit. */
14353 
test_bug12243()14354 static void test_bug12243()
14355 {
14356   MYSQL_STMT *stmt1, *stmt2;
14357   int rc;
14358   const char *stmt_text;
14359   ulong type;
14360 
14361   myheader("test_bug12243");
14362 
14363   if (! have_innodb)
14364   {
14365     if (!opt_silent)
14366       printf("This test requires InnoDB.\n");
14367     return;
14368   }
14369 
14370   /* create tables */
14371   mysql_query(mysql, "drop table if exists t1");
14372   mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
14373   rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
14374   myquery(rc);
14375   mysql_autocommit(mysql, FALSE);
14376   /* create statement */
14377   stmt1= mysql_stmt_init(mysql);
14378   stmt2= mysql_stmt_init(mysql);
14379   type= (ulong) CURSOR_TYPE_READ_ONLY;
14380   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14381   mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14382 
14383   stmt_text= "select a from t1";
14384 
14385   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14386   check_execute(stmt1, rc);
14387   rc= mysql_stmt_execute(stmt1);
14388   check_execute(stmt1, rc);
14389   rc= mysql_stmt_fetch(stmt1);
14390   check_execute(stmt1, rc);
14391 
14392   rc= mysql_stmt_prepare(stmt2, stmt_text, strlen(stmt_text));
14393   check_execute(stmt2, rc);
14394   rc= mysql_stmt_execute(stmt2);
14395   check_execute(stmt2, rc);
14396   rc= mysql_stmt_fetch(stmt2);
14397   check_execute(stmt2, rc);
14398 
14399   rc= mysql_stmt_close(stmt1);
14400   check_execute(stmt1, rc);
14401   rc= mysql_commit(mysql);
14402   myquery(rc);
14403   rc= mysql_stmt_fetch(stmt2);
14404   check_execute(stmt2, rc);
14405 
14406   mysql_stmt_close(stmt2);
14407   rc= mysql_query(mysql, "drop table t1");
14408   myquery(rc);
14409   mysql_autocommit(mysql, TRUE);                /* restore default */
14410 }
14411 
14412 
14413 /*
14414   Bug#11718: query with function, join and order by returns wrong type
14415 */
14416 
test_bug11718()14417 static void test_bug11718()
14418 {
14419   MYSQL_RES	*res;
14420   int rc;
14421   const char *query= "select str_to_date(concat(f3),'%Y%m%d') from t1,t2 "
14422                      "where f1=f2 order by f1";
14423 
14424   myheader("test_bug11718");
14425 
14426   rc= mysql_query(mysql, "drop table if exists t1, t2");
14427   myquery(rc);
14428   rc= mysql_query(mysql, "create table t1 (f1 int)");
14429   myquery(rc);
14430   rc= mysql_query(mysql, "create table t2 (f2 int, f3 numeric(8))");
14431   myquery(rc);
14432   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14433   myquery(rc);
14434   rc= mysql_query(mysql, "insert into t2 values (1,20050101), (2,20050202)");
14435   myquery(rc);
14436   rc= mysql_query(mysql, query);
14437   myquery(rc);
14438   res = mysql_store_result(mysql);
14439 
14440   if (!opt_silent)
14441     printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
14442            "not DATE");
14443   DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
14444   mysql_free_result(res);
14445   rc= mysql_query(mysql, "drop table t1, t2");
14446   myquery(rc);
14447 }
14448 
14449 
14450 /*
14451   Bug #12925: Bad handling of maximum values in getopt
14452 */
test_bug12925()14453 static void test_bug12925()
14454 {
14455   myheader("test_bug12925");
14456   if (opt_getopt_ll_test)
14457     DIE_UNLESS(opt_getopt_ll_test == LL(25600*1024*1024));
14458 }
14459 
14460 
14461 /*
14462   Bug#14210 "Simple query with > operator on large table gives server
14463   crash"
14464 */
14465 
test_bug14210()14466 static void test_bug14210()
14467 {
14468   MYSQL_STMT *stmt;
14469   int rc, i;
14470   const char *stmt_text;
14471   ulong type;
14472 
14473   myheader("test_bug14210");
14474 
14475   mysql_query(mysql, "drop table if exists t1");
14476   /*
14477     To trigger the problem the table must be InnoDB, although the problem
14478     itself is not InnoDB related. In case the table is MyISAM this test
14479     is harmless.
14480   */
14481   mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB");
14482   rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
14483   myquery(rc);
14484   rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
14485   /* Create a big enough table (more than max_heap_table_size) */
14486   for (i= 0; i < 8; i++)
14487   {
14488     rc= mysql_query(mysql, "insert into t1 (a) select a from t1");
14489     myquery(rc);
14490   }
14491   /* create statement */
14492   stmt= mysql_stmt_init(mysql);
14493   type= (ulong) CURSOR_TYPE_READ_ONLY;
14494   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14495 
14496   stmt_text= "select a from t1";
14497 
14498   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14499   check_execute(stmt, rc);
14500   rc= mysql_stmt_execute(stmt);
14501   while ((rc= mysql_stmt_fetch(stmt)) == 0)
14502     ;
14503   DIE_UNLESS(rc == MYSQL_NO_DATA);
14504 
14505   rc= mysql_stmt_close(stmt);
14506 
14507   rc= mysql_query(mysql, "drop table t1");
14508   myquery(rc);
14509   rc= mysql_query(mysql, "set @@session.max_heap_table_size=default");
14510   myquery(rc);
14511 }
14512 
14513 /* Bug#13488: wrong column metadata when fetching from cursor */
14514 
test_bug13488()14515 static void test_bug13488()
14516 {
14517   MYSQL_BIND my_bind[3];
14518   MYSQL_STMT *stmt1;
14519   int rc, f1, f2, f3, i;
14520   const ulong type= CURSOR_TYPE_READ_ONLY;
14521   const char *query= "select * from t1 left join t2 on f1=f2 where f1=1";
14522 
14523   myheader("test_bug13488");
14524 
14525   rc= mysql_query(mysql, "drop table if exists t1, t2");
14526   myquery(rc);
14527   rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)");
14528   myquery(rc);
14529   rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, "
14530                   "f3 int not null)");
14531   myquery(rc);
14532   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14533   myquery(rc);
14534   rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)");
14535   myquery(rc);
14536 
14537   memset(my_bind, 0, sizeof(my_bind));
14538   for (i= 0; i < 3; i++)
14539   {
14540     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
14541     my_bind[i].buffer_length= 4;
14542     my_bind[i].length= 0;
14543   }
14544   my_bind[0].buffer=&f1;
14545   my_bind[1].buffer=&f2;
14546   my_bind[2].buffer=&f3;
14547 
14548   stmt1= mysql_stmt_init(mysql);
14549   rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type);
14550   check_execute(stmt1, rc);
14551 
14552   rc= mysql_stmt_prepare(stmt1, query, strlen(query));
14553   check_execute(stmt1, rc);
14554 
14555   rc= mysql_stmt_execute(stmt1);
14556   check_execute(stmt1, rc);
14557 
14558   rc= mysql_stmt_bind_result(stmt1, my_bind);
14559   check_execute(stmt1, rc);
14560 
14561   rc= mysql_stmt_fetch(stmt1);
14562   check_execute(stmt1, rc);
14563 
14564   rc= mysql_stmt_free_result(stmt1);
14565   check_execute(stmt1, rc);
14566 
14567   rc= mysql_stmt_reset(stmt1);
14568   check_execute(stmt1, rc);
14569 
14570   rc= mysql_stmt_close(stmt1);
14571   check_execute(stmt1, rc);
14572 
14573   if (!opt_silent)
14574   {
14575     printf("data: f1: %d; f2: %d; f3: %d\n", f1, f2, f3);
14576     printf("data is: %s\n",
14577            (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong");
14578   }
14579   DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
14580   rc= mysql_query(mysql, "drop table t1, t2");
14581   myquery(rc);
14582 }
14583 
14584 /*
14585   Bug#13524: warnings of a previous command are not reset when fetching
14586   from a cursor.
14587 */
14588 
test_bug13524()14589 static void test_bug13524()
14590 {
14591   MYSQL_STMT *stmt;
14592   int rc;
14593   unsigned int warning_count;
14594   const ulong type= CURSOR_TYPE_READ_ONLY;
14595   const char *query= "select * from t1";
14596 
14597   myheader("test_bug13524");
14598 
14599   rc= mysql_query(mysql, "drop table if exists t1, t2");
14600   myquery(rc);
14601   rc= mysql_query(mysql, "create table t1 (a int not null primary key)");
14602   myquery(rc);
14603   rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
14604   myquery(rc);
14605 
14606   stmt= mysql_stmt_init(mysql);
14607   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14608   check_execute(stmt, rc);
14609 
14610   rc= mysql_stmt_prepare(stmt, query, strlen(query));
14611   check_execute(stmt, rc);
14612 
14613   rc= mysql_stmt_execute(stmt);
14614   check_execute(stmt, rc);
14615 
14616   rc= mysql_stmt_fetch(stmt);
14617   check_execute(stmt, rc);
14618 
14619   warning_count= mysql_warning_count(mysql);
14620   DIE_UNLESS(warning_count == 0);
14621 
14622   /* Check that DROP TABLE produced a warning (no such table) */
14623   rc= mysql_query(mysql, "drop table if exists t2");
14624   myquery(rc);
14625   warning_count= mysql_warning_count(mysql);
14626   DIE_UNLESS(warning_count == 1);
14627 
14628   /*
14629     Check that fetch from a cursor cleared the warning from the previous
14630     command.
14631   */
14632   rc= mysql_stmt_fetch(stmt);
14633   check_execute(stmt, rc);
14634   warning_count= mysql_warning_count(mysql);
14635   DIE_UNLESS(warning_count == 0);
14636 
14637   /* Cleanup */
14638   mysql_stmt_close(stmt);
14639   rc= mysql_query(mysql, "drop table t1");
14640   myquery(rc);
14641 }
14642 
14643 /*
14644   Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
14645 */
14646 
test_bug14845()14647 static void test_bug14845()
14648 {
14649   MYSQL_STMT *stmt;
14650   int rc;
14651   const ulong type= CURSOR_TYPE_READ_ONLY;
14652   const char *query= "select count(*) from t1 where 1 = 0";
14653 
14654   myheader("test_bug14845");
14655 
14656   rc= mysql_query(mysql, "drop table if exists t1");
14657   myquery(rc);
14658   rc= mysql_query(mysql, "create table t1 (id int(11) default null, "
14659                          "name varchar(20) default null)"
14660                          "engine=MyISAM DEFAULT CHARSET=utf8");
14661   myquery(rc);
14662   rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')");
14663   myquery(rc);
14664 
14665   stmt= mysql_stmt_init(mysql);
14666   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14667   check_execute(stmt, rc);
14668 
14669   rc= mysql_stmt_prepare(stmt, query, strlen(query));
14670   check_execute(stmt, rc);
14671 
14672   rc= mysql_stmt_execute(stmt);
14673   check_execute(stmt, rc);
14674 
14675   rc= mysql_stmt_fetch(stmt);
14676   DIE_UNLESS(rc == 0);
14677 
14678   rc= mysql_stmt_fetch(stmt);
14679   DIE_UNLESS(rc == MYSQL_NO_DATA);
14680 
14681   /* Cleanup */
14682   mysql_stmt_close(stmt);
14683   rc= mysql_query(mysql, "drop table t1");
14684   myquery(rc);
14685 }
14686 
14687 
14688 /*
14689   Bug #15510: mysql_warning_count returns 0 after mysql_stmt_fetch which
14690   should warn
14691 */
test_bug15510()14692 static void test_bug15510()
14693 {
14694   MYSQL_STMT *stmt;
14695   int rc;
14696   const char *query= "select 1 from dual where 1/0";
14697 
14698   myheader("test_bug15510");
14699 
14700   rc= mysql_query(mysql, "set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'");
14701   myquery(rc);
14702 
14703   stmt= mysql_stmt_init(mysql);
14704 
14705   rc= mysql_stmt_prepare(stmt, query, strlen(query));
14706   check_execute(stmt, rc);
14707 
14708   rc= mysql_stmt_execute(stmt);
14709   check_execute(stmt, rc);
14710 
14711   rc= mysql_stmt_fetch(stmt);
14712   DIE_UNLESS(mysql_warning_count(mysql));
14713 
14714   /* Cleanup */
14715   mysql_stmt_close(stmt);
14716   rc= mysql_query(mysql, "set @@sql_mode=''");
14717   myquery(rc);
14718 }
14719 
14720 
14721 /* Test MYSQL_OPT_RECONNECT, Bug#15719 */
14722 
test_opt_reconnect()14723 static void test_opt_reconnect()
14724 {
14725   MYSQL *lmysql;
14726   my_bool my_true= TRUE;
14727 
14728   myheader("test_opt_reconnect");
14729 
14730   if (!(lmysql= mysql_client_init(NULL)))
14731   {
14732     myerror("mysql_client_init() failed");
14733     exit(1);
14734   }
14735 
14736   if (!opt_silent)
14737     fprintf(stdout, "reconnect before mysql_options: %d\n", lmysql->reconnect);
14738   DIE_UNLESS(lmysql->reconnect == 0);
14739 
14740   if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
14741   {
14742     myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
14743     DIE_UNLESS(0);
14744   }
14745 
14746   /* reconnect should be 1 */
14747   if (!opt_silent)
14748     fprintf(stdout, "reconnect after mysql_options: %d\n", lmysql->reconnect);
14749   DIE_UNLESS(lmysql->reconnect == 1);
14750 
14751   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
14752                            opt_password, current_db, opt_port,
14753                            opt_unix_socket, 0)))
14754   {
14755     myerror("connection failed");
14756     DIE_UNLESS(0);
14757   }
14758 
14759   /* reconnect should still be 1 */
14760   if (!opt_silent)
14761     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
14762 	    lmysql->reconnect);
14763   DIE_UNLESS(lmysql->reconnect == 1);
14764 
14765   mysql_close(lmysql);
14766 
14767   if (!(lmysql= mysql_client_init(NULL)))
14768   {
14769     myerror("mysql_client_init() failed");
14770     DIE_UNLESS(0);
14771   }
14772 
14773   if (!opt_silent)
14774     fprintf(stdout, "reconnect before mysql_real_connect: %d\n", lmysql->reconnect);
14775   DIE_UNLESS(lmysql->reconnect == 0);
14776 
14777   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
14778                            opt_password, current_db, opt_port,
14779                            opt_unix_socket, 0)))
14780   {
14781     myerror("connection failed");
14782     DIE_UNLESS(0);
14783   }
14784 
14785   /* reconnect should still be 0 */
14786   if (!opt_silent)
14787     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
14788 	    lmysql->reconnect);
14789   DIE_UNLESS(lmysql->reconnect == 0);
14790 
14791   mysql_close(lmysql);
14792 }
14793 
14794 
14795 #ifndef EMBEDDED_LIBRARY
14796 
test_bug12744()14797 static void test_bug12744()
14798 {
14799   MYSQL_STMT *prep_stmt = NULL;
14800   MYSQL *lmysql;
14801   int rc;
14802   myheader("test_bug12744");
14803 
14804   lmysql= mysql_client_init(NULL);
14805   DIE_UNLESS(lmysql);
14806 
14807   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
14808                           current_db, opt_port, opt_unix_socket, 0))
14809   {
14810     fprintf(stderr, "Failed to connect to the database\n");
14811     DIE_UNLESS(0);
14812   }
14813 
14814   prep_stmt= mysql_stmt_init(lmysql);
14815   rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
14816   DIE_UNLESS(rc == 0);
14817 
14818   mysql_close(lmysql);
14819 
14820   rc= mysql_stmt_execute(prep_stmt);
14821   DIE_UNLESS(rc);
14822   rc= mysql_stmt_reset(prep_stmt);
14823   DIE_UNLESS(rc);
14824   rc= mysql_stmt_close(prep_stmt);
14825   DIE_UNLESS(rc == 0);
14826 }
14827 
14828 #endif /* EMBEDDED_LIBRARY */
14829 
14830 /* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
14831 
test_bug16143()14832 static void test_bug16143()
14833 {
14834   MYSQL_STMT *stmt;
14835   myheader("test_bug16143");
14836 
14837   stmt= mysql_stmt_init(mysql);
14838   /* Check mysql_stmt_sqlstate return "no error" */
14839   DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0);
14840 
14841   mysql_stmt_close(stmt);
14842 }
14843 
14844 
14845 /* Bug #16144: mysql_stmt_attr_get type error */
14846 
test_bug16144()14847 static void test_bug16144()
14848 {
14849   const my_bool flag_orig= (my_bool) 0xde;
14850   my_bool flag= flag_orig;
14851   MYSQL_STMT *stmt;
14852   myheader("test_bug16144");
14853 
14854   /* Check that attr_get returns correct data on little and big endian CPUs */
14855   stmt= mysql_stmt_init(mysql);
14856   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
14857   mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
14858   DIE_UNLESS(flag == flag_orig);
14859 
14860   mysql_stmt_close(stmt);
14861 }
14862 
14863 /*
14864   Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
14865   field length"
14866 */
14867 
test_bug15613()14868 static void test_bug15613()
14869 {
14870   MYSQL_STMT *stmt;
14871   const char *stmt_text;
14872   MYSQL_RES *metadata;
14873   MYSQL_FIELD *field;
14874   int rc;
14875   myheader("test_bug15613");
14876 
14877   /* I. Prepare the table */
14878   rc= mysql_query(mysql, "set names latin1");
14879   myquery(rc);
14880   mysql_query(mysql, "drop table if exists t1");
14881   rc= mysql_query(mysql,
14882                   "create table t1 (t text character set utf8, "
14883                                    "tt tinytext character set utf8, "
14884                                    "mt mediumtext character set utf8, "
14885                                    "lt longtext character set utf8, "
14886                                    "vl varchar(255) character set latin1,"
14887                                    "vb varchar(255) character set binary,"
14888                                    "vu varchar(255) character set utf8)");
14889   myquery(rc);
14890 
14891   stmt= mysql_stmt_init(mysql);
14892 
14893   /* II. Check SELECT metadata */
14894   stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
14895   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14896   metadata= mysql_stmt_result_metadata(stmt);
14897   field= mysql_fetch_fields(metadata);
14898   if (!opt_silent)
14899   {
14900     printf("Field lengths (client character set is latin1):\n"
14901            "text character set utf8:\t\t%lu\n"
14902            "tinytext character set utf8:\t\t%lu\n"
14903            "mediumtext character set utf8:\t\t%lu\n"
14904            "longtext character set utf8:\t\t%lu\n"
14905            "varchar(255) character set latin1:\t%lu\n"
14906            "varchar(255) character set binary:\t%lu\n"
14907            "varchar(255) character set utf8:\t%lu\n",
14908            field[0].length, field[1].length, field[2].length, field[3].length,
14909            field[4].length, field[5].length, field[6].length);
14910   }
14911   DIE_UNLESS(field[0].length == 65535);
14912   DIE_UNLESS(field[1].length == 255);
14913   DIE_UNLESS(field[2].length == 16777215);
14914   DIE_UNLESS(field[3].length == 4294967295UL);
14915   DIE_UNLESS(field[4].length == 255);
14916   DIE_UNLESS(field[5].length == 255);
14917   DIE_UNLESS(field[6].length == 255);
14918   mysql_free_result(metadata);
14919   mysql_stmt_free_result(stmt);
14920 
14921   /* III. Cleanup */
14922   rc= mysql_query(mysql, "drop table t1");
14923   myquery(rc);
14924   rc= mysql_query(mysql, "set names default");
14925   myquery(rc);
14926   mysql_stmt_close(stmt);
14927 }
14928 
14929 /*
14930   Bug#17667: An attacker has the opportunity to bypass query logging.
14931 
14932   Note! Also tests Bug#21813, where prepared statements are used to
14933   run queries
14934 */
test_bug17667()14935 static void test_bug17667()
14936 {
14937   int rc;
14938   MYSQL_STMT *stmt;
14939   enum query_type { QT_NORMAL, QT_PREPARED};
14940   struct buffer_and_length {
14941     enum query_type qt;
14942     const char *buffer;
14943     const uint length;
14944   } statements[]= {
14945     { QT_NORMAL, "drop table if exists bug17667", 29 },
14946     { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
14947     { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
14948     { QT_PREPARED,
14949       "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
14950     { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
14951     { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
14952     { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
14953     { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
14954     { QT_NORMAL, "drop table bug17667", 19 },
14955     { QT_NORMAL, NULL, 0 } };
14956 
14957   struct buffer_and_length *statement_cursor;
14958   FILE *log_file;
14959   char *master_log_filename;
14960 
14961   myheader("test_bug17667");
14962 
14963   master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1);
14964   strxmov(master_log_filename, opt_vardir, "/log/master.log", NullS);
14965   if (!opt_silent)
14966     printf("Opening '%s'\n", master_log_filename);
14967   log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0));
14968   free(master_log_filename);
14969 
14970   if (log_file == NULL)
14971   {
14972     if (!opt_silent)
14973     {
14974       printf("Could not find the log file, VARDIR/log/master.log, so "
14975              "test_bug17667 is not run.\n"
14976              "Run test from the mysql-test/mysql-test-run* program to set up "
14977              "correct environment for this test.\n\n");
14978     }
14979     return;
14980   }
14981 
14982   enable_query_logs(1);
14983 
14984   for (statement_cursor= statements; statement_cursor->buffer != NULL;
14985        statement_cursor++)
14986   {
14987     if (statement_cursor->qt == QT_NORMAL)
14988     {
14989       /* Run statement as normal query */
14990       rc= mysql_real_query(mysql, statement_cursor->buffer,
14991                            statement_cursor->length);
14992       myquery(rc);
14993     }
14994     else if (statement_cursor->qt == QT_PREPARED)
14995     {
14996       /*
14997         Run as prepared statement
14998 
14999         NOTE! All these queries should be in the log twice,
15000         one time for prepare and one time for execute
15001       */
15002       stmt= mysql_stmt_init(mysql);
15003 
15004       rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
15005                              statement_cursor->length);
15006       check_execute(stmt, rc);
15007 
15008       rc= mysql_stmt_execute(stmt);
15009       check_execute(stmt, rc);
15010 
15011       mysql_stmt_close(stmt);
15012     }
15013     else
15014     {
15015       DIE_UNLESS(0==1);
15016     }
15017   }
15018 
15019   /* Make sure the server has written the logs to disk before reading it */
15020   rc= mysql_query(mysql, "flush logs");
15021   myquery(rc);
15022 
15023   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15024        statement_cursor++)
15025   {
15026     int expected_hits= 1, hits= 0;
15027     char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15028     /* more than enough room for the query and some marginalia. */
15029 
15030     /* Prepared statments always occurs twice in log */
15031     if (statement_cursor->qt == QT_PREPARED)
15032       expected_hits++;
15033 
15034     /* Loop until we found expected number of log entries */
15035     do {
15036       /* Loop until statement is found in log */
15037       do {
15038         memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15039 
15040         if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15041         {
15042           /* If fgets returned NULL, it indicates either error or EOF */
15043           if (feof(log_file))
15044             DIE("Found EOF before all statements where found");
15045 
15046           fprintf(stderr, "Got error %d while reading from file\n",
15047                   ferror(log_file));
15048           DIE("Read error");
15049         }
15050 
15051       } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15052                          statement_cursor->buffer,
15053                          statement_cursor->length) == NULL);
15054       hits++;
15055     } while (hits < expected_hits);
15056 
15057     if (!opt_silent)
15058       printf("Found statement starting with \"%s\"\n",
15059              statement_cursor->buffer);
15060   }
15061 
15062   restore_query_logs();
15063 
15064   if (!opt_silent)
15065     printf("success.  All queries found intact in the log.\n");
15066 
15067   my_fclose(log_file, MYF(0));
15068 }
15069 
15070 
15071 /*
15072   Bug#14169: type of group_concat() result changed to blob if tmp_table was
15073   used
15074 */
test_bug14169()15075 static void test_bug14169()
15076 {
15077   MYSQL_STMT *stmt;
15078   const char *stmt_text;
15079   MYSQL_RES *res;
15080   MYSQL_FIELD *field;
15081   int rc;
15082 
15083   myheader("test_bug14169");
15084 
15085   rc= mysql_query(mysql, "drop table if exists t1");
15086   myquery(rc);
15087   rc= mysql_query(mysql, "set session group_concat_max_len=1024");
15088   myquery(rc);
15089   rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))");
15090   myquery(rc);
15091   rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255)),"
15092                          "(2,repeat('b',255))");
15093   myquery(rc);
15094   stmt= mysql_stmt_init(mysql);
15095   stmt_text= "select f2,group_concat(f1) from t1 group by f2";
15096   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15097   myquery(rc);
15098   res= mysql_stmt_result_metadata(stmt);
15099   field= mysql_fetch_fields(res);
15100   if (!opt_silent)
15101     printf("GROUP_CONCAT() result type %i", field[1].type);
15102   DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
15103   mysql_free_result(res);
15104   mysql_stmt_free_result(stmt);
15105   mysql_stmt_close(stmt);
15106 
15107   rc= mysql_query(mysql, "drop table t1");
15108   myquery(rc);
15109 }
15110 
15111 /*
15112    Test that mysql_insert_id() behaves as documented in our manual
15113 */
test_mysql_insert_id()15114 static void test_mysql_insert_id()
15115 {
15116   my_ulonglong res;
15117   int rc;
15118 
15119   myheader("test_mysql_insert_id");
15120 
15121   rc= mysql_query(mysql, "drop table if exists t1");
15122   myquery(rc);
15123   /* table without auto_increment column */
15124   rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
15125   myquery(rc);
15126   rc= mysql_query(mysql, "insert into t1 values (1,'a')");
15127   myquery(rc);
15128   res= mysql_insert_id(mysql);
15129   DIE_UNLESS(res == 0);
15130   rc= mysql_query(mysql, "insert into t1 values (null,'b')");
15131   myquery(rc);
15132   res= mysql_insert_id(mysql);
15133   DIE_UNLESS(res == 0);
15134   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15135   myquery(rc);
15136   res= mysql_insert_id(mysql);
15137   DIE_UNLESS(res == 0);
15138 
15139   /*
15140     Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
15141     sporadically
15142   */
15143   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15144   myquery(rc);
15145   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15146   myquery(rc);
15147   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15148   myquery(rc);
15149   res= mysql_insert_id(mysql);
15150   DIE_UNLESS(res == 0);
15151   rc= mysql_query(mysql, "drop table t2");
15152   myquery(rc);
15153 
15154   rc= mysql_query(mysql, "insert into t1 select null,'d'");
15155   myquery(rc);
15156   res= mysql_insert_id(mysql);
15157   DIE_UNLESS(res == 0);
15158   rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
15159   myquery(rc);
15160   res= mysql_insert_id(mysql);
15161   DIE_UNLESS(res == 300);
15162   rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
15163   myquery(rc);
15164   res= mysql_insert_id(mysql);
15165   /*
15166     Behaviour change: old code used to return 0; but 400 is consistent
15167     with INSERT VALUES, and the manual's section of mysql_insert_id() does not
15168     say INSERT SELECT should be different.
15169   */
15170   DIE_UNLESS(res == 400);
15171 
15172   /* table with auto_increment column */
15173   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15174   myquery(rc);
15175   rc= mysql_query(mysql, "insert into t2 values (1,'a')");
15176   myquery(rc);
15177   res= mysql_insert_id(mysql);
15178   DIE_UNLESS(res == 1);
15179   /* this should not influence next INSERT if it doesn't have auto_inc */
15180   rc= mysql_query(mysql, "insert into t1 values (10,'e')");
15181   myquery(rc);
15182   res= mysql_insert_id(mysql);
15183   DIE_UNLESS(res == 0);
15184 
15185   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15186   myquery(rc);
15187   res= mysql_insert_id(mysql);
15188   DIE_UNLESS(res == 2);
15189   rc= mysql_query(mysql, "insert into t2 select 5,'c'");
15190   myquery(rc);
15191   res= mysql_insert_id(mysql);
15192   /*
15193     Manual says that for multirow insert this should have been 5, but does not
15194     say for INSERT SELECT. This is a behaviour change: old code used to return
15195     0. We try to be consistent with INSERT VALUES.
15196   */
15197   DIE_UNLESS(res == 5);
15198   rc= mysql_query(mysql, "insert into t2 select null,'d'");
15199   myquery(rc);
15200   res= mysql_insert_id(mysql);
15201   DIE_UNLESS(res == 6);
15202   /* with more than one row */
15203   rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
15204   myquery(rc);
15205   res= mysql_insert_id(mysql);
15206   DIE_UNLESS(res == 11);
15207   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15208   myquery(rc);
15209   res= mysql_insert_id(mysql);
15210   /*
15211     Manual says that for multirow insert this should have been 13, but does
15212     not say for INSERT SELECT. This is a behaviour change: old code used to
15213     return 0. We try to be consistent with INSERT VALUES.
15214   */
15215   DIE_UNLESS(res == 13);
15216   rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
15217   myquery(rc);
15218   res= mysql_insert_id(mysql);
15219   DIE_UNLESS(res == 14);
15220   rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
15221   myquery(rc);
15222   res= mysql_insert_id(mysql);
15223   DIE_UNLESS(res == 16);
15224   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15225   myquery_r(rc);
15226   rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
15227   myquery(rc);
15228   res= mysql_insert_id(mysql);
15229   DIE_UNLESS(res == 0);
15230   rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
15231   myquery_r(rc);
15232   res= mysql_insert_id(mysql);
15233   DIE_UNLESS(res == 0);
15234   rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
15235   myquery(rc);
15236   res= mysql_insert_id(mysql);
15237   DIE_UNLESS(res == 0);
15238   /* mixing autogenerated and explicit values */
15239   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
15240   myquery_r(rc);
15241   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
15242   myquery_r(rc);
15243   rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
15244   myquery(rc);
15245   res= mysql_insert_id(mysql);
15246   /*
15247     according to the manual, this might be 20 or 300, but it looks like
15248     auto_increment column takes priority over last_insert_id().
15249   */
15250   DIE_UNLESS(res == 20);
15251   /* If first autogenerated number fails and 2nd works: */
15252   rc= mysql_query(mysql, "drop table t2");
15253   myquery(rc);
15254   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
15255                   "auto_increment, f2 varchar(255), unique (f2))");
15256   myquery(rc);
15257   rc= mysql_query(mysql, "insert into t2 values (null,'e')");
15258   res= mysql_insert_id(mysql);
15259   DIE_UNLESS(res == 1);
15260   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
15261   myquery(rc);
15262   res= mysql_insert_id(mysql);
15263   DIE_UNLESS(res == 2);
15264   /* If autogenerated fails and explicit works: */
15265   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
15266   myquery(rc);
15267   res= mysql_insert_id(mysql);
15268   /*
15269     Behaviour change: old code returned 3 (first autogenerated, even if it
15270     fails); we now return first successful autogenerated.
15271   */
15272   DIE_UNLESS(res == 13);
15273   /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
15274   rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
15275   myquery(rc);
15276   res= mysql_insert_id(mysql);
15277   DIE_UNLESS(res == 0);
15278   rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
15279   myquery(rc);
15280   res= mysql_insert_id(mysql);
15281   DIE_UNLESS(res == 0);
15282   rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
15283   myquery(rc);
15284   res= mysql_insert_id(mysql);
15285   DIE_UNLESS(res == 372);
15286   /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
15287   rc= mysql_query(mysql, "insert into t2 values (null,'g')");
15288   myquery(rc);
15289   res= mysql_insert_id(mysql);
15290   DIE_UNLESS(res == 15);
15291   rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
15292   myquery(rc);
15293   res= mysql_insert_id(mysql);
15294   DIE_UNLESS(res == 0);
15295   /*
15296     Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
15297     mysql_insert_id() returns the id of the row, instead of not being
15298     affected.
15299   */
15300   rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
15301                   "update f2=concat('we updated ',f2)");
15302   myquery(rc);
15303   res= mysql_insert_id(mysql);
15304   DIE_UNLESS(res == 15);
15305 
15306   rc= mysql_query(mysql, "drop table t1,t2");
15307   myquery(rc);
15308 }
15309 
15310 /*
15311   Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
15312 */
15313 
test_bug20152()15314 static void test_bug20152()
15315 {
15316   MYSQL_BIND my_bind[1];
15317   MYSQL_STMT *stmt;
15318   MYSQL_TIME tm;
15319   int rc;
15320   const char *query= "INSERT INTO t1 (f1) VALUES (?)";
15321 
15322   myheader("test_bug20152");
15323 
15324   memset(my_bind, 0, sizeof(my_bind));
15325   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
15326   my_bind[0].buffer= (void*)&tm;
15327 
15328   tm.year = 2006;
15329   tm.month = 6;
15330   tm.day = 18;
15331   tm.hour = 14;
15332   tm.minute = 9;
15333   tm.second = 42;
15334 
15335   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15336   myquery(rc);
15337   rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)");
15338   myquery(rc);
15339 
15340   stmt= mysql_stmt_init(mysql);
15341   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15342   check_execute(stmt, rc);
15343   rc= mysql_stmt_bind_param(stmt, my_bind);
15344   check_execute(stmt, rc);
15345   rc= mysql_stmt_execute(stmt);
15346   check_execute(stmt, rc);
15347   rc= mysql_stmt_close(stmt);
15348   check_execute(stmt, rc);
15349   rc= mysql_query(mysql, "DROP TABLE t1");
15350   myquery(rc);
15351 
15352   if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) {
15353     if (!opt_silent)
15354       printf("OK!");
15355   } else {
15356     printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second);
15357     DIE_UNLESS(0==1);
15358   }
15359 }
15360 
15361 /* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
15362 
test_bug15752()15363 static void test_bug15752()
15364 {
15365   MYSQL mysql_local;
15366   int rc, i;
15367   const int ITERATION_COUNT= 100;
15368   const char *query= "CALL p1()";
15369 
15370   myheader("test_bug15752");
15371 
15372   rc= mysql_query(mysql, "drop procedure if exists p1");
15373   myquery(rc);
15374   rc= mysql_query(mysql, "create procedure p1() select 1");
15375   myquery(rc);
15376 
15377   mysql_client_init(&mysql_local);
15378   if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
15379                            opt_password, current_db, opt_port,
15380                            opt_unix_socket,
15381                            CLIENT_MULTI_STATEMENTS))
15382   {
15383     printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
15384     DIE_UNLESS(0);
15385   }
15386   rc= mysql_real_query(&mysql_local, query, strlen(query));
15387   myquery(rc);
15388   mysql_free_result(mysql_store_result(&mysql_local));
15389 
15390   rc= mysql_real_query(&mysql_local, query, strlen(query));
15391   DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
15392 
15393   if (! opt_silent)
15394     printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
15395 
15396   /* Check some other commands too */
15397 
15398   DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15399   mysql_free_result(mysql_store_result(&mysql_local));
15400   DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15401 
15402   /* The second problem is not reproducible: add the test case */
15403   for (i = 0; i < ITERATION_COUNT; i++)
15404   {
15405     if (mysql_real_query(&mysql_local, query, strlen(query)))
15406     {
15407       printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
15408       break;
15409     }
15410     mysql_free_result(mysql_store_result(&mysql_local));
15411     DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15412     mysql_free_result(mysql_store_result(&mysql_local));
15413     DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15414 
15415   }
15416   mysql_close(&mysql_local);
15417   rc= mysql_query(mysql, "drop procedure p1");
15418   myquery(rc);
15419 }
15420 
15421 /*
15422   Bug#21206: memory corruption when too many cursors are opened at once
15423 
15424   Memory corruption happens when more than 1024 cursors are open
15425   simultaneously.
15426 */
test_bug21206()15427 static void test_bug21206()
15428 {
15429   const size_t cursor_count= 1025;
15430 
15431   const char *create_table[]=
15432   {
15433     "DROP TABLE IF EXISTS t1",
15434     "CREATE TABLE t1 (i INT)",
15435     "INSERT INTO t1 VALUES (1), (2), (3)"
15436   };
15437   const char *query= "SELECT * FROM t1";
15438 
15439   Stmt_fetch *fetch_array=
15440     (Stmt_fetch*) calloc(cursor_count, sizeof(Stmt_fetch));
15441 
15442   Stmt_fetch *fetch;
15443 
15444   DBUG_ENTER("test_bug21206");
15445   myheader("test_bug21206");
15446 
15447   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
15448 
15449   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15450   {
15451     /* Init will exit(1) in case of error */
15452     stmt_fetch_init(fetch, fetch - fetch_array, query);
15453   }
15454 
15455   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15456     stmt_fetch_close(fetch);
15457 
15458   free(fetch_array);
15459 
15460   DBUG_VOID_RETURN;
15461 }
15462 
15463 /*
15464   Ensure we execute the status code while testing
15465 */
15466 
test_status()15467 static void test_status()
15468 {
15469   const char *status;
15470   DBUG_ENTER("test_status");
15471   myheader("test_status");
15472 
15473   if (!(status= mysql_stat(mysql)))
15474   {
15475     myerror("mysql_stat failed");                 /* purecov: inspected */
15476     die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
15477   }
15478   DBUG_VOID_RETURN;
15479 }
15480 
15481 /*
15482   Bug#21726: Incorrect result with multiple invocations of
15483   LAST_INSERT_ID
15484 
15485   Test that client gets updated value of insert_id on UPDATE that uses
15486   LAST_INSERT_ID(expr).
15487   select_query added to test for bug
15488     #26921 Problem in mysql_insert_id() Embedded C API function
15489 */
test_bug21726()15490 static void test_bug21726()
15491 {
15492   const char *create_table[]=
15493   {
15494     "DROP TABLE IF EXISTS t1",
15495     "CREATE TABLE t1 (i INT)",
15496     "INSERT INTO t1 VALUES (1)",
15497   };
15498   const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
15499   int rc;
15500   my_ulonglong insert_id;
15501   const char *select_query= "SELECT * FROM t1";
15502   MYSQL_RES  *result;
15503 
15504   DBUG_ENTER("test_bug21726");
15505   myheader("test_bug21726");
15506 
15507   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
15508 
15509   rc= mysql_query(mysql, update_query);
15510   myquery(rc);
15511   insert_id= mysql_insert_id(mysql);
15512   DIE_UNLESS(insert_id == 2);
15513 
15514   rc= mysql_query(mysql, update_query);
15515   myquery(rc);
15516   insert_id= mysql_insert_id(mysql);
15517   DIE_UNLESS(insert_id == 3);
15518 
15519   rc= mysql_query(mysql, select_query);
15520   myquery(rc);
15521   insert_id= mysql_insert_id(mysql);
15522   DIE_UNLESS(insert_id == 3);
15523   result= mysql_store_result(mysql);
15524   mysql_free_result(result);
15525 
15526   DBUG_VOID_RETURN;
15527 }
15528 
15529 
15530 /*
15531   BUG#23383: mysql_affected_rows() returns different values than
15532   mysql_stmt_affected_rows()
15533 
15534   Test that both mysql_affected_rows() and mysql_stmt_affected_rows()
15535   return -1 on error, 0 when no rows were affected, and (positive) row
15536   count when some rows were affected.
15537 */
test_bug23383()15538 static void test_bug23383()
15539 {
15540   const char *insert_query= "INSERT INTO t1 VALUES (1), (2)";
15541   const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3";
15542   MYSQL_STMT *stmt;
15543   my_ulonglong row_count;
15544   int rc;
15545 
15546   DBUG_ENTER("test_bug23383");
15547   myheader("test_bug23383");
15548 
15549   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15550   myquery(rc);
15551 
15552   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)");
15553   myquery(rc);
15554 
15555   rc= mysql_query(mysql, insert_query);
15556   myquery(rc);
15557   row_count= mysql_affected_rows(mysql);
15558   DIE_UNLESS(row_count == 2);
15559 
15560   rc= mysql_query(mysql, insert_query);
15561   DIE_UNLESS(rc != 0);
15562   row_count= mysql_affected_rows(mysql);
15563   DIE_UNLESS(row_count == (my_ulonglong)-1);
15564 
15565   rc= mysql_query(mysql, update_query);
15566   myquery(rc);
15567   row_count= mysql_affected_rows(mysql);
15568   DIE_UNLESS(row_count == 0);
15569 
15570   rc= mysql_query(mysql, "DELETE FROM t1");
15571   myquery(rc);
15572 
15573   stmt= mysql_stmt_init(mysql);
15574   DIE_UNLESS(stmt != 0);
15575 
15576   rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query));
15577   check_execute(stmt, rc);
15578 
15579   rc= mysql_stmt_execute(stmt);
15580   check_execute(stmt, rc);
15581   row_count= mysql_stmt_affected_rows(stmt);
15582   DIE_UNLESS(row_count == 2);
15583 
15584   rc= mysql_stmt_execute(stmt);
15585   DIE_UNLESS(rc != 0);
15586   row_count= mysql_stmt_affected_rows(stmt);
15587   DIE_UNLESS(row_count == (my_ulonglong)-1);
15588 
15589   rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query));
15590   check_execute(stmt, rc);
15591 
15592   rc= mysql_stmt_execute(stmt);
15593   check_execute(stmt, rc);
15594   row_count= mysql_stmt_affected_rows(stmt);
15595   DIE_UNLESS(row_count == 0);
15596 
15597   rc= mysql_stmt_close(stmt);
15598   check_execute(stmt, rc);
15599 
15600   rc= mysql_query(mysql, "DROP TABLE t1");
15601   myquery(rc);
15602 
15603   DBUG_VOID_RETURN;
15604 }
15605 
15606 
15607 /*
15608   BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for
15609   expression cols
15610 
15611   Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set
15612   to either expression or its alias, and db, org_table, table,
15613   org_name fields are empty strings.
15614 */
test_bug21635()15615 static void test_bug21635()
15616 {
15617   const char *expr[]=
15618   {
15619     "MIN(i)", "MIN(i)",
15620     "MIN(i) AS A1", "A1",
15621     "MAX(i)", "MAX(i)",
15622     "MAX(i) AS A2", "A2",
15623     "COUNT(i)", "COUNT(i)",
15624     "COUNT(i) AS A3", "A3",
15625   };
15626   char query[MAX_TEST_QUERY_LENGTH];
15627   char *query_end;
15628   MYSQL_RES *result;
15629   MYSQL_FIELD *field;
15630   unsigned int field_count, i, j;
15631   int rc;
15632 
15633   DBUG_ENTER("test_bug21635");
15634   myheader("test_bug21635");
15635 
15636   query_end= strxmov(query, "SELECT ", NullS);
15637   for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i)
15638     query_end= strxmov(query_end, expr[i * 2], ", ", NullS);
15639   query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS);
15640   DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH);
15641 
15642   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15643   myquery(rc);
15644   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)");
15645   myquery(rc);
15646   /*
15647     We need this loop to ensure correct behavior with both constant and
15648     non-constant tables.
15649   */
15650   for (j= 0; j < 2 ; j++)
15651   {
15652     rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
15653     myquery(rc);
15654 
15655     rc= mysql_real_query(mysql, query, query_end - query);
15656     myquery(rc);
15657 
15658     result= mysql_use_result(mysql);
15659     DIE_UNLESS(result);
15660 
15661   field_count= mysql_field_count(mysql);
15662   for (i= 0; i < field_count; ++i)
15663   {
15664     field= mysql_fetch_field_direct(result, i);
15665     if (!opt_silent)
15666       if (!opt_silent)
15667         printf("%s -> %s ... ", expr[i * 2], field->name);
15668     fflush(stdout);
15669     DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
15670                field->table[0] == 0 && field->org_name[0] == 0);
15671     DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
15672     if (!opt_silent)
15673       if (!opt_silent)
15674         puts("OK");
15675   }
15676 
15677     mysql_free_result(result);
15678   }
15679   rc= mysql_query(mysql, "DROP TABLE t1");
15680   myquery(rc);
15681 
15682   DBUG_VOID_RETURN;
15683 }
15684 
15685 /*
15686   Bug#24179 "select b into $var" fails with --cursor_protocol"
15687   The failure is correct, check that the returned message is meaningful.
15688 */
15689 
test_bug24179()15690 static void test_bug24179()
15691 {
15692   int rc;
15693   MYSQL_STMT *stmt;
15694 
15695   DBUG_ENTER("test_bug24179");
15696   myheader("test_bug24179");
15697 
15698   stmt= open_cursor("select 1 into @a");
15699   rc= mysql_stmt_execute(stmt);
15700   DIE_UNLESS(rc);
15701   if (!opt_silent)
15702   {
15703     printf("Got error (as expected): %d %s\n",
15704            mysql_stmt_errno(stmt),
15705            mysql_stmt_error(stmt));
15706   }
15707   DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
15708   mysql_stmt_close(stmt);
15709 
15710   DBUG_VOID_RETURN;
15711 }
15712 
15713 
15714 /**
15715   Bug#32265 Server returns different metadata if prepared statement is used
15716 */
15717 
test_bug32265()15718 static void test_bug32265()
15719 {
15720   int rc;
15721   MYSQL_STMT *stmt;
15722   MYSQL_FIELD *field;
15723   MYSQL_RES *metadata;
15724 
15725   DBUG_ENTER("test_bug32265");
15726   myheader("test_bug32265");
15727 
15728   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15729   myquery(rc);
15730   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
15731   myquery(rc);
15732   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
15733   myquery(rc);
15734   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
15735   myquery(rc);
15736 
15737   stmt= open_cursor("SELECT * FROM t1");
15738   rc= mysql_stmt_execute(stmt);
15739   check_execute(stmt, rc);
15740 
15741   metadata= mysql_stmt_result_metadata(stmt);
15742   field= mysql_fetch_field(metadata);
15743   DIE_UNLESS(field);
15744   DIE_UNLESS(strcmp(field->table, "t1") == 0);
15745   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
15746   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
15747   mysql_free_result(metadata);
15748   mysql_stmt_close(stmt);
15749 
15750   stmt= open_cursor("SELECT a '' FROM t1 ``");
15751   rc= mysql_stmt_execute(stmt);
15752   check_execute(stmt, rc);
15753 
15754   metadata= mysql_stmt_result_metadata(stmt);
15755   field= mysql_fetch_field(metadata);
15756   DIE_UNLESS(strcmp(field->table, "") == 0);
15757   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
15758   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
15759   mysql_free_result(metadata);
15760   mysql_stmt_close(stmt);
15761 
15762   stmt= open_cursor("SELECT a '' FROM t1 ``");
15763   rc= mysql_stmt_execute(stmt);
15764   check_execute(stmt, rc);
15765 
15766   metadata= mysql_stmt_result_metadata(stmt);
15767   field= mysql_fetch_field(metadata);
15768   DIE_UNLESS(strcmp(field->table, "") == 0);
15769   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
15770   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
15771   mysql_free_result(metadata);
15772   mysql_stmt_close(stmt);
15773 
15774   stmt= open_cursor("SELECT * FROM v1");
15775   rc= mysql_stmt_execute(stmt);
15776   check_execute(stmt, rc);
15777 
15778   metadata= mysql_stmt_result_metadata(stmt);
15779   field= mysql_fetch_field(metadata);
15780   DIE_UNLESS(strcmp(field->table, "v1") == 0);
15781   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
15782   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
15783   mysql_free_result(metadata);
15784   mysql_stmt_close(stmt);
15785 
15786   stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
15787   rc= mysql_stmt_execute(stmt);
15788   check_execute(stmt, rc);
15789 
15790   metadata= mysql_stmt_result_metadata(stmt);
15791   field= mysql_fetch_field(metadata);
15792   DIE_UNLESS(strcmp(field->table, "v1") == 0);
15793   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
15794   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
15795   mysql_free_result(metadata);
15796   mysql_stmt_close(stmt);
15797 
15798   rc= mysql_query(mysql, "DROP VIEW v1");
15799   myquery(rc);
15800   rc= mysql_query(mysql, "DROP TABLE t1");
15801   myquery(rc);
15802 
15803   DBUG_VOID_RETURN;
15804 }
15805 
15806 /*
15807   Bug#28075 "COM_DEBUG crashes mysqld"
15808 */
15809 
test_bug28075()15810 static void test_bug28075()
15811 {
15812   int rc;
15813 
15814   DBUG_ENTER("test_bug28075");
15815   myheader("test_bug28075");
15816 
15817   rc= mysql_dump_debug_info(mysql);
15818   DIE_UNLESS(rc == 0);
15819 
15820   rc= mysql_ping(mysql);
15821   DIE_UNLESS(rc == 0);
15822 
15823   DBUG_VOID_RETURN;
15824 }
15825 
15826 
15827 /*
15828   Bug#27876 (SF with cyrillic variable name fails during execution (regression))
15829 */
15830 
test_bug27876()15831 static void test_bug27876()
15832 {
15833   int rc;
15834   MYSQL_RES *result;
15835 
15836   uchar utf8_func[] =
15837   {
15838     0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
15839     0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
15840     0xd0, 0xb0,
15841     0x00
15842   };
15843 
15844   uchar utf8_param[] =
15845   {
15846     0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
15847     0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
15848     0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
15849     0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
15850     0x00
15851   };
15852 
15853   char query[500];
15854 
15855   DBUG_ENTER("test_bug27876");
15856   myheader("test_bug27876");
15857 
15858   rc= mysql_query(mysql, "set names utf8");
15859   myquery(rc);
15860 
15861   rc= mysql_query(mysql, "select version()");
15862   myquery(rc);
15863   result= mysql_store_result(mysql);
15864   mytest(result);
15865   mysql_free_result(result);
15866 
15867   sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
15868   rc= mysql_query(mysql, query);
15869   myquery(rc);
15870 
15871   sprintf(query,
15872           "CREATE FUNCTION %s( %s VARCHAR(25))"
15873           " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
15874           (char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
15875   rc= mysql_query(mysql, query);
15876   myquery(rc);
15877   sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
15878   rc= mysql_query(mysql, query);
15879   myquery(rc);
15880   result= mysql_store_result(mysql);
15881   mytest(result);
15882   mysql_free_result(result);
15883 
15884   sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
15885   rc= mysql_query(mysql, query);
15886   myquery(rc);
15887 
15888   rc= mysql_query(mysql, "set names default");
15889   myquery(rc);
15890   DBUG_VOID_RETURN;
15891 }
15892 
15893 
15894 /*
15895   Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
15896   flag is set.
15897 */
15898 
test_bug28505()15899 static void test_bug28505()
15900 {
15901   my_ulonglong res;
15902 
15903   myquery(mysql_query(mysql, "drop table if exists t1"));
15904   myquery(mysql_query(mysql, "create table t1(f1 int primary key)"));
15905   myquery(mysql_query(mysql, "insert into t1 values(1)"));
15906   myquery(mysql_query(mysql,
15907                   "insert into t1 values(1) on duplicate key update f1=1"));
15908   res= mysql_affected_rows(mysql);
15909   DIE_UNLESS(!res);
15910   myquery(mysql_query(mysql, "drop table t1"));
15911 }
15912 
15913 
15914 /*
15915   Bug#28934: server crash when receiving malformed com_execute packets
15916 */
15917 
test_bug28934()15918 static void test_bug28934()
15919 {
15920   my_bool error= 0;
15921   MYSQL_BIND bind[5];
15922   MYSQL_STMT *stmt;
15923   int cnt;
15924 
15925   myquery(mysql_query(mysql, "drop table if exists t1"));
15926   myquery(mysql_query(mysql, "create table t1(id int)"));
15927 
15928   myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)"));
15929   stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)");
15930   check_stmt(stmt);
15931 
15932   memset (&bind, 0, sizeof (bind));
15933   for (cnt= 0; cnt < 5; cnt++)
15934   {
15935     bind[cnt].buffer_type= MYSQL_TYPE_LONG;
15936     bind[cnt].buffer= (char*)&cnt;
15937     bind[cnt].buffer_length= 0;
15938   }
15939   myquery(mysql_stmt_bind_param(stmt, bind));
15940 
15941   stmt->param_count=2;
15942   error= mysql_stmt_execute(stmt);
15943   DIE_UNLESS(error != 0);
15944   myerror(NULL);
15945   mysql_stmt_close(stmt);
15946 
15947   myquery(mysql_query(mysql, "drop table t1"));
15948 }
15949 
15950 /*
15951   Test mysql_change_user() C API and COM_CHANGE_USER
15952 */
15953 
test_change_user()15954 static void test_change_user()
15955 {
15956   char buff[256];
15957   const char *user_pw= "mysqltest_pw";
15958   const char *user_no_pw= "mysqltest_no_pw";
15959   const char *pw= "password";
15960   const char *db= "mysqltest_user_test_database";
15961   int rc;
15962 
15963   DBUG_ENTER("test_change_user");
15964   myheader("test_change_user");
15965 
15966   /* Prepare environment */
15967   sprintf(buff, "drop database if exists %s", db);
15968   rc= mysql_query(mysql, buff);
15969   myquery(rc);
15970 
15971   sprintf(buff, "create database %s", db);
15972   rc= mysql_query(mysql, buff);
15973   myquery(rc);
15974 
15975   sprintf(buff,
15976           "grant select on %s.* to %s@'%%' identified by '%s'",
15977           db,
15978           user_pw,
15979           pw);
15980   rc= mysql_query(mysql, buff);
15981   myquery(rc);
15982 
15983   sprintf(buff,
15984           "grant select on %s.* to %s@'localhost' identified by '%s'",
15985           db,
15986           user_pw,
15987           pw);
15988   rc= mysql_query(mysql, buff);
15989   myquery(rc);
15990 
15991   sprintf(buff,
15992           "grant select on %s.* to %s@'%%'",
15993           db,
15994           user_no_pw);
15995   rc= mysql_query(mysql, buff);
15996   myquery(rc);
15997 
15998   sprintf(buff,
15999           "grant select on %s.* to %s@'localhost'",
16000           db,
16001           user_no_pw);
16002   rc= mysql_query(mysql, buff);
16003   myquery(rc);
16004 
16005 
16006   /* Try some combinations */
16007   rc= mysql_change_user(mysql, NULL, NULL, NULL);
16008   DIE_UNLESS(rc);
16009   if (! opt_silent)
16010     printf("Got error (as expected): %s\n", mysql_error(mysql));
16011 
16012 
16013   rc= mysql_change_user(mysql, "", NULL, NULL);
16014   DIE_UNLESS(rc);
16015   if (! opt_silent)
16016     printf("Got error (as expected): %s\n", mysql_error(mysql));
16017 
16018   rc= mysql_change_user(mysql, "", "", NULL);
16019   DIE_UNLESS(rc);
16020   if (! opt_silent)
16021     printf("Got error (as expected): %s\n", mysql_error(mysql));
16022 
16023   rc= mysql_change_user(mysql, "", "", "");
16024   DIE_UNLESS(rc);
16025   if (! opt_silent)
16026     printf("Got error (as expected): %s\n", mysql_error(mysql));
16027 
16028   rc= mysql_change_user(mysql, NULL, "", "");
16029   DIE_UNLESS(rc);
16030   if (! opt_silent)
16031     printf("Got error (as expected): %s\n", mysql_error(mysql));
16032 
16033 
16034   rc= mysql_change_user(mysql, NULL, NULL, "");
16035   DIE_UNLESS(rc);
16036   if (! opt_silent)
16037     printf("Got error (as expected): %s\n", mysql_error(mysql));
16038 
16039   rc= mysql_change_user(mysql, "", NULL, "");
16040   DIE_UNLESS(rc);
16041   if (! opt_silent)
16042     printf("Got error (as expected): %s\n", mysql_error(mysql));
16043 
16044   rc= mysql_change_user(mysql, user_pw, NULL, "");
16045   DIE_UNLESS(rc);
16046   if (! opt_silent)
16047     printf("Got error (as expected): %s\n", mysql_error(mysql));
16048 
16049   rc= mysql_change_user(mysql, user_pw, "", "");
16050   DIE_UNLESS(rc);
16051   if (! opt_silent)
16052     printf("Got error (as expected): %s\n", mysql_error(mysql));
16053 
16054   rc= mysql_change_user(mysql, user_pw, "", NULL);
16055   DIE_UNLESS(rc);
16056   if (! opt_silent)
16057     printf("Got error (as expected): %s\n", mysql_error(mysql));
16058 
16059   rc= mysql_change_user(mysql, user_pw, NULL, NULL);
16060   DIE_UNLESS(rc);
16061   if (! opt_silent)
16062     printf("Got error (as expected): %s\n", mysql_error(mysql));
16063 
16064   rc= mysql_change_user(mysql, user_pw, "", db);
16065   DIE_UNLESS(rc);
16066   if (! opt_silent)
16067     printf("Got error (as expected): %s\n", mysql_error(mysql));
16068 
16069   rc= mysql_change_user(mysql, user_pw, NULL, db);
16070   DIE_UNLESS(rc);
16071   if (! opt_silent)
16072     printf("Got error (as expected): %s\n", mysql_error(mysql));
16073 
16074   rc= mysql_change_user(mysql, user_pw, pw, db);
16075   myquery(rc);
16076 
16077   rc= mysql_change_user(mysql, user_pw, pw, NULL);
16078   myquery(rc);
16079 
16080   rc= mysql_change_user(mysql, user_pw, pw, "");
16081   myquery(rc);
16082 
16083   rc= mysql_change_user(mysql, user_no_pw, pw, db);
16084   DIE_UNLESS(rc);
16085   if (! opt_silent)
16086     printf("Got error (as expected): %s\n", mysql_error(mysql));
16087 
16088   rc= mysql_change_user(mysql, user_no_pw, pw, "");
16089   DIE_UNLESS(rc);
16090   if (! opt_silent)
16091     printf("Got error (as expected): %s\n", mysql_error(mysql));
16092 
16093   rc= mysql_change_user(mysql, user_no_pw, pw, NULL);
16094   DIE_UNLESS(rc);
16095   if (! opt_silent)
16096     printf("Got error (as expected): %s\n", mysql_error(mysql));
16097 
16098   rc= mysql_change_user(mysql, user_no_pw, "", NULL);
16099   myquery(rc);
16100 
16101   rc= mysql_change_user(mysql, user_no_pw, "", "");
16102   myquery(rc);
16103 
16104   rc= mysql_change_user(mysql, user_no_pw, "", db);
16105   myquery(rc);
16106 
16107   rc= mysql_change_user(mysql, user_no_pw, NULL, db);
16108   myquery(rc);
16109 
16110   rc= mysql_change_user(mysql, "", pw, db);
16111   DIE_UNLESS(rc);
16112   if (! opt_silent)
16113     printf("Got error (as expected): %s\n", mysql_error(mysql));
16114 
16115   rc= mysql_change_user(mysql, "", pw, "");
16116   DIE_UNLESS(rc);
16117   if (! opt_silent)
16118     printf("Got error (as expected): %s\n", mysql_error(mysql));
16119 
16120   rc= mysql_change_user(mysql, "", pw, NULL);
16121   DIE_UNLESS(rc);
16122   if (! opt_silent)
16123     printf("Got error (as expected): %s\n", mysql_error(mysql));
16124 
16125   rc= mysql_change_user(mysql, NULL, pw, NULL);
16126   DIE_UNLESS(rc);
16127   if (! opt_silent)
16128     printf("Got error (as expected): %s\n", mysql_error(mysql));
16129 
16130   rc= mysql_change_user(mysql, NULL, NULL, db);
16131   DIE_UNLESS(rc);
16132   if (! opt_silent)
16133     printf("Got error (as expected): %s\n", mysql_error(mysql));
16134 
16135   rc= mysql_change_user(mysql, NULL, "", db);
16136   DIE_UNLESS(rc);
16137   if (! opt_silent)
16138     printf("Got error (as expected): %s\n", mysql_error(mysql));
16139 
16140   rc= mysql_change_user(mysql, "", "", db);
16141   DIE_UNLESS(rc);
16142   if (! opt_silent)
16143     printf("Got error (as expected): %s\n", mysql_error(mysql));
16144 
16145   /* Cleanup the environment */
16146 
16147   mysql_change_user(mysql, opt_user, opt_password, current_db);
16148 
16149   sprintf(buff, "drop database %s", db);
16150   rc= mysql_query(mysql, buff);
16151   myquery(rc);
16152 
16153   sprintf(buff, "drop user %s@'%%'", user_pw);
16154   rc= mysql_query(mysql, buff);
16155   myquery(rc);
16156 
16157   sprintf(buff, "drop user %s@'%%'", user_no_pw);
16158   rc= mysql_query(mysql, buff);
16159   myquery(rc);
16160 
16161   sprintf(buff, "drop user %s@'localhost'", user_pw);
16162   rc= mysql_query(mysql, buff);
16163   myquery(rc);
16164 
16165   sprintf(buff, "drop user %s@'localhost'", user_no_pw);
16166   rc= mysql_query(mysql, buff);
16167   myquery(rc);
16168 
16169   DBUG_VOID_RETURN;
16170 }
16171 
16172 /*
16173   Bug#27592 (stack overrun when storing datetime value using prepared statements)
16174 */
16175 
test_bug27592()16176 static void test_bug27592()
16177 {
16178   const int NUM_ITERATIONS= 40;
16179   int i;
16180   int rc;
16181   MYSQL_STMT *stmt= NULL;
16182   MYSQL_BIND bind[1];
16183   MYSQL_TIME time_val;
16184 
16185   DBUG_ENTER("test_bug27592");
16186   myheader("test_bug27592");
16187 
16188   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16189   mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
16190 
16191   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
16192   DIE_UNLESS(stmt);
16193 
16194   memset(bind, 0, sizeof(bind));
16195 
16196   bind[0].buffer_type= MYSQL_TYPE_DATETIME;
16197   bind[0].buffer= (char *) &time_val;
16198   bind[0].length= NULL;
16199 
16200   for (i= 0; i < NUM_ITERATIONS; i++)
16201   {
16202     time_val.year= 2007;
16203     time_val.month= 6;
16204     time_val.day= 7;
16205     time_val.hour= 18;
16206     time_val.minute= 41;
16207     time_val.second= 3;
16208 
16209     time_val.second_part=0;
16210     time_val.neg=0;
16211 
16212     rc= mysql_stmt_bind_param(stmt, bind);
16213     check_execute(stmt, rc);
16214 
16215     rc= mysql_stmt_execute(stmt);
16216     check_execute(stmt, rc);
16217   }
16218 
16219   mysql_stmt_close(stmt);
16220 
16221   DBUG_VOID_RETURN;
16222 }
16223 
16224 /*
16225   Bug#29687 mysql_stmt_store_result memory leak in libmysqld
16226 */
16227 
test_bug29687()16228 static void test_bug29687()
16229 {
16230   const int NUM_ITERATIONS= 40;
16231   int i;
16232   int rc;
16233   MYSQL_STMT *stmt= NULL;
16234 
16235   DBUG_ENTER("test_bug29687");
16236   myheader("test_bug29687");
16237 
16238   stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2");
16239   DIE_UNLESS(stmt);
16240 
16241   for (i= 0; i < NUM_ITERATIONS; i++)
16242   {
16243     rc= mysql_stmt_execute(stmt);
16244     check_execute(stmt, rc);
16245     mysql_stmt_store_result(stmt);
16246     while (mysql_stmt_fetch(stmt)==0);
16247     mysql_stmt_free_result(stmt);
16248   }
16249 
16250   mysql_stmt_close(stmt);
16251   DBUG_VOID_RETURN;
16252 }
16253 
16254 
16255 /*
16256   Bug #29692  	Single row inserts can incorrectly report a huge number of
16257   row insertions
16258 */
16259 
test_bug29692()16260 static void test_bug29692()
16261 {
16262   MYSQL* conn;
16263 
16264   if (!(conn= mysql_client_init(NULL)))
16265   {
16266     myerror("test_bug29692 init failed");
16267     exit(1);
16268   }
16269 
16270   if (!(mysql_real_connect(conn, opt_host, opt_user,
16271                            opt_password, opt_db ? opt_db:"test", opt_port,
16272                            opt_unix_socket,  CLIENT_FOUND_ROWS)))
16273   {
16274     myerror("test_bug29692 connection failed");
16275     mysql_close(mysql);
16276     exit(1);
16277   }
16278   myquery(mysql_query(conn, "drop table if exists t1"));
16279   myquery(mysql_query(conn, "create table t1(f1 int)"));
16280   myquery(mysql_query(conn, "insert into t1 values(1)"));
16281   DIE_UNLESS(1 == mysql_affected_rows(conn));
16282   myquery(mysql_query(conn, "drop table t1"));
16283   mysql_close(conn);
16284 }
16285 
16286 /**
16287   Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
16288 */
16289 
test_bug29306()16290 static void test_bug29306()
16291 {
16292   MYSQL_FIELD *field;
16293   int rc;
16294   MYSQL_RES *res;
16295 
16296   DBUG_ENTER("test_bug29306");
16297   myheader("test_bug29306");
16298 
16299   rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
16300   myquery(rc);
16301   rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
16302   myquery(rc);
16303   rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
16304   myquery(rc);
16305   rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
16306   myquery(rc);
16307   rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
16308   myquery(rc);
16309 
16310   /* Checking the view */
16311   res= mysql_list_fields(mysql, "view17557", NULL);
16312   while ((field= mysql_fetch_field(res)))
16313   {
16314     if (! opt_silent)
16315     {
16316       printf("field name %s\n", field->name);
16317       printf("field table %s\n", field->table);
16318       printf("field decimals %d\n", field->decimals);
16319       if (field->decimals < 1)
16320         printf("Error! No decimals! \n");
16321       printf("\n\n");
16322     }
16323     DIE_UNLESS(field->decimals == 1);
16324   }
16325   mysql_free_result(res);
16326 
16327   rc= mysql_query(mysql, "DROP TABLE tab17557");
16328   myquery(rc);
16329   rc= mysql_query(mysql, "DROP VIEW view17557");
16330   myquery(rc);
16331 
16332   DBUG_VOID_RETURN;
16333 }
16334 /*
16335   Bug#30472: libmysql doesn't reset charset, insert_id after succ.
16336   mysql_change_user() call row insertions.
16337 */
16338 
bug30472_retrieve_charset_info(MYSQL * con,char * character_set_name,char * character_set_client,char * character_set_results,char * collation_connection)16339 static void bug30472_retrieve_charset_info(MYSQL *con,
16340                                            char *character_set_name,
16341                                            char *character_set_client,
16342                                            char *character_set_results,
16343                                            char *collation_connection)
16344 {
16345   MYSQL_RES *rs;
16346   MYSQL_ROW row;
16347 
16348   /* Get the cached client character set name. */
16349 
16350   strcpy(character_set_name, mysql_character_set_name(con));
16351 
16352   /* Retrieve server character set information. */
16353 
16354   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
16355   DIE_UNLESS(rs= mysql_store_result(con));
16356   DIE_UNLESS(row= mysql_fetch_row(rs));
16357   strcpy(character_set_client, row[1]);
16358   mysql_free_result(rs);
16359 
16360   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
16361   DIE_UNLESS(rs= mysql_store_result(con));
16362   DIE_UNLESS(row= mysql_fetch_row(rs));
16363   strcpy(character_set_results, row[1]);
16364   mysql_free_result(rs);
16365 
16366   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
16367   DIE_UNLESS(rs= mysql_store_result(con));
16368   DIE_UNLESS(row= mysql_fetch_row(rs));
16369   strcpy(collation_connection, row[1]);
16370   mysql_free_result(rs);
16371 }
16372 
test_bug30472()16373 static void test_bug30472()
16374 {
16375   MYSQL con;
16376 
16377   char character_set_name_1[MY_CS_NAME_SIZE];
16378   char character_set_client_1[MY_CS_NAME_SIZE];
16379   char character_set_results_1[MY_CS_NAME_SIZE];
16380   char collation_connnection_1[MY_CS_NAME_SIZE];
16381 
16382   char character_set_name_2[MY_CS_NAME_SIZE];
16383   char character_set_client_2[MY_CS_NAME_SIZE];
16384   char character_set_results_2[MY_CS_NAME_SIZE];
16385   char collation_connnection_2[MY_CS_NAME_SIZE];
16386 
16387   char character_set_name_3[MY_CS_NAME_SIZE];
16388   char character_set_client_3[MY_CS_NAME_SIZE];
16389   char character_set_results_3[MY_CS_NAME_SIZE];
16390   char collation_connnection_3[MY_CS_NAME_SIZE];
16391 
16392   char character_set_name_4[MY_CS_NAME_SIZE];
16393   char character_set_client_4[MY_CS_NAME_SIZE];
16394   char character_set_results_4[MY_CS_NAME_SIZE];
16395   char collation_connnection_4[MY_CS_NAME_SIZE];
16396 
16397   /* Create a new connection. */
16398 
16399   DIE_UNLESS(mysql_client_init(&con));
16400 
16401   DIE_UNLESS(mysql_real_connect(&con,
16402                                 opt_host,
16403                                 opt_user,
16404                                 opt_password,
16405                                 opt_db ? opt_db : "test",
16406                                 opt_port,
16407                                 opt_unix_socket,
16408                                 CLIENT_FOUND_ROWS));
16409 
16410   /* Retrieve character set information. */
16411 
16412   bug30472_retrieve_charset_info(&con,
16413                                  character_set_name_1,
16414                                  character_set_client_1,
16415                                  character_set_results_1,
16416                                  collation_connnection_1);
16417 
16418   /* Switch client character set. */
16419 
16420   DIE_IF(mysql_set_character_set(&con, "utf8"));
16421 
16422   /* Retrieve character set information. */
16423 
16424   bug30472_retrieve_charset_info(&con,
16425                                  character_set_name_2,
16426                                  character_set_client_2,
16427                                  character_set_results_2,
16428                                  collation_connnection_2);
16429 
16430   /*
16431     Check that
16432       1) character set has been switched and
16433       2) new character set is different from the original one.
16434   */
16435 
16436   DIE_UNLESS(strcmp(character_set_name_2, "utf8") == 0);
16437   DIE_UNLESS(strcmp(character_set_client_2, "utf8") == 0);
16438   DIE_UNLESS(strcmp(character_set_results_2, "utf8") == 0);
16439   DIE_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0);
16440 
16441   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
16442   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
16443   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
16444   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
16445 
16446   /* Call mysql_change_user() with the same username, password, database. */
16447 
16448   DIE_IF(mysql_change_user(&con,
16449                            opt_user,
16450                            opt_password,
16451                            opt_db ? opt_db : "test"));
16452 
16453   /* Retrieve character set information. */
16454 
16455   bug30472_retrieve_charset_info(&con,
16456                                  character_set_name_3,
16457                                  character_set_client_3,
16458                                  character_set_results_3,
16459                                  collation_connnection_3);
16460 
16461   /* Check that character set information has been reset. */
16462 
16463   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
16464   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
16465   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
16466   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
16467 
16468   /* Change connection-default character set in the client. */
16469 
16470   mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8");
16471 
16472   /*
16473     Call mysql_change_user() in order to check that new connection will
16474     have UTF8 character set on the client and on the server.
16475   */
16476 
16477   DIE_IF(mysql_change_user(&con,
16478                            opt_user,
16479                            opt_password,
16480                            opt_db ? opt_db : "test"));
16481 
16482   /* Retrieve character set information. */
16483 
16484   bug30472_retrieve_charset_info(&con,
16485                                  character_set_name_4,
16486                                  character_set_client_4,
16487                                  character_set_results_4,
16488                                  collation_connnection_4);
16489 
16490   /* Check that we have UTF8 on the server and on the client. */
16491 
16492   DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
16493   DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
16494   DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
16495   DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
16496 
16497   /* That's it. Cleanup. */
16498 
16499   mysql_close(&con);
16500 }
16501 
bug20023_change_user(MYSQL * con)16502 static void bug20023_change_user(MYSQL *con)
16503 {
16504   DIE_IF(mysql_change_user(con,
16505                            opt_user,
16506                            opt_password,
16507                            opt_db ? opt_db : "test"));
16508 }
16509 
query_str_variable(MYSQL * con,const char * var_name,char * str,size_t len)16510 static my_bool query_str_variable(MYSQL *con,
16511                                   const char *var_name,
16512                                   char *str,
16513                                   size_t len)
16514 {
16515   MYSQL_RES *rs;
16516   MYSQL_ROW row;
16517 
16518   char query_buffer[MAX_TEST_QUERY_LENGTH];
16519 
16520   my_bool is_null;
16521 
16522   my_snprintf(query_buffer, sizeof (query_buffer),
16523               "SELECT %s", var_name);
16524 
16525   DIE_IF(mysql_query(con, query_buffer));
16526   DIE_UNLESS(rs= mysql_store_result(con));
16527   DIE_UNLESS(row= mysql_fetch_row(rs));
16528 
16529   is_null= row[0] == NULL;
16530 
16531   if (!is_null)
16532     my_snprintf(str, len, "%s", row[0]);
16533 
16534   mysql_free_result(rs);
16535 
16536   return is_null;
16537 }
16538 
query_int_variable(MYSQL * con,const char * var_name,int * var_value)16539 static my_bool query_int_variable(MYSQL *con,
16540                                   const char *var_name,
16541                                   int *var_value)
16542 {
16543   char str[32];
16544   my_bool is_null= query_str_variable(con, var_name, str, sizeof(str));
16545 
16546   if (!is_null)
16547     *var_value= atoi(str);
16548 
16549   return is_null;
16550 }
16551 
test_bug20023()16552 static void test_bug20023()
16553 {
16554   MYSQL con;
16555 
16556   int sql_big_selects_orig= 0;
16557   /*
16558     Type of max_join_size is ha_rows, which might be ulong or off_t
16559     depending on the platform or configure options. Preserve the string
16560     to avoid type overflow pitfalls.
16561   */
16562   char max_join_size_orig[32];
16563 
16564   int sql_big_selects_2= 0;
16565   int sql_big_selects_3= 0;
16566   int sql_big_selects_4= 0;
16567   int sql_big_selects_5= 0;
16568 
16569   char query_buffer[MAX_TEST_QUERY_LENGTH];
16570 
16571   /* Create a new connection. */
16572 
16573   DIE_UNLESS(mysql_client_init(&con));
16574 
16575   DIE_UNLESS(mysql_real_connect(&con,
16576                                 opt_host,
16577                                 opt_user,
16578                                 opt_password,
16579                                 opt_db ? opt_db : "test",
16580                                 opt_port,
16581                                 opt_unix_socket,
16582                                 CLIENT_FOUND_ROWS));
16583 
16584   /***********************************************************************
16585     Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
16586   ***********************************************************************/
16587 
16588   query_int_variable(&con,
16589                      "@@session.sql_big_selects",
16590                      &sql_big_selects_orig);
16591 
16592   query_str_variable(&con,
16593                      "@@global.max_join_size",
16594                      max_join_size_orig,
16595                      sizeof(max_join_size_orig));
16596 
16597   /***********************************************************************
16598     Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
16599   ***********************************************************************/
16600 
16601   /* Issue COM_CHANGE_USER. */
16602 
16603   bug20023_change_user(&con);
16604 
16605   /* Query SQL_BIG_SELECTS. */
16606 
16607   query_int_variable(&con,
16608                      "@@session.sql_big_selects",
16609                      &sql_big_selects_2);
16610 
16611   /* Check that SQL_BIG_SELECTS is reset properly. */
16612 
16613   DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2);
16614 
16615   /***********************************************************************
16616     Test that if MAX_JOIN_SIZE set to non-default value,
16617     SQL_BIG_SELECTS will be 0.
16618   ***********************************************************************/
16619 
16620   /* Set MAX_JOIN_SIZE to some non-default value. */
16621 
16622   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000"));
16623   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
16624 
16625   /* Issue COM_CHANGE_USER. */
16626 
16627   bug20023_change_user(&con);
16628 
16629   /* Query SQL_BIG_SELECTS. */
16630 
16631   query_int_variable(&con,
16632                      "@@session.sql_big_selects",
16633                      &sql_big_selects_3);
16634 
16635   /* Check that SQL_BIG_SELECTS is 0. */
16636 
16637   DIE_UNLESS(sql_big_selects_3 == 0);
16638 
16639   /***********************************************************************
16640     Test that if MAX_JOIN_SIZE set to default value,
16641     SQL_BIG_SELECTS will be 1.
16642   ***********************************************************************/
16643 
16644   /* Set MAX_JOIN_SIZE to the default value (2^64-1). */
16645 
16646   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
16647   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
16648 
16649   /* Issue COM_CHANGE_USER. */
16650 
16651   bug20023_change_user(&con);
16652 
16653   /* Query SQL_BIG_SELECTS. */
16654 
16655   query_int_variable(&con,
16656                      "@@session.sql_big_selects",
16657                      &sql_big_selects_4);
16658 
16659   /* Check that SQL_BIG_SELECTS is 1. */
16660 
16661   DIE_UNLESS(sql_big_selects_4 == 1);
16662 
16663   /***********************************************************************
16664     Restore MAX_JOIN_SIZE.
16665     Check that SQL_BIG_SELECTS will be the original one.
16666   ***********************************************************************/
16667 
16668   /* Restore MAX_JOIN_SIZE. */
16669 
16670   my_snprintf(query_buffer,
16671            sizeof (query_buffer),
16672            "SET @@global.max_join_size = %s",
16673            max_join_size_orig);
16674 
16675   DIE_IF(mysql_query(&con, query_buffer));
16676 
16677   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
16678   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
16679 
16680   /* Issue COM_CHANGE_USER. */
16681 
16682   bug20023_change_user(&con);
16683 
16684   /* Query SQL_BIG_SELECTS. */
16685 
16686   query_int_variable(&con,
16687                      "@@session.sql_big_selects",
16688                      &sql_big_selects_5);
16689 
16690   /* Check that SQL_BIG_SELECTS is 1. */
16691 
16692   DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig);
16693 
16694   /***********************************************************************
16695     That's it. Cleanup.
16696   ***********************************************************************/
16697 
16698   mysql_close(&con);
16699 }
16700 
bug31418_impl()16701 static void bug31418_impl()
16702 {
16703   MYSQL con;
16704 
16705   my_bool is_null;
16706   int rc= 0;
16707 
16708   /* Create a new connection. */
16709 
16710   DIE_UNLESS(mysql_client_init(&con));
16711 
16712   DIE_UNLESS(mysql_real_connect(&con,
16713                                 opt_host,
16714                                 opt_user,
16715                                 opt_password,
16716                                 opt_db ? opt_db : "test",
16717                                 opt_port,
16718                                 opt_unix_socket,
16719                                 CLIENT_FOUND_ROWS));
16720 
16721   /***********************************************************************
16722     Check that lock is free:
16723       - IS_FREE_LOCK() should return 1;
16724       - IS_USED_LOCK() should return NULL;
16725   ***********************************************************************/
16726 
16727   is_null= query_int_variable(&con,
16728                               "IS_FREE_LOCK('bug31418')",
16729                               &rc);
16730   DIE_UNLESS(!is_null && rc);
16731 
16732   is_null= query_int_variable(&con,
16733                               "IS_USED_LOCK('bug31418')",
16734                               &rc);
16735   DIE_UNLESS(is_null);
16736 
16737   /***********************************************************************
16738     Acquire lock and check the lock status (the lock must be in use):
16739       - IS_FREE_LOCK() should return 0;
16740       - IS_USED_LOCK() should return non-zero thread id;
16741   ***********************************************************************/
16742 
16743   query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
16744   DIE_UNLESS(rc);
16745 
16746   is_null= query_int_variable(&con,
16747                               "IS_FREE_LOCK('bug31418')",
16748                               &rc);
16749   DIE_UNLESS(!is_null && !rc);
16750 
16751   is_null= query_int_variable(&con,
16752                               "IS_USED_LOCK('bug31418')",
16753                               &rc);
16754   DIE_UNLESS(!is_null && rc);
16755 
16756   /***********************************************************************
16757     Issue COM_CHANGE_USER command and check the lock status
16758     (the lock must be free):
16759       - IS_FREE_LOCK() should return 1;
16760       - IS_USED_LOCK() should return NULL;
16761   **********************************************************************/
16762 
16763   bug20023_change_user(&con);
16764 
16765   is_null= query_int_variable(&con,
16766                               "IS_FREE_LOCK('bug31418')",
16767                               &rc);
16768   DIE_UNLESS(!is_null && rc);
16769 
16770   is_null= query_int_variable(&con,
16771                               "IS_USED_LOCK('bug31418')",
16772                               &rc);
16773   DIE_UNLESS(is_null);
16774 
16775   /***********************************************************************
16776    That's it. Cleanup.
16777   ***********************************************************************/
16778 
16779   mysql_close(&con);
16780 }
16781 
test_bug31418()16782 static void test_bug31418()
16783 {
16784   /* Run test case for BUG#31418 for three different connections. */
16785 
16786   bug31418_impl();
16787 
16788   bug31418_impl();
16789 
16790   bug31418_impl();
16791 }
16792 
16793 
16794 
16795 /**
16796   Bug#31669 Buffer overflow in mysql_change_user()
16797 */
16798 
16799 #define LARGE_BUFFER_SIZE 2048
16800 
test_bug31669()16801 static void test_bug31669()
16802 {
16803   int rc;
16804   static char buff[LARGE_BUFFER_SIZE+1];
16805 #ifndef EMBEDDED_LIBRARY
16806   static char user[USERNAME_CHAR_LENGTH+1];
16807   static char db[NAME_CHAR_LEN+1];
16808   static char query[LARGE_BUFFER_SIZE*2];
16809 #endif
16810 
16811   DBUG_ENTER("test_bug31669");
16812   myheader("test_bug31669");
16813 
16814   rc= mysql_change_user(mysql, NULL, NULL, NULL);
16815   DIE_UNLESS(rc);
16816 
16817   rc= mysql_change_user(mysql, "", "", "");
16818   DIE_UNLESS(rc);
16819 
16820   memset(buff, 'a', sizeof(buff));
16821 
16822   rc= mysql_change_user(mysql, buff, buff, buff);
16823   DIE_UNLESS(rc);
16824 
16825   rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
16826   DIE_UNLESS(!rc);
16827 
16828 #ifndef EMBEDDED_LIBRARY
16829   memset(db, 'a', sizeof(db));
16830   db[NAME_CHAR_LEN]= 0;
16831   strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
16832   rc= mysql_query(mysql, query);
16833   myquery(rc);
16834 
16835   memset(user, 'b', sizeof(user));
16836   user[USERNAME_CHAR_LENGTH]= 0;
16837   memset(buff, 'c', sizeof(buff));
16838   buff[LARGE_BUFFER_SIZE]= 0;
16839   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
16840                  "'", buff, "' WITH GRANT OPTION", NullS);
16841   rc= mysql_query(mysql, query);
16842   myquery(rc);
16843 
16844   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY "
16845                  "'", buff, "' WITH GRANT OPTION", NullS);
16846   rc= mysql_query(mysql, query);
16847   myquery(rc);
16848 
16849   rc= mysql_query(mysql, "FLUSH PRIVILEGES");
16850   myquery(rc);
16851 
16852   rc= mysql_change_user(mysql, user, buff, db);
16853   DIE_UNLESS(!rc);
16854 
16855   user[USERNAME_CHAR_LENGTH-1]= 'a';
16856   rc= mysql_change_user(mysql, user, buff, db);
16857   DIE_UNLESS(rc);
16858 
16859   user[USERNAME_CHAR_LENGTH-1]= 'b';
16860   buff[LARGE_BUFFER_SIZE-1]= 'd';
16861   rc= mysql_change_user(mysql, user, buff, db);
16862   DIE_UNLESS(rc);
16863 
16864   buff[LARGE_BUFFER_SIZE-1]= 'c';
16865   db[NAME_CHAR_LEN-1]= 'e';
16866   rc= mysql_change_user(mysql, user, buff, db);
16867   DIE_UNLESS(rc);
16868 
16869   db[NAME_CHAR_LEN-1]= 'a';
16870   rc= mysql_change_user(mysql, user, buff, db);
16871   DIE_UNLESS(!rc);
16872 
16873   rc= mysql_change_user(mysql, user + 1, buff + 1, db + 1);
16874   DIE_UNLESS(rc);
16875 
16876   rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
16877   DIE_UNLESS(!rc);
16878 
16879   strxmov(query, "DROP DATABASE ", db, NullS);
16880   rc= mysql_query(mysql, query);
16881   myquery(rc);
16882 
16883   strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
16884   rc= mysql_query(mysql, query);
16885   myquery(rc);
16886   DIE_UNLESS(mysql_affected_rows(mysql) == 2);
16887 #endif
16888 
16889   DBUG_VOID_RETURN;
16890 }
16891 
16892 
16893 /**
16894   Bug#28386 the general log is incomplete
16895 */
16896 
test_bug28386()16897 static void test_bug28386()
16898 {
16899   int rc;
16900   MYSQL_STMT *stmt;
16901   MYSQL_RES *result;
16902   MYSQL_ROW row;
16903   MYSQL_BIND bind;
16904   const char hello[]= "hello world!";
16905 
16906   DBUG_ENTER("test_bug28386");
16907   myheader("test_bug28386");
16908 
16909   rc= mysql_query(mysql, "select @@global.log_output");
16910   myquery(rc);
16911 
16912   result= mysql_store_result(mysql);
16913   DIE_UNLESS(result);
16914 
16915   row= mysql_fetch_row(result);
16916   if (! strstr(row[0], "TABLE"))
16917   {
16918     mysql_free_result(result);
16919     if (! opt_silent)
16920       printf("Skipping the test since logging to tables is not enabled\n");
16921     /* Log output is not to tables */
16922     return;
16923   }
16924   mysql_free_result(result);
16925 
16926   enable_query_logs(1);
16927 
16928   stmt= mysql_simple_prepare(mysql, "SELECT ?");
16929   check_stmt(stmt);
16930 
16931   memset(&bind, 0, sizeof(bind));
16932 
16933   bind.buffer_type= MYSQL_TYPE_STRING;
16934   bind.buffer= (void *) hello;
16935   bind.buffer_length= sizeof(hello);
16936 
16937   mysql_stmt_bind_param(stmt, &bind);
16938   mysql_stmt_send_long_data(stmt, 0, hello, sizeof(hello));
16939 
16940   rc= mysql_stmt_execute(stmt);
16941   check_execute(stmt, rc);
16942 
16943   rc= my_process_stmt_result(stmt);
16944   DIE_UNLESS(rc == 1);
16945 
16946   rc= mysql_stmt_reset(stmt);
16947   check_execute(stmt, rc);
16948 
16949   rc= mysql_stmt_close(stmt);
16950   DIE_UNLESS(!rc);
16951 
16952   rc= mysql_query(mysql, "select * from mysql.general_log where "
16953                          "command_type='Close stmt' or "
16954                          "command_type='Reset stmt' or "
16955                          "command_type='Long Data'");
16956   myquery(rc);
16957 
16958   result= mysql_store_result(mysql);
16959   mytest(result);
16960 
16961   DIE_UNLESS(mysql_num_rows(result) == 3);
16962 
16963   mysql_free_result(result);
16964 
16965   restore_query_logs();
16966 
16967   DBUG_VOID_RETURN;
16968 }
16969 
16970 
test_wl4166_1()16971 static void test_wl4166_1()
16972 {
16973   MYSQL_STMT *stmt;
16974   int        int_data;
16975   char       str_data[50];
16976   char       tiny_data;
16977   short      small_data;
16978   longlong   big_data;
16979   float      real_data;
16980   double     double_data;
16981   ulong      length[7];
16982   my_bool    is_null[7];
16983   MYSQL_BIND my_bind[7];
16984   int rc;
16985   int i;
16986 
16987   myheader("test_wl4166_1");
16988 
16989   rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
16990   myquery(rc);
16991 
16992   rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
16993                          "col2 varchar(15), col3 int, "
16994                          "col4 smallint, col5 bigint, "
16995                          "col6 float, col7 double, "
16996                          "colX varchar(10) default NULL)");
16997   myquery(rc);
16998 
16999   stmt= mysql_simple_prepare(mysql,
17000     "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
17001     "VALUES(?, ?, ?, ?, ?, ?, ?)");
17002   check_stmt(stmt);
17003 
17004   verify_param_count(stmt, 7);
17005 
17006   bzero(my_bind, sizeof(my_bind));
17007   /* tinyint */
17008   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
17009   my_bind[0].buffer= (void *)&tiny_data;
17010   /* string */
17011   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
17012   my_bind[1].buffer= (void *)str_data;
17013   my_bind[1].buffer_length= 1000;                  /* Max string length */
17014   /* integer */
17015   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
17016   my_bind[2].buffer= (void *)&int_data;
17017   /* short */
17018   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
17019   my_bind[3].buffer= (void *)&small_data;
17020   /* bigint */
17021   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
17022   my_bind[4].buffer= (void *)&big_data;
17023   /* float */
17024   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
17025   my_bind[5].buffer= (void *)&real_data;
17026   /* double */
17027   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
17028   my_bind[6].buffer= (void *)&double_data;
17029 
17030   for (i= 0; i < (int) array_elements(my_bind); i++)
17031   {
17032     my_bind[i].length= &length[i];
17033     my_bind[i].is_null= &is_null[i];
17034     is_null[i]= 0;
17035   }
17036 
17037   rc= mysql_stmt_bind_param(stmt, my_bind);
17038   check_execute(stmt, rc);
17039 
17040   int_data= 320;
17041   small_data= 1867;
17042   big_data= 1000;
17043   real_data= 2;
17044   double_data= 6578.001;
17045 
17046   /* now, execute the prepared statement to insert 10 records.. */
17047   for (tiny_data= 0; tiny_data < 10; tiny_data++)
17048   {
17049     length[1]= sprintf(str_data, "MySQL%d", int_data);
17050     rc= mysql_stmt_execute(stmt);
17051     check_execute(stmt, rc);
17052     int_data += 25;
17053     small_data += 10;
17054     big_data += 100;
17055     real_data += 1;
17056     double_data += 10.09;
17057   }
17058 
17059   /* force a re-prepare with some DDL */
17060 
17061   rc= mysql_query(mysql,
17062     "ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
17063   myquery(rc);
17064 
17065   /*
17066     execute the prepared statement again,
17067     without changing the types of parameters already bound.
17068   */
17069 
17070   for (tiny_data= 50; tiny_data < 60; tiny_data++)
17071   {
17072     length[1]= sprintf(str_data, "MySQL%d", int_data);
17073     rc= mysql_stmt_execute(stmt);
17074     check_execute(stmt, rc);
17075     int_data += 25;
17076     small_data += 10;
17077     big_data += 100;
17078     real_data += 1;
17079     double_data += 10.09;
17080   }
17081 
17082   mysql_stmt_close(stmt);
17083 
17084   rc= mysql_query(mysql, "DROP TABLE table_4166");
17085   myquery(rc);
17086 }
17087 
17088 
test_wl4166_2()17089 static void test_wl4166_2()
17090 {
17091   MYSQL_STMT *stmt;
17092   int        c_int;
17093   MYSQL_TIME d_date;
17094   MYSQL_BIND bind_out[2];
17095   int rc;
17096 
17097   myheader("test_wl4166_2");
17098 
17099   rc= mysql_query(mysql, "SET SQL_MODE=''");
17100   myquery(rc);
17101 
17102   rc= mysql_query(mysql, "drop table if exists t1");
17103   myquery(rc);
17104   rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
17105   myquery(rc);
17106   rc= mysql_query(mysql,
17107                   "insert into t1 (c_int, d_date) values (42, '1948-05-15')");
17108   myquery(rc);
17109 
17110   stmt= mysql_simple_prepare(mysql, "select * from t1");
17111   check_stmt(stmt);
17112 
17113   bzero(bind_out, sizeof(bind_out));
17114   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
17115   bind_out[0].buffer= (void*) &c_int;
17116 
17117   bind_out[1].buffer_type= MYSQL_TYPE_DATE;
17118   bind_out[1].buffer= (void*) &d_date;
17119 
17120   rc= mysql_stmt_bind_result(stmt, bind_out);
17121   check_execute(stmt, rc);
17122 
17123   /* int -> varchar transition */
17124 
17125   rc= mysql_query(mysql,
17126                   "alter table t1 change column c_int c_int varchar(11)");
17127   myquery(rc);
17128 
17129   rc= mysql_stmt_execute(stmt);
17130   check_execute(stmt, rc);
17131 
17132   rc= mysql_stmt_fetch(stmt);
17133   check_execute(stmt, rc);
17134 
17135   DIE_UNLESS(c_int == 42);
17136   DIE_UNLESS(d_date.year == 1948);
17137   DIE_UNLESS(d_date.month == 5);
17138   DIE_UNLESS(d_date.day == 15);
17139 
17140   rc= mysql_stmt_fetch(stmt);
17141   DIE_UNLESS(rc == MYSQL_NO_DATA);
17142 
17143   /* varchar to int retrieval with truncation */
17144 
17145   rc= mysql_query(mysql, "update t1 set c_int='abcde'");
17146   myquery(rc);
17147 
17148   rc= mysql_stmt_execute(stmt);
17149   check_execute(stmt, rc);
17150 
17151   rc= mysql_stmt_fetch(stmt);
17152   check_execute_r(stmt, rc);
17153 
17154   DIE_UNLESS(c_int == 0);
17155 
17156   rc= mysql_stmt_fetch(stmt);
17157   DIE_UNLESS(rc == MYSQL_NO_DATA);
17158 
17159   /* alter table and increase the number of columns */
17160   rc= mysql_query(mysql, "alter table t1 add column d_int int");
17161   myquery(rc);
17162 
17163   rc= mysql_stmt_execute(stmt);
17164   check_execute_r(stmt, rc);
17165 
17166   rc= mysql_stmt_reset(stmt);
17167   check_execute(stmt, rc);
17168 
17169   /* decrease the number of columns */
17170   rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
17171   myquery(rc);
17172 
17173   rc= mysql_stmt_execute(stmt);
17174   check_execute_r(stmt, rc);
17175 
17176   mysql_stmt_close(stmt);
17177   rc= mysql_query(mysql, "drop table t1");
17178   myquery(rc);
17179 
17180 }
17181 
17182 
17183 /**
17184   Test how warnings generated during assignment of parameters
17185   are (currently not) preserve in case of reprepare.
17186 */
17187 
test_wl4166_3()17188 static void test_wl4166_3()
17189 {
17190   int rc;
17191   MYSQL_STMT *stmt;
17192   MYSQL_BIND my_bind[1];
17193   MYSQL_TIME tm[1];
17194 
17195   myheader("test_wl4166_3");
17196 
17197   rc= mysql_query(mysql, "drop table if exists t1");
17198   myquery(rc);
17199 
17200   rc= mysql_query(mysql, "create table t1 (year datetime)");
17201   myquery(rc);
17202 
17203   stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)");
17204   check_stmt(stmt);
17205   verify_param_count(stmt, 1);
17206 
17207   bzero((char*) my_bind, sizeof(my_bind));
17208   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17209   my_bind[0].buffer= &tm[0];
17210 
17211   rc= mysql_stmt_bind_param(stmt, my_bind);
17212   check_execute(stmt, rc);
17213 
17214   tm[0].year= 10000;
17215   tm[0].month= 1; tm[0].day= 1;
17216   tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
17217   tm[0].second_part= 0; tm[0].neg= 0;
17218 
17219   /* Cause a statement reprepare */
17220   rc= mysql_query(mysql, "alter table t1 add column c int");
17221   myquery(rc);
17222 
17223   rc= mysql_stmt_execute(stmt);
17224   check_execute(stmt, rc);
17225   /*
17226     Sic: only one warning, instead of two. The warning
17227     about data truncation when assigning a parameter is lost.
17228     This is a bug.
17229   */
17230   my_process_warnings(mysql, 1);
17231 
17232   verify_col_data("t1", "year", "0000-00-00 00:00:00");
17233 
17234   mysql_stmt_close(stmt);
17235 
17236   rc= mysql_query(mysql, "drop table t1");
17237   myquery(rc);
17238 }
17239 
17240 
17241 /**
17242   Test that long data parameters, as well as parameters
17243   that were originally in a different character set, are
17244   preserved in case of reprepare.
17245 */
17246 
test_wl4166_4()17247 static void test_wl4166_4()
17248 {
17249   MYSQL_STMT *stmt;
17250   int rc;
17251   const char *stmt_text;
17252   MYSQL_BIND bind_array[2];
17253 
17254   /* Represented as numbers to keep UTF8 tools from clobbering them. */
17255   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
17256   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
17257   char buf1[16], buf2[16];
17258   ulong buf1_len, buf2_len;
17259 
17260   myheader("test_wl4166_4");
17261 
17262   rc= mysql_query(mysql, "drop table if exists t1");
17263   myquery(rc);
17264 
17265   /*
17266     Create table with binary columns, set session character set to cp1251,
17267     client character set to koi8, and make sure that there is conversion
17268     on insert and no conversion on select
17269   */
17270   rc= mysql_query(mysql,
17271                   "create table t1 (c1 varbinary(255), c2 varbinary(255))");
17272   myquery(rc);
17273   rc= mysql_query(mysql, "set character_set_client=koi8r, "
17274                          "character_set_connection=cp1251, "
17275                          "character_set_results=koi8r");
17276   myquery(rc);
17277 
17278   bzero((char*) bind_array, sizeof(bind_array));
17279 
17280   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
17281 
17282   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
17283   bind_array[1].buffer= (void *) koi8;
17284   bind_array[1].buffer_length= strlen(koi8);
17285 
17286   stmt= mysql_stmt_init(mysql);
17287   check_stmt(stmt);
17288 
17289   stmt_text= "insert into t1 (c1, c2) values (?, ?)";
17290 
17291   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17292   check_execute(stmt, rc);
17293 
17294   mysql_stmt_bind_param(stmt, bind_array);
17295 
17296   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
17297 
17298   /* Cause a reprepare at statement execute */
17299   rc= mysql_query(mysql, "alter table t1 add column d int");
17300   myquery(rc);
17301 
17302   rc= mysql_stmt_execute(stmt);
17303   check_execute(stmt, rc);
17304 
17305   stmt_text= "select c1, c2 from t1";
17306 
17307   /* c1 and c2 are binary so no conversion will be done on select */
17308   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17309   check_execute(stmt, rc);
17310 
17311   rc= mysql_stmt_execute(stmt);
17312   check_execute(stmt, rc);
17313 
17314   bind_array[0].buffer= buf1;
17315   bind_array[0].buffer_length= sizeof(buf1);
17316   bind_array[0].length= &buf1_len;
17317 
17318   bind_array[1].buffer= buf2;
17319   bind_array[1].buffer_length= sizeof(buf2);
17320   bind_array[1].length= &buf2_len;
17321 
17322   mysql_stmt_bind_result(stmt, bind_array);
17323 
17324   rc= mysql_stmt_fetch(stmt);
17325   check_execute(stmt, rc);
17326 
17327   DIE_UNLESS(buf1_len == strlen(cp1251));
17328   DIE_UNLESS(buf2_len == strlen(cp1251));
17329   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
17330   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
17331 
17332   rc= mysql_stmt_fetch(stmt);
17333   DIE_UNLESS(rc == MYSQL_NO_DATA);
17334 
17335   mysql_stmt_close(stmt);
17336 
17337   rc= mysql_query(mysql, "drop table t1");
17338   myquery(rc);
17339   rc= mysql_query(mysql, "set names default");
17340   myquery(rc);
17341 }
17342 
17343 /**
17344   Bug#36004 mysql_stmt_prepare resets the list of warnings
17345 */
17346 
test_bug36004()17347 static void test_bug36004()
17348 {
17349   int rc, warning_count= 0;
17350   MYSQL_STMT *stmt;
17351 
17352   DBUG_ENTER("test_bug36004");
17353   myheader("test_bug36004");
17354 
17355   rc= mysql_query(mysql, "drop table if exists inexistant");
17356   myquery(rc);
17357 
17358   DIE_UNLESS(mysql_warning_count(mysql) == 1);
17359   query_int_variable(mysql, "@@warning_count", &warning_count);
17360   DIE_UNLESS(warning_count);
17361 
17362   stmt= mysql_simple_prepare(mysql, "select 1");
17363   check_stmt(stmt);
17364 
17365   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17366   query_int_variable(mysql, "@@warning_count", &warning_count);
17367   DIE_UNLESS(warning_count);
17368 
17369   rc= mysql_stmt_execute(stmt);
17370   check_execute(stmt, rc);
17371 
17372   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17373   mysql_stmt_close(stmt);
17374 
17375   query_int_variable(mysql, "@@warning_count", &warning_count);
17376   DIE_UNLESS(warning_count);
17377 
17378   stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
17379   check_stmt(stmt);
17380 
17381   query_int_variable(mysql, "@@warning_count", &warning_count);
17382   DIE_UNLESS(warning_count == 0);
17383   mysql_stmt_close(stmt);
17384 
17385   DBUG_VOID_RETURN;
17386 }
17387 
17388 /**
17389   Test that COM_REFRESH issues a implicit commit.
17390 */
17391 
test_wl4284_1()17392 static void test_wl4284_1()
17393 {
17394   int rc;
17395   MYSQL_ROW row;
17396   MYSQL_RES *result;
17397 
17398   DBUG_ENTER("test_wl4284_1");
17399   myheader("test_wl4284_1");
17400 
17401   /* set AUTOCOMMIT to OFF */
17402   rc= mysql_autocommit(mysql, FALSE);
17403   myquery(rc);
17404 
17405   rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
17406   myquery(rc);
17407 
17408   rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
17409   myquery(rc);
17410 
17411   rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
17412   myquery(rc);
17413 
17414   rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
17415   myquery(rc);
17416 
17417   rc= mysql_rollback(mysql);
17418   myquery(rc);
17419 
17420   rc= mysql_query(mysql, "SELECT * FROM trans");
17421   myquery(rc);
17422 
17423   result= mysql_use_result(mysql);
17424   mytest(result);
17425 
17426   row= mysql_fetch_row(result);
17427   mytest(row);
17428 
17429   mysql_free_result(result);
17430 
17431   /* set AUTOCOMMIT to ON */
17432   rc= mysql_autocommit(mysql, TRUE);
17433   myquery(rc);
17434 
17435   rc= mysql_query(mysql, "DROP TABLE trans");
17436   myquery(rc);
17437 
17438   DBUG_VOID_RETURN;
17439 }
17440 
17441 
test_bug38486(void)17442 static void test_bug38486(void)
17443 {
17444   MYSQL_STMT *stmt;
17445   const char *stmt_text;
17446   unsigned long type= CURSOR_TYPE_READ_ONLY;
17447 
17448   DBUG_ENTER("test_bug38486");
17449   myheader("test_bug38486");
17450 
17451   stmt= mysql_stmt_init(mysql);
17452   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
17453   stmt_text= "CREATE TABLE t1 (a INT)";
17454   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17455   mysql_stmt_execute(stmt);
17456   mysql_stmt_close(stmt);
17457 
17458   stmt= mysql_stmt_init(mysql);
17459   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
17460   stmt_text= "INSERT INTO t1 VALUES (1)";
17461   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17462   mysql_stmt_execute(stmt);
17463   mysql_stmt_close(stmt);
17464 
17465   DBUG_VOID_RETURN;
17466 }
17467 
17468 
17469 /**
17470      Bug# 33831 mysql_real_connect() should fail if
17471      given an already connected MYSQL handle.
17472 */
17473 
test_bug33831(void)17474 static void test_bug33831(void)
17475 {
17476   MYSQL *l_mysql;
17477 
17478   DBUG_ENTER("test_bug33831");
17479 
17480   if (!(l_mysql= mysql_client_init(NULL)))
17481   {
17482     myerror("mysql_client_init() failed");
17483     DIE_UNLESS(0);
17484   }
17485   if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
17486                            opt_password, current_db, opt_port,
17487                            opt_unix_socket, 0)))
17488   {
17489     myerror("connection failed");
17490     DIE_UNLESS(0);
17491   }
17492 
17493   if (mysql_real_connect(l_mysql, opt_host, opt_user,
17494                          opt_password, current_db, opt_port,
17495                          opt_unix_socket, 0))
17496   {
17497     myerror("connection should have failed");
17498     DIE_UNLESS(0);
17499   }
17500 
17501   mysql_close(l_mysql);
17502 
17503   DBUG_VOID_RETURN;
17504 }
17505 
17506 
test_bug40365(void)17507 static void test_bug40365(void)
17508 {
17509   uint         rc, i;
17510   MYSQL_STMT   *stmt= 0;
17511   MYSQL_BIND   my_bind[2];
17512   my_bool      is_null[2]= {0};
17513   MYSQL_TIME   tm[2];
17514 
17515   DBUG_ENTER("test_bug40365");
17516 
17517   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
17518   myquery(rc);
17519   rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \
17520                                           c2 DATE)");
17521   myquery(rc);
17522 
17523   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)");
17524   check_stmt(stmt);
17525   verify_param_count(stmt, 2);
17526 
17527   bzero((char*) my_bind, sizeof(my_bind));
17528   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17529   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
17530   for (i= 0; i < (int) array_elements(my_bind); i++)
17531   {
17532     my_bind[i].buffer= (void *) &tm[i];
17533     my_bind[i].is_null= &is_null[i];
17534   }
17535 
17536   rc= mysql_stmt_bind_param(stmt, my_bind);
17537   check_execute(stmt, rc);
17538 
17539   for (i= 0; i < (int) array_elements(my_bind); i++)
17540   {
17541     tm[i].neg= 0;
17542     tm[i].second_part= 0;
17543     tm[i].year= 2009;
17544     tm[i].month= 2;
17545     tm[i].day= 29;
17546     tm[i].hour= 0;
17547     tm[i].minute= 0;
17548     tm[i].second= 0;
17549   }
17550   rc= mysql_stmt_execute(stmt);
17551   check_execute(stmt, rc);
17552 
17553   rc= mysql_commit(mysql);
17554   myquery(rc);
17555   mysql_stmt_close(stmt);
17556 
17557   stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1");
17558   check_stmt(stmt);
17559 
17560   rc= mysql_stmt_bind_result(stmt, my_bind);
17561   check_execute(stmt, rc);
17562 
17563   rc= mysql_stmt_execute(stmt);
17564   check_execute(stmt, rc);
17565 
17566   rc= mysql_stmt_store_result(stmt);
17567   check_execute(stmt, rc);
17568 
17569   rc= mysql_stmt_fetch(stmt);
17570   check_execute(stmt, rc);
17571 
17572   if (!opt_silent)
17573     fprintf(stdout, "\n");
17574 
17575   for (i= 0; i < array_elements(my_bind); i++)
17576   {
17577     if (!opt_silent)
17578       fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d ",
17579               i, tm[i].year, tm[i].month, tm[i].day);
17580       DIE_UNLESS(tm[i].year == 0);
17581       DIE_UNLESS(tm[i].month == 0);
17582       DIE_UNLESS(tm[i].day == 0);
17583   }
17584   mysql_stmt_close(stmt);
17585   rc= mysql_commit(mysql);
17586   myquery(rc);
17587 
17588   DBUG_VOID_RETURN;
17589 }
17590 
17591 
17592 /**
17593   Subtest for Bug#43560. Verifies that a loss of connection on the server side
17594   is handled well by the mysql_stmt_execute() call, i.e., no SIGSEGV due to
17595   a vio socket that is cleared upon closed connection.
17596 
17597   Assumes the presence of the close_conn_after_stmt_execute debug feature in
17598   the server. Verifies that it is connected to a debug server before proceeding
17599   with the test.
17600  */
test_bug43560(void)17601 static void test_bug43560(void)
17602 {
17603   MYSQL*       conn;
17604   uint         rc;
17605   MYSQL_STMT   *stmt= 0;
17606   MYSQL_BIND   bind;
17607   my_bool      is_null= 0;
17608   char         buffer[256];
17609   const uint   BUFSIZE= sizeof(buffer);
17610   const char*  values[] = {"eins", "zwei", "drei", "viele", NULL};
17611   const char   insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
17612   unsigned long length;
17613   const unsigned int drop_db= opt_drop_db;
17614 
17615   DBUG_ENTER("test_bug43560");
17616   myheader("test_bug43560");
17617 
17618   /* Make sure we only run against a debug server. */
17619   if (!strstr(mysql->server_version, "debug"))
17620   {
17621     fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
17622     DBUG_VOID_RETURN;
17623   }
17624 
17625   /*
17626     Set up a separate connection for this test to avoid messing up the
17627     general MYSQL object used in other subtests. Use TCP protocol to avoid
17628     problems with the buffer semantics of AF_UNIX, and turn off auto reconnect.
17629   */
17630   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17631 
17632   rc= mysql_query(conn, "DROP TABLE IF EXISTS t1");
17633   myquery(rc);
17634   rc= mysql_query(conn,
17635     "CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))");
17636   myquery(rc);
17637 
17638   stmt= mysql_stmt_init(conn);
17639   check_stmt(stmt);
17640   rc= mysql_stmt_prepare(stmt, insert_str, strlen(insert_str));
17641   check_execute(stmt, rc);
17642 
17643   bind.buffer_type= MYSQL_TYPE_STRING;
17644   bind.buffer_length= BUFSIZE;
17645   bind.buffer= buffer;
17646   bind.is_null= &is_null;
17647   bind.length= &length;
17648   rc= mysql_stmt_bind_param(stmt, &bind);
17649   check_execute(stmt, rc);
17650 
17651   /* First execute; should succeed. */
17652   strncpy(buffer, values[0], BUFSIZE);
17653   length= strlen(buffer);
17654   rc= mysql_stmt_execute(stmt);
17655   check_execute(stmt, rc);
17656 
17657   /*
17658     Set up the server to close this session's server-side socket after
17659     next execution of prep statement.
17660   */
17661   rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'");
17662   myquery(rc);
17663 
17664   /* Second execute; should fail due to socket closed during execution. */
17665   strncpy(buffer, values[1], BUFSIZE);
17666   length= strlen(buffer);
17667   rc= mysql_stmt_execute(stmt);
17668   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
17669 
17670   /*
17671     Third execute; should fail (connection already closed), or SIGSEGV in
17672     case of a Bug#43560 type regression in which case the whole test fails.
17673   */
17674   strncpy(buffer, values[2], BUFSIZE);
17675   length= strlen(buffer);
17676   rc= mysql_stmt_execute(stmt);
17677   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
17678 
17679   opt_drop_db= 0;
17680   client_disconnect(conn);
17681   rc= mysql_query(mysql, "DROP TABLE t1");
17682   myquery(rc);
17683   opt_drop_db= drop_db;
17684 
17685   DBUG_VOID_RETURN;
17686 }
17687 
17688 
17689 /**
17690   Bug#36326: nested transaction and select
17691 */
17692 
17693 #ifdef HAVE_QUERY_CACHE
17694 
test_bug36326()17695 static void test_bug36326()
17696 {
17697   int rc;
17698 
17699   DBUG_ENTER("test_bug36326");
17700   myheader("test_bug36326");
17701 
17702   rc= mysql_autocommit(mysql, TRUE);
17703   myquery(rc);
17704   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
17705   myquery(rc);
17706   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
17707   myquery(rc);
17708   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
17709   myquery(rc);
17710   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
17711   myquery(rc);
17712   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576");
17713   myquery(rc);
17714   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
17715   DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
17716   rc= mysql_query(mysql, "BEGIN");
17717   myquery(rc);
17718   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
17719   rc= mysql_query(mysql, "SELECT * FROM t1");
17720   myquery(rc);
17721   rc= my_process_result(mysql);
17722   DIE_UNLESS(rc == 1);
17723   rc= mysql_rollback(mysql);
17724   myquery(rc);
17725   rc= mysql_query(mysql, "ROLLBACK");
17726   myquery(rc);
17727   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
17728   rc= mysql_query(mysql, "SELECT * FROM t1");
17729   myquery(rc);
17730   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
17731   rc= my_process_result(mysql);
17732   DIE_UNLESS(rc == 1);
17733   rc= mysql_query(mysql, "DROP TABLE t1");
17734   myquery(rc);
17735   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 0");
17736   myquery(rc);
17737 
17738   DBUG_VOID_RETURN;
17739 }
17740 
17741 #endif
17742 
17743 /**
17744   Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
17745              string value.
17746 */
17747 
test_bug41078(void)17748 static void test_bug41078(void)
17749 {
17750   uint         rc;
17751   MYSQL_STMT   *stmt= 0;
17752   MYSQL_BIND   param, result;
17753   ulong        cursor_type= CURSOR_TYPE_READ_ONLY;
17754   ulong        len;
17755   char         str[64];
17756   const char   param_str[]= "abcdefghijklmn";
17757   my_bool      is_null, error;
17758 
17759   DBUG_ENTER("test_bug41078");
17760 
17761   rc= mysql_query(mysql, "SET NAMES UTF8");
17762   myquery(rc);
17763 
17764   stmt= mysql_simple_prepare(mysql, "SELECT ?");
17765   check_stmt(stmt);
17766   verify_param_count(stmt, 1);
17767 
17768   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type);
17769   check_execute(stmt, rc);
17770 
17771   bzero(&param, sizeof(param));
17772   param.buffer_type= MYSQL_TYPE_STRING;
17773   param.buffer= (void *) param_str;
17774   len= sizeof(param_str) - 1;
17775   param.length= &len;
17776 
17777   rc= mysql_stmt_bind_param(stmt, &param);
17778   check_execute(stmt, rc);
17779 
17780   rc= mysql_stmt_execute(stmt);
17781   check_execute(stmt, rc);
17782 
17783   bzero(&result, sizeof(result));
17784   result.buffer_type= MYSQL_TYPE_STRING;
17785   result.buffer= str;
17786   result.buffer_length= sizeof(str);
17787   result.is_null= &is_null;
17788   result.length= &len;
17789   result.error=  &error;
17790 
17791   rc= mysql_stmt_bind_result(stmt, &result);
17792   check_execute(stmt, rc);
17793 
17794   rc= mysql_stmt_store_result(stmt);
17795   check_execute(stmt, rc);
17796 
17797   rc= mysql_stmt_fetch(stmt);
17798   check_execute(stmt, rc);
17799 
17800   DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str));
17801 
17802   mysql_stmt_close(stmt);
17803 
17804   DBUG_VOID_RETURN;
17805 }
17806 
17807 /**
17808   Bug#45010: invalid memory reads during parsing some strange statements
17809 */
test_bug45010()17810 static void test_bug45010()
17811 {
17812   int rc;
17813   const char query1[]= "select a.\x80",
17814              query2[]= "describe `table\xef";
17815 
17816   DBUG_ENTER("test_bug45010");
17817   myheader("test_bug45010");
17818 
17819   rc= mysql_query(mysql, "set names utf8");
17820   myquery(rc);
17821 
17822   /* \x80 (-128) could be used as a index of ident_map. */
17823   rc= mysql_real_query(mysql, query1, sizeof(query1) - 1);
17824   DIE_UNLESS(rc);
17825 
17826   /* \xef (-17) could be used to skip 3 bytes past the buffer end. */
17827   rc= mysql_real_query(mysql, query2, sizeof(query2) - 1);
17828   DIE_UNLESS(rc);
17829 
17830   rc= mysql_query(mysql, "set names default");
17831   myquery(rc);
17832 
17833   DBUG_VOID_RETURN;
17834 }
17835 
17836 /**
17837   Bug#44495: Prepared Statement:
17838              CALL p(<x>) - `thd->protocol == &thd->protocol_text' failed
17839 */
17840 
test_bug44495()17841 static void test_bug44495()
17842 {
17843   int rc;
17844   MYSQL con;
17845   MYSQL_STMT *stmt;
17846 
17847   DBUG_ENTER("test_bug44495");
17848   myheader("test_44495");
17849 
17850   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
17851   myquery(rc);
17852 
17853   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN arg VARCHAR(25))"
17854                          "  BEGIN SET @stmt = CONCAT('SELECT \"', arg, '\"');"
17855                          "  PREPARE ps1 FROM @stmt;"
17856                          "  EXECUTE ps1;"
17857                          "  DROP PREPARE ps1;"
17858                          "END;");
17859   myquery(rc);
17860 
17861   DIE_UNLESS(mysql_client_init(&con));
17862 
17863   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
17864                                 current_db, opt_port, opt_unix_socket,
17865                                 CLIENT_MULTI_RESULTS));
17866 
17867   stmt= mysql_simple_prepare(&con, "CALL p1('abc')");
17868   check_stmt(stmt);
17869 
17870   rc= mysql_stmt_execute(stmt);
17871   check_execute(stmt, rc);
17872 
17873   rc= my_process_stmt_result(stmt);
17874   DIE_UNLESS(rc == 1);
17875 
17876   mysql_stmt_close(stmt);
17877 
17878   mysql_close(&con);
17879 
17880   rc= mysql_query(mysql, "DROP PROCEDURE p1");
17881   myquery(rc);
17882 
17883   DBUG_VOID_RETURN;
17884 }
17885 
test_bug53371()17886 static void test_bug53371()
17887 {
17888   int rc;
17889   MYSQL_RES *result;
17890 
17891   myheader("test_bug53371");
17892 
17893   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
17894   myquery(rc);
17895   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
17896   myquery(rc);
17897   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
17898 
17899   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
17900   myquery(rc);
17901   rc= mysql_query(mysql, "CREATE DATABASE bug53371");
17902   myquery(rc);
17903   rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
17904   myquery(rc);
17905 
17906   rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
17907   myquery(rc);
17908 
17909   rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
17910   DIE_UNLESS(rc);
17911   DIE_UNLESS(mysql_errno(mysql) == 1142);
17912 
17913   result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
17914   DIE_IF(result);
17915 
17916   result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
17917   DIE_IF(result);
17918 
17919   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
17920   myquery(rc);
17921   rc= mysql_query(mysql, "DROP TABLE t1");
17922   myquery(rc);
17923   rc= mysql_query(mysql, "DROP DATABASE bug53371");
17924   myquery(rc);
17925   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
17926   myquery(rc);
17927 }
17928 
17929 
17930 
17931 /**
17932   Bug#42373: libmysql can mess a connection at connect
17933 */
test_bug42373()17934 static void test_bug42373()
17935 {
17936   int rc;
17937   MYSQL con;
17938   MYSQL_STMT *stmt;
17939 
17940   DBUG_ENTER("test_bug42373");
17941   myheader("test_42373");
17942 
17943   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
17944   myquery(rc);
17945 
17946   rc= mysql_query(mysql, "CREATE PROCEDURE p1()"
17947                          "  BEGIN"
17948                          "  SELECT 1;"
17949                          "  INSERT INTO t1 VALUES (2);"
17950                          "END;");
17951   myquery(rc);
17952 
17953   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
17954   myquery(rc);
17955 
17956   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
17957   myquery(rc);
17958 
17959   /* Try with a stored procedure. */
17960   DIE_UNLESS(mysql_client_init(&con));
17961 
17962   mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()");
17963 
17964   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
17965                                 current_db, opt_port, opt_unix_socket,
17966                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
17967 
17968   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
17969   check_stmt(stmt);
17970 
17971   rc= mysql_stmt_execute(stmt);
17972   check_execute(stmt, rc);
17973 
17974   rc= my_process_stmt_result(stmt);
17975   DIE_UNLESS(rc == 1);
17976 
17977   mysql_stmt_close(stmt);
17978 
17979   /* Now try with a multi-statement. */
17980   DIE_UNLESS(mysql_client_init(&con));
17981 
17982   mysql_options(&con, MYSQL_INIT_COMMAND,
17983                 "SELECT 3; INSERT INTO t1 VALUES (4)");
17984 
17985   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
17986                                 current_db, opt_port, opt_unix_socket,
17987                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
17988 
17989   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
17990   check_stmt(stmt);
17991 
17992   rc= mysql_stmt_execute(stmt);
17993   check_execute(stmt, rc);
17994 
17995   rc= my_process_stmt_result(stmt);
17996   DIE_UNLESS(rc == 2);
17997 
17998   mysql_stmt_close(stmt);
17999   mysql_close(&con);
18000 
18001   rc= mysql_query(mysql, "DROP TABLE t1");
18002   myquery(rc);
18003 
18004   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18005   myquery(rc);
18006 
18007   DBUG_VOID_RETURN;
18008 }
18009 
18010 
18011 /**
18012   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18013 */
18014 
test_bug54041_impl()18015 static void test_bug54041_impl()
18016 {
18017   int rc;
18018   MYSQL_STMT *stmt;
18019   MYSQL_BIND bind;
18020 
18021   DBUG_ENTER("test_bug54041");
18022   myheader("test_bug54041");
18023 
18024   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18025   myquery(rc);
18026 
18027   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18028   myquery(rc);
18029 
18030   stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?");
18031   check_stmt(stmt);
18032   verify_param_count(stmt, 1);
18033 
18034   memset(&bind, 0, sizeof(bind));
18035 
18036   /* Any type that does not support long data handling. */
18037   bind.buffer_type= MYSQL_TYPE_LONG;
18038 
18039   rc= mysql_stmt_bind_param(stmt, &bind);
18040   check_execute(stmt, rc);
18041 
18042   /*
18043     Trick the client API into sending a long data packet for
18044     the parameter. Long data is only supported for string and
18045     binary types.
18046   */
18047   stmt->params[0].buffer_type= MYSQL_TYPE_STRING;
18048 
18049   rc= mysql_stmt_send_long_data(stmt, 0, "data", 5);
18050   check_execute(stmt, rc);
18051 
18052   /* Undo API violation. */
18053   stmt->params[0].buffer_type= MYSQL_TYPE_LONG;
18054 
18055   rc= mysql_stmt_execute(stmt);
18056   /* Incorrect arguments. */
18057   check_execute_r(stmt, rc);
18058 
18059   mysql_stmt_close(stmt);
18060 
18061   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18062   myquery(rc);
18063 
18064   DBUG_VOID_RETURN;
18065 }
18066 
18067 
18068 /**
18069   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18070 */
18071 
test_bug54041()18072 static void test_bug54041()
18073 {
18074   enable_query_logs(0);
18075   test_bug54041_impl();
18076   disable_query_logs();
18077   test_bug54041_impl();
18078   restore_query_logs();
18079 }
18080 
18081 
18082 /**
18083   Bug#47485: mysql_store_result returns a result set for a prepared statement
18084 */
test_bug47485()18085 static void test_bug47485()
18086 {
18087   MYSQL_STMT   *stmt;
18088   MYSQL_RES    *res;
18089   MYSQL_BIND    bind[2];
18090   int           rc;
18091   const char*   sql_select = "SELECT 1, 'a'";
18092   int           int_data;
18093   char          str_data[16];
18094   my_bool       is_null[2];
18095   my_bool       error[2];
18096   unsigned long length[2];
18097 
18098   DBUG_ENTER("test_bug47485");
18099   myheader("test_bug47485");
18100 
18101   stmt= mysql_stmt_init(mysql);
18102   check_stmt(stmt);
18103   rc= mysql_stmt_prepare(stmt, sql_select, strlen(sql_select));
18104   check_execute(stmt, rc);
18105 
18106   rc= mysql_stmt_execute(stmt);
18107   check_execute(stmt, rc);
18108 
18109   res = mysql_store_result(mysql);
18110   DIE_UNLESS(res == NULL);
18111 
18112   mysql_stmt_reset(stmt);
18113 
18114   rc= mysql_stmt_execute(stmt);
18115   check_execute(stmt, rc);
18116 
18117   res = mysql_use_result(mysql);
18118   DIE_UNLESS(res == NULL);
18119 
18120   mysql_stmt_reset(stmt);
18121 
18122   memset(bind, 0, sizeof(bind));
18123   bind[0].buffer_type= MYSQL_TYPE_LONG;
18124   bind[0].buffer= (char *)&int_data;
18125   bind[0].is_null= &is_null[0];
18126   bind[0].length= &length[0];
18127   bind[0].error= &error[0];
18128 
18129   bind[1].buffer_type= MYSQL_TYPE_STRING;
18130   bind[1].buffer= (char *)str_data;
18131   bind[1].buffer_length= sizeof(str_data);
18132   bind[1].is_null= &is_null[1];
18133   bind[1].length= &length[1];
18134   bind[1].error= &error[1];
18135 
18136   rc= mysql_stmt_bind_result(stmt, bind);
18137   check_execute(stmt, rc);
18138 
18139   rc= mysql_stmt_execute(stmt);
18140   check_execute(stmt, rc);
18141 
18142   rc= mysql_stmt_store_result(stmt);
18143   check_execute(stmt, rc);
18144 
18145   while (!(rc= mysql_stmt_fetch(stmt)))
18146     ;
18147 
18148   DIE_UNLESS(rc == MYSQL_NO_DATA);
18149 
18150   mysql_stmt_reset(stmt);
18151 
18152   memset(bind, 0, sizeof(bind));
18153   bind[0].buffer_type= MYSQL_TYPE_LONG;
18154   bind[0].buffer= (char *)&int_data;
18155   bind[0].is_null= &is_null[0];
18156   bind[0].length= &length[0];
18157   bind[0].error= &error[0];
18158 
18159   bind[1].buffer_type= MYSQL_TYPE_STRING;
18160   bind[1].buffer= (char *)str_data;
18161   bind[1].buffer_length= sizeof(str_data);
18162   bind[1].is_null= &is_null[1];
18163   bind[1].length= &length[1];
18164   bind[1].error= &error[1];
18165 
18166   rc= mysql_stmt_bind_result(stmt, bind);
18167   check_execute(stmt, rc);
18168 
18169   rc= mysql_stmt_execute(stmt);
18170   check_execute(stmt, rc);
18171 
18172   while (!(rc= mysql_stmt_fetch(stmt)))
18173     ;
18174 
18175   DIE_UNLESS(rc == MYSQL_NO_DATA);
18176 
18177   mysql_stmt_close(stmt);
18178 
18179   DBUG_VOID_RETURN;
18180 }
18181 
18182 
18183 /*
18184   Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server
18185 */
test_bug58036()18186 static void test_bug58036()
18187 {
18188   MYSQL *conn;
18189   DBUG_ENTER("test_bug47485");
18190   myheader("test_bug58036");
18191 
18192   /* Part1: try to connect with ucs2 client character set */
18193   conn= mysql_client_init(NULL);
18194   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18195   if (mysql_real_connect(conn, opt_host, opt_user,
18196                          opt_password,  opt_db ? opt_db : "test",
18197                          opt_port, opt_unix_socket, 0))
18198   {
18199     if (!opt_silent)
18200       printf("mysql_real_connect() succeeded (failure expected)\n");
18201     mysql_close(conn);
18202     DIE("");
18203   }
18204 
18205   if (!opt_silent)
18206     printf("Got mysql_real_connect() error (expected): %s (%d)\n",
18207            mysql_error(conn), mysql_errno(conn));
18208   DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR);
18209   mysql_close(conn);
18210 
18211 
18212   /*
18213     Part2:
18214     - connect with latin1
18215     - then change client character set to ucs2
18216     - then try mysql_change_user()
18217   */
18218   conn= mysql_client_init(NULL);
18219   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1");
18220   if (!mysql_real_connect(conn, opt_host, opt_user,
18221                          opt_password, opt_db ? opt_db : "test",
18222                          opt_port, opt_unix_socket, 0))
18223   {
18224     if (!opt_silent)
18225       printf("mysql_real_connect() failed: %s (%d)\n",
18226              mysql_error(conn), mysql_errno(conn));
18227     mysql_close(conn);
18228     DIE("");
18229   }
18230 
18231   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18232   if (!mysql_change_user(conn, opt_user, opt_password, NULL))
18233   {
18234     if (!opt_silent)
18235       printf("mysql_change_user() succedded, error expected!");
18236     mysql_close(conn);
18237     DIE("");
18238   }
18239 
18240   if (!opt_silent)
18241     printf("Got mysql_change_user() error (expected): %s (%d)\n",
18242            mysql_error(conn), mysql_errno(conn));
18243   mysql_close(conn);
18244 
18245   DBUG_VOID_RETURN;
18246 }
18247 
18248 
18249 /*
18250   Bug#49972: Crash in prepared statements.
18251 
18252   The following case lead to a server crash:
18253     - Use binary protocol;
18254     - Prepare a statement with OUT-parameter;
18255     - Execute the statement;
18256     - Cause re-prepare of the statement (change dependencies);
18257     - Execute the statement again -- crash here.
18258 */
18259 
test_bug49972()18260 static void test_bug49972()
18261 {
18262   int rc;
18263   MYSQL_STMT *stmt;
18264 
18265   MYSQL_BIND in_param_bind;
18266   MYSQL_BIND out_param_bind;
18267   int int_data;
18268   my_bool is_null;
18269 
18270   DBUG_ENTER("test_bug49972");
18271   myheader("test_bug49972");
18272 
18273   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
18274   myquery(rc);
18275 
18276   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18277   myquery(rc);
18278 
18279   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18280   myquery(rc);
18281 
18282   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a");
18283   myquery(rc);
18284 
18285   stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)");
18286   check_stmt(stmt);
18287 
18288   bzero((char *) &in_param_bind, sizeof (in_param_bind));
18289 
18290   in_param_bind.buffer_type= MYSQL_TYPE_LONG;
18291   in_param_bind.buffer= (char *) &int_data;
18292   in_param_bind.length= 0;
18293   in_param_bind.is_null= 0;
18294 
18295   rc= mysql_stmt_bind_param(stmt, &in_param_bind);
18296 
18297   rc= mysql_stmt_execute(stmt);
18298   check_execute(stmt, rc);
18299 
18300   {
18301     bzero(&out_param_bind, sizeof (out_param_bind));
18302 
18303     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18304     out_param_bind.is_null= &is_null;
18305     out_param_bind.buffer= &int_data;
18306     out_param_bind.buffer_length= sizeof (int_data);
18307 
18308     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18309     check_execute(stmt, rc);
18310 
18311     rc= mysql_stmt_fetch(stmt);
18312     rc= mysql_stmt_fetch(stmt);
18313     DBUG_ASSERT(rc == MYSQL_NO_DATA);
18314 
18315     mysql_stmt_next_result(stmt);
18316     mysql_stmt_fetch(stmt);
18317   }
18318 
18319   rc= mysql_query(mysql, "DROP FUNCTION f1");
18320   myquery(rc);
18321 
18322   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18323   myquery(rc);
18324 
18325   rc= mysql_stmt_execute(stmt);
18326   check_execute(stmt, rc);
18327 
18328   {
18329     bzero(&out_param_bind, sizeof (out_param_bind));
18330 
18331     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18332     out_param_bind.is_null= &is_null;
18333     out_param_bind.buffer= &int_data;
18334     out_param_bind.buffer_length= sizeof (int_data);
18335 
18336     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18337     check_execute(stmt, rc);
18338 
18339     rc= mysql_stmt_fetch(stmt);
18340     rc= mysql_stmt_fetch(stmt);
18341     DBUG_ASSERT(rc == MYSQL_NO_DATA);
18342 
18343     mysql_stmt_next_result(stmt);
18344     mysql_stmt_fetch(stmt);
18345   }
18346 
18347   mysql_stmt_close(stmt);
18348 
18349   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18350   myquery(rc);
18351 
18352   rc= mysql_query(mysql, "DROP FUNCTION f1");
18353   myquery(rc);
18354 
18355   DBUG_VOID_RETURN;
18356 }
18357 
18358 
18359 /*
18360   Bug #56976:   Severe Denial Of Service in prepared statements
18361 */
test_bug56976()18362 static void test_bug56976()
18363 {
18364   MYSQL_STMT   *stmt;
18365   MYSQL_BIND    bind[1];
18366   int           rc;
18367   const char*   query = "SELECT LENGTH(?)";
18368   char *long_buffer;
18369   unsigned long i, packet_len = 256 * 1024L;
18370   unsigned long dos_len    = 2 * 1024 * 1024L;
18371 
18372   DBUG_ENTER("test_bug56976");
18373   myheader("test_bug56976");
18374 
18375   stmt= mysql_stmt_init(mysql);
18376   check_stmt(stmt);
18377 
18378   rc= mysql_stmt_prepare(stmt, query, strlen(query));
18379   check_execute(stmt, rc);
18380 
18381   memset(bind, 0, sizeof(bind));
18382   bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;
18383 
18384   rc= mysql_stmt_bind_param(stmt, bind);
18385   check_execute(stmt, rc);
18386 
18387   long_buffer= (char*) my_malloc(packet_len, MYF(0));
18388   DIE_UNLESS(long_buffer);
18389 
18390   memset(long_buffer, 'a', packet_len);
18391 
18392   for (i= 0; i < dos_len / packet_len; i++)
18393   {
18394     rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len);
18395     check_execute(stmt, rc);
18396   }
18397 
18398   my_free(long_buffer);
18399   rc= mysql_stmt_execute(stmt);
18400 
18401   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);
18402 
18403   mysql_stmt_close(stmt);
18404 
18405   DBUG_VOID_RETURN;
18406 }
18407 
18408 
18409 /**
18410   Bug#57058 SERVER_QUERY_WAS_SLOW not wired up.
18411 */
18412 
test_bug57058()18413 static void test_bug57058()
18414 {
18415   MYSQL_RES *res;
18416   int rc;
18417 
18418   DBUG_ENTER("test_bug57058");
18419   myheader("test_bug57058");
18420 
18421   rc= mysql_query(mysql, "set @@session.long_query_time=0.1");
18422   myquery(rc);
18423 
18424   DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW));
18425 
18426   rc= mysql_query(mysql, "select sleep(1)");
18427   myquery(rc);
18428 
18429   /*
18430     Important: the flag is sent in the last EOF packet of
18431     the query, the one which ends the result. Read the
18432     result to see the "slow" status.
18433   */
18434   res= mysql_store_result(mysql);
18435 
18436   DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW);
18437 
18438   mysql_free_result(res);
18439 
18440   rc= mysql_query(mysql, "set @@session.long_query_time=default");
18441   myquery(rc);
18442 
18443   DBUG_VOID_RETURN;
18444 }
18445 
18446 
18447 /**
18448   Bug#11766854: 60075: MYSQL_LOAD_CLIENT_PLUGIN DOESN'T CLEAR ERROR
18449 */
18450 
test_bug11766854()18451 static void test_bug11766854()
18452 {
18453   struct st_mysql_client_plugin *plugin;
18454 
18455   DBUG_ENTER("test_bug11766854");
18456   myheader("test_bug11766854");
18457 
18458   plugin= mysql_load_plugin(mysql, "foo", -1, 0);
18459   DIE_UNLESS(plugin == 0);
18460 
18461   plugin= mysql_load_plugin(mysql, "qa_auth_client", -1, 0);
18462   DIE_UNLESS(plugin != 0);
18463   DIE_IF(mysql_errno(mysql));
18464 
18465   DBUG_VOID_RETURN;
18466 }
18467 
18468 /**
18469   Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR
18470                        CHAR/VARCHAR/TEXT COLUMNS IN VIEWS
18471 */
test_bug12337762()18472 static void test_bug12337762()
18473 {
18474   int rc,i=0;
18475   MYSQL_RES *result;
18476   MYSQL_FIELD *field;
18477   unsigned int tab_charsetnr[3]= {0};
18478 
18479   DBUG_ENTER("test_bug12337762");
18480   myheader("test_bug12337762");
18481 
18482   /*
18483     Creating table with specific charset.
18484   */
18485   rc= mysql_query(mysql, "drop table if exists charset_tab");
18486   rc= mysql_query(mysql, "create table charset_tab("\
18487                          "txt1 varchar(32) character set Latin1,"\
18488                          "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
18489                          "txt3 varchar(32) character set utf8 collate utf8_bin"\
18490 						 ")");
18491 
18492   DIE_UNLESS(rc == 0);
18493   DIE_IF(mysql_errno(mysql));
18494 
18495   /*
18496     Creating view from table created earlier.
18497   */
18498   rc= mysql_query(mysql, "drop view if exists charset_view");
18499   rc= mysql_query(mysql, "create view charset_view as "\
18500                          "select * from charset_tab;");
18501   DIE_UNLESS(rc == 0);
18502   DIE_IF(mysql_errno(mysql));
18503 
18504   /*
18505     Checking field information for table.
18506   */
18507   result= mysql_list_fields(mysql, "charset_tab", NULL);
18508   DIE_IF(mysql_errno(mysql));
18509   i=0;
18510   while((field= mysql_fetch_field(result)))
18511   {
18512     printf("field name %s\n", field->name);
18513     printf("field table %s\n", field->table);
18514     printf("field type %d\n", field->type);
18515     printf("field charset %d\n", field->charsetnr);
18516     tab_charsetnr[i++]= field->charsetnr;
18517     printf("\n");
18518   }
18519   mysql_free_result(result);
18520 
18521   /*
18522     Checking field information for view.
18523   */
18524   result= mysql_list_fields(mysql, "charset_view", NULL);
18525   DIE_IF(mysql_errno(mysql));
18526   i=0;
18527   while((field= mysql_fetch_field(result)))
18528   {
18529     printf("field name %s\n", field->name);
18530     printf("field table %s\n", field->table);
18531     printf("field type %d\n", field->type);
18532     printf("field charset %d\n", field->charsetnr);
18533     printf("\n");
18534     /*
18535       charset value for field must be same for both, view and table.
18536     */
18537     DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
18538   }
18539   mysql_free_result(result);
18540 
18541   DBUG_VOID_RETURN;
18542 }
18543 
18544 
18545 /*
18546   BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
18547 */
18548 
test_bug11754979()18549 static void test_bug11754979()
18550 {
18551   MYSQL* conn;
18552   DBUG_ENTER("test_bug11754979");
18553 
18554   myheader("test_bug11754979");
18555   DIE_UNLESS((conn= mysql_client_init(NULL)));
18556   DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
18557              opt_password, opt_db ? opt_db:"test", opt_port,
18558              opt_unix_socket,  CLIENT_FOUND_ROWS));
18559   myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
18560   myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
18561   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
18562   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
18563                             "ON DUPLICATE KEY UPDATE id = 4"));
18564   DIE_UNLESS(mysql_affected_rows(conn) == 2);
18565   myquery(mysql_query(conn, "DROP TABLE t1"));
18566   mysql_close(conn);
18567 
18568   DBUG_VOID_RETURN;
18569 }
18570 
18571 
18572 /*
18573   Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
18574 */
test_bug13001491()18575 static void test_bug13001491()
18576 {
18577   int rc;
18578   char query[MAX_TEST_QUERY_LENGTH];
18579   MYSQL *c;
18580 
18581   myheader("test_bug13001491");
18582 
18583   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
18584            "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
18585            opt_host ? opt_host : "'localhost'");
18586 
18587   rc= mysql_query(mysql, query);
18588   myquery(rc);
18589 
18590   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
18591            "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
18592            opt_host ? opt_host : "'localhost'");
18593 
18594   rc= mysql_query(mysql, query);
18595   myquery(rc);
18596 
18597   c= mysql_client_init(NULL);
18598 
18599   DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
18600                                 current_db, opt_port, opt_unix_socket,
18601                                 CLIENT_MULTI_STATEMENTS |
18602                                 CLIENT_MULTI_RESULTS));
18603 
18604   rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
18605   myquery(rc);
18606 
18607   rc= mysql_query(c,
18608     "CREATE PROCEDURE p1() "
18609     "BEGIN "
18610     " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
18611     " SELECT COUNT(*) "
18612     " FROM INFORMATION_SCHEMA.PROCESSLIST "
18613     " GROUP BY user "
18614     " ORDER BY NULL "
18615     " INTO @a; "
18616     "END");
18617   myquery(rc);
18618 
18619   rc= mysql_query(c, "CALL p1()");
18620   myquery(rc);
18621 
18622   mysql_free_result(mysql_store_result(c));
18623 
18624   /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
18625   rc= mysql_refresh(c, REFRESH_GRANT |
18626                        REFRESH_TABLES | REFRESH_HOSTS |
18627                        REFRESH_STATUS | REFRESH_THREADS);
18628   myquery(rc);
18629 
18630   /*
18631     Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
18632     fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
18633     location.
18634   */
18635   mysql_refresh(c, REFRESH_LOG);
18636 
18637   rc= mysql_query(c, "DROP PROCEDURE p1");
18638   myquery(rc);
18639 
18640   mysql_close(c);
18641   c= NULL;
18642 
18643   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
18644            "DROP USER mysqltest_u1@%s",
18645            opt_host ? opt_host : "'localhost'");
18646 
18647   rc= mysql_query(mysql, query);
18648   myquery(rc);
18649 }
18650 
18651 
18652 static struct my_tests_st my_tests[]= {
18653   { "disable_query_logs", disable_query_logs },
18654   { "test_view_sp_list_fields", test_view_sp_list_fields },
18655   { "client_query", client_query },
18656   { "test_prepare_insert_update", test_prepare_insert_update},
18657 #if NOT_YET_WORKING
18658   { "test_drop_temp", test_drop_temp },
18659 #endif
18660   { "test_fetch_seek", test_fetch_seek },
18661   { "test_fetch_nobuffs", test_fetch_nobuffs },
18662   { "test_open_direct", test_open_direct },
18663   { "test_fetch_null", test_fetch_null },
18664   { "test_ps_null_param", test_ps_null_param },
18665   { "test_fetch_date", test_fetch_date },
18666   { "test_fetch_str", test_fetch_str },
18667   { "test_fetch_long", test_fetch_long },
18668   { "test_fetch_short", test_fetch_short },
18669   { "test_fetch_tiny", test_fetch_tiny },
18670   { "test_fetch_bigint", test_fetch_bigint },
18671   { "test_fetch_float", test_fetch_float },
18672   { "test_fetch_double", test_fetch_double },
18673   { "test_bind_result_ext", test_bind_result_ext },
18674   { "test_bind_result_ext1", test_bind_result_ext1 },
18675   { "test_select_direct", test_select_direct },
18676   { "test_select_prepare", test_select_prepare },
18677   { "test_select", test_select },
18678   { "test_select_version", test_select_version },
18679   { "test_ps_conj_select", test_ps_conj_select },
18680   { "test_select_show_table", test_select_show_table },
18681   { "test_func_fields", test_func_fields },
18682   { "test_long_data", test_long_data },
18683   { "test_insert", test_insert },
18684   { "test_set_variable", test_set_variable },
18685   { "test_select_show", test_select_show },
18686   { "test_prepare_noparam", test_prepare_noparam },
18687   { "test_bind_result", test_bind_result },
18688   { "test_prepare_simple", test_prepare_simple },
18689   { "test_prepare", test_prepare },
18690   { "test_null", test_null },
18691   { "test_debug_example", test_debug_example },
18692   { "test_update", test_update },
18693   { "test_simple_update", test_simple_update },
18694   { "test_simple_delete", test_simple_delete },
18695   { "test_double_compare", test_double_compare },
18696   { "client_store_result", client_store_result },
18697   { "client_use_result", client_use_result },
18698   { "test_tran_bdb", test_tran_bdb },
18699   { "test_tran_innodb", test_tran_innodb },
18700   { "test_prepare_ext", test_prepare_ext },
18701   { "test_prepare_syntax", test_prepare_syntax },
18702   { "test_field_names", test_field_names },
18703   { "test_field_flags", test_field_flags },
18704   { "test_long_data_str", test_long_data_str },
18705   { "test_long_data_str1", test_long_data_str1 },
18706   { "test_long_data_bin", test_long_data_bin },
18707   { "test_warnings", test_warnings },
18708   { "test_errors", test_errors },
18709   { "test_prepare_resultset", test_prepare_resultset },
18710   { "test_stmt_close", test_stmt_close },
18711   { "test_prepare_field_result", test_prepare_field_result },
18712   { "test_multi_stmt", test_multi_stmt },
18713   { "test_multi_statements", test_multi_statements },
18714   { "test_prepare_multi_statements", test_prepare_multi_statements },
18715   { "test_store_result", test_store_result },
18716   { "test_store_result1", test_store_result1 },
18717   { "test_store_result2", test_store_result2 },
18718   { "test_subselect", test_subselect },
18719   { "test_date", test_date },
18720   { "test_date_date", test_date_date },
18721   { "test_date_time", test_date_time },
18722   { "test_date_ts", test_date_ts },
18723   { "test_date_dt", test_date_dt },
18724   { "test_prepare_alter", test_prepare_alter },
18725   { "test_manual_sample", test_manual_sample },
18726   { "test_pure_coverage", test_pure_coverage },
18727   { "test_buffers", test_buffers },
18728   { "test_ushort_bug", test_ushort_bug },
18729   { "test_sshort_bug", test_sshort_bug },
18730   { "test_stiny_bug", test_stiny_bug },
18731   { "test_field_misc", test_field_misc },
18732   { "test_set_option", test_set_option },
18733 #ifndef EMBEDDED_LIBRARY
18734   { "test_prepare_grant", test_prepare_grant },
18735 #endif
18736   { "test_frm_bug", test_frm_bug },
18737   { "test_explain_bug", test_explain_bug },
18738   { "test_decimal_bug", test_decimal_bug },
18739   { "test_nstmts", test_nstmts },
18740   { "test_logs;", test_logs },
18741   { "test_cuted_rows", test_cuted_rows },
18742   { "test_fetch_offset", test_fetch_offset },
18743   { "test_fetch_column", test_fetch_column },
18744   { "test_mem_overun", test_mem_overun },
18745   { "test_list_fields", test_list_fields },
18746   { "test_free_result", test_free_result },
18747   { "test_free_store_result", test_free_store_result },
18748   { "test_sqlmode", test_sqlmode },
18749   { "test_ts", test_ts },
18750   { "test_bug1115", test_bug1115 },
18751   { "test_bug1180", test_bug1180 },
18752   { "test_bug1500", test_bug1500 },
18753   { "test_bug1644", test_bug1644 },
18754   { "test_bug1946", test_bug1946 },
18755   { "test_bug2248", test_bug2248 },
18756   { "test_parse_error_and_bad_length", test_parse_error_and_bad_length },
18757   { "test_bug2247", test_bug2247 },
18758   { "test_subqueries", test_subqueries },
18759   { "test_bad_union", test_bad_union },
18760   { "test_distinct", test_distinct },
18761   { "test_subqueries_ref", test_subqueries_ref },
18762   { "test_union", test_union },
18763   { "test_bug3117", test_bug3117 },
18764   { "test_join", test_join },
18765   { "test_selecttmp", test_selecttmp },
18766   { "test_create_drop", test_create_drop },
18767   { "test_rename", test_rename },
18768   { "test_do_set", test_do_set },
18769   { "test_multi", test_multi },
18770   { "test_insert_select", test_insert_select },
18771   { "test_bind_nagative", test_bind_nagative },
18772   { "test_derived", test_derived },
18773   { "test_xjoin", test_xjoin },
18774   { "test_bug3035", test_bug3035 },
18775   { "test_union2", test_union2 },
18776   { "test_bug1664", test_bug1664 },
18777   { "test_union_param", test_union_param },
18778   { "test_order_param", test_order_param },
18779   { "test_ps_i18n", test_ps_i18n },
18780   { "test_bug3796", test_bug3796 },
18781   { "test_bug4026", test_bug4026 },
18782   { "test_bug4079", test_bug4079 },
18783   { "test_bug4236", test_bug4236 },
18784   { "test_bug4030", test_bug4030 },
18785   { "test_bug5126", test_bug5126 },
18786   { "test_bug4231", test_bug4231 },
18787   { "test_bug5399", test_bug5399 },
18788   { "test_bug5194", test_bug5194 },
18789   { "test_bug5315", test_bug5315 },
18790   { "test_bug6049", test_bug6049 },
18791   { "test_bug6058", test_bug6058 },
18792   { "test_bug6059", test_bug6059 },
18793   { "test_bug6046", test_bug6046 },
18794   { "test_bug6081", test_bug6081 },
18795   { "test_bug6096", test_bug6096 },
18796   { "test_datetime_ranges", test_datetime_ranges },
18797   { "test_bug4172", test_bug4172 },
18798   { "test_conversion", test_conversion },
18799   { "test_rewind", test_rewind },
18800   { "test_bug6761", test_bug6761 },
18801   { "test_view", test_view },
18802   { "test_view_where", test_view_where },
18803   { "test_view_2where", test_view_2where },
18804   { "test_view_star", test_view_star },
18805   { "test_view_insert", test_view_insert },
18806   { "test_left_join_view", test_left_join_view },
18807   { "test_view_insert_fields", test_view_insert_fields },
18808   { "test_basic_cursors", test_basic_cursors },
18809   { "test_cursors_with_union", test_cursors_with_union },
18810   { "test_cursors_with_procedure", test_cursors_with_procedure },
18811   { "test_truncation", test_truncation },
18812   { "test_truncation_option", test_truncation_option },
18813   { "test_client_character_set", test_client_character_set },
18814   { "test_bug8330", test_bug8330 },
18815   { "test_bug7990", test_bug7990 },
18816   { "test_bug8378", test_bug8378 },
18817   { "test_bug8722", test_bug8722 },
18818   { "test_bug8880", test_bug8880 },
18819   { "test_bug9159", test_bug9159 },
18820   { "test_bug9520", test_bug9520 },
18821   { "test_bug9478", test_bug9478 },
18822   { "test_bug9643", test_bug9643 },
18823   { "test_bug10729", test_bug10729 },
18824   { "test_bug11111", test_bug11111 },
18825   { "test_bug9992", test_bug9992 },
18826   { "test_bug10736", test_bug10736 },
18827   { "test_bug10794", test_bug10794 },
18828   { "test_bug11172", test_bug11172 },
18829   { "test_bug11656", test_bug11656 },
18830   { "test_bug10214", test_bug10214 },
18831   { "test_bug9735", test_bug9735 },
18832   { "test_bug11183", test_bug11183 },
18833   { "test_bug11037", test_bug11037 },
18834   { "test_bug10760", test_bug10760 },
18835   { "test_bug12001", test_bug12001 },
18836   { "test_bug11718", test_bug11718 },
18837   { "test_bug12925", test_bug12925 },
18838   { "test_bug11909", test_bug11909 },
18839   { "test_bug11901", test_bug11901 },
18840   { "test_bug11904", test_bug11904 },
18841   { "test_bug12243", test_bug12243 },
18842   { "test_bug14210", test_bug14210 },
18843   { "test_bug13488", test_bug13488 },
18844   { "test_bug13524", test_bug13524 },
18845   { "test_bug14845", test_bug14845 },
18846   { "test_opt_reconnect", test_opt_reconnect },
18847   { "test_bug15510", test_bug15510},
18848 #ifndef EMBEDDED_LIBRARY
18849   { "test_bug12744", test_bug12744 },
18850 #endif
18851   { "test_bug16143", test_bug16143 },
18852   { "test_bug16144", test_bug16144 },
18853   { "test_bug15613", test_bug15613 },
18854   { "test_bug20152", test_bug20152 },
18855   { "test_bug14169", test_bug14169 },
18856   { "test_bug17667", test_bug17667 },
18857   { "test_bug15752", test_bug15752 },
18858   { "test_mysql_insert_id", test_mysql_insert_id },
18859   { "test_bug19671", test_bug19671 },
18860   { "test_bug21206", test_bug21206 },
18861   { "test_bug21726", test_bug21726 },
18862   { "test_bug15518", test_bug15518 },
18863   { "test_bug23383", test_bug23383 },
18864   { "test_bug32265", test_bug32265 },
18865   { "test_bug21635", test_bug21635 },
18866   { "test_status",   test_status   },
18867   { "test_bug24179", test_bug24179 },
18868   { "test_ps_query_cache", test_ps_query_cache },
18869   { "test_bug28075", test_bug28075 },
18870   { "test_bug27876", test_bug27876 },
18871   { "test_bug28505", test_bug28505 },
18872   { "test_bug28934", test_bug28934 },
18873   { "test_bug27592", test_bug27592 },
18874   { "test_bug29687", test_bug29687 },
18875   { "test_bug29692", test_bug29692 },
18876   { "test_bug29306", test_bug29306 },
18877   { "test_change_user", test_change_user },
18878   { "test_bug30472", test_bug30472 },
18879   { "test_bug20023", test_bug20023 },
18880   { "test_bug45010", test_bug45010 },
18881   { "test_bug53371", test_bug53371 },
18882   { "test_bug31418", test_bug31418 },
18883   { "test_bug31669", test_bug31669 },
18884   { "test_bug28386", test_bug28386 },
18885   { "test_wl4166_1", test_wl4166_1 },
18886   { "test_wl4166_2", test_wl4166_2 },
18887   { "test_wl4166_3", test_wl4166_3 },
18888   { "test_wl4166_4", test_wl4166_4 },
18889   { "test_bug36004", test_bug36004 },
18890   { "test_wl4284_1", test_wl4284_1 },
18891   { "test_wl4435",   test_wl4435 },
18892   { "test_wl4435_2", test_wl4435_2 },
18893   { "test_wl4435_3", test_wl4435_3 },
18894   { "test_bug38486", test_bug38486 },
18895   { "test_bug33831", test_bug33831 },
18896   { "test_bug40365", test_bug40365 },
18897   { "test_bug43560", test_bug43560 },
18898 #ifdef HAVE_QUERY_CACHE
18899   { "test_bug36326", test_bug36326 },
18900 #endif
18901   { "test_bug41078", test_bug41078 },
18902   { "test_bug44495", test_bug44495 },
18903   { "test_bug49972", test_bug49972 },
18904   { "test_bug42373", test_bug42373 },
18905   { "test_bug54041", test_bug54041 },
18906   { "test_bug47485", test_bug47485 },
18907   { "test_bug58036", test_bug58036 },
18908   { "test_bug57058", test_bug57058 },
18909   { "test_bug56976", test_bug56976 },
18910   { "test_bug11766854", test_bug11766854 },
18911   { "test_bug12337762", test_bug12337762 },
18912   { "test_bug11754979", test_bug11754979 },
18913   { "test_bug13001491", test_bug13001491 },
18914   { 0, 0 }
18915 };
18916 
18917 
get_my_tests()18918 static struct my_tests_st *get_my_tests() { return my_tests; }
18919