MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mysql_client_test.c
1 /* Copyright (c) 2002, 2013, 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  XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
18  DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
19 */
20 
21 
22 /*
23  The fw.c file includes all the mysql_client_test framework; this file
24  contains only the actual tests, plus the list of test functions to call.
25 */
26 
27 #include "mysql_client_fw.c"
28 
29 /* Query processing */
30 
31 static void client_query()
32 {
33  int rc;
34 
35  myheader("client_query");
36 
37  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
38  myquery(rc);
39 
40  rc= mysql_query(mysql, "CREATE TABLE t1("
41  "id int primary key auto_increment, "
42  "name varchar(20))");
43  myquery(rc);
44 
45  rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))");
46  myquery_r(rc);
47 
48  rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')");
49  myquery(rc);
50 
51  rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')");
52  myquery(rc);
53 
54  rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')");
55  myquery(rc);
56 
57  rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
58  myquery(rc);
59 
60  rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
61  myquery(rc);
62 
63  rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' "
64  "WHERE name= 'deleted'");
65  myquery(rc);
66 
67  rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'");
68  myquery_r(rc);
69 
70  myquery(mysql_query(mysql, "drop table t1"));
71 }
72 
73 
74 /* Store result processing */
75 
76 static void client_store_result()
77 {
78  MYSQL_RES *result;
79  int rc;
80 
81  myheader("client_store_result");
82 
83  rc= mysql_query(mysql, "SELECT * FROM t1");
84  myquery(rc);
85 
86  /* get the result */
87  result= mysql_store_result(mysql);
88  mytest(result);
89 
90  (void) my_process_result_set(result);
91  mysql_free_result(result);
92 }
93 
94 
95 /* Fetch the results */
96 
97 static void client_use_result()
98 {
99  MYSQL_RES *result;
100  int rc;
101  myheader("client_use_result");
102 
103  rc= mysql_query(mysql, "SELECT * FROM t1");
104  myquery(rc);
105 
106  /* get the result */
107  result= mysql_use_result(mysql);
108  mytest(result);
109 
110  (void) my_process_result_set(result);
111  mysql_free_result(result);
112 }
113 
114 
115 /* Query processing */
116 
117 static void test_debug_example()
118 {
119  int rc;
120  MYSQL_RES *result;
121 
122  myheader("test_debug_example");
123 
124  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_debug_example");
125  myquery(rc);
126 
127  rc= mysql_query(mysql, "CREATE TABLE test_debug_example("
128  "id INT PRIMARY KEY AUTO_INCREMENT, "
129  "name VARCHAR(20), xxx INT)");
130  myquery(rc);
131 
132  rc= mysql_query(mysql, "INSERT INTO test_debug_example (name) "
133  "VALUES ('mysql')");
134  myquery(rc);
135 
136  rc= mysql_query(mysql, "UPDATE test_debug_example SET name='updated' "
137  "WHERE name='deleted'");
138  myquery(rc);
139 
140  rc= mysql_query(mysql, "SELECT * FROM test_debug_example where name='mysql'");
141  myquery(rc);
142 
143  result= mysql_use_result(mysql);
144  mytest(result);
145 
146  (void) my_process_result_set(result);
147  mysql_free_result(result);
148 
149  rc= mysql_query(mysql, "DROP TABLE test_debug_example");
150  myquery(rc);
151 }
152 
153 
154 /* Test autocommit feature for BDB tables */
155 
156 static void test_tran_bdb()
157 {
158  MYSQL_RES *result;
159  MYSQL_ROW row;
160  int rc;
161 
162  myheader("test_tran_bdb");
163 
164  /* set AUTOCOMMIT to OFF */
165  rc= mysql_autocommit(mysql, FALSE);
166  myquery(rc);
167 
168  rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction");
169  myquery(rc);
170 
171 
172  /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
173  rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction( "
174  "col1 int , col2 varchar(30)) ENGINE= BDB");
175  myquery(rc);
176 
177  /* insert a row and commit the transaction */
178  rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')");
179  myquery(rc);
180 
181  rc= mysql_commit(mysql);
182  myquery(rc);
183 
184  /* now insert the second row, and roll back the transaction */
185  rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
186  myquery(rc);
187 
188  rc= mysql_rollback(mysql);
189  myquery(rc);
190 
191  /* delete first row, and roll it back */
192  rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
193  myquery(rc);
194 
195  rc= mysql_rollback(mysql);
196  myquery(rc);
197 
198  /* test the results now, only one row should exist */
199  rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
200  myquery(rc);
201 
202  /* get the result */
203  result= mysql_store_result(mysql);
204  mytest(result);
205 
206  (void) my_process_result_set(result);
207  mysql_free_result(result);
208 
209  /* test the results now, only one row should exist */
210  rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
211  myquery(rc);
212 
213  /* get the result */
214  result= mysql_use_result(mysql);
215  mytest(result);
216 
217  row= mysql_fetch_row(result);
218  mytest(row);
219 
220  row= mysql_fetch_row(result);
221  mytest_r(row);
222 
223  mysql_free_result(result);
224  mysql_autocommit(mysql, TRUE);
225 }
226 
227 
228 /* Test autocommit feature for InnoDB tables */
229 
230 static void test_tran_innodb()
231 {
232  MYSQL_RES *result;
233  MYSQL_ROW row;
234  int rc;
235 
236  myheader("test_tran_innodb");
237 
238  /* set AUTOCOMMIT to OFF */
239  rc= mysql_autocommit(mysql, FALSE);
240  myquery(rc);
241 
242  rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction");
243  myquery(rc);
244 
245  /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
246  rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction(col1 int, "
247  "col2 varchar(30)) ENGINE= InnoDB");
248  myquery(rc);
249 
250  /* insert a row and commit the transaction */
251  rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')");
252  myquery(rc);
253 
254  rc= mysql_commit(mysql);
255  myquery(rc);
256 
257  /* now insert the second row, and roll back the transaction */
258  rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
259  myquery(rc);
260 
261  rc= mysql_rollback(mysql);
262  myquery(rc);
263 
264  /* delete first row, and roll it back */
265  rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
266  myquery(rc);
267 
268  rc= mysql_rollback(mysql);
269  myquery(rc);
270 
271  /* test the results now, only one row should exist */
272  rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
273  myquery(rc);
274 
275  /* get the result */
276  result= mysql_store_result(mysql);
277  mytest(result);
278 
279  (void) my_process_result_set(result);
280  mysql_free_result(result);
281 
282  /* test the results now, only one row should exist */
283  rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
284  myquery(rc);
285 
286  /* get the result */
287  result= mysql_use_result(mysql);
288  mytest(result);
289 
290  row= mysql_fetch_row(result);
291  mytest(row);
292 
293  row= mysql_fetch_row(result);
294  mytest_r(row);
295 
296  mysql_free_result(result);
297  mysql_autocommit(mysql, TRUE);
298 }
299 
300 
301 /* Test for BUG#7242 */
302 
303 static void test_prepare_insert_update()
304 {
305  MYSQL_STMT *stmt;
306  int rc;
307  int i;
308  const char *testcase[]= {
309  "CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B))",
310  "INSERT t1 VALUES (1,2,10), (3,4,20)",
311  "INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100",
312  "SELECT * FROM t1",
313  "INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0",
314  "SELECT * FROM t1",
315  "INSERT t1 VALUES (2,1,11), (7,4,40) ON DUPLICATE KEY UPDATE c=c+VALUES(a)",
316  NULL};
317  const char **cur_query;
318 
319  myheader("test_prepare_insert_update");
320 
321  for (cur_query= testcase; *cur_query; cur_query++)
322  {
323  char query[MAX_TEST_QUERY_LENGTH];
324  printf("\nRunning query: %s", *cur_query);
325  strmov(query, *cur_query);
326  stmt= mysql_simple_prepare(mysql, query);
327  check_stmt(stmt);
328 
329  verify_param_count(stmt, 0);
330  rc= mysql_stmt_execute(stmt);
331 
332  check_execute(stmt, rc);
333  /* try the last query several times */
334  if (!cur_query[1])
335  {
336  for (i=0; i < 3;i++)
337  {
338  printf("\nExecuting last statement again");
339  rc= mysql_stmt_execute(stmt);
340  check_execute(stmt, rc);
341  rc= mysql_stmt_execute(stmt);
342  check_execute(stmt, rc);
343  }
344  }
345  mysql_stmt_close(stmt);
346  }
347 
348  rc= mysql_commit(mysql);
349  myquery(rc);
350 }
351 
352 /* Test simple prepares of all DML statements */
353 
354 static void test_prepare_simple()
355 {
356  MYSQL_STMT *stmt;
357  int rc;
358  char query[MAX_TEST_QUERY_LENGTH];
359 
360  myheader("test_prepare_simple");
361 
362  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_simple");
363  myquery(rc);
364 
365  rc= mysql_query(mysql, "CREATE TABLE test_prepare_simple("
366  "id int, name varchar(50))");
367  myquery(rc);
368 
369  /* insert */
370  strmov(query, "INSERT INTO test_prepare_simple VALUES(?, ?)");
371  stmt= mysql_simple_prepare(mysql, query);
372  check_stmt(stmt);
373 
374  verify_param_count(stmt, 2);
375  mysql_stmt_close(stmt);
376 
377  /* update */
378  strmov(query, "UPDATE test_prepare_simple SET id=? "
379  "WHERE id=? AND CONVERT(name USING utf8)= ?");
380  stmt= mysql_simple_prepare(mysql, query);
381  check_stmt(stmt);
382 
383  verify_param_count(stmt, 3);
384  mysql_stmt_close(stmt);
385 
386  /* delete */
387  strmov(query, "DELETE FROM test_prepare_simple WHERE id=10");
388  stmt= mysql_simple_prepare(mysql, query);
389  check_stmt(stmt);
390 
391  verify_param_count(stmt, 0);
392 
393  rc= mysql_stmt_execute(stmt);
394  check_execute(stmt, rc);
395  mysql_stmt_close(stmt);
396 
397  /* delete */
398  strmov(query, "DELETE FROM test_prepare_simple WHERE id=?");
399  stmt= mysql_simple_prepare(mysql, query);
400  check_stmt(stmt);
401 
402  verify_param_count(stmt, 1);
403 
404  mysql_stmt_close(stmt);
405 
406  /* select */
407  strmov(query, "SELECT * FROM test_prepare_simple WHERE id=? "
408  "AND CONVERT(name USING utf8)= ?");
409  stmt= mysql_simple_prepare(mysql, query);
410  check_stmt(stmt);
411 
412  verify_param_count(stmt, 2);
413 
414  mysql_stmt_close(stmt);
415 
416  /* now fetch the results ..*/
417  rc= mysql_commit(mysql);
418  myquery(rc);
419 }
420 
421 /************************************************************************/
422 
423 #define FILE_PATH_SIZE 4096
424 
425 char mct_log_file_path[FILE_PATH_SIZE];
426 FILE *mct_log_file= NULL;
427 
428 void mct_start_logging(const char *test_case_name)
429 {
430  const char *tmp_dir= getenv("MYSQL_TMP_DIR");
431 
432  if (!tmp_dir)
433  {
434  printf("Warning: MYSQL_TMP_DIR is not set. Logging is disabled.\n");
435  return;
436  }
437 
438  if (mct_log_file)
439  {
440  printf("Warning: can not start logging for test case '%s' "
441  "because log is already open\n",
442  (const char *) test_case_name);
443  return;
444  }
445 
446  /*
447  Path is: <tmp_dir>/<test_case_name>.out.log
448  10 is length of '/' + '.out.log' + \0
449  */
450 
451  if (strlen(tmp_dir) + strlen(test_case_name) + 10 > FILE_PATH_SIZE)
452  {
453  printf("Warning: MYSQL_TMP_DIR is too long. Logging is disabled.\n");
454  return;
455  }
456 
457  my_snprintf(mct_log_file_path, FILE_PATH_SIZE,
458  "%s/%s.out.log",
459  (const char *) tmp_dir,
460  (const char *) test_case_name);
461 
462  mct_log_file= my_fopen(mct_log_file_path, O_WRONLY | O_BINARY, MYF(MY_WME));
463 
464  if (!mct_log_file)
465  {
466  printf("Warning: can not open log file (%s): %s. Logging is disabled.\n",
467  (const char *) mct_log_file_path,
468  (const char *) strerror(errno));
469  return;
470  }
471 }
472 
473 void mct_log(const char *format, ...)
474 {
475  va_list args;
476  va_start(args, format);
477  vprintf(format, args);
478  va_end(args);
479 
480  if (mct_log_file)
481  {
482  va_list args;
483  va_start(args, format);
484  vfprintf(mct_log_file, format, args);
485  va_end(args);
486  }
487 }
488 
489 void mct_close_log()
490 {
491  if (!mct_log_file)
492  return;
493 
494  my_fclose(mct_log_file, MYF(0));
495  mct_log_file= NULL;
496 }
497 
498 #define WL4435_NUM_PARAMS 10
499 #define WL4435_STRING_SIZE 30
500 
501 static void test_wl4435()
502 {
503  MYSQL_STMT *stmt;
504  int rc;
505  char query[MAX_TEST_QUERY_LENGTH];
506 
507  char str_data[20][WL4435_STRING_SIZE];
508  double dbl_data[20];
509  char dec_data[20][WL4435_STRING_SIZE];
510  int int_data[20];
511  ulong str_length= WL4435_STRING_SIZE;
512  my_bool is_null;
513  MYSQL_BIND ps_params[WL4435_NUM_PARAMS];
514 
515  int exec_counter;
516 
517  myheader("test_wl4435");
518  mct_start_logging("test_wl4435");
519 
520  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
521  myquery(rc);
522 
523  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p2");
524  myquery(rc);
525 
526  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
527  myquery(rc);
528 
529  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
530  myquery(rc);
531 
532  rc= mysql_query(mysql, "CREATE TABLE t1(a1 INT, a2 CHAR(32), "
533  " a3 DOUBLE(4, 2), a4 DECIMAL(3, 1))");
534  myquery(rc);
535 
536  rc= mysql_query(mysql, "CREATE TABLE t2(b0 INT, b1 INT, b2 CHAR(32), "
537  " b3 DOUBLE(4, 2), b4 DECIMAL(3, 1))");
538  myquery(rc);
539 
540  rc= mysql_query(mysql, "INSERT INTO t1 VALUES"
541  "(1, '11', 12.34, 56.7), "
542  "(2, '12', 56.78, 90.1), "
543  "(3, '13', 23.45, 67.8)");
544  myquery(rc);
545 
546  rc= mysql_query(mysql, "INSERT INTO t2 VALUES"
547  "(100, 10, '110', 70.70, 10.1), "
548  "(200, 20, '120', 80.80, 20.2), "
549  "(300, 30, '130', 90.90, 30.3)");
550  myquery(rc);
551 
552  rc= mysql_query(mysql,
553  "CREATE PROCEDURE p1("
554  " IN v0 INT, "
555  " OUT v_str_1 CHAR(32), "
556  " OUT v_dbl_1 DOUBLE(4, 2), "
557  " OUT v_dec_1 DECIMAL(6, 3), "
558  " OUT v_int_1 INT, "
559  " IN v1 INT, "
560  " INOUT v_str_2 CHAR(64), "
561  " INOUT v_dbl_2 DOUBLE(5, 3), "
562  " INOUT v_dec_2 DECIMAL(7, 4), "
563  " INOUT v_int_2 INT)"
564  "BEGIN "
565  " SET v0 = -1; "
566  " SET v1 = -1; "
567  " SET v_str_1 = 'test_1'; "
568  " SET v_dbl_1 = 12.34; "
569  " SET v_dec_1 = 567.891; "
570  " SET v_int_1 = 2345; "
571  " SET v_str_2 = 'test_2'; "
572  " SET v_dbl_2 = 67.891; "
573  " SET v_dec_2 = 234.6789; "
574  " SET v_int_2 = 6789; "
575  " SELECT * FROM t1; "
576  " SELECT * FROM t2; "
577  "END");
578  myquery(rc);
579 
580  rc= mysql_query(mysql,
581  "CREATE PROCEDURE p2("
582  " IN i1 VARCHAR(255) CHARACTER SET koi8r, "
583  " OUT o1 VARCHAR(255) CHARACTER SET cp1251, "
584  " OUT o2 VARBINARY(255)) "
585  "BEGIN "
586  " SET o1 = i1; "
587  " SET o2 = i1; "
588  "END");
589  myquery(rc);
590 
591  strmov(query, "CALL p1(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
592  stmt= mysql_simple_prepare(mysql, query);
593  check_stmt(stmt);
594 
595  /* Init PS-parameters. */
596 
597  memset(ps_params, 0, sizeof (ps_params));
598 
599  /* - v0 -- INT */
600 
601  ps_params[0].buffer_type= MYSQL_TYPE_LONG;
602  ps_params[0].buffer= (char *) &int_data[0];
603  ps_params[0].length= 0;
604  ps_params[0].is_null= 0;
605 
606  /* - v_str_1 -- CHAR(32) */
607 
608  ps_params[1].buffer_type= MYSQL_TYPE_STRING;
609  ps_params[1].buffer= (char *) str_data[0];
610  ps_params[1].buffer_length= WL4435_STRING_SIZE;
611  ps_params[1].length= &str_length;
612  ps_params[1].is_null= 0;
613 
614  /* - v_dbl_1 -- DOUBLE */
615 
616  ps_params[2].buffer_type= MYSQL_TYPE_DOUBLE;
617  ps_params[2].buffer= (char *) &dbl_data[0];
618  ps_params[2].length= 0;
619  ps_params[2].is_null= 0;
620 
621  /* - v_dec_1 -- DECIMAL */
622 
623  ps_params[3].buffer_type= MYSQL_TYPE_NEWDECIMAL;
624  ps_params[3].buffer= (char *) dec_data[0];
625  ps_params[3].buffer_length= WL4435_STRING_SIZE;
626  ps_params[3].length= 0;
627  ps_params[3].is_null= 0;
628 
629  /* - v_int_1 -- INT */
630 
631  ps_params[4].buffer_type= MYSQL_TYPE_LONG;
632  ps_params[4].buffer= (char *) &int_data[0];
633  ps_params[4].length= 0;
634  ps_params[4].is_null= 0;
635 
636  /* - v1 -- INT */
637 
638  ps_params[5].buffer_type= MYSQL_TYPE_LONG;
639  ps_params[5].buffer= (char *) &int_data[0];
640  ps_params[5].length= 0;
641  ps_params[5].is_null= 0;
642 
643  /* - v_str_2 -- CHAR(32) */
644 
645  ps_params[6].buffer_type= MYSQL_TYPE_STRING;
646  ps_params[6].buffer= (char *) str_data[0];
647  ps_params[6].buffer_length= WL4435_STRING_SIZE;
648  ps_params[6].length= &str_length;
649  ps_params[6].is_null= 0;
650 
651  /* - v_dbl_2 -- DOUBLE */
652 
653  ps_params[7].buffer_type= MYSQL_TYPE_DOUBLE;
654  ps_params[7].buffer= (char *) &dbl_data[0];
655  ps_params[7].length= 0;
656  ps_params[7].is_null= 0;
657 
658  /* - v_dec_2 -- DECIMAL */
659 
660  ps_params[8].buffer_type= MYSQL_TYPE_DECIMAL;
661  ps_params[8].buffer= (char *) dec_data[0];
662  ps_params[8].buffer_length= WL4435_STRING_SIZE;
663  ps_params[8].length= 0;
664  ps_params[8].is_null= 0;
665 
666  /* - v_int_2 -- INT */
667 
668  ps_params[9].buffer_type= MYSQL_TYPE_LONG;
669  ps_params[9].buffer= (char *) &int_data[0];
670  ps_params[9].length= 0;
671  ps_params[9].is_null= 0;
672 
673  /* Bind parameters. */
674 
675  rc= mysql_stmt_bind_param(stmt, ps_params);
676 
677  /* Execute! */
678 
679  for (exec_counter= 0; exec_counter < 3; ++exec_counter)
680  {
681  int i;
682  int num_fields;
683  MYSQL_BIND *rs_bind;
684 
685  mct_log("\nexec_counter: %d\n", (int) exec_counter);
686 
687  rc= mysql_stmt_execute(stmt);
688  check_execute(stmt, rc);
689 
690  while (1)
691  {
692  MYSQL_FIELD *fields;
693 
694  MYSQL_RES *rs_metadata= mysql_stmt_result_metadata(stmt);
695 
696  num_fields= mysql_stmt_field_count(stmt);
697  fields= mysql_fetch_fields(rs_metadata);
698 
699  rs_bind= (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
700  memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);
701 
702  mct_log("num_fields: %d\n", (int) num_fields);
703 
704  for (i = 0; i < num_fields; ++i)
705  {
706  mct_log(" - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
707  "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
708  "type: %d; decimals: %d\n",
709  (int) i,
710  (const char *) fields[i].name,
711  (const char *) fields[i].org_name,
712  (const char *) fields[i].table,
713  (const char *) fields[i].org_table,
714  (const char *) fields[i].db,
715  (const char *) fields[i].catalog,
716  (int) fields[i].length,
717  (int) fields[i].max_length,
718  (int) fields[i].type,
719  (int) fields[i].decimals);
720 
721  rs_bind[i].buffer_type= fields[i].type;
722  rs_bind[i].is_null= &is_null;
723 
724  switch (fields[i].type)
725  {
726  case MYSQL_TYPE_LONG:
727  rs_bind[i].buffer= (char *) &(int_data[i]);
728  rs_bind[i].buffer_length= sizeof (int_data);
729  break;
730 
731  case MYSQL_TYPE_STRING:
732  rs_bind[i].buffer= (char *) str_data[i];
733  rs_bind[i].buffer_length= WL4435_STRING_SIZE;
734  rs_bind[i].length= &str_length;
735  break;
736 
737  case MYSQL_TYPE_DOUBLE:
738  rs_bind[i].buffer= (char *) &dbl_data[i];
739  rs_bind[i].buffer_length= sizeof (dbl_data);
740  break;
741 
742  case MYSQL_TYPE_NEWDECIMAL:
743  rs_bind[i].buffer= (char *) dec_data[i];
744  rs_bind[i].buffer_length= WL4435_STRING_SIZE;
745  rs_bind[i].length= &str_length;
746  break;
747 
748  default:
749  fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
750  exit(1);
751  }
752  }
753 
754  rc= mysql_stmt_bind_result(stmt, rs_bind);
755  check_execute(stmt, rc);
756 
757  mct_log("Data:\n");
758 
759  while (1)
760  {
761  int rc= mysql_stmt_fetch(stmt);
762 
763  if (rc == 1 || rc == MYSQL_NO_DATA)
764  break;
765 
766  mct_log(" ");
767 
768  for (i = 0; i < num_fields; ++i)
769  {
770  switch (rs_bind[i].buffer_type)
771  {
772  case MYSQL_TYPE_LONG:
773  mct_log(" int: %ld;",
774  (long) *((int *) rs_bind[i].buffer));
775  break;
776 
777  case MYSQL_TYPE_STRING:
778  mct_log(" str: '%s';",
779  (char *) rs_bind[i].buffer);
780  break;
781 
782  case MYSQL_TYPE_DOUBLE:
783  mct_log(" dbl: %lf;",
784  (double) *((double *) rs_bind[i].buffer));
785  break;
786 
787  case MYSQL_TYPE_NEWDECIMAL:
788  mct_log(" dec: '%s';",
789  (char *) rs_bind[i].buffer);
790  break;
791 
792  default:
793  printf(" unexpected type (%d)\n",
794  rs_bind[i].buffer_type);
795  }
796  }
797  mct_log("\n");
798  }
799 
800  mct_log("EOF\n");
801 
802  rc= mysql_stmt_next_result(stmt);
803  mct_log("mysql_stmt_next_result(): %d; field_count: %d\n",
804  (int) rc, (int) mysql->field_count);
805 
806  free(rs_bind);
807  mysql_free_result(rs_metadata);
808 
809  if (rc > 0)
810  {
811  printf("Error: %s (errno: %d)\n",
812  mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
813  DIE(rc > 0);
814  }
815 
816  if (rc)
817  break;
818 
819  if (!mysql->field_count)
820  {
821  /* This is the last OK-packet. No more resultsets. */
822  break;
823  }
824  }
825 
826  }
827 
828  mysql_stmt_close(stmt);
829 
830  mct_close_log();
831 
832  rc= mysql_commit(mysql);
833  myquery(rc);
834 
835  /* i18n part of test case. */
836 
837  {
838  const char *str_koi8r= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
839  const char *str_cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
840  char o1_buffer[255];
841  ulong o1_length;
842  char o2_buffer[255];
843  ulong o2_length;
844 
845  MYSQL_BIND rs_bind[2];
846 
847  strmov(query, "CALL p2(?, ?, ?)");
848  stmt= mysql_simple_prepare(mysql, query);
849  check_stmt(stmt);
850 
851  /* Init PS-parameters. */
852 
853  memset(ps_params, 0, sizeof (ps_params));
854 
855  ps_params[0].buffer_type= MYSQL_TYPE_STRING;
856  ps_params[0].buffer= (char *) str_koi8r;
857  ps_params[0].buffer_length= strlen(str_koi8r);
858 
859  ps_params[1].buffer_type= MYSQL_TYPE_STRING;
860  ps_params[1].buffer= o1_buffer;
861  ps_params[1].buffer_length= 0;
862 
863  ps_params[2].buffer_type= MYSQL_TYPE_STRING;
864  ps_params[2].buffer= o2_buffer;
865  ps_params[2].buffer_length= 0;
866 
867  /* Bind parameters. */
868 
869  rc= mysql_stmt_bind_param(stmt, ps_params);
870  check_execute(stmt, rc);
871 
872  /* Prevent converting to character_set_results. */
873 
874  rc= mysql_query(mysql, "SET NAMES binary");
875  myquery(rc);
876 
877  /* Execute statement. */
878 
879  rc= mysql_stmt_execute(stmt);
880  check_execute(stmt, rc);
881 
882  /* Bind result. */
883 
884  memset(rs_bind, 0, sizeof (rs_bind));
885 
886  rs_bind[0].buffer_type= MYSQL_TYPE_STRING;
887  rs_bind[0].buffer= o1_buffer;
888  rs_bind[0].buffer_length= sizeof (o1_buffer);
889  rs_bind[0].length= &o1_length;
890 
891  rs_bind[1].buffer_type= MYSQL_TYPE_BLOB;
892  rs_bind[1].buffer= o2_buffer;
893  rs_bind[1].buffer_length= sizeof (o2_buffer);
894  rs_bind[1].length= &o2_length;
895 
896  rc= mysql_stmt_bind_result(stmt, rs_bind);
897  check_execute(stmt, rc);
898 
899  /* Fetch result. */
900 
901  rc= mysql_stmt_fetch(stmt);
902  check_execute(stmt, rc);
903 
904  /* Check result. */
905 
906  DIE_UNLESS(o1_length == strlen(str_cp1251));
907  DIE_UNLESS(o2_length == strlen(str_koi8r));
908  DIE_UNLESS(!memcmp(o1_buffer, str_cp1251, o1_length));
909  DIE_UNLESS(!memcmp(o2_buffer, str_koi8r, o2_length));
910 
911  rc= mysql_stmt_fetch(stmt);
912  DIE_UNLESS(rc == MYSQL_NO_DATA);
913 
914  rc= mysql_stmt_next_result(stmt);
915  DIE_UNLESS(rc == 0 && mysql->field_count == 0);
916 
917  mysql_stmt_close(stmt);
918 
919  rc= mysql_commit(mysql);
920  myquery(rc);
921  }
922 }
923 
924 static void test_wl4435_2()
925 {
926  MYSQL_STMT *stmt;
927  int i;
928  int rc;
929  char query[MAX_TEST_QUERY_LENGTH];
930 
931  myheader("test_wl4435_2");
932  mct_start_logging("test_wl4435_2");
933 
934  /*
935  Do a few iterations so that we catch any problem with incorrect
936  handling/flushing prepared statement results.
937  */
938 
939  for (i= 0; i < 10; ++i)
940  {
941  /*
942  Prepare a procedure. That can be moved out of the loop, but it was
943  left in the loop for the sake of having as many statements as
944  possible.
945  */
946 
947  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
948  myquery(rc);
949 
950  rc= mysql_query(mysql,
951  "CREATE PROCEDURE p1()"
952  "BEGIN "
953  " SELECT 1; "
954  " SELECT 2, 3 UNION SELECT 4, 5; "
955  " SELECT 6, 7, 8; "
956  "END");
957  myquery(rc);
958 
959  /* Invoke a procedure, that returns several result sets. */
960 
961  strmov(query, "CALL p1()");
962  stmt= mysql_simple_prepare(mysql, query);
963  check_stmt(stmt);
964 
965  /* Execute! */
966 
967  rc= mysql_stmt_execute(stmt);
968  check_execute(stmt, rc);
969 
970  /* Flush all the results. */
971 
972  mysql_stmt_close(stmt);
973 
974  /* Clean up. */
975  rc= mysql_commit(mysql);
976  myquery(rc);
977 
978  rc= mysql_query(mysql, "DROP PROCEDURE p1");
979  myquery(rc);
980  }
981  mct_close_log();
982 }
983 
984 
985 #define WL4435_TEST(sql_type, sql_value, \
986  c_api_in_type, c_api_out_type, \
987  c_type, c_type_ext, \
988  printf_args, assert_condition) \
989 \
990  do { \
991  int rc; \
992  MYSQL_STMT *ps; \
993  MYSQL_BIND psp; \
994  MYSQL_RES *rs_metadata; \
995  MYSQL_FIELD *fields; \
996  c_type pspv c_type_ext; \
997  my_bool psp_null; \
998  \
999  memset(&pspv, 0, sizeof (pspv)); \
1000  \
1001  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); \
1002  myquery(rc); \
1003  \
1004  rc= mysql_query(mysql, \
1005  "CREATE PROCEDURE p1(OUT v " sql_type ") SET v = " sql_value ";"); \
1006  myquery(rc); \
1007  \
1008  ps = mysql_simple_prepare(mysql, "CALL p1(?)"); \
1009  check_stmt(ps); \
1010  memset(&psp, 0, sizeof (psp)); \
1011  psp.buffer_type= c_api_in_type; \
1012  psp.is_null= &psp_null; \
1013  psp.buffer= (char *) &pspv; \
1014  psp.buffer_length= sizeof (psp); \
1015  \
1016  rc= mysql_stmt_bind_param(ps, &psp); \
1017  check_execute(ps, rc); \
1018  \
1019  rc= mysql_stmt_execute(ps); \
1020  check_execute(ps, rc); \
1021  \
1022  DIE_UNLESS(mysql->server_status & SERVER_PS_OUT_PARAMS); \
1023  DIE_UNLESS(mysql_stmt_field_count(ps) == 1); \
1024  \
1025  rs_metadata= mysql_stmt_result_metadata(ps); \
1026  fields= mysql_fetch_fields(rs_metadata); \
1027  \
1028  rc= mysql_stmt_bind_result(ps, &psp); \
1029  check_execute(ps, rc); \
1030  \
1031  rc= mysql_stmt_fetch(ps); \
1032  DIE_UNLESS(rc == 0); \
1033  \
1034  DIE_UNLESS(fields[0].type == c_api_out_type); \
1035  printf printf_args; \
1036  printf("; in type: %d; out type: %d\n", \
1037  (int) c_api_in_type, (int) c_api_out_type); \
1038  \
1039  rc= mysql_stmt_fetch(ps); \
1040  DIE_UNLESS(rc == MYSQL_NO_DATA); \
1041  \
1042  rc= mysql_stmt_next_result(ps); \
1043  DIE_UNLESS(rc == 0); \
1044  \
1045  mysql_free_result(rs_metadata); \
1046  mysql_stmt_free_result(ps); \
1047  mysql_stmt_close(ps); \
1048  \
1049  DIE_UNLESS(assert_condition); \
1050  \
1051  } while (0)
1052 
1053 static void test_wl4435_3()
1054 {
1055  char tmp[255];
1056 
1057  puts("");
1058 
1059  /*
1060  The following types are not supported:
1061  - ENUM
1062  - SET
1063 
1064  The following types are supported but can not be used for
1065  OUT-parameters:
1066  - MEDIUMINT;
1067  - BIT(..);
1068 
1069  The problem is that those types are not supported for IN-parameters,
1070  and OUT-parameters should be bound as IN-parameters before execution
1071 
1072  The following types should not be used:
1073  - MYSQL_TYPE_YEAR (use MYSQL_TYPE_SHORT instead);
1074  - MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB
1075  (use MYSQL_TYPE_BLOB instead);
1076  */
1077 
1078  WL4435_TEST("TINYINT", "127",
1079  MYSQL_TYPE_TINY, MYSQL_TYPE_TINY,
1080  char, ,
1081  (" - TINYINT / char / MYSQL_TYPE_TINY:\t\t\t %d", (int) pspv),
1082  pspv == 127);
1083 
1084  WL4435_TEST("SMALLINT", "32767",
1085  MYSQL_TYPE_SHORT, MYSQL_TYPE_SHORT,
1086  short, ,
1087  (" - SMALLINT / short / MYSQL_TYPE_SHORT:\t\t %d", (int) pspv),
1088  pspv == 32767);
1089 
1090  WL4435_TEST("INT", "2147483647",
1091  MYSQL_TYPE_LONG, MYSQL_TYPE_LONG,
1092  int, ,
1093  (" - INT / int / MYSQL_TYPE_LONG:\t\t\t %d", pspv),
1094  pspv == 2147483647l);
1095 
1096  WL4435_TEST("BIGINT", "9223372036854775807",
1097  MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG,
1098  long long, ,
1099  (" - BIGINT / long long / MYSQL_TYPE_LONGLONG:\t\t %lld", pspv),
1100  pspv == 9223372036854775807ll);
1101 
1102  WL4435_TEST("TIMESTAMP", "'2007-11-18 15:01:02'",
1103  MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP,
1104  MYSQL_TIME, ,
1105  (" - TIMESTAMP / MYSQL_TIME / MYSQL_TYPE_TIMESTAMP:\t "
1106  "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1107  (int) pspv.year, (int) pspv.month, (int) pspv.day,
1108  (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1109  pspv.year == 2007 && pspv.month == 11 && pspv.day == 18 &&
1110  pspv.hour == 15 && pspv.minute == 1 && pspv.second == 2);
1111 
1112  WL4435_TEST("DATETIME", "'1234-11-12 12:34:59'",
1113  MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME,
1114  MYSQL_TIME, ,
1115  (" - DATETIME / MYSQL_TIME / MYSQL_TYPE_DATETIME:\t "
1116  "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1117  (int) pspv.year, (int) pspv.month, (int) pspv.day,
1118  (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1119  pspv.year == 1234 && pspv.month == 11 && pspv.day == 12 &&
1120  pspv.hour == 12 && pspv.minute == 34 && pspv.second == 59);
1121 
1122  WL4435_TEST("TIME", "'123:45:01'",
1123  MYSQL_TYPE_TIME, MYSQL_TYPE_TIME,
1124  MYSQL_TIME, ,
1125  (" - TIME / MYSQL_TIME / MYSQL_TYPE_TIME:\t\t "
1126  "%.3d:%.2d:%.2d",
1127  (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1128  pspv.hour == 123 && pspv.minute == 45 && pspv.second == 1);
1129 
1130  WL4435_TEST("DATE", "'1234-11-12'",
1131  MYSQL_TYPE_DATE, MYSQL_TYPE_DATE,
1132  MYSQL_TIME, ,
1133  (" - DATE / MYSQL_TIME / MYSQL_TYPE_DATE:\t\t "
1134  "%.4d-%.2d-%.2d",
1135  (int) pspv.year, (int) pspv.month, (int) pspv.day),
1136  pspv.year == 1234 && pspv.month == 11 && pspv.day == 12);
1137 
1138  WL4435_TEST("YEAR", "'2010'",
1139  MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR,
1140  short, ,
1141  (" - YEAR / short / MYSQL_TYPE_SHORT:\t\t\t %.4d", (int) pspv),
1142  pspv == 2010);
1143 
1144  WL4435_TEST("FLOAT(7, 4)", "123.4567",
1145  MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT,
1146  float, ,
1147  (" - FLOAT / float / MYSQL_TYPE_FLOAT:\t\t\t %g", (double) pspv),
1148  pspv - 123.4567 < 0.0001);
1149 
1150  WL4435_TEST("DOUBLE(8, 5)", "123.45678",
1151  MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE,
1152  double, ,
1153  (" - DOUBLE / double / MYSQL_TYPE_DOUBLE:\t\t %g", (double) pspv),
1154  pspv - 123.45678 < 0.00001);
1155 
1156  WL4435_TEST("DECIMAL(9, 6)", "123.456789",
1157  MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL,
1158  char, [255],
1159  (" - DECIMAL / char[] / MYSQL_TYPE_NEWDECIMAL:\t\t '%s'", (char *) pspv),
1160  !strcmp(pspv, "123.456789"));
1161 
1162  WL4435_TEST("CHAR(32)", "REPEAT('C', 16)",
1163  MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1164  char, [255],
1165  (" - CHAR(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1166  !strcmp(pspv, "CCCCCCCCCCCCCCCC"));
1167 
1168  WL4435_TEST("VARCHAR(32)", "REPEAT('V', 16)",
1169  MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1170  char, [255],
1171  (" - VARCHAR(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1172  !strcmp(pspv, "VVVVVVVVVVVVVVVV"));
1173 
1174  WL4435_TEST("TINYTEXT", "REPEAT('t', 16)",
1175  MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1176  char, [255],
1177  (" - TINYTEXT / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1178  !strcmp(pspv, "tttttttttttttttt"));
1179 
1180  WL4435_TEST("TEXT", "REPEAT('t', 16)",
1181  MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1182  char, [255],
1183  (" - TEXT / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1184  !strcmp(pspv, "tttttttttttttttt"));
1185 
1186  WL4435_TEST("MEDIUMTEXT", "REPEAT('t', 16)",
1187  MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1188  char, [255],
1189  (" - MEDIUMTEXT / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1190  !strcmp(pspv, "tttttttttttttttt"));
1191 
1192  WL4435_TEST("LONGTEXT", "REPEAT('t', 16)",
1193  MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1194  char, [255],
1195  (" - LONGTEXT / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1196  !strcmp(pspv, "tttttttttttttttt"));
1197 
1198  WL4435_TEST("BINARY(32)", "REPEAT('\1', 16)",
1199  MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1200  char, [255],
1201  (" - BINARY(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1202  memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1203 
1204  WL4435_TEST("VARBINARY(32)", "REPEAT('\1', 16)",
1205  MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1206  char, [255],
1207  (" - VARBINARY(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1208  memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1209 
1210  WL4435_TEST("TINYBLOB", "REPEAT('\2', 16)",
1211  MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1212  char, [255],
1213  (" - TINYBLOB / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1214  memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1215 
1216  WL4435_TEST("BLOB", "REPEAT('\2', 16)",
1217  MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1218  char, [255],
1219  (" - BLOB / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1220  memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1221 
1222  WL4435_TEST("MEDIUMBLOB", "REPEAT('\2', 16)",
1223  MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1224  char, [255],
1225  (" - MEDIUMBLOB / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1226  memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1227 
1228  WL4435_TEST("LONGBLOB", "REPEAT('\2', 16)",
1229  MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1230  char, [255],
1231  (" - LONGBLOB / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1232  memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1233 }
1234 
1235 
1236 /* Test simple prepare field results */
1237 
1238 static void test_prepare_field_result()
1239 {
1240  MYSQL_STMT *stmt;
1241  MYSQL_RES *result;
1242  int rc;
1243  char query[MAX_TEST_QUERY_LENGTH];
1244 
1245  myheader("test_prepare_field_result");
1246 
1247  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_field_result");
1248  myquery(rc);
1249 
1250  rc= mysql_query(mysql, "CREATE TABLE test_prepare_field_result(int_c int, "
1251  "var_c varchar(50), ts_c timestamp, "
1252  "char_c char(4), date_c date, extra tinyint)");
1253  myquery(rc);
1254 
1255  /* insert */
1256  strmov(query, "SELECT int_c, var_c, date_c as date, ts_c, char_c FROM "
1257  " test_prepare_field_result as t1 WHERE int_c=?");
1258  stmt= mysql_simple_prepare(mysql, query);
1259  check_stmt(stmt);
1260 
1261  verify_param_count(stmt, 1);
1262 
1263  result= mysql_stmt_result_metadata(stmt);
1264  mytest(result);
1265 
1266  my_print_result_metadata(result);
1267 
1268  if (!opt_silent)
1269  fprintf(stdout, "\n\n field attributes:\n");
1270  verify_prepare_field(result, 0, "int_c", "int_c", MYSQL_TYPE_LONG,
1271  "t1", "test_prepare_field_result", current_db, 11, 0);
1272  verify_prepare_field(result, 1, "var_c", "var_c", MYSQL_TYPE_VAR_STRING,
1273  "t1", "test_prepare_field_result", current_db, 50, 0);
1274  verify_prepare_field(result, 2, "date", "date_c", MYSQL_TYPE_DATE,
1275  "t1", "test_prepare_field_result", current_db, 10, 0);
1276  verify_prepare_field(result, 3, "ts_c", "ts_c", MYSQL_TYPE_TIMESTAMP,
1277  "t1", "test_prepare_field_result", current_db, 19, 0);
1278  verify_prepare_field(result, 4, "char_c", "char_c",
1279  (mysql_get_server_version(mysql) <= 50000 ?
1280  MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING),
1281  "t1", "test_prepare_field_result", current_db, 4, 0);
1282 
1283  verify_field_count(result, 5);
1284  mysql_free_result(result);
1285  mysql_stmt_close(stmt);
1286 }
1287 
1288 
1289 /* Test simple prepare field results */
1290 
1291 static void test_prepare_syntax()
1292 {
1293  MYSQL_STMT *stmt;
1294  int rc;
1295  char query[MAX_TEST_QUERY_LENGTH];
1296 
1297  myheader("test_prepare_syntax");
1298 
1299  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_syntax");
1300  myquery(rc);
1301 
1302  rc= mysql_query(mysql, "CREATE TABLE test_prepare_syntax("
1303  "id int, name varchar(50), extra int)");
1304  myquery(rc);
1305 
1306  strmov(query, "INSERT INTO test_prepare_syntax VALUES(?");
1307  stmt= mysql_simple_prepare(mysql, query);
1308  check_stmt_r(stmt);
1309 
1310  strmov(query, "SELECT id, name FROM test_prepare_syntax WHERE id=? AND WHERE");
1311  stmt= mysql_simple_prepare(mysql, query);
1312  check_stmt_r(stmt);
1313 
1314  /* now fetch the results ..*/
1315  rc= mysql_commit(mysql);
1316  myquery(rc);
1317 }
1318 
1319 
1320 /* Test a simple prepare */
1321 
1322 static void test_prepare()
1323 {
1324  MYSQL_STMT *stmt;
1325  int rc, i;
1326  int int_data, o_int_data;
1327  char str_data[50], data[50];
1328  char tiny_data, o_tiny_data;
1329  short small_data, o_small_data;
1330  longlong big_data, o_big_data;
1331  float real_data, o_real_data;
1332  double double_data, o_double_data;
1333  ulong length[7], len;
1334  my_bool is_null[7];
1335  char llbuf[22];
1336  MYSQL_BIND my_bind[7];
1337  char query[MAX_TEST_QUERY_LENGTH];
1338 
1339  myheader("test_prepare");
1340 
1341  rc= mysql_autocommit(mysql, TRUE);
1342  myquery(rc);
1343 
1344  rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
1345  myquery(rc);
1346 
1347  rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 tinyint, "
1348  "col2 varchar(15), col3 int, "
1349  "col4 smallint, col5 bigint, "
1350  "col6 float, col7 double )");
1351  myquery(rc);
1352 
1353  /* insert by prepare */
1354  strxmov(query, "INSERT INTO my_prepare VALUES(?, ?, ?, ?, ?, ?, ?)", NullS);
1355  stmt= mysql_simple_prepare(mysql, query);
1356  check_stmt(stmt);
1357 
1358  verify_param_count(stmt, 7);
1359 
1360  memset(my_bind, 0, sizeof(my_bind));
1361 
1362  /* tinyint */
1363  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1364  my_bind[0].buffer= (void *)&tiny_data;
1365  /* string */
1366  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1367  my_bind[1].buffer= (void *)str_data;
1368  my_bind[1].buffer_length= 1000; /* Max string length */
1369  /* integer */
1370  my_bind[2].buffer_type= MYSQL_TYPE_LONG;
1371  my_bind[2].buffer= (void *)&int_data;
1372  /* short */
1373  my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
1374  my_bind[3].buffer= (void *)&small_data;
1375  /* bigint */
1376  my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
1377  my_bind[4].buffer= (void *)&big_data;
1378  /* float */
1379  my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
1380  my_bind[5].buffer= (void *)&real_data;
1381  /* double */
1382  my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
1383  my_bind[6].buffer= (void *)&double_data;
1384 
1385  for (i= 0; i < (int) array_elements(my_bind); i++)
1386  {
1387  my_bind[i].length= &length[i];
1388  my_bind[i].is_null= &is_null[i];
1389  is_null[i]= 0;
1390  }
1391 
1392  rc= mysql_stmt_bind_param(stmt, my_bind);
1393  check_execute(stmt, rc);
1394 
1395  int_data= 320;
1396  small_data= 1867;
1397  big_data= 1000;
1398  real_data= 2;
1399  double_data= 6578.001;
1400 
1401  /* now, execute the prepared statement to insert 10 records.. */
1402  for (tiny_data= 0; tiny_data < 100; tiny_data++)
1403  {
1404  length[1]= sprintf(str_data, "MySQL%d", int_data);
1405  rc= mysql_stmt_execute(stmt);
1406  check_execute(stmt, rc);
1407  int_data += 25;
1408  small_data += 10;
1409  big_data += 100;
1410  real_data += 1;
1411  double_data += 10.09;
1412  }
1413 
1414  mysql_stmt_close(stmt);
1415 
1416  /* now fetch the results ..*/
1417  rc= mysql_commit(mysql);
1418  myquery(rc);
1419 
1420  /* test the results now, only one row should exist */
1421  rc= my_stmt_result("SELECT * FROM my_prepare");
1422  DIE_UNLESS(tiny_data == (char) rc);
1423 
1424  stmt= mysql_simple_prepare(mysql, "SELECT * FROM my_prepare");
1425  check_stmt(stmt);
1426 
1427  rc= mysql_stmt_bind_result(stmt, my_bind);
1428  check_execute(stmt, rc);
1429 
1430  /* get the result */
1431  rc= mysql_stmt_execute(stmt);
1432  check_execute(stmt, rc);
1433 
1434  o_int_data= 320;
1435  o_small_data= 1867;
1436  o_big_data= 1000;
1437  o_real_data= 2;
1438  o_double_data= 6578.001;
1439 
1440  /* now, execute the prepared statement to insert 10 records.. */
1441  for (o_tiny_data= 0; o_tiny_data < 100; o_tiny_data++)
1442  {
1443  len= sprintf(data, "MySQL%d", o_int_data);
1444 
1445  rc= mysql_stmt_fetch(stmt);
1446  check_execute(stmt, rc);
1447 
1448  if (!opt_silent)
1449  {
1450  fprintf(stdout, "\n");
1451  fprintf(stdout, "\n\t tiny : %d (%lu)", tiny_data, length[0]);
1452  fprintf(stdout, "\n\t short : %d (%lu)", small_data, length[3]);
1453  fprintf(stdout, "\n\t int : %d (%lu)", int_data, length[2]);
1454  fprintf(stdout, "\n\t big : %s (%lu)", llstr(big_data, llbuf),
1455  length[4]);
1456 
1457  fprintf(stdout, "\n\t float : %f (%lu)", real_data, length[5]);
1458  fprintf(stdout, "\n\t double : %f (%lu)", double_data, length[6]);
1459 
1460  fprintf(stdout, "\n\t str : %s (%lu)", str_data, length[1]);
1461  }
1462 
1463  DIE_UNLESS(tiny_data == o_tiny_data);
1464  DIE_UNLESS(is_null[0] == 0);
1465  DIE_UNLESS(length[0] == 1);
1466 
1467  DIE_UNLESS(int_data == o_int_data);
1468  DIE_UNLESS(length[2] == 4);
1469 
1470  DIE_UNLESS(small_data == o_small_data);
1471  DIE_UNLESS(length[3] == 2);
1472 
1473  DIE_UNLESS(big_data == o_big_data);
1474  DIE_UNLESS(length[4] == 8);
1475 
1476  DIE_UNLESS(real_data == o_real_data);
1477  DIE_UNLESS(length[5] == 4);
1478 
1479  DIE_UNLESS(cmp_double(&double_data, &o_double_data));
1480  DIE_UNLESS(length[6] == 8);
1481 
1482  DIE_UNLESS(strcmp(data, str_data) == 0);
1483  DIE_UNLESS(length[1] == len);
1484 
1485  o_int_data += 25;
1486  o_small_data += 10;
1487  o_big_data += 100;
1488  o_real_data += 1;
1489  o_double_data += 10.09;
1490  }
1491 
1492  rc= mysql_stmt_fetch(stmt);
1493  DIE_UNLESS(rc == MYSQL_NO_DATA);
1494 
1495  mysql_stmt_close(stmt);
1496 
1497 }
1498 
1499 
1500 /* Test double comparision */
1501 
1502 static void test_double_compare()
1503 {
1504  MYSQL_STMT *stmt;
1505  int rc;
1506  char real_data[10], tiny_data;
1507  double double_data;
1508  MYSQL_RES *result;
1509  MYSQL_BIND my_bind[3];
1510  ulong length[3];
1511  char query[MAX_TEST_QUERY_LENGTH];
1512 
1513  myheader("test_double_compare");
1514 
1515  rc= mysql_autocommit(mysql, TRUE);
1516  myquery(rc);
1517 
1518  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_double_compare");
1519  myquery(rc);
1520 
1521  rc= mysql_query(mysql, "CREATE TABLE test_double_compare(col1 tinyint, "
1522  " col2 float, col3 double )");
1523  myquery(rc);
1524 
1525  rc= mysql_query(mysql, "INSERT INTO test_double_compare "
1526  "VALUES (1, 10.2, 34.5)");
1527  myquery(rc);
1528 
1529  strmov(query, "UPDATE test_double_compare SET col1=100 "
1530  "WHERE col1 = ? AND col2 = ? AND COL3 = ?");
1531  stmt= mysql_simple_prepare(mysql, query);
1532  check_stmt(stmt);
1533 
1534  verify_param_count(stmt, 3);
1535 
1536  /* Always memset bind array because there can be internal members */
1537  memset(my_bind, 0, sizeof(my_bind));
1538 
1539  /* tinyint */
1540  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1541  my_bind[0].buffer= (void *)&tiny_data;
1542 
1543  /* string->float */
1544  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1545  my_bind[1].buffer= (void *)&real_data;
1546  my_bind[1].buffer_length= sizeof(real_data);
1547  my_bind[1].length= &length[1];
1548  length[1]= 10;
1549 
1550  /* double */
1551  my_bind[2].buffer_type= MYSQL_TYPE_DOUBLE;
1552  my_bind[2].buffer= (void *)&double_data;
1553 
1554  tiny_data= 1;
1555  strmov(real_data, "10.2");
1556  double_data= 34.5;
1557  rc= mysql_stmt_bind_param(stmt, my_bind);
1558  check_execute(stmt, rc);
1559 
1560  rc= mysql_stmt_execute(stmt);
1561  check_execute(stmt, rc);
1562 
1563  verify_affected_rows(0);
1564 
1565  mysql_stmt_close(stmt);
1566 
1567  /* now fetch the results ..*/
1568  rc= mysql_commit(mysql);
1569  myquery(rc);
1570 
1571  /* test the results now, only one row should exist */
1572  rc= mysql_query(mysql, "SELECT * FROM test_double_compare");
1573  myquery(rc);
1574 
1575  /* get the result */
1576  result= mysql_store_result(mysql);
1577  mytest(result);
1578 
1579  rc= my_process_result_set(result);
1580  DIE_UNLESS((int)tiny_data == rc);
1581  mysql_free_result(result);
1582 }
1583 
1584 
1585 /* Test simple null */
1586 
1587 static void test_null()
1588 {
1589  MYSQL_STMT *stmt;
1590  int rc;
1591  uint nData;
1592  MYSQL_BIND my_bind[2];
1593  my_bool is_null[2];
1594  char query[MAX_TEST_QUERY_LENGTH];
1595 
1596  myheader("test_null");
1597 
1598  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_null");
1599  myquery(rc);
1600 
1601  rc= mysql_query(mysql, "CREATE TABLE test_null(col1 int, col2 varchar(50))");
1602  myquery(rc);
1603 
1604  /* insert by prepare, wrong column name */
1605  strmov(query, "INSERT INTO test_null(col3, col2) VALUES(?, ?)");
1606  stmt= mysql_simple_prepare(mysql, query);
1607  check_stmt_r(stmt);
1608 
1609  strmov(query, "INSERT INTO test_null(col1, col2) VALUES(?, ?)");
1610  stmt= mysql_simple_prepare(mysql, query);
1611  check_stmt(stmt);
1612 
1613  verify_param_count(stmt, 2);
1614 
1615  /* Always memset all members of bind parameter */
1616  memset(my_bind, 0, sizeof(my_bind));
1617 
1618  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1619  my_bind[0].is_null= &is_null[0];
1620  is_null[0]= 1;
1621  my_bind[1]= my_bind[0];
1622 
1623  rc= mysql_stmt_bind_param(stmt, my_bind);
1624  check_execute(stmt, rc);
1625 
1626  /* now, execute the prepared statement to insert 10 records.. */
1627  for (nData= 0; nData<10; nData++)
1628  {
1629  rc= mysql_stmt_execute(stmt);
1630  check_execute(stmt, rc);
1631  }
1632 
1633  /* Re-bind with MYSQL_TYPE_NULL */
1634  my_bind[0].buffer_type= MYSQL_TYPE_NULL;
1635  is_null[0]= 0; /* reset */
1636  my_bind[1]= my_bind[0];
1637 
1638  rc= mysql_stmt_bind_param(stmt, my_bind);
1639  check_execute(stmt, rc);
1640 
1641  for (nData= 0; nData<10; nData++)
1642  {
1643  rc= mysql_stmt_execute(stmt);
1644  check_execute(stmt, rc);
1645  }
1646 
1647  mysql_stmt_close(stmt);
1648 
1649  /* now fetch the results ..*/
1650  rc= mysql_commit(mysql);
1651  myquery(rc);
1652 
1653  nData*= 2;
1654  rc= my_stmt_result("SELECT * FROM test_null");;
1655  DIE_UNLESS((int) nData == rc);
1656 
1657  /* Fetch results */
1658  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1659  my_bind[0].buffer= (void *)&nData; /* this buffer won't be altered */
1660  my_bind[0].length= 0;
1661  my_bind[1]= my_bind[0];
1662  my_bind[0].is_null= &is_null[0];
1663  my_bind[1].is_null= &is_null[1];
1664 
1665  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_null");
1666  check_stmt(stmt);
1667 
1668  rc= mysql_stmt_execute(stmt);
1669  check_execute(stmt, rc);
1670 
1671  rc= mysql_stmt_bind_result(stmt, my_bind);
1672  check_execute(stmt, rc);
1673 
1674  rc= 0;
1675  is_null[0]= is_null[1]= 0;
1676  while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1677  {
1678  DIE_UNLESS(is_null[0]);
1679  DIE_UNLESS(is_null[1]);
1680  rc++;
1681  is_null[0]= is_null[1]= 0;
1682  }
1683  DIE_UNLESS(rc == (int) nData);
1684  mysql_stmt_close(stmt);
1685 }
1686 
1687 
1688 /* Test for NULL as PS parameter (BUG#3367, BUG#3371) */
1689 
1690 static void test_ps_null_param()
1691 {
1692  MYSQL_STMT *stmt;
1693  int rc;
1694 
1695  MYSQL_BIND in_bind;
1696  my_bool in_is_null;
1697  long int in_long;
1698 
1699  MYSQL_BIND out_bind;
1700  ulong out_length;
1701  my_bool out_is_null;
1702  char out_str_data[20];
1703 
1704  const char *queries[]= {"select ?", "select ?+1",
1705  "select col1 from test_ps_nulls where col1 <=> ?",
1706  NULL
1707  };
1708  const char **cur_query= queries;
1709 
1710  myheader("test_null_ps_param_in_result");
1711 
1712  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ps_nulls");
1713  myquery(rc);
1714 
1715  rc= mysql_query(mysql, "CREATE TABLE test_ps_nulls(col1 int)");
1716  myquery(rc);
1717 
1718  rc= mysql_query(mysql, "INSERT INTO test_ps_nulls values (1), (null)");
1719  myquery(rc);
1720 
1721  /* Always memset all members of bind parameter */
1722  memset(&in_bind, 0, sizeof(in_bind));
1723  memset(&out_bind, 0, sizeof(out_bind));
1724 
1725  in_bind.buffer_type= MYSQL_TYPE_LONG;
1726  in_bind.is_null= &in_is_null;
1727  in_bind.length= 0;
1728  in_bind.buffer= (void *)&in_long;
1729  in_is_null= 1;
1730  in_long= 1;
1731 
1732  out_bind.buffer_type= MYSQL_TYPE_STRING;
1733  out_bind.is_null= &out_is_null;
1734  out_bind.length= &out_length;
1735  out_bind.buffer= out_str_data;
1736  out_bind.buffer_length= array_elements(out_str_data);
1737 
1738  /* Execute several queries, all returning NULL in result. */
1739  for(cur_query= queries; *cur_query; cur_query++)
1740  {
1741  char query[MAX_TEST_QUERY_LENGTH];
1742  strmov(query, *cur_query);
1743  stmt= mysql_simple_prepare(mysql, query);
1744  check_stmt(stmt);
1745  verify_param_count(stmt, 1);
1746 
1747  rc= mysql_stmt_bind_param(stmt, &in_bind);
1748  check_execute(stmt, rc);
1749  rc= mysql_stmt_bind_result(stmt, &out_bind);
1750  check_execute(stmt, rc);
1751  rc= mysql_stmt_execute(stmt);
1752  check_execute(stmt, rc);
1753  rc= mysql_stmt_fetch(stmt);
1754  DIE_UNLESS(rc != MYSQL_NO_DATA);
1755  DIE_UNLESS(out_is_null);
1756  rc= mysql_stmt_fetch(stmt);
1757  DIE_UNLESS(rc == MYSQL_NO_DATA);
1758  mysql_stmt_close(stmt);
1759  }
1760 }
1761 
1762 
1763 /* Test fetch null */
1764 
1765 static void test_fetch_null()
1766 {
1767  MYSQL_STMT *stmt;
1768  int rc;
1769  int i, nData;
1770  MYSQL_BIND my_bind[11];
1771  ulong length[11];
1772  my_bool is_null[11];
1773  char query[MAX_TEST_QUERY_LENGTH];
1774 
1775  myheader("test_fetch_null");
1776 
1777  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null");
1778  myquery(rc);
1779 
1780  rc= mysql_query(mysql, "CREATE TABLE test_fetch_null("
1781  " col1 tinyint, col2 smallint, "
1782  " col3 int, col4 bigint, "
1783  " col5 float, col6 double, "
1784  " col7 date, col8 time, "
1785  " col9 varbinary(10), "
1786  " col10 varchar(50), "
1787  " col11 char(20))");
1788  myquery(rc);
1789 
1790  rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) "
1791  "VALUES (1000), (88), (389789)");
1792  myquery(rc);
1793 
1794  rc= mysql_commit(mysql);
1795  myquery(rc);
1796 
1797  /* fetch */
1798  memset(my_bind, 0, sizeof(my_bind));
1799  for (i= 0; i < (int) array_elements(my_bind); i++)
1800  {
1801  my_bind[i].buffer_type= MYSQL_TYPE_LONG;
1802  my_bind[i].is_null= &is_null[i];
1803  my_bind[i].length= &length[i];
1804  }
1805  my_bind[i-1].buffer= (void *)&nData; /* Last column is not null */
1806 
1807  strmov((char *)query , "SELECT * FROM test_fetch_null");
1808 
1809  rc= my_stmt_result(query);
1810  DIE_UNLESS(rc == 3);
1811 
1812  stmt= mysql_simple_prepare(mysql, query);
1813  check_stmt(stmt);
1814 
1815  rc= mysql_stmt_bind_result(stmt, my_bind);
1816  check_execute(stmt, rc);
1817 
1818  rc= mysql_stmt_execute(stmt);
1819  check_execute(stmt, rc);
1820 
1821  rc= 0;
1822  while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1823  {
1824  rc++;
1825  for (i= 0; i < 10; i++)
1826  {
1827  if (!opt_silent)
1828  fprintf(stdout, "\n data[%d] : %s", i,
1829  is_null[i] ? "NULL" : "NOT NULL");
1830  DIE_UNLESS(is_null[i]);
1831  }
1832  if (!opt_silent)
1833  fprintf(stdout, "\n data[%d]: %d", i, nData);
1834  DIE_UNLESS(nData == 1000 || nData == 88 || nData == 389789);
1835  DIE_UNLESS(is_null[i] == 0);
1836  DIE_UNLESS(length[i] == 4);
1837  }
1838  DIE_UNLESS(rc == 3);
1839  mysql_stmt_close(stmt);
1840 }
1841 
1842 
1843 /* Test simple select */
1844 
1845 static void test_select_version()
1846 {
1847  MYSQL_STMT *stmt;
1848  int rc;
1849 
1850  myheader("test_select_version");
1851 
1852  stmt= mysql_simple_prepare(mysql, "SELECT @@version");
1853  check_stmt(stmt);
1854 
1855  verify_param_count(stmt, 0);
1856 
1857  rc= mysql_stmt_execute(stmt);
1858  check_execute(stmt, rc);
1859 
1860  my_process_stmt_result(stmt);
1861  mysql_stmt_close(stmt);
1862 }
1863 
1864 
1865 /* Test simple show */
1866 
1867 static void test_select_show_table()
1868 {
1869  MYSQL_STMT *stmt;
1870  int rc, i;
1871 
1872  myheader("test_select_show_table");
1873 
1874  stmt= mysql_simple_prepare(mysql, "SHOW TABLES FROM mysql");
1875  check_stmt(stmt);
1876 
1877  verify_param_count(stmt, 0);
1878 
1879  for (i= 1; i < 3; i++)
1880  {
1881  rc= mysql_stmt_execute(stmt);
1882  check_execute(stmt, rc);
1883  }
1884 
1885  my_process_stmt_result(stmt);
1886  mysql_stmt_close(stmt);
1887 }
1888 
1889 
1890 /* Test simple select to debug */
1891 
1892 static void test_select_direct()
1893 {
1894  int rc;
1895  MYSQL_RES *result;
1896 
1897  myheader("test_select_direct");
1898 
1899  rc= mysql_autocommit(mysql, TRUE);
1900  myquery(rc);
1901 
1902  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
1903  myquery(rc);
1904 
1905  rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
1906  " id2 float, "
1907  " id3 double, "
1908  " name varchar(50))");
1909  myquery(rc);
1910 
1911  /* insert a row and commit the transaction */
1912  rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')");
1913  myquery(rc);
1914 
1915  rc= mysql_commit(mysql);
1916  myquery(rc);
1917 
1918  rc= mysql_query(mysql, "SELECT * FROM test_select");
1919  myquery(rc);
1920 
1921  /* get the result */
1922  result= mysql_store_result(mysql);
1923  mytest(result);
1924 
1925  (void) my_process_result_set(result);
1926  mysql_free_result(result);
1927 }
1928 
1929 
1930 /* Test simple select with prepare */
1931 
1932 static void test_select_prepare()
1933 {
1934  int rc;
1935  MYSQL_STMT *stmt;
1936 
1937  myheader("test_select_prepare");
1938 
1939  rc= mysql_autocommit(mysql, TRUE);
1940  myquery(rc);
1941 
1942  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
1943  myquery(rc);
1944 
1945  rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
1946  myquery(rc);
1947 
1948  /* insert a row and commit the transaction */
1949  rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
1950  myquery(rc);
1951 
1952  rc= mysql_commit(mysql);
1953  myquery(rc);
1954 
1955  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
1956  check_stmt(stmt);
1957 
1958  rc= mysql_stmt_execute(stmt);
1959  check_execute(stmt, rc);
1960 
1961  rc= my_process_stmt_result(stmt);
1962  DIE_UNLESS(rc == 1);
1963  mysql_stmt_close(stmt);
1964 
1965  rc= mysql_query(mysql, "DROP TABLE test_select");
1966  myquery(rc);
1967 
1968  rc= mysql_query(mysql, "CREATE TABLE test_select(id tinyint, id1 int, "
1969  " id2 float, id3 float, "
1970  " name varchar(50))");
1971  myquery(rc);
1972 
1973  /* insert a row and commit the transaction */
1974  rc= mysql_query(mysql, "INSERT INTO test_select(id, id1, id2, name) VALUES(10, 5, 2.3, 'venu')");
1975  myquery(rc);
1976 
1977  rc= mysql_commit(mysql);
1978  myquery(rc);
1979 
1980  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
1981  check_stmt(stmt);
1982 
1983  rc= mysql_stmt_execute(stmt);
1984  check_execute(stmt, rc);
1985 
1986  rc= my_process_stmt_result(stmt);
1987  DIE_UNLESS(rc == 1);
1988  mysql_stmt_close(stmt);
1989 }
1990 
1991 
1992 /* Test simple select */
1993 
1994 static void test_select()
1995 {
1996  MYSQL_STMT *stmt;
1997  int rc;
1998  char szData[25];
1999  int nData= 1;
2000  MYSQL_BIND my_bind[2];
2001  ulong length[2];
2002  char query[MAX_TEST_QUERY_LENGTH];
2003 
2004  myheader("test_select");
2005 
2006  rc= mysql_autocommit(mysql, TRUE);
2007  myquery(rc);
2008 
2009  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2010  myquery(rc);
2011 
2012  rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
2013  myquery(rc);
2014 
2015  /* insert a row and commit the transaction */
2016  rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
2017  myquery(rc);
2018 
2019  /* now insert the second row, and roll back the transaction */
2020  rc= mysql_query(mysql, "INSERT INTO test_select VALUES(20, 'mysql')");
2021  myquery(rc);
2022 
2023  rc= mysql_commit(mysql);
2024  myquery(rc);
2025 
2026  strmov(query, "SELECT * FROM test_select WHERE id= ? "
2027  "AND CONVERT(name USING utf8) =?");
2028  stmt= mysql_simple_prepare(mysql, query);
2029  check_stmt(stmt);
2030 
2031  verify_param_count(stmt, 2);
2032 
2033  /* Always memset all members of bind parameter */
2034  memset(my_bind, 0, sizeof(my_bind));
2035 
2036  /* string data */
2037  nData= 10;
2038  strmov(szData, (char *)"venu");
2039  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2040  my_bind[1].buffer= (void *)szData;
2041  my_bind[1].buffer_length= 4;
2042  my_bind[1].length= &length[1];
2043  length[1]= 4;
2044 
2045  my_bind[0].buffer= (void *)&nData;
2046  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2047 
2048  rc= mysql_stmt_bind_param(stmt, my_bind);
2049  check_execute(stmt, rc);
2050 
2051  rc= mysql_stmt_execute(stmt);
2052  check_execute(stmt, rc);
2053 
2054  rc= my_process_stmt_result(stmt);
2055  DIE_UNLESS(rc == 1);
2056 
2057  mysql_stmt_close(stmt);
2058 }
2059 
2060 
2061 /*
2062  Test for BUG#3420 ("select id1, value1 from t where id= ? or value= ?"
2063  returns all rows in the table)
2064 */
2065 
2066 static void test_ps_conj_select()
2067 {
2068  MYSQL_STMT *stmt;
2069  int rc;
2070  MYSQL_BIND my_bind[2];
2071  int32 int_data;
2072  char str_data[32];
2073  unsigned long str_length;
2074  char query[MAX_TEST_QUERY_LENGTH];
2075  myheader("test_ps_conj_select");
2076 
2077  rc= mysql_query(mysql, "drop table if exists t1");
2078  myquery(rc);
2079 
2080  rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2081  "value2 varchar(100), value1 varchar(100))");
2082  myquery(rc);
2083 
2084  rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2085  "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2086  myquery(rc);
2087 
2088  strmov(query, "select id1, value1 from t1 where id1= ? or "
2089  "CONVERT(value1 USING utf8)= ?");
2090  stmt= mysql_simple_prepare(mysql, query);
2091  check_stmt(stmt);
2092 
2093  verify_param_count(stmt, 2);
2094 
2095  /* Always memset all members of bind parameter */
2096  memset(my_bind, 0, sizeof(my_bind));
2097 
2098  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2099  my_bind[0].buffer= (void *)&int_data;
2100 
2101  my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2102  my_bind[1].buffer= (void *)str_data;
2103  my_bind[1].buffer_length= array_elements(str_data);
2104  my_bind[1].length= &str_length;
2105 
2106  rc= mysql_stmt_bind_param(stmt, my_bind);
2107  check_execute(stmt, rc);
2108 
2109  int_data= 1;
2110  strmov(str_data, "hh");
2111  str_length= strlen(str_data);
2112 
2113  rc= mysql_stmt_execute(stmt);
2114  check_execute(stmt, rc);
2115 
2116  rc= my_process_stmt_result(stmt);
2117  DIE_UNLESS(rc == 3);
2118 
2119  mysql_stmt_close(stmt);
2120 }
2121 
2122 
2123 /* reads Qcache_hits from server and returns its value */
2124 static uint query_cache_hits(MYSQL *conn)
2125 {
2126  MYSQL_RES *res;
2127  MYSQL_ROW row;
2128  int rc;
2129  uint result;
2130 
2131  rc= mysql_query(conn, "show status like 'qcache_hits'");
2132  myquery(rc);
2133  res= mysql_use_result(conn);
2134  DIE_UNLESS(res);
2135 
2136  row= mysql_fetch_row(res);
2137  DIE_UNLESS(row);
2138 
2139  result= atoi(row[1]);
2140  mysql_free_result(res);
2141  return result;
2142 }
2143 
2144 
2145 /*
2146  utility for the next test; expects 3 rows in the result from a SELECT,
2147  compares each row/field with an expected value.
2148  */
2149 #define test_ps_query_cache_result(i1,s1,l1,i2,s2,l2,i3,s3,l3) \
2150  r_metadata= mysql_stmt_result_metadata(stmt); \
2151  DIE_UNLESS(r_metadata != NULL); \
2152  rc= mysql_stmt_fetch(stmt); \
2153  check_execute(stmt, rc); \
2154  if (!opt_silent) \
2155  fprintf(stdout, "\n row 1: %d, %s(%lu)", r_int_data, \
2156  r_str_data, r_str_length); \
2157  DIE_UNLESS((r_int_data == i1) && (r_str_length == l1) && \
2158  (strcmp(r_str_data, s1) == 0)); \
2159  rc= mysql_stmt_fetch(stmt); \
2160  check_execute(stmt, rc); \
2161  if (!opt_silent) \
2162  fprintf(stdout, "\n row 2: %d, %s(%lu)", r_int_data, \
2163  r_str_data, r_str_length); \
2164  DIE_UNLESS((r_int_data == i2) && (r_str_length == l2) && \
2165  (strcmp(r_str_data, s2) == 0)); \
2166  rc= mysql_stmt_fetch(stmt); \
2167  check_execute(stmt, rc); \
2168  if (!opt_silent) \
2169  fprintf(stdout, "\n row 3: %d, %s(%lu)", r_int_data, \
2170  r_str_data, r_str_length); \
2171  DIE_UNLESS((r_int_data == i3) && (r_str_length == l3) && \
2172  (strcmp(r_str_data, s3) == 0)); \
2173  rc= mysql_stmt_fetch(stmt); \
2174  DIE_UNLESS(rc == MYSQL_NO_DATA); \
2175  mysql_free_result(r_metadata);
2176 
2177 
2178 /*
2179  Test that prepared statements make use of the query cache just as normal
2180  statements (BUG#735).
2181 */
2182 static void test_ps_query_cache()
2183 {
2184  MYSQL *lmysql= mysql;
2185  MYSQL_STMT *stmt;
2186  int rc;
2187  MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */
2188  int32 p_int_data, r_int_data;
2189  char p_str_data[32], r_str_data[32];
2190  unsigned long p_str_length, r_str_length;
2191  MYSQL_RES *r_metadata;
2192  char query[MAX_TEST_QUERY_LENGTH];
2193  uint hits1, hits2;
2194  enum enum_test_ps_query_cache
2195  {
2196  /*
2197  We iterate the same prepare/executes block, but have iterations where
2198  we vary the query cache conditions.
2199  */
2200  /* the query cache is enabled for the duration of prep&execs: */
2201  TEST_QCACHE_ON= 0,
2202  /*
2203  same but using a new connection (to see if qcache serves results from
2204  the previous connection as it should):
2205  */
2206  TEST_QCACHE_ON_WITH_OTHER_CONN,
2207  /*
2208  First border case: disables the query cache before prepare and
2209  re-enables it before execution (to test if we have no bug then):
2210  */
2211  TEST_QCACHE_OFF_ON,
2212  /*
2213  Second border case: enables the query cache before prepare and
2214  disables it before execution:
2215  */
2216  TEST_QCACHE_ON_OFF
2217  };
2218  enum enum_test_ps_query_cache iteration;
2219 
2220  myheader("test_ps_query_cache");
2221 
2222  rc= mysql_query(mysql, "SET SQL_MODE=''");
2223  myquery(rc);
2224 
2225  /* prepare the table */
2226 
2227  rc= mysql_query(mysql, "drop table if exists t1");
2228  myquery(rc);
2229 
2230  rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2231  "value2 varchar(100), value1 varchar(100))");
2232  myquery(rc);
2233 
2234  rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2235  "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2236  myquery(rc);
2237 
2238  for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++)
2239  {
2240 
2241  switch (iteration) {
2242  case TEST_QCACHE_ON:
2243  case TEST_QCACHE_ON_OFF:
2244  rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2245  myquery(rc);
2246  break;
2247  case TEST_QCACHE_OFF_ON:
2248  rc= mysql_query(lmysql, "set global query_cache_size=0");
2249  myquery(rc);
2250  break;
2251  case TEST_QCACHE_ON_WITH_OTHER_CONN:
2252  if (!opt_silent)
2253  fprintf(stdout, "\n Establishing a test connection ...");
2254  if (!(lmysql= mysql_client_init(NULL)))
2255  {
2256  printf("mysql_client_init() failed");
2257  DIE_UNLESS(0);
2258  }
2259  if (!(mysql_real_connect(lmysql, opt_host, opt_user,
2260  opt_password, current_db, opt_port,
2261  opt_unix_socket, 0)))
2262  {
2263  printf("connection failed");
2264  mysql_close(lmysql);
2265  DIE_UNLESS(0);
2266  }
2267  rc= mysql_query(lmysql, "SET SQL_MODE=''");
2268  myquery(rc);
2269 
2270  if (!opt_silent)
2271  fprintf(stdout, "OK");
2272  }
2273 
2274  strmov(query, "select id1, value1 from t1 where id1= ? or "
2275  "CONVERT(value1 USING utf8)= ?");
2276  stmt= mysql_simple_prepare(lmysql, query);
2277  check_stmt(stmt);
2278 
2279  verify_param_count(stmt, 2);
2280 
2281  switch (iteration) {
2282  case TEST_QCACHE_OFF_ON:
2283  rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2284  myquery(rc);
2285  break;
2286  case TEST_QCACHE_ON_OFF:
2287  rc= mysql_query(lmysql, "set global query_cache_size=0");
2288  myquery(rc);
2289  default:
2290  break;
2291  }
2292 
2293  memset(p_bind, 0, sizeof(p_bind));
2294  p_bind[0].buffer_type= MYSQL_TYPE_LONG;
2295  p_bind[0].buffer= (void *)&p_int_data;
2296  p_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2297  p_bind[1].buffer= (void *)p_str_data;
2298  p_bind[1].buffer_length= array_elements(p_str_data);
2299  p_bind[1].length= &p_str_length;
2300 
2301  rc= mysql_stmt_bind_param(stmt, p_bind);
2302  check_execute(stmt, rc);
2303 
2304  p_int_data= 1;
2305  strmov(p_str_data, "hh");
2306  p_str_length= strlen(p_str_data);
2307 
2308  memset(r_bind, 0, sizeof(r_bind));
2309  r_bind[0].buffer_type= MYSQL_TYPE_LONG;
2310  r_bind[0].buffer= (void *)&r_int_data;
2311  r_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2312  r_bind[1].buffer= (void *)r_str_data;
2313  r_bind[1].buffer_length= array_elements(r_str_data);
2314  r_bind[1].length= &r_str_length;
2315 
2316  rc= mysql_stmt_bind_result(stmt, r_bind);
2317  check_execute(stmt, rc);
2318 
2319  rc= mysql_stmt_execute(stmt);
2320  check_execute(stmt, rc);
2321 
2322  test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2323 
2324  /* now retry with the same parameter values and see qcache hits */
2325  hits1= query_cache_hits(lmysql);
2326  rc= mysql_stmt_execute(stmt);
2327  check_execute(stmt, rc);
2328  test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2329  hits2= query_cache_hits(lmysql);
2330  switch(iteration) {
2331  case TEST_QCACHE_ON_WITH_OTHER_CONN:
2332  case TEST_QCACHE_ON: /* should have hit */
2333  DIE_UNLESS(hits2-hits1 == 1);
2334  break;
2335  case TEST_QCACHE_OFF_ON:
2336  case TEST_QCACHE_ON_OFF: /* should not have hit */
2337  DIE_UNLESS(hits2-hits1 == 0);
2338  break;
2339  }
2340 
2341  /* now modify parameter values and see qcache hits */
2342  strmov(p_str_data, "ii");
2343  p_str_length= strlen(p_str_data);
2344  rc= mysql_stmt_execute(stmt);
2345  check_execute(stmt, rc);
2346  test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2347  hits1= query_cache_hits(lmysql);
2348 
2349  switch(iteration) {
2350  case TEST_QCACHE_ON:
2351  case TEST_QCACHE_OFF_ON:
2352  case TEST_QCACHE_ON_OFF: /* should not have hit */
2353  DIE_UNLESS(hits2-hits1 == 0);
2354  break;
2355  case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2356  DIE_UNLESS(hits1-hits2 == 1);
2357  break;
2358  }
2359 
2360  rc= mysql_stmt_execute(stmt);
2361  check_execute(stmt, rc);
2362 
2363  test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2364  hits2= query_cache_hits(lmysql);
2365 
2366  mysql_stmt_close(stmt);
2367 
2368  switch(iteration) {
2369  case TEST_QCACHE_ON: /* should have hit */
2370  DIE_UNLESS(hits2-hits1 == 1);
2371  break;
2372  case TEST_QCACHE_OFF_ON:
2373  case TEST_QCACHE_ON_OFF: /* should not have hit */
2374  DIE_UNLESS(hits2-hits1 == 0);
2375  break;
2376  case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2377  DIE_UNLESS(hits2-hits1 == 1);
2378  break;
2379  }
2380 
2381  } /* for(iteration=...) */
2382 
2383  if (lmysql != mysql)
2384  mysql_close(lmysql);
2385 
2386  rc= mysql_query(mysql, "set global query_cache_size=DEFAULT");
2387  myquery(rc);
2388 }
2389 
2390 
2391 /* Test BUG#1115 (incorrect string parameter value allocation) */
2392 
2393 static void test_bug1115()
2394 {
2395  MYSQL_STMT *stmt;
2396  int rc;
2397  MYSQL_BIND my_bind[1];
2398  ulong length[1];
2399  char szData[11];
2400  char query[MAX_TEST_QUERY_LENGTH];
2401 
2402  myheader("test_bug1115");
2403 
2404  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2405  myquery(rc);
2406 
2407  rc= mysql_query(mysql, "CREATE TABLE test_select(\
2408 session_id char(9) NOT NULL, \
2409  a int(8) unsigned NOT NULL, \
2410  b int(5) NOT NULL, \
2411  c int(5) NOT NULL, \
2412  d datetime NOT NULL)");
2413  myquery(rc);
2414  rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2415  "(\"abc\", 1, 2, 3, 2003-08-30), "
2416  "(\"abd\", 1, 2, 3, 2003-08-30), "
2417  "(\"abf\", 1, 2, 3, 2003-08-30), "
2418  "(\"abg\", 1, 2, 3, 2003-08-30), "
2419  "(\"abh\", 1, 2, 3, 2003-08-30), "
2420  "(\"abj\", 1, 2, 3, 2003-08-30), "
2421  "(\"abk\", 1, 2, 3, 2003-08-30), "
2422  "(\"abl\", 1, 2, 3, 2003-08-30), "
2423  "(\"abq\", 1, 2, 3, 2003-08-30) ");
2424  myquery(rc);
2425  rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2426  "(\"abw\", 1, 2, 3, 2003-08-30), "
2427  "(\"abe\", 1, 2, 3, 2003-08-30), "
2428  "(\"abr\", 1, 2, 3, 2003-08-30), "
2429  "(\"abt\", 1, 2, 3, 2003-08-30), "
2430  "(\"aby\", 1, 2, 3, 2003-08-30), "
2431  "(\"abu\", 1, 2, 3, 2003-08-30), "
2432  "(\"abi\", 1, 2, 3, 2003-08-30), "
2433  "(\"abo\", 1, 2, 3, 2003-08-30), "
2434  "(\"abp\", 1, 2, 3, 2003-08-30), "
2435  "(\"abz\", 1, 2, 3, 2003-08-30), "
2436  "(\"abx\", 1, 2, 3, 2003-08-30)");
2437  myquery(rc);
2438 
2439  strmov(query, "SELECT * FROM test_select WHERE "
2440  "CONVERT(session_id USING utf8)= ?");
2441  stmt= mysql_simple_prepare(mysql, query);
2442  check_stmt(stmt);
2443 
2444  verify_param_count(stmt, 1);
2445 
2446  /* Always memset all members of bind parameter */
2447  memset(my_bind, 0, sizeof(my_bind));
2448 
2449  strmov(szData, (char *)"abc");
2450  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2451  my_bind[0].buffer= (void *)szData;
2452  my_bind[0].buffer_length= 10;
2453  my_bind[0].length= &length[0];
2454  length[0]= 3;
2455 
2456  rc= mysql_stmt_bind_param(stmt, my_bind);
2457  check_execute(stmt, rc);
2458 
2459  rc= mysql_stmt_execute(stmt);
2460  check_execute(stmt, rc);
2461 
2462  rc= my_process_stmt_result(stmt);
2463  DIE_UNLESS(rc == 1);
2464 
2465  strmov(szData, (char *)"venu");
2466  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2467  my_bind[0].buffer= (void *)szData;
2468  my_bind[0].buffer_length= 10;
2469  my_bind[0].length= &length[0];
2470  length[0]= 4;
2471  my_bind[0].is_null= 0;
2472 
2473  rc= mysql_stmt_bind_param(stmt, my_bind);
2474  check_execute(stmt, rc);
2475 
2476  rc= mysql_stmt_execute(stmt);
2477  check_execute(stmt, rc);
2478 
2479  rc= my_process_stmt_result(stmt);
2480  DIE_UNLESS(rc == 0);
2481 
2482  strmov(szData, (char *)"abc");
2483  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2484  my_bind[0].buffer= (void *)szData;
2485  my_bind[0].buffer_length= 10;
2486  my_bind[0].length= &length[0];
2487  length[0]= 3;
2488  my_bind[0].is_null= 0;
2489 
2490  rc= mysql_stmt_bind_param(stmt, my_bind);
2491  check_execute(stmt, rc);
2492 
2493  rc= mysql_stmt_execute(stmt);
2494  check_execute(stmt, rc);
2495 
2496  rc= my_process_stmt_result(stmt);
2497  DIE_UNLESS(rc == 1);
2498 
2499  mysql_stmt_close(stmt);
2500 }
2501 
2502 
2503 /* Test BUG#1180 (optimized away part of WHERE clause) */
2504 
2505 static void test_bug1180()
2506 {
2507  MYSQL_STMT *stmt;
2508  int rc;
2509  MYSQL_BIND my_bind[1];
2510  ulong length[1];
2511  char szData[11];
2512  char query[MAX_TEST_QUERY_LENGTH];
2513 
2514  myheader("test_select_bug");
2515 
2516  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2517  myquery(rc);
2518 
2519  rc= mysql_query(mysql, "CREATE TABLE test_select(session_id char(9) NOT NULL)");
2520  myquery(rc);
2521  rc= mysql_query(mysql, "INSERT INTO test_select VALUES (\"abc\")");
2522  myquery(rc);
2523 
2524  strmov(query, "SELECT * FROM test_select WHERE ?= \"1111\" and "
2525  "session_id= \"abc\"");
2526  stmt= mysql_simple_prepare(mysql, query);
2527  check_stmt(stmt);
2528 
2529  verify_param_count(stmt, 1);
2530 
2531  /* Always memset all members of bind parameter */
2532  memset(my_bind, 0, sizeof(my_bind));
2533 
2534  strmov(szData, (char *)"abc");
2535  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2536  my_bind[0].buffer= (void *)szData;
2537  my_bind[0].buffer_length= 10;
2538  my_bind[0].length= &length[0];
2539  length[0]= 3;
2540  my_bind[0].is_null= 0;
2541 
2542  rc= mysql_stmt_bind_param(stmt, my_bind);
2543  check_execute(stmt, rc);
2544 
2545  rc= mysql_stmt_execute(stmt);
2546  check_execute(stmt, rc);
2547 
2548  rc= my_process_stmt_result(stmt);
2549  DIE_UNLESS(rc == 0);
2550 
2551  strmov(szData, (char *)"1111");
2552  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2553  my_bind[0].buffer= (void *)szData;
2554  my_bind[0].buffer_length= 10;
2555  my_bind[0].length= &length[0];
2556  length[0]= 4;
2557  my_bind[0].is_null= 0;
2558 
2559  rc= mysql_stmt_bind_param(stmt, my_bind);
2560  check_execute(stmt, rc);
2561 
2562  rc= mysql_stmt_execute(stmt);
2563  check_execute(stmt, rc);
2564 
2565  rc= my_process_stmt_result(stmt);
2566  DIE_UNLESS(rc == 1);
2567 
2568  strmov(szData, (char *)"abc");
2569  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2570  my_bind[0].buffer= (void *)szData;
2571  my_bind[0].buffer_length= 10;
2572  my_bind[0].length= &length[0];
2573  length[0]= 3;
2574  my_bind[0].is_null= 0;
2575 
2576  rc= mysql_stmt_bind_param(stmt, my_bind);
2577  check_execute(stmt, rc);
2578 
2579  rc= mysql_stmt_execute(stmt);
2580  check_execute(stmt, rc);
2581 
2582  rc= my_process_stmt_result(stmt);
2583  DIE_UNLESS(rc == 0);
2584 
2585  mysql_stmt_close(stmt);
2586 }
2587 
2588 
2589 /*
2590  Test BUG#1644 (Insertion of more than 3 NULL columns with parameter
2591  binding fails)
2592 */
2593 
2594 static void test_bug1644()
2595 {
2596  MYSQL_STMT *stmt;
2597  MYSQL_RES *result;
2598  MYSQL_ROW row;
2599  MYSQL_BIND my_bind[4];
2600  int num;
2601  my_bool isnull;
2602  int rc, i;
2603  char query[MAX_TEST_QUERY_LENGTH];
2604 
2605  myheader("test_bug1644");
2606 
2607  rc= mysql_query(mysql, "DROP TABLE IF EXISTS foo_dfr");
2608  myquery(rc);
2609 
2610  rc= mysql_query(mysql,
2611  "CREATE TABLE foo_dfr(col1 int, col2 int, col3 int, col4 int);");
2612  myquery(rc);
2613 
2614  strmov(query, "INSERT INTO foo_dfr VALUES (?, ?, ?, ? )");
2615  stmt= mysql_simple_prepare(mysql, query);
2616  check_stmt(stmt);
2617 
2618  verify_param_count(stmt, 4);
2619 
2620  /* Always memset all members of bind parameter */
2621  memset(my_bind, 0, sizeof(my_bind));
2622 
2623  num= 22;
2624  isnull= 0;
2625  for (i= 0 ; i < 4 ; i++)
2626  {
2627  my_bind[i].buffer_type= MYSQL_TYPE_LONG;
2628  my_bind[i].buffer= (void *)&num;
2629  my_bind[i].is_null= &isnull;
2630  }
2631 
2632  rc= mysql_stmt_bind_param(stmt, my_bind);
2633  check_execute(stmt, rc);
2634 
2635  rc= mysql_stmt_execute(stmt);
2636  check_execute(stmt, rc);
2637 
2638  isnull= 1;
2639  for (i= 0 ; i < 4 ; i++)
2640  my_bind[i].is_null= &isnull;
2641 
2642  rc= mysql_stmt_bind_param(stmt, my_bind);
2643  check_execute(stmt, rc);
2644 
2645  rc= mysql_stmt_execute(stmt);
2646  check_execute(stmt, rc);
2647 
2648  isnull= 0;
2649  num= 88;
2650  for (i= 0 ; i < 4 ; i++)
2651  my_bind[i].is_null= &isnull;
2652 
2653  rc= mysql_stmt_bind_param(stmt, my_bind);
2654  check_execute(stmt, rc);
2655 
2656  rc= mysql_stmt_execute(stmt);
2657  check_execute(stmt, rc);
2658 
2659  mysql_stmt_close(stmt);
2660 
2661  rc= mysql_query(mysql, "SELECT * FROM foo_dfr");
2662  myquery(rc);
2663 
2664  result= mysql_store_result(mysql);
2665  mytest(result);
2666 
2667  rc= my_process_result_set(result);
2668  DIE_UNLESS(rc == 3);
2669 
2670  mysql_data_seek(result, 0);
2671 
2672  row= mysql_fetch_row(result);
2673  mytest(row);
2674  for (i= 0 ; i < 4 ; i++)
2675  {
2676  DIE_UNLESS(strcmp(row[i], "22") == 0);
2677  }
2678  row= mysql_fetch_row(result);
2679  mytest(row);
2680  for (i= 0 ; i < 4 ; i++)
2681  {
2682  DIE_UNLESS(row[i] == 0);
2683  }
2684  row= mysql_fetch_row(result);
2685  mytest(row);
2686  for (i= 0 ; i < 4 ; i++)
2687  {
2688  DIE_UNLESS(strcmp(row[i], "88") == 0);
2689  }
2690  row= mysql_fetch_row(result);
2691  mytest_r(row);
2692 
2693  mysql_free_result(result);
2694 }
2695 
2696 
2697 /* Test simple select show */
2698 
2699 static void test_select_show()
2700 {
2701  MYSQL_STMT *stmt;
2702  int rc;
2703  char query[MAX_TEST_QUERY_LENGTH];
2704 
2705  myheader("test_select_show");
2706 
2707  mysql_autocommit(mysql, TRUE);
2708 
2709  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_show");
2710  myquery(rc);
2711 
2712  rc= mysql_query(mysql, "CREATE TABLE test_show(id int(4) NOT NULL primary "
2713  " key, name char(2))");
2714  myquery(rc);
2715 
2716  stmt= mysql_simple_prepare(mysql, "show columns from test_show");
2717  check_stmt(stmt);
2718 
2719  verify_param_count(stmt, 0);
2720 
2721  rc= mysql_stmt_execute(stmt);
2722  check_execute(stmt, rc);
2723 
2724  my_process_stmt_result(stmt);
2725  mysql_stmt_close(stmt);
2726 
2727  stmt= mysql_simple_prepare(mysql, "show tables from mysql like ?");
2728  check_stmt_r(stmt);
2729 
2730  strxmov(query, "show tables from ", current_db, " like \'test_show\'", NullS);
2731  stmt= mysql_simple_prepare(mysql, query);
2732  check_stmt(stmt);
2733 
2734  rc= mysql_stmt_execute(stmt);
2735  check_execute(stmt, rc);
2736 
2737  my_process_stmt_result(stmt);
2738  mysql_stmt_close(stmt);
2739 
2740  stmt= mysql_simple_prepare(mysql, "describe test_show");
2741  check_stmt(stmt);
2742 
2743  rc= mysql_stmt_execute(stmt);
2744  check_execute(stmt, rc);
2745 
2746  my_process_stmt_result(stmt);
2747  mysql_stmt_close(stmt);
2748 
2749  stmt= mysql_simple_prepare(mysql, "show keys from test_show");
2750  check_stmt(stmt);
2751 
2752  rc= mysql_stmt_execute(stmt);
2753  check_execute(stmt, rc);
2754 
2755  rc= my_process_stmt_result(stmt);
2756  DIE_UNLESS(rc == 1);
2757  mysql_stmt_close(stmt);
2758 }
2759 
2760 
2761 /* Test simple update */
2762 
2763 static void test_simple_update()
2764 {
2765  MYSQL_STMT *stmt;
2766  int rc;
2767  char szData[25];
2768  int nData= 1;
2769  MYSQL_RES *result;
2770  MYSQL_BIND my_bind[2];
2771  ulong length[2];
2772  char query[MAX_TEST_QUERY_LENGTH];
2773 
2774  myheader("test_simple_update");
2775 
2776  rc= mysql_autocommit(mysql, TRUE);
2777  myquery(rc);
2778 
2779  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
2780  myquery(rc);
2781 
2782  rc= mysql_query(mysql, "CREATE TABLE test_update(col1 int, "
2783  " col2 varchar(50), col3 int )");
2784  myquery(rc);
2785 
2786  rc= mysql_query(mysql, "INSERT INTO test_update VALUES(1, 'MySQL', 100)");
2787  myquery(rc);
2788 
2789  verify_affected_rows(1);
2790 
2791  rc= mysql_commit(mysql);
2792  myquery(rc);
2793 
2794  /* insert by prepare */
2795  strmov(query, "UPDATE test_update SET col2= ? WHERE col1= ?");
2796  stmt= mysql_simple_prepare(mysql, query);
2797  check_stmt(stmt);
2798 
2799  verify_param_count(stmt, 2);
2800 
2801  /* Always memset all members of bind parameter */
2802  memset(my_bind, 0, sizeof(my_bind));
2803 
2804  nData= 1;
2805  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2806  my_bind[0].buffer= szData; /* string data */
2807  my_bind[0].buffer_length= sizeof(szData);
2808  my_bind[0].length= &length[0];
2809  length[0]= sprintf(szData, "updated-data");
2810 
2811  my_bind[1].buffer= (void *) &nData;
2812  my_bind[1].buffer_type= MYSQL_TYPE_LONG;
2813 
2814  rc= mysql_stmt_bind_param(stmt, my_bind);
2815  check_execute(stmt, rc);
2816 
2817  rc= mysql_stmt_execute(stmt);
2818  check_execute(stmt, rc);
2819  verify_affected_rows(1);
2820 
2821  mysql_stmt_close(stmt);
2822 
2823  /* now fetch the results ..*/
2824  rc= mysql_commit(mysql);
2825  myquery(rc);
2826 
2827  /* test the results now, only one row should exist */
2828  rc= mysql_query(mysql, "SELECT * FROM test_update");
2829  myquery(rc);
2830 
2831  /* get the result */
2832  result= mysql_store_result(mysql);
2833  mytest(result);
2834 
2835  rc= my_process_result_set(result);
2836  DIE_UNLESS(rc == 1);
2837  mysql_free_result(result);
2838 }
2839 
2840 
2841 /* Test simple long data handling */
2842 
2843 static void test_long_data()
2844 {
2845  MYSQL_STMT *stmt;
2846  int rc, int_data;
2847  char *data= NullS;
2848  MYSQL_RES *result;
2849  MYSQL_BIND my_bind[3];
2850  char query[MAX_TEST_QUERY_LENGTH];
2851 
2852  myheader("test_long_data");
2853 
2854  rc= mysql_autocommit(mysql, TRUE);
2855  myquery(rc);
2856 
2857  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
2858  myquery(rc);
2859 
2860  rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, "
2861  " col2 long varchar, col3 long varbinary)");
2862  myquery(rc);
2863 
2864  strmov(query, "INSERT INTO test_long_data(col1, col2) VALUES(?)");
2865  stmt= mysql_simple_prepare(mysql, query);
2866  check_stmt_r(stmt);
2867 
2868  strmov(query, "INSERT INTO test_long_data(col1, col2, col3) VALUES(?, ?, ?)");
2869  stmt= mysql_simple_prepare(mysql, query);
2870  check_stmt(stmt);
2871 
2872  verify_param_count(stmt, 3);
2873 
2874  /* Always memset all members of bind parameter */
2875  memset(my_bind, 0, sizeof(my_bind));
2876 
2877  my_bind[0].buffer= (void *)&int_data;
2878  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2879 
2880  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2881 
2882  my_bind[2]= my_bind[1];
2883  rc= mysql_stmt_bind_param(stmt, my_bind);
2884  check_execute(stmt, rc);
2885 
2886  int_data= 999;
2887  data= (char *)"Michael";
2888 
2889  /* supply data in pieces */
2890  rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
2891  data= (char *)" 'Monty' Widenius";
2892  rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
2893  check_execute(stmt, rc);
2894  rc= mysql_stmt_send_long_data(stmt, 2, "Venu (venu@mysql.com)", 4);
2895  check_execute(stmt, rc);
2896 
2897  /* execute */
2898  rc= mysql_stmt_execute(stmt);
2899  if (!opt_silent)
2900  fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
2901  check_execute(stmt, rc);
2902 
2903  rc= mysql_commit(mysql);
2904  myquery(rc);
2905 
2906  /* now fetch the results ..*/
2907  rc= mysql_query(mysql, "SELECT * FROM test_long_data");
2908  myquery(rc);
2909 
2910  /* get the result */
2911  result= mysql_store_result(mysql);
2912  mytest(result);
2913 
2914  rc= my_process_result_set(result);
2915  DIE_UNLESS(rc == 1);
2916  mysql_free_result(result);
2917 
2918  verify_col_data("test_long_data", "col1", "999");
2919  verify_col_data("test_long_data", "col2", "Michael 'Monty' Widenius");
2920  verify_col_data("test_long_data", "col3", "Venu");
2921  mysql_stmt_close(stmt);
2922 }
2923 
2924 
2925 /* Test long data (string) handling */
2926 
2927 static void test_long_data_str()
2928 {
2929  MYSQL_STMT *stmt;
2930  int rc, i;
2931  char data[255];
2932  long length;
2933  ulong length1;
2934  MYSQL_RES *result;
2935  MYSQL_BIND my_bind[2];
2936  my_bool is_null[2];
2937  char query[MAX_TEST_QUERY_LENGTH];
2938 
2939  myheader("test_long_data_str");
2940 
2941  rc= mysql_autocommit(mysql, TRUE);
2942  myquery(rc);
2943 
2944  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
2945  myquery(rc);
2946 
2947  rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(id int, longstr long varchar)");
2948  myquery(rc);
2949 
2950  strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
2951  stmt= mysql_simple_prepare(mysql, query);
2952  check_stmt(stmt);
2953 
2954  verify_param_count(stmt, 2);
2955 
2956  /* Always memset all members of bind parameter */
2957  memset(my_bind, 0, sizeof(my_bind));
2958 
2959  my_bind[0].buffer= (void *)&length;
2960  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2961  my_bind[0].is_null= &is_null[0];
2962  is_null[0]= 0;
2963  length= 0;
2964 
2965  my_bind[1].buffer= data; /* string data */
2966  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2967  my_bind[1].length= &length1;
2968  my_bind[1].is_null= &is_null[1];
2969  is_null[1]= 0;
2970  rc= mysql_stmt_bind_param(stmt, my_bind);
2971  check_execute(stmt, rc);
2972 
2973  length= 40;
2974  strmov(data, "MySQL AB");
2975 
2976  /* supply data in pieces */
2977  for(i= 0; i < 4; i++)
2978  {
2979  rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 5);
2980  check_execute(stmt, rc);
2981  }
2982  /* execute */
2983  rc= mysql_stmt_execute(stmt);
2984  if (!opt_silent)
2985  fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
2986  check_execute(stmt, rc);
2987 
2988  mysql_stmt_close(stmt);
2989 
2990  rc= mysql_commit(mysql);
2991  myquery(rc);
2992 
2993  /* now fetch the results ..*/
2994  rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr FROM test_long_data_str");
2995  myquery(rc);
2996 
2997  /* get the result */
2998  result= mysql_store_result(mysql);
2999  mytest(result);
3000 
3001  rc= my_process_result_set(result);
3002  DIE_UNLESS(rc == 1);
3003  mysql_free_result(result);
3004 
3005  sprintf(data, "%d", i*5);
3006  verify_col_data("test_long_data_str", "LENGTH(longstr)", data);
3007  data[0]= '\0';
3008  while (i--)
3009  strxmov(data, data, "MySQL", NullS);
3010  verify_col_data("test_long_data_str", "longstr", data);
3011 
3012  rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3013  myquery(rc);
3014 }
3015 
3016 
3017 /* Test long data (string) handling */
3018 
3019 static void test_long_data_str1()
3020 {
3021  MYSQL_STMT *stmt;
3022  int rc, i;
3023  char data[255];
3024  long length;
3025  ulong max_blob_length, blob_length, length1;
3026  my_bool true_value;
3027  MYSQL_RES *result;
3028  MYSQL_BIND my_bind[2];
3029  MYSQL_FIELD *field;
3030  char query[MAX_TEST_QUERY_LENGTH];
3031 
3032  myheader("test_long_data_str1");
3033 
3034  rc= mysql_autocommit(mysql, TRUE);
3035  myquery(rc);
3036 
3037  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
3038  myquery(rc);
3039 
3040  rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(longstr long varchar, blb long varbinary)");
3041  myquery(rc);
3042 
3043  strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
3044  stmt= mysql_simple_prepare(mysql, query);
3045  check_stmt(stmt);
3046 
3047  verify_param_count(stmt, 2);
3048 
3049  /* Always memset all members of bind parameter */
3050  memset(my_bind, 0, sizeof(my_bind));
3051 
3052  my_bind[0].buffer= data; /* string data */
3053  my_bind[0].buffer_length= sizeof(data);
3054  my_bind[0].length= &length1;
3055  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3056  length1= 0;
3057 
3058  my_bind[1]= my_bind[0];
3059  my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3060 
3061  rc= mysql_stmt_bind_param(stmt, my_bind);
3062  check_execute(stmt, rc);
3063  length= sprintf(data, "MySQL AB");
3064 
3065  /* supply data in pieces */
3066  for (i= 0; i < 3; i++)
3067  {
3068  rc= mysql_stmt_send_long_data(stmt, 0, data, length);
3069  check_execute(stmt, rc);
3070 
3071  rc= mysql_stmt_send_long_data(stmt, 1, data, 2);
3072  check_execute(stmt, rc);
3073  }
3074 
3075  /* execute */
3076  rc= mysql_stmt_execute(stmt);
3077  if (!opt_silent)
3078  fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3079  check_execute(stmt, rc);
3080 
3081  mysql_stmt_close(stmt);
3082 
3083  rc= mysql_commit(mysql);
3084  myquery(rc);
3085 
3086  /* now fetch the results ..*/
3087  rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr, LENGTH(blb), blb FROM test_long_data_str");
3088  myquery(rc);
3089 
3090  /* get the result */
3091  result= mysql_store_result(mysql);
3092 
3093  mysql_field_seek(result, 1);
3094  field= mysql_fetch_field(result);
3095  max_blob_length= field->max_length;
3096 
3097  mytest(result);
3098 
3099  rc= my_process_result_set(result);
3100  DIE_UNLESS(rc == 1);
3101  mysql_free_result(result);
3102 
3103  sprintf(data, "%ld", (long)i*length);
3104  verify_col_data("test_long_data_str", "length(longstr)", data);
3105 
3106  sprintf(data, "%d", i*2);
3107  verify_col_data("test_long_data_str", "length(blb)", data);
3108 
3109  /* Test length of field->max_length */
3110  stmt= mysql_simple_prepare(mysql, "SELECT * from test_long_data_str");
3111  check_stmt(stmt);
3112  verify_param_count(stmt, 0);
3113 
3114  rc= mysql_stmt_execute(stmt);
3115  check_execute(stmt, rc);
3116 
3117  rc= mysql_stmt_store_result(stmt);
3118  check_execute(stmt, rc);
3119 
3120  result= mysql_stmt_result_metadata(stmt);
3121  field= mysql_fetch_fields(result);
3122 
3123  /* First test what happens if STMT_ATTR_UPDATE_MAX_LENGTH is not used */
3124  DIE_UNLESS(field->max_length == 0);
3125  mysql_free_result(result);
3126 
3127  /* Enable updating of field->max_length */
3128  true_value= 1;
3129  mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &true_value);
3130  rc= mysql_stmt_execute(stmt);
3131  check_execute(stmt, rc);
3132 
3133  rc= mysql_stmt_store_result(stmt);
3134  check_execute(stmt, rc);
3135 
3136  result= mysql_stmt_result_metadata(stmt);
3137  field= mysql_fetch_fields(result);
3138 
3139  DIE_UNLESS(field->max_length == max_blob_length);
3140 
3141  /* Fetch results into a data buffer that is smaller than data */
3142  memset(my_bind, 0, sizeof(*my_bind));
3143  my_bind[0].buffer_type= MYSQL_TYPE_BLOB;
3144  my_bind[0].buffer= (void *) &data; /* this buffer won't be altered */
3145  my_bind[0].buffer_length= 16;
3146  my_bind[0].length= &blob_length;
3147  my_bind[0].error= &my_bind[0].error_value;
3148  rc= mysql_stmt_bind_result(stmt, my_bind);
3149  data[16]= 0;
3150 
3151  rc= mysql_stmt_fetch(stmt);
3152  DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
3153  DIE_UNLESS(my_bind[0].error_value);
3154  DIE_UNLESS(strlen(data) == 16);
3155  DIE_UNLESS(blob_length == max_blob_length);
3156 
3157  /* Fetch all data */
3158  memset((my_bind+1), 0, sizeof(*my_bind));
3159  my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3160  my_bind[1].buffer= (void *) &data; /* this buffer won't be altered */
3161  my_bind[1].buffer_length= sizeof(data);
3162  my_bind[1].length= &blob_length;
3163  memset(data, 0, sizeof(data));
3164  mysql_stmt_fetch_column(stmt, my_bind+1, 0, 0);
3165  DIE_UNLESS(strlen(data) == max_blob_length);
3166 
3167  mysql_free_result(result);
3168  mysql_stmt_close(stmt);
3169 
3170  /* Drop created table */
3171  rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3172  myquery(rc);
3173 }
3174 
3175 
3176 /* Test long data (binary) handling */
3177 
3178 static void test_long_data_bin()
3179 {
3180  MYSQL_STMT *stmt;
3181  int rc;
3182  char data[255];
3183  long length;
3184  MYSQL_RES *result;
3185  MYSQL_BIND my_bind[2];
3186  char query[MAX_TEST_QUERY_LENGTH];
3187 
3188 
3189  myheader("test_long_data_bin");
3190 
3191  rc= mysql_autocommit(mysql, TRUE);
3192  myquery(rc);
3193 
3194  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_bin");
3195  myquery(rc);
3196 
3197  rc= mysql_query(mysql, "CREATE TABLE test_long_data_bin(id int, longbin long varbinary)");
3198  myquery(rc);
3199 
3200  strmov(query, "INSERT INTO test_long_data_bin VALUES(?, ?)");
3201  stmt= mysql_simple_prepare(mysql, query);
3202  check_stmt(stmt);
3203 
3204  verify_param_count(stmt, 2);
3205 
3206  /* Always memset all members of bind parameter */
3207  memset(my_bind, 0, sizeof(my_bind));
3208 
3209  my_bind[0].buffer= (void *)&length;
3210  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3211  length= 0;
3212 
3213  my_bind[1].buffer= data; /* string data */
3214  my_bind[1].buffer_type= MYSQL_TYPE_LONG_BLOB;
3215  rc= mysql_stmt_bind_param(stmt, my_bind);
3216  check_execute(stmt, rc);
3217 
3218  length= 10;
3219  strmov(data, "MySQL AB");
3220 
3221  /* supply data in pieces */
3222  {
3223  int i;
3224  for (i= 0; i < 100; i++)
3225  {
3226  rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 4);
3227  check_execute(stmt, rc);
3228  }
3229  }
3230  /* execute */
3231  rc= mysql_stmt_execute(stmt);
3232  if (!opt_silent)
3233  fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3234  check_execute(stmt, rc);
3235 
3236  mysql_stmt_close(stmt);
3237 
3238  rc= mysql_commit(mysql);
3239  myquery(rc);
3240 
3241  /* now fetch the results ..*/
3242  rc= mysql_query(mysql, "SELECT LENGTH(longbin), longbin FROM test_long_data_bin");
3243  myquery(rc);
3244 
3245  /* get the result */
3246  result= mysql_store_result(mysql);
3247  mytest(result);
3248 
3249  rc= my_process_result_set(result);
3250  DIE_UNLESS(rc == 1);
3251  mysql_free_result(result);
3252 }
3253 
3254 
3255 /* Test simple delete */
3256 
3257 static void test_simple_delete()
3258 {
3259  MYSQL_STMT *stmt;
3260  int rc;
3261  char szData[30]= {0};
3262  int nData= 1;
3263  MYSQL_RES *result;
3264  MYSQL_BIND my_bind[2];
3265  ulong length[2];
3266  char query[MAX_TEST_QUERY_LENGTH];
3267 
3268  myheader("test_simple_delete");
3269 
3270  rc= mysql_autocommit(mysql, TRUE);
3271  myquery(rc);
3272 
3273  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_simple_delete");
3274  myquery(rc);
3275 
3276  rc= mysql_query(mysql, "CREATE TABLE test_simple_delete(col1 int, \
3277  col2 varchar(50), col3 int )");
3278  myquery(rc);
3279 
3280  rc= mysql_query(mysql, "INSERT INTO test_simple_delete VALUES(1, 'MySQL', 100)");
3281  myquery(rc);
3282 
3283  verify_affected_rows(1);
3284 
3285  rc= mysql_commit(mysql);
3286  myquery(rc);
3287 
3288  /* insert by prepare */
3289  strmov(query, "DELETE FROM test_simple_delete WHERE col1= ? AND "
3290  "CONVERT(col2 USING utf8)= ? AND col3= 100");
3291  stmt= mysql_simple_prepare(mysql, query);
3292  check_stmt(stmt);
3293 
3294  verify_param_count(stmt, 2);
3295 
3296  /* Always memset all members of bind parameter */
3297  memset(my_bind, 0, sizeof(my_bind));
3298 
3299  nData= 1;
3300  strmov(szData, "MySQL");
3301  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3302  my_bind[1].buffer= szData; /* string data */
3303  my_bind[1].buffer_length= sizeof(szData);
3304  my_bind[1].length= &length[1];
3305  length[1]= 5;
3306 
3307  my_bind[0].buffer= (void *)&nData;
3308  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3309 
3310  rc= mysql_stmt_bind_param(stmt, my_bind);
3311  check_execute(stmt, rc);
3312 
3313  rc= mysql_stmt_execute(stmt);
3314  check_execute(stmt, rc);
3315 
3316  verify_affected_rows(1);
3317 
3318  mysql_stmt_close(stmt);
3319 
3320  /* now fetch the results ..*/
3321  rc= mysql_commit(mysql);
3322  myquery(rc);
3323 
3324  /* test the results now, only one row should exist */
3325  rc= mysql_query(mysql, "SELECT * FROM test_simple_delete");
3326  myquery(rc);
3327 
3328  /* get the result */
3329  result= mysql_store_result(mysql);
3330  mytest(result);
3331 
3332  rc= my_process_result_set(result);
3333  DIE_UNLESS(rc == 0);
3334  mysql_free_result(result);
3335 }
3336 
3337 
3338 /* Test simple update */
3339 
3340 static void test_update()
3341 {
3342  MYSQL_STMT *stmt;
3343  int rc;
3344  char szData[25];
3345  int nData= 1;
3346  MYSQL_RES *result;
3347  MYSQL_BIND my_bind[2];
3348  ulong length[2];
3349  char query[MAX_TEST_QUERY_LENGTH];
3350 
3351  myheader("test_update");
3352 
3353  rc= mysql_autocommit(mysql, TRUE);
3354  myquery(rc);
3355 
3356  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
3357  myquery(rc);
3358 
3359  rc= mysql_query(mysql, "CREATE TABLE test_update("
3360  "col1 int primary key auto_increment, "
3361  "col2 varchar(50), col3 int )");
3362  myquery(rc);
3363 
3364  strmov(query, "INSERT INTO test_update(col2, col3) VALUES(?, ?)");
3365  stmt= mysql_simple_prepare(mysql, query);
3366  check_stmt(stmt);
3367 
3368  verify_param_count(stmt, 2);
3369 
3370  /* Always memset all members of bind parameter */
3371  memset(my_bind, 0, sizeof(my_bind));
3372 
3373  /* string data */
3374  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3375  my_bind[0].buffer= szData;
3376  my_bind[0].buffer_length= sizeof(szData);
3377  my_bind[0].length= &length[0];
3378  length[0]= sprintf(szData, "inserted-data");
3379 
3380  my_bind[1].buffer= (void *)&nData;
3381  my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3382 
3383  rc= mysql_stmt_bind_param(stmt, my_bind);
3384  check_execute(stmt, rc);
3385 
3386  nData= 100;
3387  rc= mysql_stmt_execute(stmt);
3388  check_execute(stmt, rc);
3389 
3390  verify_affected_rows(1);
3391  mysql_stmt_close(stmt);
3392 
3393  strmov(query, "UPDATE test_update SET col2= ? WHERE col3= ?");
3394  stmt= mysql_simple_prepare(mysql, query);
3395  check_stmt(stmt);
3396 
3397  verify_param_count(stmt, 2);
3398  nData= 100;
3399 
3400  /* Always memset all members of bind parameter */
3401  memset(my_bind, 0, sizeof(my_bind));
3402 
3403  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3404  my_bind[0].buffer= szData;
3405  my_bind[0].buffer_length= sizeof(szData);
3406  my_bind[0].length= &length[0];
3407  length[0]= sprintf(szData, "updated-data");
3408 
3409  my_bind[1].buffer= (void *)&nData;
3410  my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3411 
3412  rc= mysql_stmt_bind_param(stmt, my_bind);
3413  check_execute(stmt, rc);
3414 
3415  rc= mysql_stmt_execute(stmt);
3416  check_execute(stmt, rc);
3417  verify_affected_rows(1);
3418 
3419  mysql_stmt_close(stmt);
3420 
3421  /* now fetch the results ..*/
3422  rc= mysql_commit(mysql);
3423  myquery(rc);
3424 
3425  /* test the results now, only one row should exist */
3426  rc= mysql_query(mysql, "SELECT * FROM test_update");
3427  myquery(rc);
3428 
3429  /* get the result */
3430  result= mysql_store_result(mysql);
3431  mytest(result);
3432 
3433  rc= my_process_result_set(result);
3434  DIE_UNLESS(rc == 1);
3435  mysql_free_result(result);
3436 }
3437 
3438 
3439 /* Test prepare without parameters */
3440 
3441 static void test_prepare_noparam()
3442 {
3443  MYSQL_STMT *stmt;
3444  int rc;
3445  MYSQL_RES *result;
3446  char query[MAX_TEST_QUERY_LENGTH];
3447 
3448  myheader("test_prepare_noparam");
3449 
3450  rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
3451  myquery(rc);
3452 
3453 
3454  rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 int, col2 varchar(50))");
3455  myquery(rc);
3456 
3457  /* insert by prepare */
3458  strmov(query, "INSERT INTO my_prepare VALUES(10, 'venu')");
3459  stmt= mysql_simple_prepare(mysql, query);
3460  check_stmt(stmt);
3461 
3462  verify_param_count(stmt, 0);
3463 
3464  rc= mysql_stmt_execute(stmt);
3465  check_execute(stmt, rc);
3466 
3467  mysql_stmt_close(stmt);
3468 
3469  /* now fetch the results ..*/
3470  rc= mysql_commit(mysql);
3471  myquery(rc);
3472 
3473  /* test the results now, only one row should exist */
3474  rc= mysql_query(mysql, "SELECT * FROM my_prepare");
3475  myquery(rc);
3476 
3477  /* get the result */
3478  result= mysql_store_result(mysql);
3479  mytest(result);
3480 
3481  rc= my_process_result_set(result);
3482  DIE_UNLESS(rc == 1);
3483  mysql_free_result(result);
3484 }
3485 
3486 
3487 /* Test simple bind result */
3488 
3489 static void test_bind_result()
3490 {
3491  MYSQL_STMT *stmt;
3492  int rc;
3493  int nData;
3494  ulong length1;
3495  char szData[100];
3496  MYSQL_BIND my_bind[2];
3497  my_bool is_null[2];
3498 
3499  myheader("test_bind_result");
3500 
3501  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3502  myquery(rc);
3503 
3504  rc= mysql_query(mysql, "CREATE TABLE test_bind_result(col1 int , col2 varchar(50))");
3505  myquery(rc);
3506 
3507  rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(10, 'venu')");
3508  myquery(rc);
3509 
3510  rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(20, 'MySQL')");
3511  myquery(rc);
3512 
3513  rc= mysql_query(mysql, "INSERT INTO test_bind_result(col2) VALUES('monty')");
3514  myquery(rc);
3515 
3516  rc= mysql_commit(mysql);
3517  myquery(rc);
3518 
3519  /* fetch */
3520 
3521  memset(my_bind, 0, sizeof(my_bind));
3522  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3523  my_bind[0].buffer= (void *) &nData; /* integer data */
3524  my_bind[0].is_null= &is_null[0];
3525 
3526  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3527  my_bind[1].buffer= szData; /* string data */
3528  my_bind[1].buffer_length= sizeof(szData);
3529  my_bind[1].length= &length1;
3530  my_bind[1].is_null= &is_null[1];
3531 
3532  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
3533  check_stmt(stmt);
3534 
3535  rc= mysql_stmt_bind_result(stmt, my_bind);
3536  check_execute(stmt, rc);
3537 
3538  rc= mysql_stmt_execute(stmt);
3539  check_execute(stmt, rc);
3540 
3541  rc= mysql_stmt_fetch(stmt);
3542  check_execute(stmt, rc);
3543 
3544  if (!opt_silent)
3545  fprintf(stdout, "\n row 1: %d, %s(%lu)", nData, szData, length1);
3546  DIE_UNLESS(nData == 10);
3547  DIE_UNLESS(strcmp(szData, "venu") == 0);
3548  DIE_UNLESS(length1 == 4);
3549 
3550  rc= mysql_stmt_fetch(stmt);
3551  check_execute(stmt, rc);
3552 
3553  if (!opt_silent)
3554  fprintf(stdout, "\n row 2: %d, %s(%lu)", nData, szData, length1);
3555  DIE_UNLESS(nData == 20);
3556  DIE_UNLESS(strcmp(szData, "MySQL") == 0);
3557  DIE_UNLESS(length1 == 5);
3558 
3559  rc= mysql_stmt_fetch(stmt);
3560  check_execute(stmt, rc);
3561 
3562  if (!opt_silent && is_null[0])
3563  fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
3564  DIE_UNLESS(is_null[0]);
3565  DIE_UNLESS(strcmp(szData, "monty") == 0);
3566  DIE_UNLESS(length1 == 5);
3567 
3568  rc= mysql_stmt_fetch(stmt);
3569  DIE_UNLESS(rc == MYSQL_NO_DATA);
3570 
3571  mysql_stmt_close(stmt);
3572 }
3573 
3574 
3575 /* Test ext bind result */
3576 
3577 static void test_bind_result_ext()
3578 {
3579  MYSQL_STMT *stmt;
3580  int rc, i;
3581  uchar t_data;
3582  short s_data;
3583  int i_data;
3584  longlong b_data;
3585  float f_data;
3586  double d_data;
3587  char szData[20], bData[20];
3588  ulong szLength, bLength;
3589  MYSQL_BIND my_bind[8];
3590  ulong length[8];
3591  my_bool is_null[8];
3592  char llbuf[22];
3593  myheader("test_bind_result_ext");
3594 
3595  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3596  myquery(rc);
3597 
3598  rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, "
3599  " c2 smallint, "
3600  " c3 int, c4 bigint, "
3601  " c5 float, c6 double, "
3602  " c7 varbinary(10), "
3603  " c8 varchar(50))");
3604  myquery(rc);
3605 
3606  rc= mysql_query(mysql, "INSERT INTO test_bind_result "
3607  "VALUES (19, 2999, 3999, 4999999, "
3608  " 2345.6, 5678.89563, 'venu', 'mysql')");
3609  myquery(rc);
3610 
3611  rc= mysql_commit(mysql);
3612  myquery(rc);
3613 
3614  memset(my_bind, 0, sizeof(my_bind));
3615  for (i= 0; i < (int) array_elements(my_bind); i++)
3616  {
3617  my_bind[i].length= &length[i];
3618  my_bind[i].is_null= &is_null[i];
3619  }
3620 
3621  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
3622  my_bind[0].buffer= (void *)&t_data;
3623 
3624  my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
3625  my_bind[2].buffer_type= MYSQL_TYPE_LONG;
3626 
3627  my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
3628  my_bind[1].buffer= (void *)&s_data;
3629 
3630  my_bind[2].buffer= (void *)&i_data;
3631  my_bind[3].buffer= (void *)&b_data;
3632 
3633  my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
3634  my_bind[4].buffer= (void *)&f_data;
3635 
3636  my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
3637  my_bind[5].buffer= (void *)&d_data;
3638 
3639  my_bind[6].buffer_type= MYSQL_TYPE_STRING;
3640  my_bind[6].buffer= (void *)szData;
3641  my_bind[6].buffer_length= sizeof(szData);
3642  my_bind[6].length= &szLength;
3643 
3644  my_bind[7].buffer_type= MYSQL_TYPE_TINY_BLOB;
3645  my_bind[7].buffer= (void *)&bData;
3646  my_bind[7].length= &bLength;
3647  my_bind[7].buffer_length= sizeof(bData);
3648 
3649  stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3650  check_stmt(stmt);
3651 
3652  rc= mysql_stmt_bind_result(stmt, my_bind);
3653  check_execute(stmt, rc);
3654 
3655  rc= mysql_stmt_execute(stmt);
3656  check_execute(stmt, rc);
3657 
3658  rc= mysql_stmt_fetch(stmt);
3659  check_execute(stmt, rc);
3660 
3661  if (!opt_silent)
3662  {
3663  fprintf(stdout, "\n data (tiny) : %d", t_data);
3664  fprintf(stdout, "\n data (short) : %d", s_data);
3665  fprintf(stdout, "\n data (int) : %d", i_data);
3666  fprintf(stdout, "\n data (big) : %s", llstr(b_data, llbuf));
3667 
3668  fprintf(stdout, "\n data (float) : %f", f_data);
3669  fprintf(stdout, "\n data (double) : %f", d_data);
3670 
3671  fprintf(stdout, "\n data (str) : %s(%lu)", szData, szLength);
3672 
3673  bData[bLength]= '\0'; /* bData is binary */
3674  fprintf(stdout, "\n data (bin) : %s(%lu)", bData, bLength);
3675  }
3676 
3677  DIE_UNLESS(t_data == 19);
3678  DIE_UNLESS(s_data == 2999);
3679  DIE_UNLESS(i_data == 3999);
3680  DIE_UNLESS(b_data == 4999999);
3681  /*DIE_UNLESS(f_data == 2345.60);*/
3682  /*DIE_UNLESS(d_data == 5678.89563);*/
3683  DIE_UNLESS(strcmp(szData, "venu") == 0);
3684  DIE_UNLESS(strncmp(bData, "mysql", 5) == 0);
3685  DIE_UNLESS(szLength == 4);
3686  DIE_UNLESS(bLength == 5);
3687 
3688  rc= mysql_stmt_fetch(stmt);
3689  DIE_UNLESS(rc == MYSQL_NO_DATA);
3690 
3691  mysql_stmt_close(stmt);
3692 }
3693 
3694 
3695 /* Test ext bind result */
3696 
3697 static void test_bind_result_ext1()
3698 {
3699  MYSQL_STMT *stmt;
3700  uint i;
3701  int rc;
3702  char t_data[20];
3703  float s_data;
3704  short i_data;
3705  uchar b_data;
3706  int f_data;
3707  long bData;
3708  char d_data[20];
3709  double szData;
3710  MYSQL_BIND my_bind[8];
3711  ulong length[8];
3712  my_bool is_null[8];
3713  myheader("test_bind_result_ext1");
3714 
3715  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3716  myquery(rc);
3717 
3718  rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, \
3719  c3 int, c4 bigint, \
3720  c5 float, c6 double, \
3721  c7 varbinary(10), \
3722  c8 varchar(10))");
3723  myquery(rc);
3724 
3725  rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(120, 2999, 3999, 54, \
3726  2.6, 58.89, \
3727  '206', '6.7')");
3728  myquery(rc);
3729 
3730  rc= mysql_commit(mysql);
3731  myquery(rc);
3732 
3733  memset(my_bind, 0, sizeof(my_bind));
3734  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3735  my_bind[0].buffer= (void *) t_data;
3736  my_bind[0].buffer_length= sizeof(t_data);
3737  my_bind[0].error= &my_bind[0].error_value;
3738 
3739  my_bind[1].buffer_type= MYSQL_TYPE_FLOAT;
3740  my_bind[1].buffer= (void *)&s_data;
3741  my_bind[1].buffer_length= 0;
3742  my_bind[1].error= &my_bind[1].error_value;
3743 
3744  my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
3745  my_bind[2].buffer= (void *)&i_data;
3746  my_bind[2].buffer_length= 0;
3747  my_bind[2].error= &my_bind[2].error_value;
3748 
3749  my_bind[3].buffer_type= MYSQL_TYPE_TINY;
3750  my_bind[3].buffer= (void *)&b_data;
3751  my_bind[3].buffer_length= 0;
3752  my_bind[3].error= &my_bind[3].error_value;
3753 
3754  my_bind[4].buffer_type= MYSQL_TYPE_LONG;
3755  my_bind[4].buffer= (void *)&f_data;
3756  my_bind[4].buffer_length= 0;
3757  my_bind[4].error= &my_bind[4].error_value;
3758 
3759  my_bind[5].buffer_type= MYSQL_TYPE_STRING;
3760  my_bind[5].buffer= (void *)d_data;
3761  my_bind[5].buffer_length= sizeof(d_data);
3762  my_bind[5].error= &my_bind[5].error_value;
3763 
3764  my_bind[6].buffer_type= MYSQL_TYPE_LONG;
3765  my_bind[6].buffer= (void *)&bData;
3766  my_bind[6].buffer_length= 0;
3767  my_bind[6].error= &my_bind[6].error_value;
3768 
3769  my_bind[7].buffer_type= MYSQL_TYPE_DOUBLE;
3770  my_bind[7].buffer= (void *)&szData;
3771  my_bind[7].buffer_length= 0;
3772  my_bind[7].error= &my_bind[7].error_value;
3773 
3774  for (i= 0; i < array_elements(my_bind); i++)
3775  {
3776  my_bind[i].is_null= &is_null[i];
3777  my_bind[i].length= &length[i];
3778  }
3779 
3780  stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3781  check_stmt(stmt);
3782 
3783  rc= mysql_stmt_bind_result(stmt, my_bind);
3784  check_execute(stmt, rc);
3785 
3786  rc= mysql_stmt_execute(stmt);
3787  check_execute(stmt, rc);
3788 
3789  rc= mysql_stmt_fetch(stmt);
3790  printf("rc=%d\n", rc);
3791  DIE_UNLESS(rc == 0);
3792 
3793  if (!opt_silent)
3794  {
3795  fprintf(stdout, "\n data (tiny) : %s(%lu)", t_data, length[0]);
3796  fprintf(stdout, "\n data (short) : %f(%lu)", s_data, length[1]);
3797  fprintf(stdout, "\n data (int) : %d(%lu)", i_data, length[2]);
3798  fprintf(stdout, "\n data (big) : %d(%lu)", b_data, length[3]);
3799 
3800  fprintf(stdout, "\n data (float) : %d(%lu)", f_data, length[4]);
3801  fprintf(stdout, "\n data (double) : %s(%lu)", d_data, length[5]);
3802 
3803  fprintf(stdout, "\n data (bin) : %ld(%lu)", bData, length[6]);
3804  fprintf(stdout, "\n data (str) : %g(%lu)", szData, length[7]);
3805  }
3806 
3807  DIE_UNLESS(strcmp(t_data, "120") == 0);
3808  DIE_UNLESS(i_data == 3999);
3809  DIE_UNLESS(f_data == 2);
3810  DIE_UNLESS(strcmp(d_data, "58.89") == 0);
3811  DIE_UNLESS(b_data == 54);
3812 
3813  DIE_UNLESS(length[0] == 3);
3814  DIE_UNLESS(length[1] == 4);
3815  DIE_UNLESS(length[2] == 2);
3816  DIE_UNLESS(length[3] == 1);
3817  DIE_UNLESS(length[4] == 4);
3818  DIE_UNLESS(length[5] == 5);
3819  DIE_UNLESS(length[6] == 4);
3820  DIE_UNLESS(length[7] == 8);
3821 
3822  rc= mysql_stmt_fetch(stmt);
3823  DIE_UNLESS(rc == MYSQL_NO_DATA);
3824 
3825  mysql_stmt_close(stmt);
3826 }
3827 
3828 
3829 /* Generalized fetch conversion routine for all basic types */
3830 
3831 static void bind_fetch(int row_count)
3832 {
3833  MYSQL_STMT *stmt;
3834  int rc, i, count= row_count;
3835  int32 data[10];
3836  int8 i8_data;
3837  int16 i16_data;
3838  int32 i32_data;
3839  longlong i64_data;
3840  float f_data;
3841  double d_data;
3842  char s_data[10];
3843  ulong length[10];
3844  MYSQL_BIND my_bind[7];
3845  my_bool is_null[7];
3846 
3847  stmt= mysql_simple_prepare(mysql, "INSERT INTO test_bind_fetch VALUES "
3848  "(?, ?, ?, ?, ?, ?, ?)");
3849  check_stmt(stmt);
3850 
3851  verify_param_count(stmt, 7);
3852 
3853  /* Always memset all members of bind parameter */
3854  memset(my_bind, 0, sizeof(my_bind));
3855 
3856  for (i= 0; i < (int) array_elements(my_bind); i++)
3857  {
3858  my_bind[i].buffer_type= MYSQL_TYPE_LONG;
3859  my_bind[i].buffer= (void *) &data[i];
3860  }
3861  rc= mysql_stmt_bind_param(stmt, my_bind);
3862  check_execute(stmt, rc);
3863 
3864  while (count--)
3865  {
3866  rc= 10+count;
3867  for (i= 0; i < (int) array_elements(my_bind); i++)
3868  {
3869  data[i]= rc+i;
3870  rc+= 12;
3871  }
3872  rc= mysql_stmt_execute(stmt);
3873  check_execute(stmt, rc);
3874  }
3875 
3876  rc= mysql_commit(mysql);
3877  myquery(rc);
3878 
3879  mysql_stmt_close(stmt);
3880 
3881  rc= my_stmt_result("SELECT * FROM test_bind_fetch");
3882  DIE_UNLESS(row_count == rc);
3883 
3884  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_fetch");
3885  check_stmt(stmt);
3886 
3887  for (i= 0; i < (int) array_elements(my_bind); i++)
3888  {
3889  my_bind[i].buffer= (void *) &data[i];
3890  my_bind[i].length= &length[i];
3891  my_bind[i].is_null= &is_null[i];
3892  }
3893 
3894  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
3895  my_bind[0].buffer= (void *)&i8_data;
3896 
3897  my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
3898  my_bind[1].buffer= (void *)&i16_data;
3899 
3900  my_bind[2].buffer_type= MYSQL_TYPE_LONG;
3901  my_bind[2].buffer= (void *)&i32_data;
3902 
3903  my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
3904  my_bind[3].buffer= (void *)&i64_data;
3905 
3906  my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
3907  my_bind[4].buffer= (void *)&f_data;
3908 
3909  my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
3910  my_bind[5].buffer= (void *)&d_data;
3911 
3912  my_bind[6].buffer_type= MYSQL_TYPE_STRING;
3913  my_bind[6].buffer= (void *)&s_data;
3914  my_bind[6].buffer_length= sizeof(s_data);
3915 
3916  rc= mysql_stmt_bind_result(stmt, my_bind);
3917  check_execute(stmt, rc);
3918 
3919  rc= mysql_stmt_execute(stmt);
3920  check_execute(stmt, rc);
3921 
3922  rc= mysql_stmt_store_result(stmt);
3923  check_execute(stmt, rc);
3924 
3925  while (row_count--)
3926  {
3927  rc= mysql_stmt_fetch(stmt);
3928  check_execute(stmt, rc);
3929 
3930  if (!opt_silent)
3931  {
3932  fprintf(stdout, "\n");
3933  fprintf(stdout, "\n tiny : %ld(%lu)", (ulong) i8_data, length[0]);
3934  fprintf(stdout, "\n short : %ld(%lu)", (ulong) i16_data, length[1]);
3935  fprintf(stdout, "\n int : %ld(%lu)", (ulong) i32_data, length[2]);
3936  fprintf(stdout, "\n longlong : %ld(%lu)", (ulong) i64_data, length[3]);
3937  fprintf(stdout, "\n float : %f(%lu)", f_data, length[4]);
3938  fprintf(stdout, "\n double : %g(%lu)", d_data, length[5]);
3939  fprintf(stdout, "\n char : %s(%lu)", s_data, length[6]);
3940  }
3941  rc= 10+row_count;
3942 
3943  /* TINY */
3944  DIE_UNLESS((int) i8_data == rc);
3945  DIE_UNLESS(length[0] == 1);
3946  rc+= 13;
3947 
3948  /* SHORT */
3949  DIE_UNLESS((int) i16_data == rc);
3950  DIE_UNLESS(length[1] == 2);
3951  rc+= 13;
3952 
3953  /* LONG */
3954  DIE_UNLESS((int) i32_data == rc);
3955  DIE_UNLESS(length[2] == 4);
3956  rc+= 13;
3957 
3958  /* LONGLONG */
3959  DIE_UNLESS((int) i64_data == rc);
3960  DIE_UNLESS(length[3] == 8);
3961  rc+= 13;
3962 
3963  /* FLOAT */
3964  DIE_UNLESS((int)f_data == rc);
3965  DIE_UNLESS(length[4] == 4);
3966  rc+= 13;
3967 
3968  /* DOUBLE */
3969  DIE_UNLESS((int)d_data == rc);
3970  DIE_UNLESS(length[5] == 8);
3971  rc+= 13;
3972 
3973  /* CHAR */
3974  {
3975  char buff[20];
3976  long len= sprintf(buff, "%d", rc);
3977  DIE_UNLESS(strcmp(s_data, buff) == 0);
3978  DIE_UNLESS(length[6] == (ulong) len);
3979  }
3980  }
3981  rc= mysql_stmt_fetch(stmt);
3982  DIE_UNLESS(rc == MYSQL_NO_DATA);
3983 
3984  mysql_stmt_close(stmt);
3985 }
3986 
3987 
3988 /* Test fetching of date, time and ts */
3989 
3990 static void test_fetch_date()
3991 {
3992  MYSQL_STMT *stmt;
3993  uint i;
3994  int rc, year;
3995  char date[25], my_time[25], ts[25], ts_4[25], ts_6[20], dt[20];
3996  ulong d_length, t_length, ts_length, ts4_length, ts6_length,
3997  dt_length, y_length;
3998  MYSQL_BIND my_bind[8];
3999  my_bool is_null[8];
4000  ulong length[8];
4001 
4002  myheader("test_fetch_date");
4003 
4004  /* Will not work if sql_mode is NO_ZERO_DATE (implicit if TRADITIONAL) */
4005  rc= mysql_query(mysql, "SET SQL_MODE=''");
4006  myquery(rc);
4007 
4008  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
4009  myquery(rc);
4010 
4011  rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \
4012  c3 timestamp, \
4013  c4 year, \
4014  c5 datetime, \
4015  c6 timestamp, \
4016  c7 timestamp)");
4017  myquery(rc);
4018 
4019  rc= mysql_query(mysql, "SET SQL_MODE=''");
4020  rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \
4021  '12:49:00', \
4022  '2002-01-02 17:46:59', \
4023  2010, \
4024  '2010-07-10', \
4025  '2020', '1999-12-29')");
4026  myquery(rc);
4027 
4028  rc= mysql_commit(mysql);
4029  myquery(rc);
4030 
4031  memset(my_bind, 0, sizeof(my_bind));
4032  for (i= 0; i < array_elements(my_bind); i++)
4033  {
4034  my_bind[i].is_null= &is_null[i];
4035  my_bind[i].length= &length[i];
4036  }
4037 
4038  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
4039  my_bind[1]= my_bind[2]= my_bind[0];
4040 
4041  my_bind[0].buffer= (void *)&date;
4042  my_bind[0].buffer_length= sizeof(date);
4043  my_bind[0].length= &d_length;
4044 
4045  my_bind[1].buffer= (void *)&my_time;
4046  my_bind[1].buffer_length= sizeof(my_time);
4047  my_bind[1].length= &t_length;
4048 
4049  my_bind[2].buffer= (void *)&ts;
4050  my_bind[2].buffer_length= sizeof(ts);
4051  my_bind[2].length= &ts_length;
4052 
4053  my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4054  my_bind[3].buffer= (void *)&year;
4055  my_bind[3].length= &y_length;
4056 
4057  my_bind[4].buffer_type= MYSQL_TYPE_STRING;
4058  my_bind[4].buffer= (void *)&dt;
4059  my_bind[4].buffer_length= sizeof(dt);
4060  my_bind[4].length= &dt_length;
4061 
4062  my_bind[5].buffer_type= MYSQL_TYPE_STRING;
4063  my_bind[5].buffer= (void *)&ts_4;
4064  my_bind[5].buffer_length= sizeof(ts_4);
4065  my_bind[5].length= &ts4_length;
4066 
4067  my_bind[6].buffer_type= MYSQL_TYPE_STRING;
4068  my_bind[6].buffer= (void *)&ts_6;
4069  my_bind[6].buffer_length= sizeof(ts_6);
4070  my_bind[6].length= &ts6_length;
4071 
4072  rc= my_stmt_result("SELECT * FROM test_bind_result");
4073  DIE_UNLESS(rc == 1);
4074 
4075  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
4076  check_stmt(stmt);
4077 
4078  rc= mysql_stmt_bind_result(stmt, my_bind);
4079  check_execute(stmt, rc);
4080 
4081  rc= mysql_stmt_execute(stmt);
4082  check_execute(stmt, rc);
4083 
4084  ts_4[0]= '\0';
4085  rc= mysql_stmt_fetch(stmt);
4086  check_execute(stmt, rc);
4087 
4088  if (!opt_silent)
4089  {
4090  fprintf(stdout, "\n date : %s(%lu)", date, d_length);
4091  fprintf(stdout, "\n time : %s(%lu)", my_time, t_length);
4092  fprintf(stdout, "\n ts : %s(%lu)", ts, ts_length);
4093  fprintf(stdout, "\n year : %d(%lu)", year, y_length);
4094  fprintf(stdout, "\n dt : %s(%lu)", dt, dt_length);
4095  fprintf(stdout, "\n ts(4) : %s(%lu)", ts_4, ts4_length);
4096  fprintf(stdout, "\n ts(6) : %s(%lu)", ts_6, ts6_length);
4097  }
4098 
4099  DIE_UNLESS(strcmp(date, "2002-01-02") == 0);
4100  DIE_UNLESS(d_length == 10);
4101 
4102  DIE_UNLESS(strcmp(my_time, "12:49:00") == 0);
4103  DIE_UNLESS(t_length == 8);
4104 
4105  DIE_UNLESS(strcmp(ts, "2002-01-02 17:46:59") == 0);
4106  DIE_UNLESS(ts_length == 19);
4107 
4108  DIE_UNLESS(year == 2010);
4109  DIE_UNLESS(y_length == 4);
4110 
4111  DIE_UNLESS(strcmp(dt, "2010-07-10 00:00:00") == 0);
4112  DIE_UNLESS(dt_length == 19);
4113 
4114  DIE_UNLESS(strcmp(ts_4, "0000-00-00 00:00:00") == 0);
4115  DIE_UNLESS(ts4_length == strlen("0000-00-00 00:00:00"));
4116 
4117  DIE_UNLESS(strcmp(ts_6, "1999-12-29 00:00:00") == 0);
4118  DIE_UNLESS(ts6_length == 19);
4119 
4120  rc= mysql_stmt_fetch(stmt);
4121  DIE_UNLESS(rc == MYSQL_NO_DATA);
4122 
4123  mysql_stmt_close(stmt);
4124 }
4125 
4126 
4127 /* Test fetching of str to all types */
4128 
4129 static void test_fetch_str()
4130 {
4131  int rc;
4132 
4133  myheader("test_fetch_str");
4134 
4135  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4136  myquery(rc);
4137 
4138  rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 char(10), \
4139  c2 char(10), \
4140  c3 char(20), \
4141  c4 char(20), \
4142  c5 char(30), \
4143  c6 char(40), \
4144  c7 char(20))");
4145  myquery(rc);
4146 
4147  bind_fetch(3);
4148 }
4149 
4150 
4151 /* Test fetching of long to all types */
4152 
4153 static void test_fetch_long()
4154 {
4155  int rc;
4156 
4157  myheader("test_fetch_long");
4158 
4159  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4160  myquery(rc);
4161 
4162  rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 int unsigned, \
4163  c2 int unsigned, \
4164  c3 int, \
4165  c4 int, \
4166  c5 int, \
4167  c6 int unsigned, \
4168  c7 int)");
4169  myquery(rc);
4170 
4171  bind_fetch(4);
4172 }
4173 
4174 
4175 /* Test fetching of short to all types */
4176 
4177 static void test_fetch_short()
4178 {
4179  int rc;
4180 
4181  myheader("test_fetch_short");
4182 
4183  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4184  myquery(rc);
4185 
4186  rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, \
4187  c2 smallint, \
4188  c3 smallint unsigned, \
4189  c4 smallint, \
4190  c5 smallint, \
4191  c6 smallint, \
4192  c7 smallint unsigned)");
4193  myquery(rc);
4194 
4195  bind_fetch(5);
4196 }
4197 
4198 
4199 /* Test fetching of tiny to all types */
4200 
4201 static void test_fetch_tiny()
4202 {
4203  int rc;
4204 
4205  myheader("test_fetch_tiny");
4206 
4207  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4208  myquery(rc);
4209 
4210  rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 tinyint unsigned, \
4211  c2 tinyint, \
4212  c3 tinyint unsigned, \
4213  c4 tinyint, \
4214  c5 tinyint, \
4215  c6 tinyint, \
4216  c7 tinyint unsigned)");
4217  myquery(rc);
4218 
4219  bind_fetch(3);
4220 
4221 }
4222 
4223 
4224 /* Test fetching of longlong to all types */
4225 
4226 static void test_fetch_bigint()
4227 {
4228  int rc;
4229 
4230  myheader("test_fetch_bigint");
4231 
4232  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4233  myquery(rc);
4234 
4235  rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 bigint, \
4236  c2 bigint, \
4237  c3 bigint unsigned, \
4238  c4 bigint unsigned, \
4239  c5 bigint unsigned, \
4240  c6 bigint unsigned, \
4241  c7 bigint unsigned)");
4242  myquery(rc);
4243 
4244  bind_fetch(2);
4245 
4246 }
4247 
4248 
4249 /* Test fetching of float to all types */
4250 
4251 static void test_fetch_float()
4252 {
4253  int rc;
4254 
4255  myheader("test_fetch_float");
4256 
4257  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4258  myquery(rc);
4259 
4260  rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 float(3), \
4261  c2 float, \
4262  c3 float unsigned, \
4263  c4 float, \
4264  c5 float, \
4265  c6 float, \
4266  c7 float(10) unsigned)");
4267  myquery(rc);
4268 
4269  bind_fetch(2);
4270 
4271 }
4272 
4273 
4274 /* Test fetching of double to all types */
4275 
4276 static void test_fetch_double()
4277 {
4278  int rc;
4279 
4280  myheader("test_fetch_double");
4281 
4282  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4283  myquery(rc);
4284 
4285  rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 double(5, 2), "
4286  "c2 double unsigned, c3 double unsigned, "
4287  "c4 double unsigned, c5 double unsigned, "
4288  "c6 double unsigned, c7 double unsigned)");
4289  myquery(rc);
4290 
4291  bind_fetch(3);
4292 
4293 }
4294 
4295 
4296 /* Test simple prepare with all possible types */
4297 
4298 static void test_prepare_ext()
4299 {
4300  MYSQL_STMT *stmt;
4301  int rc;
4302  char *sql;
4303  int nData= 1;
4304  char tData= 1;
4305  short sData= 10;
4306  longlong bData= 20;
4307  MYSQL_BIND my_bind[6];
4308  char query[MAX_TEST_QUERY_LENGTH];
4309  myheader("test_prepare_ext");
4310 
4311  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext");
4312  myquery(rc);
4313 
4314  sql= (char *)"CREATE TABLE test_prepare_ext"
4315  "("
4316  " c1 tinyint,"
4317  " c2 smallint,"
4318  " c3 mediumint,"
4319  " c4 int,"
4320  " c5 integer,"
4321  " c6 bigint,"
4322  " c7 float,"
4323  " c8 double,"
4324  " c9 double precision,"
4325  " c10 real,"
4326  " c11 decimal(7, 4),"
4327  " c12 numeric(8, 4),"
4328  " c13 date,"
4329  " c14 datetime,"
4330  " c15 timestamp,"
4331  " c16 time,"
4332  " c17 year,"
4333  " c18 bit,"
4334  " c19 bool,"
4335  " c20 char,"
4336  " c21 char(10),"
4337  " c22 varchar(30),"
4338  " c23 tinyblob,"
4339  " c24 tinytext,"
4340  " c25 blob,"
4341  " c26 text,"
4342  " c27 mediumblob,"
4343  " c28 mediumtext,"
4344  " c29 longblob,"
4345  " c30 longtext,"
4346  " c31 enum('one', 'two', 'three'),"
4347  " c32 set('monday', 'tuesday', 'wednesday'))";
4348 
4349  rc= mysql_query(mysql, sql);
4350  myquery(rc);
4351 
4352  /* insert by prepare - all integers */
4353  strmov(query, (char *)"INSERT INTO test_prepare_ext(c1, c2, c3, c4, c5, c6) VALUES(?, ?, ?, ?, ?, ?)");
4354  stmt= mysql_simple_prepare(mysql, query);
4355  check_stmt(stmt);
4356 
4357  verify_param_count(stmt, 6);
4358 
4359  /* Always memset all members of bind parameter */
4360  memset(my_bind, 0, sizeof(my_bind));
4361 
4362  /*tinyint*/
4363  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4364  my_bind[0].buffer= (void *)&tData;
4365 
4366  /*smallint*/
4367  my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
4368  my_bind[1].buffer= (void *)&sData;
4369 
4370  /*mediumint*/
4371  my_bind[2].buffer_type= MYSQL_TYPE_LONG;
4372  my_bind[2].buffer= (void *)&nData;
4373 
4374  /*int*/
4375  my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4376  my_bind[3].buffer= (void *)&nData;
4377 
4378  /*integer*/
4379  my_bind[4].buffer_type= MYSQL_TYPE_LONG;
4380  my_bind[4].buffer= (void *)&nData;
4381 
4382  /*bigint*/
4383  my_bind[5].buffer_type= MYSQL_TYPE_LONGLONG;
4384  my_bind[5].buffer= (void *)&bData;
4385 
4386  rc= mysql_stmt_bind_param(stmt, my_bind);
4387  check_execute(stmt, rc);
4388 
4389  /*
4390  * integer to integer
4391  */
4392  for (nData= 0; nData<10; nData++, tData++, sData++, bData++)
4393  {
4394  rc= mysql_stmt_execute(stmt);
4395  check_execute(stmt, rc);
4396  }
4397  mysql_stmt_close(stmt);
4398 
4399  /* now fetch the results ..*/
4400 
4401  stmt= mysql_simple_prepare(mysql, "SELECT c1, c2, c3, c4, c5, c6 "
4402  "FROM test_prepare_ext");
4403  check_stmt(stmt);
4404 
4405  /* get the result */
4406  rc= mysql_stmt_execute(stmt);
4407  check_execute(stmt, rc);
4408 
4409  rc= my_process_stmt_result(stmt);
4410  DIE_UNLESS(nData == rc);
4411 
4412  mysql_stmt_close(stmt);
4413 }
4414 
4415 
4416 /* Test real and alias names */
4417 
4418 static void test_field_names()
4419 {
4420  int rc;
4421  MYSQL_RES *result;
4422 
4423  myheader("test_field_names");
4424 
4425  if (!opt_silent)
4426  fprintf(stdout, "\n %d, %d, %d", MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_ENUM);
4427  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names1");
4428  myquery(rc);
4429 
4430  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names2");
4431  myquery(rc);
4432 
4433  rc= mysql_query(mysql, "CREATE TABLE test_field_names1(id int, name varchar(50))");
4434  myquery(rc);
4435 
4436  rc= mysql_query(mysql, "CREATE TABLE test_field_names2(id int, name varchar(50))");
4437  myquery(rc);
4438 
4439  /* with table name included with TRUE column name */
4440  rc= mysql_query(mysql, "SELECT id as 'id-alias' FROM test_field_names1");
4441  myquery(rc);
4442 
4443  result= mysql_use_result(mysql);
4444  mytest(result);
4445 
4446  rc= my_process_result_set(result);
4447  DIE_UNLESS(rc == 0);
4448  mysql_free_result(result);
4449 
4450  /* with table name included with TRUE column name */
4451  rc= mysql_query(mysql, "SELECT t1.id as 'id-alias', test_field_names2.name FROM test_field_names1 t1, test_field_names2");
4452  myquery(rc);
4453 
4454  result= mysql_use_result(mysql);
4455  mytest(result);
4456 
4457  rc= my_process_result_set(result);
4458  DIE_UNLESS(rc == 0);
4459  mysql_free_result(result);
4460 }
4461 
4462 
4463 /* Test warnings */
4464 
4465 static void test_warnings()
4466 {
4467  int rc;
4468  MYSQL_RES *result;
4469 
4470  myheader("test_warnings");
4471 
4472  mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4473 
4474  rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4475  myquery(rc);
4476 
4477  if (!opt_silent)
4478  fprintf(stdout, "\n total warnings: %d", mysql_warning_count(mysql));
4479  rc= mysql_query(mysql, "SHOW WARNINGS");
4480  myquery(rc);
4481 
4482  result= mysql_store_result(mysql);
4483  mytest(result);
4484 
4485  rc= my_process_result_set(result);
4486  DIE_UNLESS(rc == 1);
4487  mysql_free_result(result);
4488 }
4489 
4490 
4491 /* Test errors */
4492 
4493 static void test_errors()
4494 {
4495  int rc;
4496  MYSQL_RES *result;
4497 
4498  myheader("test_errors");
4499 
4500  mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4501 
4502  rc= mysql_query(mysql, "DROP TABLE test_non_exists");
4503  myquery_r(rc);
4504 
4505  rc= mysql_query(mysql, "SHOW ERRORS");
4506  myquery(rc);
4507 
4508  result= mysql_store_result(mysql);
4509  mytest(result);
4510 
4511  (void) my_process_result_set(result);
4512  mysql_free_result(result);
4513 }
4514 
4515 
4516 /* Test simple prepare-insert */
4517 
4518 static void test_insert()
4519 {
4520  MYSQL_STMT *stmt;
4521  int rc;
4522  char str_data[50];
4523  char tiny_data;
4524  MYSQL_RES *result;
4525  MYSQL_BIND my_bind[2];
4526  ulong length;
4527 
4528  myheader("test_insert");
4529 
4530  rc= mysql_autocommit(mysql, TRUE);
4531  myquery(rc);
4532 
4533  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_insert");
4534  myquery(rc);
4535 
4536  rc= mysql_query(mysql, "CREATE TABLE test_prep_insert(col1 tinyint, \
4537  col2 varchar(50))");
4538  myquery(rc);
4539 
4540  /* insert by prepare */
4541  stmt= mysql_simple_prepare(mysql,
4542  "INSERT INTO test_prep_insert VALUES(?, ?)");
4543  check_stmt(stmt);
4544 
4545  verify_param_count(stmt, 2);
4546 
4547  /*
4548  We need to memset bind structure because mysql_stmt_bind_param checks all
4549  its members.
4550  */
4551  memset(my_bind, 0, sizeof(my_bind));
4552 
4553  /* tinyint */
4554  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4555  my_bind[0].buffer= (void *)&tiny_data;
4556 
4557  /* string */
4558  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
4559  my_bind[1].buffer= str_data;
4560  my_bind[1].buffer_length= sizeof(str_data);;
4561  my_bind[1].length= &length;
4562 
4563  rc= mysql_stmt_bind_param(stmt, my_bind);
4564  check_execute(stmt, rc);
4565 
4566  /* now, execute the prepared statement to insert 10 records.. */
4567  for (tiny_data= 0; tiny_data < 3; tiny_data++)
4568  {
4569  length= sprintf(str_data, "MySQL%d", tiny_data);
4570  rc= mysql_stmt_execute(stmt);
4571  check_execute(stmt, rc);
4572  }
4573 
4574  mysql_stmt_close(stmt);
4575 
4576  /* now fetch the results ..*/
4577  rc= mysql_commit(mysql);
4578  myquery(rc);
4579 
4580  /* test the results now, only one row should exist */
4581  rc= mysql_query(mysql, "SELECT * FROM test_prep_insert");
4582  myquery(rc);
4583 
4584  /* get the result */
4585  result= mysql_store_result(mysql);
4586  mytest(result);
4587 
4588  rc= my_process_result_set(result);
4589  DIE_UNLESS((int) tiny_data == rc);
4590  mysql_free_result(result);
4591 
4592 }
4593 
4594 
4595 /* Test simple prepare-resultset info */
4596 
4597 static void test_prepare_resultset()
4598 {
4599  MYSQL_STMT *stmt;
4600  int rc;
4601  MYSQL_RES *result;
4602 
4603  myheader("test_prepare_resultset");
4604 
4605  rc= mysql_autocommit(mysql, TRUE);
4606  myquery(rc);
4607 
4608  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_resultset");
4609  myquery(rc);
4610 
4611  rc= mysql_query(mysql, "CREATE TABLE test_prepare_resultset(id int, \
4612  name varchar(50), extra double)");
4613  myquery(rc);
4614 
4615  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_prepare_resultset");
4616  check_stmt(stmt);
4617 
4618  verify_param_count(stmt, 0);
4619 
4620  result= mysql_stmt_result_metadata(stmt);
4621  mytest(result);
4622  my_print_result_metadata(result);
4623  mysql_free_result(result);
4624  mysql_stmt_close(stmt);
4625 }
4626 
4627 
4628 /* Test field flags (verify .NET provider) */
4629 
4630 static void test_field_flags()
4631 {
4632  int rc;
4633  MYSQL_RES *result;
4634  MYSQL_FIELD *field;
4635  unsigned int i;
4636 
4637 
4638  myheader("test_field_flags");
4639 
4640  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_flags");
4641  myquery(rc);
4642 
4643  rc= mysql_query(mysql, "CREATE TABLE test_field_flags(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, \
4644  id1 int NOT NULL, \
4645  id2 int UNIQUE, \
4646  id3 int, \
4647  id4 int NOT NULL, \
4648  id5 int, \
4649  KEY(id3, id4))");
4650  myquery(rc);
4651 
4652  /* with table name included with TRUE column name */
4653  rc= mysql_query(mysql, "SELECT * FROM test_field_flags");
4654  myquery(rc);
4655 
4656  result= mysql_use_result(mysql);
4657  mytest(result);
4658 
4659  mysql_field_seek(result, 0);
4660  if (!opt_silent)
4661  fputc('\n', stdout);
4662 
4663  for(i= 0; i< mysql_num_fields(result); i++)
4664  {
4665  field= mysql_fetch_field(result);
4666  if (!opt_silent)
4667  {
4668  fprintf(stdout, "\n field:%d", i);
4669  if (field->flags & NOT_NULL_FLAG)
4670  fprintf(stdout, "\n NOT_NULL_FLAG");
4671  if (field->flags & PRI_KEY_FLAG)
4672  fprintf(stdout, "\n PRI_KEY_FLAG");
4673  if (field->flags & UNIQUE_KEY_FLAG)
4674  fprintf(stdout, "\n UNIQUE_KEY_FLAG");
4675  if (field->flags & MULTIPLE_KEY_FLAG)
4676  fprintf(stdout, "\n MULTIPLE_KEY_FLAG");
4677  if (field->flags & AUTO_INCREMENT_FLAG)
4678  fprintf(stdout, "\n AUTO_INCREMENT_FLAG");
4679 
4680  }
4681  }
4682  mysql_free_result(result);
4683 }
4684 
4685 
4686 /* Test mysql_stmt_close for open stmts */
4687 
4688 static void test_stmt_close()
4689 {
4690  MYSQL *lmysql;
4691  MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x;
4692  MYSQL_BIND my_bind[1];
4693  MYSQL_RES *result;
4694  unsigned int count;
4695  int rc;
4696  char query[MAX_TEST_QUERY_LENGTH];
4697 
4698  myheader("test_stmt_close");
4699 
4700  if (!opt_silent)
4701  fprintf(stdout, "\n Establishing a test connection ...");
4702  if (!(lmysql= mysql_client_init(NULL)))
4703  {
4704  myerror("mysql_client_init() failed");
4705  exit(1);
4706  }
4707  if (!(mysql_real_connect(lmysql, opt_host, opt_user,
4708  opt_password, current_db, opt_port,
4709  opt_unix_socket, 0)))
4710  {
4711  myerror("connection failed");
4712  exit(1);
4713  }
4714  lmysql->reconnect= 1;
4715  if (!opt_silent)
4716  fprintf(stdout, "OK");
4717 
4718 
4719  /* set AUTOCOMMIT to ON*/
4720  mysql_autocommit(lmysql, TRUE);
4721 
4722  rc= mysql_query(lmysql, "SET SQL_MODE = ''");
4723  myquery(rc);
4724 
4725  rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close");
4726  myquery(rc);
4727 
4728  rc= mysql_query(lmysql, "CREATE TABLE test_stmt_close(id int)");
4729  myquery(rc);
4730 
4731  strmov(query, "DO \"nothing\"");
4732  stmt1= mysql_simple_prepare(lmysql, query);
4733  check_stmt(stmt1);
4734 
4735  verify_param_count(stmt1, 0);
4736 
4737  strmov(query, "INSERT INTO test_stmt_close(id) VALUES(?)");
4738  stmt_x= mysql_simple_prepare(mysql, query);
4739  check_stmt(stmt_x);
4740 
4741  verify_param_count(stmt_x, 1);
4742 
4743  strmov(query, "UPDATE test_stmt_close SET id= ? WHERE id= ?");
4744  stmt3= mysql_simple_prepare(lmysql, query);
4745  check_stmt(stmt3);
4746 
4747  verify_param_count(stmt3, 2);
4748 
4749  strmov(query, "SELECT * FROM test_stmt_close WHERE id= ?");
4750  stmt2= mysql_simple_prepare(lmysql, query);
4751  check_stmt(stmt2);
4752 
4753  verify_param_count(stmt2, 1);
4754 
4755  rc= mysql_stmt_close(stmt1);
4756  if (!opt_silent)
4757  fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
4758  DIE_UNLESS(rc == 0);
4759 
4760  /*
4761  Originally we were going to close all statements automatically in
4762  mysql_close(). This proved to not work well - users weren't able to
4763  close statements by hand once mysql_close() had been called.
4764  Now mysql_close() doesn't free any statements, so this test doesn't
4765  serve its original designation any more.
4766  Here we free stmt2 and stmt3 by hand to avoid memory leaks.
4767  */
4768  mysql_stmt_close(stmt2);
4769  mysql_stmt_close(stmt3);
4770  mysql_close(lmysql);
4771 
4772  /*
4773  We need to memset bind structure because mysql_stmt_bind_param checks all
4774  its members.
4775  */
4776  memset(my_bind, 0, sizeof(my_bind));
4777 
4778  my_bind[0].buffer= (void *)&count;
4779  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
4780  count= 100;
4781 
4782  rc= mysql_stmt_bind_param(stmt_x, my_bind);
4783  check_execute(stmt_x, rc);
4784 
4785  rc= mysql_stmt_execute(stmt_x);
4786  check_execute(stmt_x, rc);
4787 
4788  verify_st_affected_rows(stmt_x, 1);
4789 
4790  rc= mysql_stmt_close(stmt_x);
4791  if (!opt_silent)
4792  fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
4793  DIE_UNLESS( rc == 0);
4794 
4795  rc= mysql_query(mysql, "SELECT id FROM test_stmt_close");
4796  myquery(rc);
4797 
4798  result= mysql_store_result(mysql);
4799  mytest(result);
4800 
4801  rc= my_process_result_set(result);
4802  DIE_UNLESS(rc == 1);
4803  mysql_free_result(result);
4804 }
4805 
4806 
4807 /* Test simple set variable prepare */
4808 
4809 static void test_set_variable()
4810 {
4811  MYSQL_STMT *stmt, *stmt1;
4812  int rc;
4813  int set_count, def_count, get_count;
4814  ulong length;
4815  char var[NAME_LEN+1];
4816  MYSQL_BIND set_bind[1], get_bind[2];
4817 
4818  myheader("test_set_variable");
4819 
4820  mysql_autocommit(mysql, TRUE);
4821 
4822  stmt1= mysql_simple_prepare(mysql, "show variables like 'max_error_count'");
4823  check_stmt(stmt1);
4824 
4825  /*
4826  We need to memset bind structure because mysql_stmt_bind_param checks all
4827  its members.
4828  */
4829  memset(get_bind, 0, sizeof(get_bind));
4830 
4831  get_bind[0].buffer_type= MYSQL_TYPE_STRING;
4832  get_bind[0].buffer= (void *)var;
4833  get_bind[0].length= &length;
4834  get_bind[0].buffer_length= (int)NAME_LEN;
4835  length= NAME_LEN;
4836 
4837  get_bind[1].buffer_type= MYSQL_TYPE_LONG;
4838  get_bind[1].buffer= (void *)&get_count;
4839 
4840  rc= mysql_stmt_execute(stmt1);
4841  check_execute(stmt1, rc);
4842 
4843  rc= mysql_stmt_bind_result(stmt1, get_bind);
4844  check_execute(stmt1, rc);
4845 
4846  rc= mysql_stmt_fetch(stmt1);
4847  check_execute(stmt1, rc);
4848 
4849  if (!opt_silent)
4850  fprintf(stdout, "\n max_error_count(default): %d", get_count);
4851  def_count= get_count;
4852 
4853  DIE_UNLESS(strcmp(var, "max_error_count") == 0);
4854  rc= mysql_stmt_fetch(stmt1);
4855  DIE_UNLESS(rc == MYSQL_NO_DATA);
4856 
4857  stmt= mysql_simple_prepare(mysql, "set max_error_count= ?");
4858  check_stmt(stmt);
4859 
4860  memset(set_bind, 0, sizeof(set_bind));
4861 
4862  set_bind[0].buffer_type= MYSQL_TYPE_LONG;
4863  set_bind[0].buffer= (void *)&set_count;
4864 
4865  rc= mysql_stmt_bind_param(stmt, set_bind);
4866  check_execute(stmt, rc);
4867 
4868  set_count= 31;
4869  rc= mysql_stmt_execute(stmt);
4870  check_execute(stmt, rc);
4871 
4872  mysql_commit(mysql);
4873 
4874  rc= mysql_stmt_execute(stmt1);
4875  check_execute(stmt1, rc);
4876 
4877  rc= mysql_stmt_fetch(stmt1);
4878  check_execute(stmt1, rc);
4879 
4880  if (!opt_silent)
4881  fprintf(stdout, "\n max_error_count : %d", get_count);
4882  DIE_UNLESS(get_count == set_count);
4883 
4884  rc= mysql_stmt_fetch(stmt1);
4885  DIE_UNLESS(rc == MYSQL_NO_DATA);
4886 
4887  /* restore back to default */
4888  set_count= def_count;
4889  rc= mysql_stmt_execute(stmt);
4890  check_execute(stmt, rc);
4891 
4892  rc= mysql_stmt_execute(stmt1);
4893  check_execute(stmt1, rc);
4894 
4895  rc= mysql_stmt_fetch(stmt1);
4896  check_execute(stmt1, rc);
4897 
4898  if (!opt_silent)
4899  fprintf(stdout, "\n max_error_count(default): %d", get_count);
4900  DIE_UNLESS(get_count == set_count);
4901 
4902  rc= mysql_stmt_fetch(stmt1);
4903  DIE_UNLESS(rc == MYSQL_NO_DATA);
4904 
4905  mysql_stmt_close(stmt);
4906  mysql_stmt_close(stmt1);
4907 }
4908 
4909 /* Test FUNCTION field info / DATE_FORMAT() table_name . */
4910 
4911 static void test_func_fields()
4912 {
4913  int rc;
4914  MYSQL_RES *result;
4915  MYSQL_FIELD *field;
4916 
4917  myheader("test_func_fields");
4918 
4919  rc= mysql_autocommit(mysql, TRUE);
4920  myquery(rc);
4921 
4922  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_dateformat");
4923  myquery(rc);
4924 
4925  rc= mysql_query(mysql, "CREATE TABLE test_dateformat(id int, \
4926  ts timestamp)");
4927  myquery(rc);
4928 
4929  rc= mysql_query(mysql, "INSERT INTO test_dateformat(id) values(10)");
4930  myquery(rc);
4931 
4932  rc= mysql_query(mysql, "SELECT ts FROM test_dateformat");
4933  myquery(rc);
4934 
4935  result= mysql_store_result(mysql);
4936  mytest(result);
4937 
4938  field= mysql_fetch_field(result);
4939  mytest(field);
4940  if (!opt_silent)
4941  fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table,
4942  "test_dateformat");
4943  DIE_UNLESS(strcmp(field->table, "test_dateformat") == 0);
4944 
4945  field= mysql_fetch_field(result);
4946  mytest_r(field); /* no more fields */
4947 
4948  mysql_free_result(result);
4949 
4950  /* DATE_FORMAT */
4951  rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'venu' FROM test_dateformat");
4952  myquery(rc);
4953 
4954  result= mysql_store_result(mysql);
4955  mytest(result);
4956 
4957  field= mysql_fetch_field(result);
4958  mytest(field);
4959  if (!opt_silent)
4960  fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table, "");
4961  DIE_UNLESS(field->table[0] == '\0');
4962 
4963  field= mysql_fetch_field(result);
4964  mytest_r(field); /* no more fields */
4965 
4966  mysql_free_result(result);
4967 
4968  /* FIELD ALIAS TEST */
4969  rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'YEAR' FROM test_dateformat");
4970  myquery(rc);
4971 
4972  result= mysql_store_result(mysql);
4973  mytest(result);
4974 
4975  field= mysql_fetch_field(result);
4976  mytest(field);
4977  if (!opt_silent)
4978  {
4979  printf("\n field name: `%s` (expected: `%s`)", field->name, "YEAR");
4980  printf("\n field org name: `%s` (expected: `%s`)", field->org_name, "");
4981  }
4982  DIE_UNLESS(strcmp(field->name, "YEAR") == 0);
4983  DIE_UNLESS(field->org_name[0] == '\0');
4984 
4985  field= mysql_fetch_field(result);
4986  mytest_r(field); /* no more fields */
4987 
4988  mysql_free_result(result);
4989 }
4990 
4991 
4992 /* Multiple stmts .. */
4993 
4994 static void test_multi_stmt()
4995 {
4996 
4997  MYSQL_STMT *stmt, *stmt1, *stmt2;
4998  int rc;
4999  uint32 id;
5000  char name[50];
5001  MYSQL_BIND my_bind[2];
5002  ulong length[2];
5003  my_bool is_null[2];
5004  myheader("test_multi_stmt");
5005 
5006  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_multi_table");
5007  myquery(rc);
5008 
5009  rc= mysql_query(mysql, "CREATE TABLE test_multi_table(id int, name char(20))");
5010  myquery(rc);
5011 
5012  rc= mysql_query(mysql, "INSERT INTO test_multi_table values(10, 'mysql')");
5013  myquery(rc);
5014 
5015  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_multi_table "
5016  "WHERE id= ?");
5017  check_stmt(stmt);
5018 
5019  stmt2= mysql_simple_prepare(mysql, "UPDATE test_multi_table "
5020  "SET name='updated' WHERE id=10");
5021  check_stmt(stmt2);
5022 
5023  verify_param_count(stmt, 1);
5024 
5025  /*
5026  We need to memset bind structure because mysql_stmt_bind_param checks all
5027  its members.
5028  */
5029  memset(my_bind, 0, sizeof(my_bind));
5030 
5031  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5032  my_bind[0].buffer= (void *)&id;
5033  my_bind[0].is_null= &is_null[0];
5034  my_bind[0].length= &length[0];
5035  is_null[0]= 0;
5036  length[0]= 0;
5037 
5038  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5039  my_bind[1].buffer= (void *)name;
5040  my_bind[1].buffer_length= sizeof(name);
5041  my_bind[1].length= &length[1];
5042  my_bind[1].is_null= &is_null[1];
5043 
5044  rc= mysql_stmt_bind_param(stmt, my_bind);
5045  check_execute(stmt, rc);
5046 
5047  rc= mysql_stmt_bind_result(stmt, my_bind);
5048  check_execute(stmt, rc);
5049 
5050  id= 10;
5051  rc= mysql_stmt_execute(stmt);
5052  check_execute(stmt, rc);
5053 
5054  id= 999;
5055  rc= mysql_stmt_fetch(stmt);
5056  check_execute(stmt, rc);
5057 
5058  if (!opt_silent)
5059  {
5060  fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5061  fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5062  }
5063  DIE_UNLESS(id == 10);
5064  DIE_UNLESS(strcmp(name, "mysql") == 0);
5065 
5066  rc= mysql_stmt_fetch(stmt);
5067  DIE_UNLESS(rc == MYSQL_NO_DATA);
5068 
5069  /* alter the table schema now */
5070  stmt1= mysql_simple_prepare(mysql, "DELETE FROM test_multi_table "
5071  "WHERE id= ? AND "
5072  "CONVERT(name USING utf8)=?");
5073  check_stmt(stmt1);
5074 
5075  verify_param_count(stmt1, 2);
5076 
5077  rc= mysql_stmt_bind_param(stmt1, my_bind);
5078  check_execute(stmt1, rc);
5079 
5080  rc= mysql_stmt_execute(stmt2);
5081  check_execute(stmt2, rc);
5082 
5083  verify_st_affected_rows(stmt2, 1);
5084 
5085  rc= mysql_stmt_execute(stmt);
5086  check_execute(stmt, rc);
5087 
5088  rc= mysql_stmt_fetch(stmt);
5089  check_execute(stmt, rc);
5090 
5091  if (!opt_silent)
5092  {
5093  fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5094  fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5095  }
5096  DIE_UNLESS(id == 10);
5097  DIE_UNLESS(strcmp(name, "updated") == 0);
5098 
5099  rc= mysql_stmt_fetch(stmt);
5100  DIE_UNLESS(rc == MYSQL_NO_DATA);
5101 
5102  rc= mysql_stmt_execute(stmt1);
5103  check_execute(stmt1, rc);
5104 
5105  verify_st_affected_rows(stmt1, 1);
5106 
5107  mysql_stmt_close(stmt1);
5108 
5109  rc= mysql_stmt_execute(stmt);
5110  check_execute(stmt, rc);
5111 
5112  rc= mysql_stmt_fetch(stmt);
5113  DIE_UNLESS(rc == MYSQL_NO_DATA);
5114 
5115  rc= my_stmt_result("SELECT * FROM test_multi_table");
5116  DIE_UNLESS(rc == 0);
5117 
5118  mysql_stmt_close(stmt);
5119  mysql_stmt_close(stmt2);
5120 
5121 }
5122 
5123 
5124 /* Test simple sample - manual */
5125 
5126 static void test_manual_sample()
5127 {
5128  unsigned int param_count;
5129  MYSQL_STMT *stmt;
5130  short small_data;
5131  int int_data;
5132  int rc;
5133  char str_data[50];
5134  ulonglong affected_rows;
5135  MYSQL_BIND my_bind[3];
5136  my_bool is_null;
5137  char query[MAX_TEST_QUERY_LENGTH];
5138 
5139  myheader("test_manual_sample");
5140 
5141  /*
5142  Sample which is incorporated directly in the manual under Prepared
5143  statements section (Example from mysql_stmt_execute()
5144  */
5145 
5146  mysql_autocommit(mysql, 1);
5147  if (mysql_query(mysql, "DROP TABLE IF EXISTS test_table"))
5148  {
5149  fprintf(stderr, "\n drop table failed");
5150  fprintf(stderr, "\n %s", mysql_error(mysql));
5151  exit(1);
5152  }
5153  if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \
5154  col3 smallint, \
5155  col4 timestamp)"))
5156  {
5157  fprintf(stderr, "\n create table failed");
5158  fprintf(stderr, "\n %s", mysql_error(mysql));
5159  exit(1);
5160  }
5161 
5162  /* Prepare a insert query with 3 parameters */
5163  strmov(query, "INSERT INTO test_table(col1, col2, col3) values(?, ?, ?)");
5164  if (!(stmt= mysql_simple_prepare(mysql, query)))
5165  {
5166  fprintf(stderr, "\n prepare, insert failed");
5167  fprintf(stderr, "\n %s", mysql_error(mysql));
5168  exit(1);
5169  }
5170  if (!opt_silent)
5171  fprintf(stdout, "\n prepare, insert successful");
5172 
5173  /* Get the parameter count from the statement */
5174  param_count= mysql_stmt_param_count(stmt);
5175 
5176  if (!opt_silent)
5177  fprintf(stdout, "\n total parameters in insert: %d", param_count);
5178  if (param_count != 3) /* validate parameter count */
5179  {
5180  fprintf(stderr, "\n invalid parameter count returned by MySQL");
5181  exit(1);
5182  }
5183 
5184  /* Bind the data for the parameters */
5185 
5186  /*
5187  We need to memset bind structure because mysql_stmt_bind_param checks all
5188  its members.
5189  */
5190  memset(my_bind, 0, sizeof(my_bind));
5191 
5192  /* INTEGER PART */
5193  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5194  my_bind[0].buffer= (void *)&int_data;
5195 
5196  /* STRING PART */
5197  my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
5198  my_bind[1].buffer= (void *)str_data;
5199  my_bind[1].buffer_length= sizeof(str_data);
5200 
5201  /* SMALLINT PART */
5202  my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
5203  my_bind[2].buffer= (void *)&small_data;
5204  my_bind[2].is_null= &is_null;
5205  is_null= 0;
5206 
5207  /* Bind the buffers */
5208  if (mysql_stmt_bind_param(stmt, my_bind))
5209  {
5210  fprintf(stderr, "\n param bind failed");
5211  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5212  exit(1);
5213  }
5214 
5215  /* Specify the data */
5216  int_data= 10; /* integer */
5217  strmov(str_data, "MySQL"); /* string */
5218 
5219  /* INSERT SMALLINT data as NULL */
5220  is_null= 1;
5221 
5222  /* Execute the insert statement - 1*/
5223  if (mysql_stmt_execute(stmt))
5224  {
5225  fprintf(stderr, "\n execute 1 failed");
5226  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5227  exit(1);
5228  }
5229 
5230  /* Get the total rows affected */
5231  affected_rows= mysql_stmt_affected_rows(stmt);
5232 
5233  if (!opt_silent)
5234  fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5235  if (affected_rows != 1) /* validate affected rows */
5236  {
5237  fprintf(stderr, "\n invalid affected rows by MySQL");
5238  exit(1);
5239  }
5240 
5241  /* Re-execute the insert, by changing the values */
5242  int_data= 1000;
5243  strmov(str_data, "The most popular open source database");
5244  small_data= 1000; /* smallint */
5245  is_null= 0; /* reset */
5246 
5247  /* Execute the insert statement - 2*/
5248  if (mysql_stmt_execute(stmt))
5249  {
5250  fprintf(stderr, "\n execute 2 failed");
5251  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5252  exit(1);
5253  }
5254 
5255  /* Get the total rows affected */
5256  affected_rows= mysql_stmt_affected_rows(stmt);
5257 
5258  if (!opt_silent)
5259  fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5260  if (affected_rows != 1) /* validate affected rows */
5261  {
5262  fprintf(stderr, "\n invalid affected rows by MySQL");
5263  exit(1);
5264  }
5265 
5266  /* Close the statement */
5267  if (mysql_stmt_close(stmt))
5268  {
5269  fprintf(stderr, "\n failed while closing the statement");
5270  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5271  exit(1);
5272  }
5273  rc= my_stmt_result("SELECT * FROM test_table");
5274  DIE_UNLESS(rc == 2);
5275 
5276  /* DROP THE TABLE */
5277  if (mysql_query(mysql, "DROP TABLE test_table"))
5278  {
5279  fprintf(stderr, "\n drop table failed");
5280  fprintf(stderr, "\n %s", mysql_error(mysql));
5281  exit(1);
5282  }
5283  if (!opt_silent)
5284  fprintf(stdout, "Success !!!");
5285 }
5286 
5287 
5288 /* Test alter table scenario in the middle of prepare */
5289 
5290 static void test_prepare_alter()
5291 {
5292  MYSQL_STMT *stmt;
5293  int rc, id;
5294  MYSQL_BIND my_bind[1];
5295  my_bool is_null;
5296 
5297  myheader("test_prepare_alter");
5298 
5299  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_alter");
5300  myquery(rc);
5301 
5302  rc= mysql_query(mysql, "CREATE TABLE test_prep_alter(id int, name char(20))");
5303  myquery(rc);
5304 
5305  rc= mysql_query(mysql, "INSERT INTO test_prep_alter values(10, 'venu'), (20, 'mysql')");
5306  myquery(rc);
5307 
5308  stmt= mysql_simple_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?, 'monty')");
5309  check_stmt(stmt);
5310 
5311  verify_param_count(stmt, 1);
5312 
5313  /*
5314  We need to memset bind structure because mysql_stmt_bind_param checks all
5315  its members.
5316  */
5317  memset(my_bind, 0, sizeof(my_bind));
5318 
5319  is_null= 0;
5320  my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
5321  my_bind[0].buffer= (void *)&id;
5322  my_bind[0].is_null= &is_null;
5323 
5324  rc= mysql_stmt_bind_param(stmt, my_bind);
5325  check_execute(stmt, rc);
5326 
5327  id= 30;
5328  rc= mysql_stmt_execute(stmt);
5329  check_execute(stmt, rc);
5330 
5331  if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)"))
5332  exit(1);
5333 
5334  is_null= 1;
5335  rc= mysql_stmt_execute(stmt);
5336  check_execute(stmt, rc);
5337 
5338  rc= my_stmt_result("SELECT * FROM test_prep_alter");
5339  DIE_UNLESS(rc == 4);
5340 
5341  mysql_stmt_close(stmt);
5342 }
5343 
5344 
5345 /* Test the support of multi-statement executions */
5346 
5347 static void test_multi_statements()
5348 {
5349  MYSQL *mysql_local;
5350  MYSQL_RES *result;
5351  int rc;
5352 
5353  const char *query= "\
5354 DROP TABLE IF EXISTS test_multi_tab;\
5355 CREATE TABLE test_multi_tab(id int, name char(20));\
5356 INSERT INTO test_multi_tab(id) VALUES(10), (20);\
5357 INSERT INTO test_multi_tab VALUES(20, 'insert;comma');\
5358 SELECT * FROM test_multi_tab;\
5359 UPDATE test_multi_tab SET name='new;name' WHERE id=20;\
5360 DELETE FROM test_multi_tab WHERE name='new;name';\
5361 SELECT * FROM test_multi_tab;\
5362 DELETE FROM test_multi_tab WHERE id=10;\
5363 SELECT * FROM test_multi_tab;\
5364 DROP TABLE test_multi_tab;\
5365 select 1;\
5366 DROP TABLE IF EXISTS test_multi_tab";
5367  uint count, exp_value;
5368  uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0};
5369 
5370  myheader("test_multi_statements");
5371 
5372  /*
5373  First test that we get an error for multi statements
5374  (Because default connection is not opened with CLIENT_MULTI_STATEMENTS)
5375  */
5376  rc= mysql_query(mysql, query); /* syntax error */
5377  myquery_r(rc);
5378 
5379  rc= mysql_next_result(mysql);
5380  DIE_UNLESS(rc == -1);
5381  rc= mysql_more_results(mysql);
5382  DIE_UNLESS(rc == 0);
5383 
5384  if (!(mysql_local= mysql_client_init(NULL)))
5385  {
5386  fprintf(stdout, "\n mysql_client_init() failed");
5387  exit(1);
5388  }
5389 
5390  /* Create connection that supports multi statements */
5391  if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5392  opt_password, current_db, opt_port,
5393  opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5394  {
5395  fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local));
5396  exit(1);
5397  }
5398  mysql_local->reconnect= 1;
5399 
5400  rc= mysql_query(mysql_local, query);
5401  myquery(rc);
5402 
5403  for (count= 0 ; count < array_elements(rows) ; count++)
5404  {
5405  if (!opt_silent)
5406  fprintf(stdout, "\n Query %d: ", count);
5407  if ((result= mysql_store_result(mysql_local)))
5408  {
5409  (void) my_process_result_set(result);
5410  mysql_free_result(result);
5411  }
5412  else if (!opt_silent)
5413  fprintf(stdout, "OK, %ld row(s) affected, %ld warning(s)\n",
5414  (ulong) mysql_affected_rows(mysql_local),
5415  (ulong) mysql_warning_count(mysql_local));
5416 
5417  exp_value= (uint) mysql_affected_rows(mysql_local);
5418  if (rows[count] != exp_value)
5419  {
5420  fprintf(stderr, "row %d had affected rows: %d, should be %d\n",
5421  count, exp_value, rows[count]);
5422  exit(1);
5423  }
5424  if (count != array_elements(rows) -1)
5425  {
5426  if (!(rc= mysql_more_results(mysql_local)))
5427  {
5428  fprintf(stdout,
5429  "mysql_more_result returned wrong value: %d for row %d\n",
5430  rc, count);
5431  exit(1);
5432  }
5433  if ((rc= mysql_next_result(mysql_local)))
5434  {
5435  exp_value= mysql_errno(mysql_local);
5436 
5437  exit(1);
5438  }
5439  }
5440  else
5441  {
5442  rc= mysql_more_results(mysql_local);
5443  DIE_UNLESS(rc == 0);
5444  rc= mysql_next_result(mysql_local);
5445  DIE_UNLESS(rc == -1);
5446  }
5447  }
5448 
5449  /* check that errors abort multi statements */
5450 
5451  rc= mysql_query(mysql_local, "select 1+1+a;select 1+1");
5452  myquery_r(rc);
5453  rc= mysql_more_results(mysql_local);
5454  DIE_UNLESS(rc == 0);
5455  rc= mysql_next_result(mysql_local);
5456  DIE_UNLESS(rc == -1);
5457 
5458  rc= mysql_query(mysql_local, "select 1+1;select 1+1+a;select 1");
5459  myquery(rc);
5460  result= mysql_store_result(mysql_local);
5461  mytest(result);
5462  mysql_free_result(result);
5463  rc= mysql_more_results(mysql_local);
5464  DIE_UNLESS(rc == 1);
5465  rc= mysql_next_result(mysql_local);
5466  DIE_UNLESS(rc > 0);
5467 
5468  /*
5469  Ensure that we can now do a simple query (this checks that the server is
5470  not trying to send us the results for the last 'select 1'
5471  */
5472  rc= mysql_query(mysql_local, "select 1+1+1");
5473  myquery(rc);
5474  result= mysql_store_result(mysql_local);
5475  mytest(result);
5476  (void) my_process_result_set(result);
5477  mysql_free_result(result);
5478 
5479  /*
5480  Check if errors in one of the queries handled properly.
5481  */
5482  rc= mysql_query(mysql_local, "select 1; select * from not_existing_table");
5483  myquery(rc);
5484  result= mysql_store_result(mysql_local);
5485  mysql_free_result(result);
5486 
5487  rc= mysql_next_result(mysql_local);
5488  DIE_UNLESS(rc > 0);
5489 
5490  rc= mysql_next_result(mysql_local);
5491  DIE_UNLESS(rc < 0);
5492 
5493  mysql_close(mysql_local);
5494 }
5495 
5496 
5497 /*
5498  Check that Prepared statement cannot contain several
5499  SQL statements
5500 */
5501 
5502 static void test_prepare_multi_statements()
5503 {
5504  MYSQL *mysql_local;
5505  MYSQL_STMT *stmt;
5506  char query[MAX_TEST_QUERY_LENGTH];
5507  myheader("test_prepare_multi_statements");
5508 
5509  if (!(mysql_local= mysql_client_init(NULL)))
5510  {
5511  fprintf(stderr, "\n mysql_client_init() failed");
5512  exit(1);
5513  }
5514 
5515  if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5516  opt_password, current_db, opt_port,
5517  opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5518  {
5519  fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
5520  exit(1);
5521  }
5522  mysql_local->reconnect= 1;
5523  strmov(query, "select 1; select 'another value'");
5524  stmt= mysql_simple_prepare(mysql_local, query);
5525  check_stmt_r(stmt);
5526  mysql_close(mysql_local);
5527 }
5528 
5529 
5530 /* Test simple bind store result */
5531 
5532 static void test_store_result()
5533 {
5534  MYSQL_STMT *stmt;
5535  int rc;
5536  int32 nData;
5537  char szData[100];
5538  MYSQL_BIND my_bind[2];
5539  ulong length, length1;
5540  my_bool is_null[2];
5541 
5542  myheader("test_store_result");
5543 
5544  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5545  myquery(rc);
5546 
5547  rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5548  myquery(rc);
5549 
5550  rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5551  myquery(rc);
5552 
5553  rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5554  myquery(rc);
5555 
5556  rc= mysql_commit(mysql);
5557  myquery(rc);
5558 
5559  /* fetch */
5560  memset(my_bind, 0, sizeof(my_bind));
5561  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5562  my_bind[0].buffer= (void *) &nData; /* integer data */
5563  my_bind[0].length= &length;
5564  my_bind[0].is_null= &is_null[0];
5565 
5566  length= 0;
5567  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5568  my_bind[1].buffer= szData; /* string data */
5569  my_bind[1].buffer_length= sizeof(szData);
5570  my_bind[1].length= &length1;
5571  my_bind[1].is_null= &is_null[1];
5572  length1= 0;
5573 
5574  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5575  check_stmt(stmt);
5576 
5577  rc= mysql_stmt_bind_result(stmt, my_bind);
5578  check_execute(stmt, rc);
5579 
5580  rc= mysql_stmt_execute(stmt);
5581  check_execute(stmt, rc);
5582 
5583  rc= mysql_stmt_store_result(stmt);
5584  check_execute(stmt, rc);
5585 
5586  rc= mysql_stmt_fetch(stmt);
5587  check_execute(stmt, rc);
5588 
5589  if (!opt_silent)
5590  fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5591  DIE_UNLESS(nData == 10);
5592  DIE_UNLESS(strcmp(szData, "venu") == 0);
5593  DIE_UNLESS(length1 == 4);
5594 
5595  rc= mysql_stmt_fetch(stmt);
5596  check_execute(stmt, rc);
5597 
5598  if (!opt_silent)
5599  fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5600  DIE_UNLESS(nData == 20);
5601  DIE_UNLESS(strcmp(szData, "mysql") == 0);
5602  DIE_UNLESS(length1 == 5);
5603 
5604  length= 99;
5605  rc= mysql_stmt_fetch(stmt);
5606  check_execute(stmt, rc);
5607 
5608  if (!opt_silent && is_null[0])
5609  fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5610  DIE_UNLESS(is_null[0]);
5611  DIE_UNLESS(strcmp(szData, "monty") == 0);
5612  DIE_UNLESS(length1 == 5);
5613 
5614  rc= mysql_stmt_fetch(stmt);
5615  DIE_UNLESS(rc == MYSQL_NO_DATA);
5616 
5617  rc= mysql_stmt_execute(stmt);
5618  check_execute(stmt, rc);
5619 
5620  rc= mysql_stmt_store_result(stmt);
5621  check_execute(stmt, rc);
5622 
5623  rc= mysql_stmt_fetch(stmt);
5624  check_execute(stmt, rc);
5625 
5626  if (!opt_silent)
5627  fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5628  DIE_UNLESS(nData == 10);
5629  DIE_UNLESS(strcmp(szData, "venu") == 0);
5630  DIE_UNLESS(length1 == 4);
5631 
5632  rc= mysql_stmt_fetch(stmt);
5633  check_execute(stmt, rc);
5634 
5635  if (!opt_silent)
5636  fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5637  DIE_UNLESS(nData == 20);
5638  DIE_UNLESS(strcmp(szData, "mysql") == 0);
5639  DIE_UNLESS(length1 == 5);
5640 
5641  length= 99;
5642  rc= mysql_stmt_fetch(stmt);
5643  check_execute(stmt, rc);
5644 
5645  if (!opt_silent && is_null[0])
5646  fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5647  DIE_UNLESS(is_null[0]);
5648  DIE_UNLESS(strcmp(szData, "monty") == 0);
5649  DIE_UNLESS(length1 == 5);
5650 
5651  rc= mysql_stmt_fetch(stmt);
5652  DIE_UNLESS(rc == MYSQL_NO_DATA);
5653 
5654  mysql_stmt_close(stmt);
5655 }
5656 
5657 
5658 /* Test simple bind store result */
5659 
5660 static void test_store_result1()
5661 {
5662  MYSQL_STMT *stmt;
5663  int rc;
5664 
5665  myheader("test_store_result1");
5666 
5667  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5668  myquery(rc);
5669 
5670  rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5671  myquery(rc);
5672 
5673  rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5674  myquery(rc);
5675 
5676  rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5677  myquery(rc);
5678 
5679  rc= mysql_commit(mysql);
5680  myquery(rc);
5681 
5682  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5683  check_stmt(stmt);
5684 
5685  rc= mysql_stmt_execute(stmt);
5686  check_execute(stmt, rc);
5687 
5688  rc= mysql_stmt_store_result(stmt);
5689  check_execute(stmt, rc);
5690 
5691  rc= 0;
5692  while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5693  rc++;
5694  if (!opt_silent)
5695  fprintf(stdout, "\n total rows: %d", rc);
5696  DIE_UNLESS(rc == 3);
5697 
5698  rc= mysql_stmt_execute(stmt);
5699  check_execute(stmt, rc);
5700 
5701  rc= mysql_stmt_store_result(stmt);
5702  check_execute(stmt, rc);
5703 
5704  rc= 0;
5705  while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5706  rc++;
5707  if (!opt_silent)
5708  fprintf(stdout, "\n total rows: %d", rc);
5709  DIE_UNLESS(rc == 3);
5710 
5711  mysql_stmt_close(stmt);
5712 }
5713 
5714 
5715 /* Another test for bind and store result */
5716 
5717 static void test_store_result2()
5718 {
5719  MYSQL_STMT *stmt;
5720  int rc;
5721  int nData;
5722  ulong length;
5723  MYSQL_BIND my_bind[1];
5724  char query[MAX_TEST_QUERY_LENGTH];
5725 
5726  myheader("test_store_result2");
5727 
5728  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5729  myquery(rc);
5730 
5731  rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5732  myquery(rc);
5733 
5734  rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5735  myquery(rc);
5736 
5737  rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5738  myquery(rc);
5739 
5740  rc= mysql_commit(mysql);
5741  myquery(rc);
5742 
5743  /*
5744  We need to memset bind structure because mysql_stmt_bind_param checks all
5745  its members.
5746  */
5747  memset(my_bind, 0, sizeof(my_bind));
5748 
5749  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5750  my_bind[0].buffer= (void *) &nData; /* integer data */
5751  my_bind[0].length= &length;
5752  my_bind[0].is_null= 0;
5753 
5754  strmov((char *)query , "SELECT col1 FROM test_store_result where col1= ?");
5755  stmt= mysql_simple_prepare(mysql, query);
5756  check_stmt(stmt);
5757 
5758  rc= mysql_stmt_bind_param(stmt, my_bind);
5759  check_execute(stmt, rc);
5760 
5761  rc= mysql_stmt_bind_result(stmt, my_bind);
5762  check_execute(stmt, rc);
5763 
5764  nData= 10; length= 0;
5765  rc= mysql_stmt_execute(stmt);
5766  check_execute(stmt, rc);
5767 
5768  nData= 0;
5769  rc= mysql_stmt_store_result(stmt);
5770  check_execute(stmt, rc);
5771 
5772  rc= mysql_stmt_fetch(stmt);
5773  check_execute(stmt, rc);
5774 
5775  if (!opt_silent)
5776  fprintf(stdout, "\n row 1: %d", nData);
5777  DIE_UNLESS(nData == 10);
5778 
5779  rc= mysql_stmt_fetch(stmt);
5780  DIE_UNLESS(rc == MYSQL_NO_DATA);
5781 
5782  nData= 20;
5783  rc= mysql_stmt_execute(stmt);
5784  check_execute(stmt, rc);
5785 
5786  nData= 0;
5787  rc= mysql_stmt_store_result(stmt);
5788  check_execute(stmt, rc);
5789 
5790  rc= mysql_stmt_fetch(stmt);
5791  check_execute(stmt, rc);
5792 
5793  if (!opt_silent)
5794  fprintf(stdout, "\n row 1: %d", nData);
5795  DIE_UNLESS(nData == 20);
5796 
5797  rc= mysql_stmt_fetch(stmt);
5798  DIE_UNLESS(rc == MYSQL_NO_DATA);
5799  mysql_stmt_close(stmt);
5800 }
5801 
5802 
5803 /* Test simple subselect prepare */
5804 
5805 static void test_subselect()
5806 {
5807 
5808  MYSQL_STMT *stmt;
5809  int rc, id;
5810  MYSQL_BIND my_bind[1];
5811  DBUG_ENTER("test_subselect");
5812 
5813  myheader("test_subselect");
5814 
5815  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub1");
5816  myquery(rc);
5817 
5818  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub2");
5819  myquery(rc);
5820 
5821  rc= mysql_query(mysql, "CREATE TABLE test_sub1(id int)");
5822  myquery(rc);
5823 
5824  rc= mysql_query(mysql, "CREATE TABLE test_sub2(id int, id1 int)");
5825  myquery(rc);
5826 
5827  rc= mysql_query(mysql, "INSERT INTO test_sub1 values(2)");
5828  myquery(rc);
5829 
5830  rc= mysql_query(mysql, "INSERT INTO test_sub2 VALUES(1, 7), (2, 7)");
5831  myquery(rc);
5832 
5833  rc= mysql_commit(mysql);
5834  myquery(rc);
5835 
5836  /* fetch */
5837  /*
5838  We need to memset bind structure because mysql_stmt_bind_param checks all
5839  its members.
5840  */
5841  memset(my_bind, 0, sizeof(my_bind));
5842 
5843  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5844  my_bind[0].buffer= (void *) &id;
5845  my_bind[0].length= 0;
5846  my_bind[0].is_null= 0;
5847 
5848  stmt= mysql_simple_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id= ?");
5849  check_stmt(stmt);
5850 
5851  rc= mysql_stmt_bind_param(stmt, my_bind);
5852  check_execute(stmt, rc);
5853 
5854  id= 2;
5855  rc= mysql_stmt_execute(stmt);
5856  check_execute(stmt, rc);
5857 
5858  verify_st_affected_rows(stmt, 1);
5859 
5860  id= 9;
5861  rc= mysql_stmt_execute(stmt);
5862  check_execute(stmt, rc);
5863 
5864  verify_st_affected_rows(stmt, 0);
5865 
5866  mysql_stmt_close(stmt);
5867 
5868  rc= my_stmt_result("SELECT * FROM test_sub2");
5869  DIE_UNLESS(rc == 3);
5870 
5871  rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
5872  "from test_sub2 WHERE id1= 8)");
5873  DIE_UNLESS(rc == 1);
5874  rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
5875  "from test_sub2 WHERE id1= 7)");
5876  DIE_UNLESS(rc == 1);
5877 
5878  stmt= mysql_simple_prepare(mysql, ("SELECT ROW(1, 7) IN (select id, id1 "
5879  "from test_sub2 WHERE id1= ?)"));
5880  check_stmt(stmt);
5881 
5882  rc= mysql_stmt_bind_param(stmt, my_bind);
5883  check_execute(stmt, rc);
5884 
5885  rc= mysql_stmt_bind_result(stmt, my_bind);
5886  check_execute(stmt, rc);
5887 
5888  id= 7;
5889  rc= mysql_stmt_execute(stmt);
5890  check_execute(stmt, rc);
5891 
5892  rc= mysql_stmt_fetch(stmt);
5893  check_execute(stmt, rc);
5894 
5895  if (!opt_silent)
5896  fprintf(stdout, "\n row 1: %d", id);
5897  DIE_UNLESS(id == 1);
5898 
5899  rc= mysql_stmt_fetch(stmt);
5900  DIE_UNLESS(rc == MYSQL_NO_DATA);
5901 
5902  id= 8;
5903  rc= mysql_stmt_execute(stmt);
5904  check_execute(stmt, rc);
5905 
5906  rc= mysql_stmt_fetch(stmt);
5907  check_execute(stmt, rc);
5908 
5909  if (!opt_silent)
5910  fprintf(stdout, "\n row 1: %d", id);
5911  DIE_UNLESS(id == 0);
5912 
5913  rc= mysql_stmt_fetch(stmt);
5914  DIE_UNLESS(rc == MYSQL_NO_DATA);
5915 
5916  mysql_stmt_close(stmt);
5917  DBUG_VOID_RETURN;
5918 }
5919 
5920 
5921 /*
5922  Generalized conversion routine to handle DATE, TIME and DATETIME
5923  conversion using MYSQL_TIME structure
5924 */
5925 
5926 static void bind_date_conv(uint row_count, my_bool preserveFractions)
5927 {
5928  MYSQL_STMT *stmt= 0;
5929  uint rc, i, count= row_count;
5930  ulong length[4];
5931  MYSQL_BIND my_bind[4];
5932  my_bool is_null[4]= {0};
5933  MYSQL_TIME tm[4];
5934  ulong second_part;
5935  uint year, month, day, hour, minute, sec;
5936  uint now_year= 1990, now_month= 3, now_day= 13;
5937 
5938  rc= mysql_query(mysql, "SET timestamp=UNIX_TIMESTAMP('1990-03-13')");
5939  myquery(rc);
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 memset bind structure because mysql_stmt_bind_param checks all
5948  its members.
5949  */
5950  memset(my_bind, 0, 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.%06lu",
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  (tm[i].year == now_year &&
6042  my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6043  DIE_UNLESS(tm[i].month == 0 || tm[i].month == month + count ||
6044  (tm[i].month == now_month &&
6045  my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6046  DIE_UNLESS(tm[i].day == 0 || tm[i].day == day + count ||
6047  (tm[i].day == now_day &&
6048  my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6049 
6050  DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count);
6051  DIE_UNLESS(tm[i].minute == 0 || tm[i].minute == minute+count);
6052  DIE_UNLESS(tm[i].second == 0 || tm[i].second == sec+count);
6053  if (preserveFractions) {
6054  if (i == 3) { /* Dates dont have fractions */
6055  DIE_UNLESS(tm[i].second_part == 0);
6056  } else {
6057  DIE_UNLESS(tm[i].second_part == second_part+count);
6058  }
6059  } else {
6060  DIE_UNLESS((tm[i].second_part == 0)||
6061  tm[i].second_part == second_part+count);
6062  }
6063  }
6064  }
6065  rc= mysql_stmt_fetch(stmt);
6066  DIE_UNLESS(rc == MYSQL_NO_DATA);
6067 
6068  mysql_stmt_close(stmt);
6069 }
6070 
6071 
6072 /* Test DATE, TIME, DATETIME and TS with MYSQL_TIME conversion */
6073 
6074 static void test_date()
6075 {
6076  int rc;
6077 
6078  myheader("test_date");
6079 
6080  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6081  myquery(rc);
6082 
6083  rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6084  c2 TIME, \
6085  c3 DATETIME, \
6086  c4 DATE)");
6087 
6088  myquery(rc);
6089 
6090  bind_date_conv(5,FALSE);
6091 }
6092 
6093 
6094 /* Test DATE, TIME(6), DATETIME(6) and TS(6) with MYSQL_TIME conversion */
6095 
6096 static void test_date_frac()
6097 {
6098  int rc;
6099 
6100  myheader("test_date");
6101 
6102  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6103  myquery(rc);
6104 
6105  rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP(6), \
6106  c2 TIME(6), \
6107  c3 DATETIME(6), \
6108  c4 DATE)");
6109 
6110  myquery(rc);
6111 
6112  bind_date_conv(5,TRUE);
6113 }
6114 
6115 
6116 /* Test all time types to DATE and DATE to all types */
6117 
6118 static void test_date_date()
6119 {
6120  int rc;
6121 
6122  myheader("test_date_date");
6123 
6124  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6125  myquery(rc);
6126 
6127  rc= mysql_query(mysql, "CREATE TABLE test_date(c1 DATE, \
6128  c2 DATE, \
6129  c3 DATE, \
6130  c4 DATE)");
6131 
6132  myquery(rc);
6133 
6134  bind_date_conv(3,FALSE);
6135 }
6136 
6137 
6138 /* Test all time types to TIME and TIME to all types */
6139 
6140 static void test_date_time()
6141 {
6142  int rc;
6143 
6144  myheader("test_date_time");
6145 
6146  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6147  myquery(rc);
6148 
6149  rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIME, \
6150  c2 TIME, \
6151  c3 TIME, \
6152  c4 TIME)");
6153 
6154  myquery(rc);
6155 
6156  bind_date_conv(3, FALSE);
6157 }
6158 
6159 
6160 /* Test all time types to TIMESTAMP and TIMESTAMP to all types */
6161 
6162 static void test_date_ts()
6163 {
6164  int rc;
6165 
6166  myheader("test_date_ts");
6167 
6168  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6169  myquery(rc);
6170 
6171  rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6172  c2 TIMESTAMP, \
6173  c3 TIMESTAMP, \
6174  c4 TIMESTAMP)");
6175 
6176  myquery(rc);
6177 
6178  bind_date_conv(2, FALSE);
6179 }
6180 
6181 
6182 /* Test all time types to DATETIME and DATETIME to all types */
6183 
6184 static void test_date_dt()
6185 {
6186  int rc;
6187 
6188  myheader("test_date_dt");
6189 
6190  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6191  myquery(rc);
6192 
6193  rc= mysql_query(mysql, "CREATE TABLE test_date(c1 datetime, "
6194  " c2 datetime, c3 datetime, c4 date)");
6195  myquery(rc);
6196 
6197  bind_date_conv(2, FALSE);
6198 }
6199 
6200 
6201 /*
6202  Test TIME/DATETIME parameters to cover the following methods:
6203  Item_param::val_int()
6204  Item_param::val_real()
6205  Item_param::val_decimal()
6206 */
6207 static void test_temporal_param()
6208 {
6209 #define N_PARAMS 3
6210  MYSQL_STMT *stmt= 0;
6211  uint rc;
6212  ulong length[N_PARAMS], length2[N_PARAMS];
6213  MYSQL_BIND my_bind[N_PARAMS], my_bind2[N_PARAMS];
6214  my_bool is_null[N_PARAMS], is_null2[N_PARAMS];
6215  MYSQL_TIME tm;
6216  longlong bigint= 123;
6217  double real= 123;
6218  char dec[40];
6219 
6220  /* Initialize param/fetch buffers for data, null flags, lengths */
6221  memset(&my_bind, 0, sizeof(my_bind));
6222  memset(&my_bind2, 0, sizeof(my_bind2));
6223  memset(&length, 0, sizeof(length));
6224  memset(&length2, 0, sizeof(length2));
6225  memset(&is_null, 0, sizeof(is_null));
6226  memset(&is_null2, 0, sizeof(is_null2));
6227 
6228  /* Initialize the first input parameter */
6229  my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
6230  my_bind[0].buffer= (void *) &tm;
6231  my_bind[0].is_null= &is_null[0];
6232  my_bind[0].length= &length[0];
6233  my_bind[0].buffer_length= sizeof(tm);
6234 
6235  /* Clone the second and the third input parameter */
6236  my_bind[2]= my_bind[1]= my_bind[0];
6237 
6238  /* Initialize fetch parameters */
6239  my_bind2[0].buffer_type= MYSQL_TYPE_LONGLONG;
6240  my_bind2[0].length= &length2[0];
6241  my_bind2[0].is_null= &is_null2[0];
6242  my_bind2[0].buffer_length= sizeof(bigint);
6243  my_bind2[0].buffer= (void *) &bigint;
6244 
6245  my_bind2[1].buffer_type= MYSQL_TYPE_DOUBLE;
6246  my_bind2[1].length= &length2[1];
6247  my_bind2[1].is_null= &is_null2[1];
6248  my_bind2[1].buffer_length= sizeof(real);
6249  my_bind2[1].buffer= (void *) &real;
6250 
6251  my_bind2[2].buffer_type= MYSQL_TYPE_STRING;
6252  my_bind2[2].length= &length2[2];
6253  my_bind2[2].is_null= &is_null2[2];
6254  my_bind2[2].buffer_length= sizeof(dec);
6255  my_bind2[2].buffer= (void *) &dec;
6256 
6257 
6258  /* Prepare and bind input and output parameters */
6259  stmt= mysql_simple_prepare(mysql, "SELECT CAST(? AS SIGNED), ?+0e0, ?+0.0");
6260  check_stmt(stmt);
6261  verify_param_count(stmt, N_PARAMS);
6262 
6263  rc= mysql_stmt_bind_param(stmt, my_bind);
6264  check_execute(stmt, rc);
6265 
6266  rc= mysql_stmt_bind_result(stmt, my_bind2);
6267  check_execute(stmt, rc);
6268 
6269  /* Initialize DATETIME value */
6270  tm.neg= 0;
6271  tm.time_type= MYSQL_TIMESTAMP_DATETIME;
6272  tm.year= 2001;
6273  tm.month= 10;
6274  tm.day= 20;
6275  tm.hour= 10;
6276  tm.minute= 10;
6277  tm.second= 59;
6278  tm.second_part= 500000;
6279 
6280  /* Execute and fetch */
6281  rc= mysql_stmt_execute(stmt);
6282  check_execute(stmt, rc);
6283 
6284  rc= mysql_stmt_store_result(stmt);
6285  check_execute(stmt, rc);
6286 
6287  rc= mysql_stmt_fetch(stmt);
6288  check_execute(stmt, rc);
6289 
6290  if (!opt_silent)
6291  printf("\n%lld %f '%s'\n", bigint, real, dec);
6292 
6293  /* Check values. */
6294  DIE_UNLESS(bigint == 20011020101100LL);
6295  DIE_UNLESS(real == 20011020101059.5);
6296  DIE_UNLESS(!strcmp(dec, "20011020101059.5"));
6297 
6298  mysql_stmt_close(stmt);
6299 
6300  /* Re-initialize input parameters to TIME data type */
6301  my_bind[0].buffer_type= my_bind[1].buffer_type=
6302  my_bind[2].buffer_type= MYSQL_TYPE_TIME;
6303 
6304  /* Prepare and bind intput and output parameters */
6305  stmt= mysql_simple_prepare(mysql, "SELECT CAST(? AS SIGNED), ?+0e0, ?+0.0");
6306  check_stmt(stmt);
6307  verify_param_count(stmt, N_PARAMS);
6308 
6309  rc= mysql_stmt_bind_param(stmt, my_bind);
6310  check_execute(stmt, rc);
6311 
6312  rc= mysql_stmt_bind_result(stmt, my_bind2);
6313  check_execute(stmt, rc);
6314 
6315  /* Initialize TIME value */
6316  tm.neg= 0;
6317  tm.time_type= MYSQL_TIMESTAMP_TIME;
6318  tm.year= tm.month= tm.day= 0;
6319  tm.hour= 10;
6320  tm.minute= 10;
6321  tm.second= 59;
6322  tm.second_part= 500000;
6323 
6324  /* Execute and fetch */
6325  rc= mysql_stmt_execute(stmt);
6326  check_execute(stmt, rc);
6327 
6328  rc= mysql_stmt_store_result(stmt);
6329  check_execute(stmt, rc);
6330 
6331  rc= mysql_stmt_fetch(stmt);
6332  check_execute(stmt, rc);
6333 
6334  if (!opt_silent)
6335  printf("\n%lld %f '%s'\n", bigint, real, dec);
6336 
6337  /* Check returned values */
6338  DIE_UNLESS(bigint == 101100);
6339  DIE_UNLESS(real == 101059.5);
6340  DIE_UNLESS(!strcmp(dec, "101059.5"));
6341 
6342  mysql_stmt_close(stmt);
6343 }
6344 
6345 
6346 
6347 
6348 /* Misc tests to keep pure coverage happy */
6349 
6350 static void test_pure_coverage()
6351 {
6352  MYSQL_STMT *stmt;
6353  MYSQL_BIND my_bind[2];
6354  int rc;
6355  ulong length;
6356 
6357  myheader("test_pure_coverage");
6358 
6359  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_pure");
6360  myquery(rc);
6361 
6362  rc= mysql_query(mysql, "CREATE TABLE test_pure(c1 int, c2 varchar(20))");
6363  myquery(rc);
6364 
6365  stmt= mysql_simple_prepare(mysql, "insert into test_pure(c67788) values(10)");
6366  check_stmt_r(stmt);
6367 
6368  /* Query without params and result should allow to bind 0 arrays */
6369  stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(10)");
6370  check_stmt(stmt);
6371 
6372  rc= mysql_stmt_bind_param(stmt, (MYSQL_BIND*)0);
6373  check_execute(stmt, rc);
6374 
6375  rc= mysql_stmt_execute(stmt);
6376  check_execute(stmt, rc);
6377 
6378  rc= mysql_stmt_bind_result(stmt, (MYSQL_BIND*)0);
6379  DIE_UNLESS(rc == 1);
6380 
6381  mysql_stmt_close(stmt);
6382 
6383  stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(?)");
6384  check_stmt(stmt);
6385 
6386  /*
6387  We need to memset bind structure because mysql_stmt_bind_param checks all
6388  its members.
6389  */
6390  memset(my_bind, 0, sizeof(my_bind));
6391 
6392  my_bind[0].length= &length;
6393  my_bind[0].is_null= 0;
6394  my_bind[0].buffer_length= 0;
6395 
6396  my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6397  rc= mysql_stmt_bind_param(stmt, my_bind);
6398  check_execute_r(stmt, rc); /* unsupported buffer type */
6399 
6400  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6401  rc= mysql_stmt_bind_param(stmt, my_bind);
6402  check_execute(stmt, rc);
6403 
6404  rc= mysql_stmt_store_result(stmt);
6405  check_execute(stmt, rc);
6406 
6407  mysql_stmt_close(stmt);
6408 
6409  stmt= mysql_simple_prepare(mysql, "select * from test_pure");
6410  check_execute(stmt, rc);
6411 
6412  rc= mysql_stmt_execute(stmt);
6413  check_execute(stmt, rc);
6414 
6415  // NOTE: stmt now has two columns, but only my_bind[0] is initialized.
6416  my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6417  rc= mysql_stmt_bind_result(stmt, my_bind);
6418  check_execute_r(stmt, rc); /* unsupported buffer type */
6419 
6420  rc= mysql_stmt_store_result(stmt);
6421  DIE_UNLESS(rc);
6422 
6423  rc= mysql_stmt_store_result(stmt);
6424  DIE_UNLESS(rc); /* Old error must be reset first */
6425 
6426  mysql_stmt_close(stmt);
6427 
6428  mysql_query(mysql, "DROP TABLE test_pure");
6429 }
6430 
6431 
6432 /* Test for string buffer fetch */
6433 
6434 static void test_buffers()
6435 {
6436  MYSQL_STMT *stmt;
6437  // The test_pure table has two columns.
6438  MYSQL_BIND my_bind[2];
6439  int rc;
6440  ulong length;
6441  my_bool is_null;
6442  char buffer[20];
6443 
6444  myheader("test_buffers");
6445 
6446  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_buffer");
6447  myquery(rc);
6448 
6449  rc= mysql_query(mysql, "CREATE TABLE test_buffer(str varchar(20))");
6450  myquery(rc);
6451 
6452  rc= mysql_query(mysql, "insert into test_buffer values('MySQL')\
6453  , ('Database'), ('Open-Source'), ('Popular')");
6454  myquery(rc);
6455 
6456  stmt= mysql_simple_prepare(mysql, "select str from test_buffer");
6457  check_stmt(stmt);
6458 
6459  rc= mysql_stmt_execute(stmt);
6460  check_execute(stmt, rc);
6461 
6462  memset(buffer, 0, sizeof(buffer)); /* Avoid overruns in printf() */
6463 
6464  memset(my_bind, 0, sizeof(my_bind));
6465  my_bind[0].length= &length;
6466  my_bind[0].is_null= &is_null;
6467  my_bind[0].buffer_length= 1;
6468  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6469  my_bind[0].buffer= (void *)buffer;
6470  my_bind[0].error= &my_bind[0].error_value;
6471 
6472  rc= mysql_stmt_bind_result(stmt, my_bind);
6473  check_execute(stmt, rc);
6474 
6475  rc= mysql_stmt_store_result(stmt);
6476  check_execute(stmt, rc);
6477 
6478  buffer[1]= 'X';
6479  rc= mysql_stmt_fetch(stmt);
6480  DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6481  DIE_UNLESS(my_bind[0].error_value);
6482  if (!opt_silent)
6483  fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6484  DIE_UNLESS(buffer[0] == 'M');
6485  DIE_UNLESS(buffer[1] == 'X');
6486  DIE_UNLESS(length == 5);
6487 
6488  my_bind[0].buffer_length= 8;
6489  rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6490  check_execute(stmt, rc);
6491 
6492  rc= mysql_stmt_fetch(stmt);
6493  check_execute(stmt, rc);
6494  if (!opt_silent)
6495  fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6496  DIE_UNLESS(strncmp(buffer, "Database", 8) == 0);
6497  DIE_UNLESS(length == 8);
6498 
6499  my_bind[0].buffer_length= 12;
6500  rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6501  check_execute(stmt, rc);
6502 
6503  rc= mysql_stmt_fetch(stmt);
6504  check_execute(stmt, rc);
6505  if (!opt_silent)
6506  fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6507  DIE_UNLESS(strcmp(buffer, "Open-Source") == 0);
6508  DIE_UNLESS(length == 11);
6509 
6510  my_bind[0].buffer_length= 6;
6511  rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6512  check_execute(stmt, rc);
6513 
6514  rc= mysql_stmt_fetch(stmt);
6515  DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6516  DIE_UNLESS(my_bind[0].error_value);
6517  if (!opt_silent)
6518  fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6519  DIE_UNLESS(strncmp(buffer, "Popula", 6) == 0);
6520  DIE_UNLESS(length == 7);
6521 
6522  mysql_stmt_close(stmt);
6523 }
6524 
6525 
6526 /* Test the direct query execution in the middle of open stmts */
6527 
6528 static void test_open_direct()
6529 {
6530  MYSQL_STMT *stmt;
6531  MYSQL_RES *result;
6532  int rc;
6533 
6534  myheader("test_open_direct");
6535 
6536  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_open_direct");
6537  myquery(rc);
6538 
6539  rc= mysql_query(mysql, "CREATE TABLE test_open_direct(id int, name char(6))");
6540  myquery(rc);
6541 
6542  stmt= mysql_simple_prepare(mysql, "INSERT INTO test_open_direct values(10, 'mysql')");
6543  check_stmt(stmt);
6544 
6545  rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6546  myquery(rc);
6547 
6548  result= mysql_store_result(mysql);
6549  mytest(result);
6550 
6551  rc= my_process_result_set(result);
6552  DIE_UNLESS(rc == 0);
6553  mysql_free_result(result);
6554 
6555  rc= mysql_stmt_execute(stmt);
6556  check_execute(stmt, rc);
6557 
6558  verify_st_affected_rows(stmt, 1);
6559 
6560  rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6561  myquery(rc);
6562 
6563  result= mysql_store_result(mysql);
6564  mytest(result);
6565 
6566  rc= my_process_result_set(result);
6567  DIE_UNLESS(rc == 1);
6568  mysql_free_result(result);
6569 
6570  rc= mysql_stmt_execute(stmt);
6571  check_execute(stmt, rc);
6572 
6573  verify_st_affected_rows(stmt, 1);
6574 
6575  rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6576  myquery(rc);
6577 
6578  result= mysql_store_result(mysql);
6579  mytest(result);
6580 
6581  rc= my_process_result_set(result);
6582  DIE_UNLESS(rc == 2);
6583  mysql_free_result(result);
6584 
6585  mysql_stmt_close(stmt);
6586 
6587  /* run a direct query in the middle of a fetch */
6588  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6589  check_stmt(stmt);
6590 
6591  rc= mysql_stmt_execute(stmt);
6592  check_execute(stmt, rc);
6593 
6594  rc= mysql_stmt_fetch(stmt);
6595  check_execute(stmt, rc);
6596 
6597  rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6598  myquery_r(rc);
6599 
6600  rc= mysql_stmt_close(stmt);
6601  check_execute(stmt, rc);
6602 
6603  rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6604  myquery(rc);
6605 
6606  /* run a direct query with store result */
6607  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6608  check_stmt(stmt);
6609 
6610  rc= mysql_stmt_execute(stmt);
6611  check_execute(stmt, rc);
6612 
6613  rc= mysql_stmt_store_result(stmt);
6614  check_execute(stmt, rc);
6615 
6616  rc= mysql_stmt_fetch(stmt);
6617  check_execute(stmt, rc);
6618 
6619  rc= mysql_query(mysql, "drop table test_open_direct");
6620  myquery(rc);
6621 
6622  rc= mysql_stmt_close(stmt);
6623  check_execute(stmt, rc);
6624 }
6625 
6626 
6627 /* Test fetch without prior bound buffers */
6628 
6629 static void test_fetch_nobuffs()
6630 {
6631  MYSQL_STMT *stmt;
6632  MYSQL_BIND my_bind[4];
6633  char str[4][50];
6634  int rc;
6635 
6636  myheader("test_fetch_nobuffs");
6637 
6638  stmt= mysql_simple_prepare(mysql, "SELECT DATABASE(), CURRENT_USER(), \
6639  CURRENT_DATE(), CURRENT_TIME()");
6640  check_stmt(stmt);
6641 
6642  rc= mysql_stmt_execute(stmt);
6643  check_execute(stmt, rc);
6644 
6645  rc= 0;
6646  while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6647  rc++;
6648 
6649  if (!opt_silent)
6650  fprintf(stdout, "\n total rows : %d", rc);
6651  DIE_UNLESS(rc == 1);
6652 
6653  memset(my_bind, 0, sizeof(MYSQL_BIND));
6654  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6655  my_bind[0].buffer= (void *)str[0];
6656  my_bind[0].buffer_length= sizeof(str[0]);
6657  my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0];
6658  my_bind[1].buffer= (void *)str[1];
6659  my_bind[2].buffer= (void *)str[2];
6660  my_bind[3].buffer= (void *)str[3];
6661 
6662  rc= mysql_stmt_bind_result(stmt, my_bind);
6663  check_execute(stmt, rc);
6664 
6665  rc= mysql_stmt_execute(stmt);
6666  check_execute(stmt, rc);
6667 
6668  rc= 0;
6669  while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6670  {
6671  rc++;
6672  if (!opt_silent)
6673  {
6674  fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
6675  fprintf(stdout, "\n CURRENT_USER() : %s", str[1]);
6676  fprintf(stdout, "\n CURRENT_DATE() : %s", str[2]);
6677  fprintf(stdout, "\n CURRENT_TIME() : %s", str[3]);
6678  }
6679  }
6680  if (!opt_silent)
6681  fprintf(stdout, "\n total rows : %d", rc);
6682  DIE_UNLESS(rc == 1);
6683 
6684  mysql_stmt_close(stmt);
6685 }
6686 
6687 
6688 /* Test a misc bug */
6689 
6690 static void test_ushort_bug()
6691 {
6692  MYSQL_STMT *stmt;
6693  MYSQL_BIND my_bind[4];
6694  ushort short_value;
6695  uint32 long_value;
6696  ulong s_length, l_length, ll_length, t_length;
6697  ulonglong longlong_value;
6698  int rc;
6699  uchar tiny_value;
6700  char llbuf[22];
6701  myheader("test_ushort_bug");
6702 
6703  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ushort");
6704  myquery(rc);
6705 
6706  rc= mysql_query(mysql, "CREATE TABLE test_ushort(a smallint unsigned, \
6707  b smallint unsigned, \
6708  c smallint unsigned, \
6709  d smallint unsigned)");
6710  myquery(rc);
6711 
6712  rc= mysql_query(mysql,
6713  "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)");
6714  myquery(rc);
6715 
6716 
6717  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ushort");
6718  check_stmt(stmt);
6719 
6720  rc= mysql_stmt_execute(stmt);
6721  check_execute(stmt, rc);
6722 
6723  memset(my_bind, 0, sizeof(my_bind));
6724  my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6725  my_bind[0].buffer= (void *)&short_value;
6726  my_bind[0].is_unsigned= TRUE;
6727  my_bind[0].length= &s_length;
6728 
6729  my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6730  my_bind[1].buffer= (void *)&long_value;
6731  my_bind[1].length= &l_length;
6732 
6733  my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6734  my_bind[2].buffer= (void *)&longlong_value;
6735  my_bind[2].length= &ll_length;
6736 
6737  my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6738  my_bind[3].buffer= (void *)&tiny_value;
6739  my_bind[3].is_unsigned= TRUE;
6740  my_bind[3].length= &t_length;
6741 
6742  rc= mysql_stmt_bind_result(stmt, my_bind);
6743  check_execute(stmt, rc);
6744 
6745  rc= mysql_stmt_fetch(stmt);
6746  check_execute(stmt, rc);
6747 
6748  if (!opt_silent)
6749  {
6750  fprintf(stdout, "\n ushort : %d (%ld)", short_value, s_length);
6751  fprintf(stdout, "\n ulong : %lu (%ld)", (ulong) long_value, l_length);
6752  fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6753  ll_length);
6754  fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
6755  }
6756 
6757  DIE_UNLESS(short_value == 35999);
6758  DIE_UNLESS(s_length == 2);
6759 
6760  DIE_UNLESS(long_value == 35999);
6761  DIE_UNLESS(l_length == 4);
6762 
6763  DIE_UNLESS(longlong_value == 35999);
6764  DIE_UNLESS(ll_length == 8);
6765 
6766  DIE_UNLESS(tiny_value == 200);
6767  DIE_UNLESS(t_length == 1);
6768 
6769  rc= mysql_stmt_fetch(stmt);
6770  DIE_UNLESS(rc == MYSQL_NO_DATA);
6771 
6772  mysql_stmt_close(stmt);
6773 }
6774 
6775 
6776 /* Test a misc smallint-signed conversion bug */
6777 
6778 static void test_sshort_bug()
6779 {
6780  MYSQL_STMT *stmt;
6781  MYSQL_BIND my_bind[4];
6782  short short_value;
6783  int32 long_value;
6784  ulong s_length, l_length, ll_length, t_length;
6785  ulonglong longlong_value;
6786  int rc;
6787  uchar tiny_value;
6788  char llbuf[22];
6789 
6790  myheader("test_sshort_bug");
6791 
6792  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sshort");
6793  myquery(rc);
6794 
6795  rc= mysql_query(mysql, "CREATE TABLE test_sshort(a smallint signed, \
6796  b smallint signed, \
6797  c smallint unsigned, \
6798  d smallint unsigned)");
6799  myquery(rc);
6800 
6801  rc= mysql_query(mysql, "INSERT INTO test_sshort VALUES(-5999, -5999, 35999, 200)");
6802  myquery(rc);
6803 
6804 
6805  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_sshort");
6806  check_stmt(stmt);
6807 
6808  rc= mysql_stmt_execute(stmt);
6809  check_execute(stmt, rc);
6810 
6811  memset(my_bind, 0, sizeof(my_bind));
6812  my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6813  my_bind[0].buffer= (void *)&short_value;
6814  my_bind[0].length= &s_length;
6815 
6816  my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6817  my_bind[1].buffer= (void *)&long_value;
6818  my_bind[1].length= &l_length;
6819 
6820  my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6821  my_bind[2].buffer= (void *)&longlong_value;
6822  my_bind[2].length= &ll_length;
6823 
6824  my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6825  my_bind[3].buffer= (void *)&tiny_value;
6826  my_bind[3].is_unsigned= TRUE;
6827  my_bind[3].length= &t_length;
6828 
6829  rc= mysql_stmt_bind_result(stmt, my_bind);
6830  check_execute(stmt, rc);
6831 
6832  rc= mysql_stmt_fetch(stmt);
6833  check_execute(stmt, rc);
6834 
6835  if (!opt_silent)
6836  {
6837  fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length);
6838  fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length);
6839  fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6840  ll_length);
6841  fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
6842  }
6843 
6844  DIE_UNLESS(short_value == -5999);
6845  DIE_UNLESS(s_length == 2);
6846 
6847  DIE_UNLESS(long_value == -5999);
6848  DIE_UNLESS(l_length == 4);
6849 
6850  DIE_UNLESS(longlong_value == 35999);
6851  DIE_UNLESS(ll_length == 8);
6852 
6853  DIE_UNLESS(tiny_value == 200);
6854  DIE_UNLESS(t_length == 1);
6855 
6856  rc= mysql_stmt_fetch(stmt);
6857  DIE_UNLESS(rc == MYSQL_NO_DATA);
6858 
6859  mysql_stmt_close(stmt);
6860 }
6861 
6862 
6863 /* Test a misc tinyint-signed conversion bug */
6864 
6865 static void test_stiny_bug()
6866 {
6867  MYSQL_STMT *stmt;
6868  MYSQL_BIND my_bind[4];
6869  short short_value;
6870  int32 long_value;
6871  ulong s_length, l_length, ll_length, t_length;
6872  ulonglong longlong_value;
6873  int rc;
6874  uchar tiny_value;
6875  char llbuf[22];
6876 
6877  myheader("test_stiny_bug");
6878 
6879  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_stiny");
6880  myquery(rc);
6881 
6882  rc= mysql_query(mysql, "CREATE TABLE test_stiny(a tinyint signed, \
6883  b tinyint signed, \
6884  c tinyint unsigned, \
6885  d tinyint unsigned)");
6886  myquery(rc);
6887 
6888  rc= mysql_query(mysql, "INSERT INTO test_stiny VALUES(-128, -127, 255, 0)");
6889  myquery(rc);
6890 
6891 
6892  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_stiny");
6893  check_stmt(stmt);
6894 
6895  rc= mysql_stmt_execute(stmt);
6896  check_execute(stmt, rc);
6897 
6898  memset(my_bind, 0, sizeof(my_bind));
6899  my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6900  my_bind[0].buffer= (void *)&short_value;
6901  my_bind[0].length= &s_length;
6902 
6903  my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6904  my_bind[1].buffer= (void *)&long_value;
6905  my_bind[1].length= &l_length;
6906 
6907  my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6908  my_bind[2].buffer= (void *)&longlong_value;
6909  my_bind[2].length= &ll_length;
6910 
6911  my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6912  my_bind[3].buffer= (void *)&tiny_value;
6913  my_bind[3].length= &t_length;
6914 
6915  rc= mysql_stmt_bind_result(stmt, my_bind);
6916  check_execute(stmt, rc);
6917 
6918  rc= mysql_stmt_fetch(stmt);
6919  check_execute(stmt, rc);
6920 
6921  if (!opt_silent)
6922  {
6923  fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length);
6924  fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length);
6925  fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6926  ll_length);
6927  fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
6928  }
6929 
6930  DIE_UNLESS(short_value == -128);
6931  DIE_UNLESS(s_length == 2);
6932 
6933  DIE_UNLESS(long_value == -127);
6934  DIE_UNLESS(l_length == 4);
6935 
6936  DIE_UNLESS(longlong_value == 255);
6937  DIE_UNLESS(ll_length == 8);
6938 
6939  DIE_UNLESS(tiny_value == 0);
6940  DIE_UNLESS(t_length == 1);
6941 
6942  rc= mysql_stmt_fetch(stmt);
6943  DIE_UNLESS(rc == MYSQL_NO_DATA);
6944 
6945  mysql_stmt_close(stmt);
6946 }
6947 
6948 
6949 /* Test misc field information, bug: #74 */
6950 
6951 static void test_field_misc()
6952 {
6953  MYSQL_STMT *stmt;
6954  MYSQL_RES *result;
6955  int rc;
6956 
6957  myheader("test_field_misc");
6958 
6959  rc= mysql_query(mysql, "SELECT @@autocommit");
6960  myquery(rc);
6961 
6962  result= mysql_store_result(mysql);
6963  mytest(result);
6964 
6965  rc= my_process_result_set(result);
6966  DIE_UNLESS(rc == 1);
6967 
6968  verify_prepare_field(result, 0,
6969  "@@autocommit", "", /* field and its org name */
6970  MYSQL_TYPE_LONGLONG, /* field type */
6971  "", "", /* table and its org name */
6972  "", 1, 0); /* db name, length(its bool flag)*/
6973 
6974  mysql_free_result(result);
6975 
6976  stmt= mysql_simple_prepare(mysql, "SELECT @@autocommit");
6977  check_stmt(stmt);
6978 
6979  rc= mysql_stmt_execute(stmt);
6980  check_execute(stmt, rc);
6981 
6982  result= mysql_stmt_result_metadata(stmt);
6983  mytest(result);
6984 
6985  rc= my_process_stmt_result(stmt);
6986  DIE_UNLESS(rc == 1);
6987 
6988  verify_prepare_field(result, 0,
6989  "@@autocommit", "", /* field and its org name */
6990  MYSQL_TYPE_LONGLONG, /* field type */
6991  "", "", /* table and its org name */
6992  "", 1, 0); /* db name, length(its bool flag)*/
6993 
6994  mysql_free_result(result);
6995  mysql_stmt_close(stmt);
6996 
6997  stmt= mysql_simple_prepare(mysql, "SELECT @@max_error_count");
6998  check_stmt(stmt);
6999 
7000  result= mysql_stmt_result_metadata(stmt);
7001  mytest(result);
7002 
7003  rc= mysql_stmt_execute(stmt);
7004  check_execute(stmt, rc);
7005 
7006  rc= my_process_stmt_result(stmt);
7007  DIE_UNLESS(rc == 1);
7008 
7009  verify_prepare_field(result, 0,
7010  "@@max_error_count", "", /* field and its org name */
7011  MYSQL_TYPE_LONGLONG, /* field type */
7012  "", "", /* table and its org name */
7013  /* db name, length */
7014  "", MY_INT64_NUM_DECIMAL_DIGITS , 0);
7015 
7016  mysql_free_result(result);
7017  mysql_stmt_close(stmt);
7018 
7019  stmt= mysql_simple_prepare(mysql, "SELECT @@max_allowed_packet");
7020  check_stmt(stmt);
7021 
7022  result= mysql_stmt_result_metadata(stmt);
7023  mytest(result);
7024 
7025  rc= mysql_stmt_execute(stmt);
7026  check_execute(stmt, rc);
7027 
7028  DIE_UNLESS(1 == my_process_stmt_result(stmt));
7029 
7030  verify_prepare_field(result, 0,
7031  "@@max_allowed_packet", "", /* field and its org name */
7032  MYSQL_TYPE_LONGLONG, /* field type */
7033  "", "", /* table and its org name */
7034  /* db name, length */
7035  "", MY_INT64_NUM_DECIMAL_DIGITS, 0);
7036 
7037  mysql_free_result(result);
7038  mysql_stmt_close(stmt);
7039 
7040  stmt= mysql_simple_prepare(mysql, "SELECT @@sql_warnings");
7041  check_stmt(stmt);
7042 
7043  result= mysql_stmt_result_metadata(stmt);
7044  mytest(result);
7045 
7046  rc= mysql_stmt_execute(stmt);
7047  check_execute(stmt, rc);
7048 
7049  rc= my_process_stmt_result(stmt);
7050  DIE_UNLESS(rc == 1);
7051 
7052  verify_prepare_field(result, 0,
7053  "@@sql_warnings", "", /* field and its org name */
7054  MYSQL_TYPE_LONGLONG, /* field type */
7055  "", "", /* table and its org name */
7056  "", 1, 0); /* db name, length */
7057 
7058  mysql_free_result(result);
7059  mysql_stmt_close(stmt);
7060 }
7061 
7062 
7063 /*
7064  Test SET feature with prepare stmts
7065  bug #85 (reported by mark@mysql.com)
7066 */
7067 
7068 static void test_set_option()
7069 {
7070  MYSQL_STMT *stmt;
7071  MYSQL_RES *result;
7072  int rc;
7073 
7074  myheader("test_set_option");
7075 
7076  mysql_autocommit(mysql, TRUE);
7077 
7078  /* LIMIT the rows count to 2 */
7079  rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT= 2");
7080  myquery(rc);
7081 
7082  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_limit");
7083  myquery(rc);
7084 
7085  rc= mysql_query(mysql, "CREATE TABLE test_limit(a tinyint)");
7086  myquery(rc);
7087 
7088  rc= mysql_query(mysql, "INSERT INTO test_limit VALUES(10), (20), (30), (40)");
7089  myquery(rc);
7090 
7091  if (!opt_silent)
7092  fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)");
7093  rc= mysql_query(mysql, "SELECT * FROM test_limit");
7094  myquery(rc);
7095 
7096  result= mysql_store_result(mysql);
7097  mytest(result);
7098 
7099  rc= my_process_result_set(result);
7100  DIE_UNLESS(rc == 2);
7101 
7102  mysql_free_result(result);
7103 
7104  if (!opt_silent)
7105  fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)");
7106  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7107  check_stmt(stmt);
7108 
7109  rc= mysql_stmt_execute(stmt);
7110  check_execute(stmt, rc);
7111 
7112  rc= my_process_stmt_result(stmt);
7113  DIE_UNLESS(rc == 2);
7114 
7115  mysql_stmt_close(stmt);
7116 
7117  /* RESET the LIMIT the rows count to 0 */
7118  if (!opt_silent)
7119  fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)");
7120  rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT=DEFAULT");
7121  myquery(rc);
7122 
7123  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7124  check_stmt(stmt);
7125 
7126  rc= mysql_stmt_execute(stmt);
7127  check_execute(stmt, rc);
7128 
7129  rc= my_process_stmt_result(stmt);
7130  DIE_UNLESS(rc == 4);
7131 
7132  mysql_stmt_close(stmt);
7133 }
7134 
7135 
7136 #ifdef EMBEDDED_LIBRARY
7137 static void test_embedded_start_stop()
7138 {
7139  MYSQL *mysql_emb=NULL;
7140  int i, j;
7141  int argc= original_argc; // Start with the original args
7142  char **argv, **my_argv;
7143  char test_name[]= "test_embedded_start_stop";
7144  const unsigned int drop_db= opt_drop_db;
7145 #define EMBEDDED_RESTARTS 64
7146 
7147  myheader("test_embedded_start_stop");
7148 
7149  /* Must stop the main embedded server, since we use the same config. */
7150  opt_drop_db= 0;
7151  client_disconnect(mysql); /* disconnect from server */
7152  free_defaults(defaults_argv);
7153  mysql_server_end();
7154  /* Free everything allocated by my_once_alloc */
7155  my_end(0);
7156  opt_drop_db= drop_db;
7157 
7158  /*
7159  Use a copy of the original arguments.
7160  The arguments will be altered when reading the configs and parsing
7161  options.
7162  */
7163  my_argv= malloc((argc + 1) * sizeof(char*));
7164  if (!my_argv)
7165  exit(1);
7166 
7167  /* Test restarting the embedded library many times. */
7168  for (i= 1; i <= EMBEDDED_RESTARTS; i++)
7169  {
7170  argv= my_argv;
7171  argv[0]= test_name;
7172  for (j= 1; j < argc; j++)
7173  argv[j]= original_argv[j];
7174 
7175  /* Initialize everything again. */
7176  MY_INIT(argv[0]);
7177 
7178  /* Load the client defaults from the .cnf file[s]. */
7179  if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
7180  {
7181  myerror("load_defaults failed");
7182  exit(1);
7183  }
7184 
7185  /* Parse the options (including the ones given from defaults files). */
7186  get_options(&argc, &argv);
7187 
7188  /* mysql_library_init is the same as mysql_server_init. */
7189  if (mysql_library_init(embedded_server_arg_count,
7190  embedded_server_args,
7191  (char**) embedded_server_groups))
7192  {
7193  myerror("mysql_library_init failed");
7194  exit(1);
7195  }
7196 
7197  /* Create a client connection. */
7198  if (!(mysql_emb= mysql_client_init(NULL)))
7199  {
7200  myerror("mysql_client_init failed");
7201  exit(1);
7202  }
7203 
7204  /* Connect it and see if we can use the database. */
7205  if (!(mysql_real_connect(mysql_emb, opt_host, opt_user,
7206  opt_password, current_db, 0,
7207  NULL, 0)))
7208  {
7209  myerror("mysql_real_connect failed");
7210  }
7211 
7212  /* Close the client connection */
7213  mysql_close(mysql_emb);
7214  mysql_emb = NULL;
7215  /* Free arguments allocated for defaults files. */
7216  free_defaults(defaults_argv);
7217  /* mysql_library_end is a define for mysql_server_end. */
7218  mysql_library_end();
7219  /* Free everything allocated by my_once_alloc */
7220  my_end(0);
7221  }
7222 
7223  argc= original_argc;
7224  argv= my_argv;
7225  argv[0]= test_name;
7226  for (j= 1; j < argc; j++)
7227  argv[j]= original_argv[j];
7228 
7229  MY_INIT(argv[0]);
7230 
7231  if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
7232  {
7233  myerror("load_defaults failed \n ");
7234  exit(1);
7235  }
7236 
7237  get_options(&argc, &argv);
7238 
7239  /* Must start the main embedded server again after the test. */
7240  if (mysql_server_init(embedded_server_arg_count,
7241  embedded_server_args,
7242  (char**) embedded_server_groups))
7243  DIE("Can't initialize MySQL server");
7244 
7245  /* connect to server with no flags, default protocol, auto reconnect true */
7246  mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
7247  free(my_argv);
7248 }
7249 #endif /* EMBEDDED_LIBRARY */
7250 
7251 
7252 /*
7253  Test a misc GRANT option
7254  bug #89 (reported by mark@mysql.com)
7255 */
7256 
7257 #ifndef EMBEDDED_LIBRARY
7258 static void test_prepare_grant()
7259 {
7260  int rc;
7261  char query[MAX_TEST_QUERY_LENGTH];
7262 
7263  myheader("test_prepare_grant");
7264 
7265  mysql_autocommit(mysql, TRUE);
7266 
7267  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_grant");
7268  myquery(rc);
7269 
7270  rc= mysql_query(mysql, "CREATE TABLE test_grant(a tinyint primary key auto_increment)");
7271  myquery(rc);
7272 
7273  strxmov(query, "GRANT INSERT, UPDATE, SELECT ON ", current_db,
7274  ".test_grant TO 'test_grant'@",
7275  opt_host ? opt_host : "'localhost'", NullS);
7276 
7277  if (mysql_query(mysql, query))
7278  {
7279  myerror("GRANT failed");
7280 
7281  /*
7282  If server started with --skip-grant-tables, skip this test, else
7283  exit to indicate an error
7284 
7285  ER_UNKNOWN_COM_ERROR= 1047
7286  */
7287  if (mysql_errno(mysql) != 1047)
7288  exit(1);
7289  }
7290  else
7291  {
7292  MYSQL *org_mysql= mysql, *lmysql;
7293  MYSQL_STMT *stmt;
7294 
7295  if (!opt_silent)
7296  fprintf(stdout, "\n Establishing a test connection ...");
7297  if (!(lmysql= mysql_client_init(NULL)))
7298  {
7299  myerror("mysql_client_init() failed");
7300  exit(1);
7301  }
7302  if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
7303  "", current_db, opt_port,
7304  opt_unix_socket, 0)))
7305  {
7306  myerror("connection failed");
7307  mysql_close(lmysql);
7308  exit(1);
7309  }
7310  lmysql->reconnect= 1;
7311  if (!opt_silent)
7312  fprintf(stdout, "OK");
7313 
7314  mysql= lmysql;
7315  rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)");
7316  myquery(rc);
7317 
7318  rc= mysql_query(mysql, "INSERT INTO test_grant(a) VALUES(NULL)");
7319  myquery(rc);
7320 
7321  execute_prepare_query("INSERT INTO test_grant(a) VALUES(NULL)", 1);
7322  execute_prepare_query("INSERT INTO test_grant VALUES(NULL)", 1);
7323  execute_prepare_query("UPDATE test_grant SET a=9 WHERE a=1", 1);
7324  rc= my_stmt_result("SELECT a FROM test_grant");
7325  DIE_UNLESS(rc == 4);
7326 
7327  /* Both DELETE expected to fail as user does not have DELETE privs */
7328 
7329  rc= mysql_query(mysql, "DELETE FROM test_grant");
7330  myquery_r(rc);
7331 
7332  stmt= mysql_simple_prepare(mysql, "DELETE FROM test_grant");
7333  check_stmt_r(stmt);
7334 
7335  rc= my_stmt_result("SELECT * FROM test_grant");
7336  DIE_UNLESS(rc == 4);
7337 
7338  mysql_close(lmysql);
7339  mysql= org_mysql;
7340 
7341  rc= mysql_query(mysql, "delete from mysql.user where User='test_grant'");
7342  myquery(rc);
7343  DIE_UNLESS(1 == mysql_affected_rows(mysql));
7344 
7345  rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_grant'");
7346  myquery(rc);
7347  DIE_UNLESS(1 == mysql_affected_rows(mysql));
7348 
7349  }
7350 }
7351 #endif /* EMBEDDED_LIBRARY */
7352 
7353 /*
7354  Test a crash when invalid/corrupted .frm is used in the
7355  SHOW TABLE STATUS
7356  bug #93 (reported by serg@mysql.com).
7357 */
7358 
7359 static void test_frm_bug()
7360 {
7361  MYSQL_STMT *stmt;
7362  MYSQL_BIND my_bind[2];
7363  MYSQL_RES *result;
7364  MYSQL_ROW row;
7365  FILE *test_file;
7366  char data_dir[FN_REFLEN];
7367  char test_frm[FN_REFLEN];
7368  int rc;
7369 
7370  myheader("test_frm_bug");
7371 
7372  mysql_autocommit(mysql, TRUE);
7373 
7374  rc= mysql_query(mysql, "drop table if exists test_frm_bug");
7375  myquery(rc);
7376 
7377  rc= mysql_query(mysql, "flush tables");
7378  myquery(rc);
7379 
7380  stmt= mysql_simple_prepare(mysql, "show variables like 'datadir'");
7381  check_stmt(stmt);
7382 
7383  rc= mysql_stmt_execute(stmt);
7384  check_execute(stmt, rc);
7385 
7386  memset(my_bind, 0, sizeof(my_bind));
7387  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
7388  my_bind[0].buffer= data_dir;
7389  my_bind[0].buffer_length= FN_REFLEN;
7390  my_bind[1]= my_bind[0];
7391 
7392  rc= mysql_stmt_bind_result(stmt, my_bind);
7393  check_execute(stmt, rc);
7394 
7395  rc= mysql_stmt_fetch(stmt);
7396  check_execute(stmt, rc);
7397 
7398  if (!opt_silent)
7399  fprintf(stdout, "\n data directory: %s", data_dir);
7400 
7401  rc= mysql_stmt_fetch(stmt);
7402  DIE_UNLESS(rc == MYSQL_NO_DATA);
7403 
7404  strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS);
7405 
7406  if (!opt_silent)
7407  fprintf(stdout, "\n test_frm: %s", test_frm);
7408 
7409  if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
7410  {
7411  fprintf(stdout, "\n ERROR: my_fopen failed for '%s'", test_frm);
7412  fprintf(stdout, "\n test cancelled");
7413  exit(1);
7414  }
7415  if (!opt_silent)
7416  fprintf(test_file, "this is a junk file for test");
7417 
7418  rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'");
7419  myquery(rc);
7420 
7421  result= mysql_store_result(mysql);
7422  mytest(result);/* It can't be NULL */
7423 
7424  rc= my_process_result_set(result);
7425  DIE_UNLESS(rc == 1);
7426 
7427  mysql_data_seek(result, 0);
7428 
7429  row= mysql_fetch_row(result);
7430  mytest(row);
7431 
7432  if (!opt_silent)
7433  fprintf(stdout, "\n Comment: %s", row[17]);
7434  DIE_UNLESS(row[17] != 0);
7435 
7436  mysql_free_result(result);
7437  mysql_stmt_close(stmt);
7438 
7439  my_fclose(test_file, MYF(0));
7440  mysql_query(mysql, "drop table if exists test_frm_bug");
7441 }
7442 
7443 
7444 /* Test DECIMAL conversion */
7445 
7446 static void test_decimal_bug()
7447 {
7448  MYSQL_STMT *stmt;
7449  MYSQL_BIND my_bind[1];
7450  char data[30];
7451  int rc;
7452  my_bool is_null;
7453 
7454  myheader("test_decimal_bug");
7455 
7456  mysql_autocommit(mysql, TRUE);
7457 
7458  rc= mysql_query(mysql, "drop table if exists test_decimal_bug");
7459  myquery(rc);
7460 
7461  rc= mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10, 2))");
7462  myquery(rc);
7463 
7464  rc= mysql_query(mysql, "insert into test_decimal_bug value(8), (10.22), (5.61)");
7465  myquery(rc);
7466 
7467  stmt= mysql_simple_prepare(mysql, "select c1 from test_decimal_bug where c1= ?");
7468  check_stmt(stmt);
7469 
7470  /*
7471  We need to memset bind structure because mysql_stmt_bind_param checks all
7472  its members.
7473  */
7474  memset(my_bind, 0, sizeof(my_bind));
7475 
7476  my_bind[0].buffer_type= MYSQL_TYPE_NEWDECIMAL;
7477  my_bind[0].buffer= (void *)data;
7478  my_bind[0].buffer_length= 25;
7479  my_bind[0].is_null= &is_null;
7480 
7481  is_null= 0;
7482  rc= mysql_stmt_bind_param(stmt, my_bind);
7483  check_execute(stmt, rc);
7484 
7485  strmov(data, "8.0");
7486  rc= mysql_stmt_execute(stmt);
7487  check_execute(stmt, rc);
7488 
7489  data[0]= 0;
7490  rc= mysql_stmt_bind_result(stmt, my_bind);
7491  check_execute(stmt, rc);
7492 
7493  rc= mysql_stmt_fetch(stmt);
7494  check_execute(stmt, rc);
7495 
7496  if (!opt_silent)
7497  fprintf(stdout, "\n data: %s", data);
7498  DIE_UNLESS(strcmp(data, "8.00") == 0);
7499 
7500  rc= mysql_stmt_fetch(stmt);
7501  DIE_UNLESS(rc == MYSQL_NO_DATA);
7502 
7503  strmov(data, "5.61");
7504  rc= mysql_stmt_execute(stmt);
7505  check_execute(stmt, rc);
7506 
7507  data[0]= 0;
7508  rc= mysql_stmt_bind_result(stmt, my_bind);
7509  check_execute(stmt, rc);
7510 
7511  rc= mysql_stmt_fetch(stmt);
7512  check_execute(stmt, rc);
7513 
7514  if (!opt_silent)
7515  fprintf(stdout, "\n data: %s", data);
7516  DIE_UNLESS(strcmp(data, "5.61") == 0);
7517 
7518  rc= mysql_stmt_fetch(stmt);
7519  DIE_UNLESS(rc == MYSQL_NO_DATA);
7520 
7521  is_null= 1;
7522  rc= mysql_stmt_execute(stmt);
7523  check_execute(stmt, rc);
7524 
7525  rc= mysql_stmt_fetch(stmt);
7526  DIE_UNLESS(rc == MYSQL_NO_DATA);
7527 
7528  strmov(data, "10.22"); is_null= 0;
7529  rc= mysql_stmt_execute(stmt);
7530  check_execute(stmt, rc);
7531 
7532  data[0]= 0;
7533  rc= mysql_stmt_bind_result(stmt, my_bind);
7534  check_execute(stmt, rc);
7535 
7536  rc= mysql_stmt_fetch(stmt);
7537  check_execute(stmt, rc);
7538 
7539  if (!opt_silent)
7540  fprintf(stdout, "\n data: %s", data);
7541  DIE_UNLESS(strcmp(data, "10.22") == 0);
7542 
7543  rc= mysql_stmt_fetch(stmt);
7544  DIE_UNLESS(rc == MYSQL_NO_DATA);
7545 
7546  mysql_stmt_close(stmt);
7547 }
7548 
7549 
7550 /* Test EXPLAIN bug (#115, reported by mark@mysql.com & georg@php.net). */
7551 
7552 static void test_explain_bug()
7553 {
7554  MYSQL_STMT *stmt;
7555  MYSQL_RES *result;
7556  int rc;
7557 
7558  myheader("test_explain_bug");
7559 
7560  mysql_autocommit(mysql, TRUE);
7561 
7562  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_explain");
7563  myquery(rc);
7564 
7565  rc= mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))");
7566  myquery(rc);
7567 
7568  stmt= mysql_simple_prepare(mysql, "explain test_explain");
7569  check_stmt(stmt);
7570 
7571  rc= mysql_stmt_execute(stmt);
7572  check_execute(stmt, rc);
7573 
7574  rc= my_process_stmt_result(stmt);
7575  DIE_UNLESS(rc == 2);
7576 
7577  result= mysql_stmt_result_metadata(stmt);
7578  mytest(result);
7579 
7580  if (!opt_silent)
7581  fprintf(stdout, "\n total fields in the result: %d",
7582  mysql_num_fields(result));
7583  DIE_UNLESS(6 == mysql_num_fields(result));
7584 
7585  verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
7586  mysql_get_server_version(mysql) <= 50000 ?
7587  MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7588  0, 0, "information_schema", 64, 0);
7589 
7590  verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
7591  0, 0, "information_schema", 0, 0);
7592 
7593  verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
7594  mysql_get_server_version(mysql) <= 50000 ?
7595  MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7596  0, 0, "information_schema", 3, 0);
7597 
7598  verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
7599  mysql_get_server_version(mysql) <= 50000 ?
7600  MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7601  0, 0, "information_schema", 3, 0);
7602 
7603  if ( mysql_get_server_version(mysql) >= 50027 )
7604  {
7605  /* The patch for bug#23037 changes column type of DEAULT to blob */
7606  verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7607  MYSQL_TYPE_BLOB, 0, 0, "information_schema", 0, 0);
7608  }
7609  else
7610  {
7611  verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7612  mysql_get_server_version(mysql) >= 50027 ?
7613  MYSQL_TYPE_BLOB :
7614  mysql_get_server_version(mysql) <= 50000 ?
7615  MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7616  0, 0, "information_schema",
7617  mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
7618  }
7619 
7620  verify_prepare_field(result, 5, "Extra", "EXTRA",
7621  mysql_get_server_version(mysql) <= 50000 ?
7622  MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7623  0, 0, "information_schema",
7624  mysql_get_server_version(mysql) <= 50602 ? 27 : 30,
7625  0);
7626 
7627  mysql_free_result(result);
7628  mysql_stmt_close(stmt);
7629 
7630  stmt= mysql_simple_prepare(mysql, "explain select id, name FROM test_explain");
7631  check_stmt(stmt);
7632 
7633  rc= mysql_stmt_execute(stmt);
7634  check_execute(stmt, rc);
7635 
7636  rc= my_process_stmt_result(stmt);
7637  DIE_UNLESS(rc == 1);
7638 
7639  result= mysql_stmt_result_metadata(stmt);
7640  mytest(result);
7641 
7642  if (!opt_silent)
7643  fprintf(stdout, "\n total fields in the result: %d",
7644  mysql_num_fields(result));
7645  DIE_UNLESS(10 == mysql_num_fields(result));
7646 
7647  verify_prepare_field(result, 0, "id", "", MYSQL_TYPE_LONGLONG,
7648  "", "", "", 3, 0);
7649 
7650  verify_prepare_field(result, 1, "select_type", "", MYSQL_TYPE_VAR_STRING,
7651  "", "", "", 19, 0);
7652 
7653  verify_prepare_field(result, 2, "table", "", MYSQL_TYPE_VAR_STRING,
7654  "", "", "", NAME_CHAR_LEN, 0);
7655 
7656  verify_prepare_field(result, 3, "type", "", MYSQL_TYPE_VAR_STRING,
7657  "", "", "", 10, 0);
7658 
7659  verify_prepare_field(result, 4, "possible_keys", "", MYSQL_TYPE_VAR_STRING,
7660  "", "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7661 
7662  verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
7663  "", "", "", NAME_CHAR_LEN, 0);
7664 
7665  if (mysql_get_server_version(mysql) <= 50000)
7666  {
7667  verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG, "",
7668  "", "", 3, 0);
7669  }
7670  else
7671  {
7672  verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
7673  "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7674  }
7675 
7676  verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
7677  "", "", "", NAME_CHAR_LEN*16, 0);
7678 
7679  verify_prepare_field(result, 8, "rows", "", MYSQL_TYPE_LONGLONG,
7680  "", "", "", 10, 0);
7681 
7682  verify_prepare_field(result, 9, "Extra", "", MYSQL_TYPE_VAR_STRING,
7683  "", "", "", 255, 0);
7684 
7685  mysql_free_result(result);
7686  mysql_stmt_close(stmt);
7687 }
7688 
7689 #ifdef NOT_YET_WORKING
7690 
7691 /*
7692  Test math functions.
7693  Bug #148 (reported by salle@mysql.com).
7694 */
7695 
7696 #define myerrno(n) check_errcode(n)
7697 
7698 static void check_errcode(const unsigned int err)
7699 {
7700  if (!opt_silent || mysql_errno(mysql) != err)
7701  {
7702  if (mysql->server_version)
7703  fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
7704  else
7705  fprintf(stdout, "\n [MySQL]");
7706  fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
7707  }
7708  DIE_UNLESS(mysql_errno(mysql) == err);
7709 }
7710 
7711 
7712 static void test_drop_temp()
7713 {
7714  int rc;
7715 
7716  myheader("test_drop_temp");
7717 
7718  rc= mysql_query(mysql, "DROP DATABASE IF EXISTS test_drop_temp_db");
7719  myquery(rc);
7720 
7721  rc= mysql_query(mysql, "CREATE DATABASE test_drop_temp_db");
7722  myquery(rc);
7723 
7724  rc= mysql_query(mysql, "CREATE TABLE test_drop_temp_db.t1(c1 int, c2 char(1))");
7725  myquery(rc);
7726 
7727  rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7728  myquery(rc);
7729 
7730  rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7731  myquery(rc);
7732 
7733  strxmov(query, "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@",
7734  opt_host ? opt_host : "localhost", NullS);
7735 
7736  if (mysql_query(mysql, query))
7737  {
7738  myerror("GRANT failed");
7739 
7740  /*
7741  If server started with --skip-grant-tables, skip this test, else
7742  exit to indicate an error
7743 
7744  ER_UNKNOWN_COM_ERROR= 1047
7745  */
7746  if (mysql_errno(mysql) != 1047)
7747  exit(1);
7748  }
7749  else
7750  {
7751  MYSQL *org_mysql= mysql, *lmysql;
7752 
7753  if (!opt_silent)
7754  fprintf(stdout, "\n Establishing a test connection ...");
7755  if (!(lmysql= mysql_client_init(NULL)))
7756  {
7757  myerror("mysql_client_init() failed");
7758  exit(1);
7759  }
7760 
7761  rc= mysql_query(mysql, "flush privileges");
7762  myquery(rc);
7763 
7764  if (!(mysql_real_connect(lmysql, opt_host ? opt_host : "localhost", "test_temp",
7765  "", "test_drop_temp_db", opt_port,
7766  opt_unix_socket, 0)))
7767  {
7768  mysql= lmysql;
7769  myerror("connection failed");
7770  mysql_close(lmysql);
7771  exit(1);
7772  }
7773  lmysql->reconnect= 1;
7774  if (!opt_silent)
7775  fprintf(stdout, "OK");
7776 
7777  mysql= lmysql;
7778  rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')");
7779  myerrno((uint)1142);
7780 
7781  rc= mysql_query(mysql, "DROP TABLE t1");
7782  myerrno((uint)1142);
7783 
7784  mysql= org_mysql;
7785  rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t1(c1 int)");
7786  myquery(rc);
7787 
7788  rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t2 LIKE test_drop_temp_db.t1");
7789  myquery(rc);
7790 
7791  mysql= lmysql;
7792 
7793  rc= mysql_query(mysql, "DROP TABLE t1, t2");
7794  myquery_r(rc);
7795 
7796  rc= mysql_query(mysql, "DROP TEMPORARY TABLE t1");
7797  myquery_r(rc);
7798 
7799  rc= mysql_query(mysql, "DROP TEMPORARY TABLE t2");
7800  myquery_r(rc);
7801 
7802  mysql_close(lmysql);
7803  mysql= org_mysql;
7804 
7805  rc= mysql_query(mysql, "drop database test_drop_temp_db");
7806  myquery(rc);
7807  DIE_UNLESS(1 == mysql_affected_rows(mysql));
7808 
7809  rc= mysql_query(mysql, "delete from mysql.user where User='test_temp'");
7810  myquery(rc);
7811  DIE_UNLESS(1 == mysql_affected_rows(mysql));
7812 
7813 
7814  rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_temp'");
7815  myquery(rc);
7816  DIE_UNLESS(1 == mysql_affected_rows(mysql));
7817  }
7818 }
7819 #endif
7820 
7821 
7822 /* Test warnings for cuted rows */
7823 
7824 static void test_cuted_rows()
7825 {
7826  int rc, count;
7827  MYSQL_RES *result;
7828 
7829  myheader("test_cuted_rows");
7830 
7831  mysql_query(mysql, "DROP TABLE if exists t1");
7832  mysql_query(mysql, "DROP TABLE if exists t2");
7833 
7834  rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)");
7835  myquery(rc);
7836 
7837  rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)");
7838  myquery(rc);
7839 
7840  rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)");
7841  myquery(rc);
7842 
7843  count= mysql_warning_count(mysql);
7844  if (!opt_silent)
7845  fprintf(stdout, "\n total warnings: %d", count);
7846  DIE_UNLESS(count == 0);
7847 
7848  rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
7849  myquery(rc);
7850 
7851  count= mysql_warning_count(mysql);
7852  if (!opt_silent)
7853  fprintf(stdout, "\n total warnings: %d", count);
7854  DIE_UNLESS(count == 2);
7855 
7856  rc= mysql_query(mysql, "SHOW WARNINGS");
7857  myquery(rc);
7858 
7859  result= mysql_store_result(mysql);
7860  mytest(result);
7861 
7862  rc= my_process_result_set(result);
7863  DIE_UNLESS(rc == 2);
7864  mysql_free_result(result);
7865 
7866  rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)");
7867  myquery(rc);
7868 
7869  count= mysql_warning_count(mysql);
7870  if (!opt_silent)
7871  fprintf(stdout, "\n total warnings: %d", count);
7872  DIE_UNLESS(count == 2);
7873 
7874  rc= mysql_query(mysql, "SHOW WARNINGS");
7875  myquery(rc);
7876 
7877  result= mysql_store_result(mysql);
7878  mytest(result);
7879 
7880  rc= my_process_result_set(result);
7881  DIE_UNLESS(rc == 2);
7882  mysql_free_result(result);
7883 }
7884 
7885 
7886 /* Test update/binary logs */
7887 
7888 static void test_logs()
7889 {
7890  MYSQL_STMT *stmt;
7891  MYSQL_BIND my_bind[2];
7892  char data[255];
7893  ulong length;
7894  int rc;
7895  short id;
7896 
7897  myheader("test_logs");
7898 
7899 
7900  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs");
7901  myquery(rc);
7902 
7903  rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))");
7904  myquery(rc);
7905 
7906  strmov((char *)data, "INSERT INTO test_logs VALUES(?, ?)");
7907  stmt= mysql_simple_prepare(mysql, data);
7908  check_stmt(stmt);
7909 
7910  /*
7911  We need to memset bind structure because mysql_stmt_bind_param checks all
7912  its members.
7913  */
7914  memset(my_bind, 0, sizeof(my_bind));
7915 
7916  my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
7917  my_bind[0].buffer= (void *)&id;
7918 
7919  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
7920  my_bind[1].buffer= (void *)&data;
7921  my_bind[1].buffer_length= 255;
7922  my_bind[1].length= &length;
7923 
7924  id= 9876;
7925  length= (ulong)(strmov((char *)data, "MySQL - Open Source Database")- data);
7926 
7927  rc= mysql_stmt_bind_param(stmt, my_bind);
7928  check_execute(stmt, rc);
7929 
7930  rc= mysql_stmt_execute(stmt);
7931  check_execute(stmt, rc);
7932 
7933  strmov((char *)data, "'");
7934  length= 1;
7935 
7936  rc= mysql_stmt_execute(stmt);
7937  check_execute(stmt, rc);
7938 
7939  strmov((char *)data, "\"");
7940  length= 1;
7941 
7942  rc= mysql_stmt_execute(stmt);
7943  check_execute(stmt, rc);
7944 
7945  length= (ulong)(strmov((char *)data, "my\'sql\'")-data);
7946  rc= mysql_stmt_execute(stmt);
7947  check_execute(stmt, rc);
7948 
7949  length= (ulong)(strmov((char *)data, "my\"sql\"")-data);
7950  rc= mysql_stmt_execute(stmt);
7951  check_execute(stmt, rc);
7952 
7953  mysql_stmt_close(stmt);
7954 
7955  strmov((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')");
7956  stmt= mysql_simple_prepare(mysql, data);
7957  check_stmt(stmt);
7958 
7959  rc= mysql_stmt_execute(stmt);
7960  check_execute(stmt, rc);
7961 
7962  rc= mysql_stmt_execute(stmt);
7963  check_execute(stmt, rc);
7964 
7965  mysql_stmt_close(stmt);
7966 
7967  strmov((char *)data, "SELECT * FROM test_logs WHERE id=?");
7968  stmt= mysql_simple_prepare(mysql, data);
7969  check_stmt(stmt);
7970 
7971  rc= mysql_stmt_bind_param(stmt, my_bind);
7972  check_execute(stmt, rc);
7973 
7974  rc= mysql_stmt_execute(stmt);
7975  check_execute(stmt, rc);
7976 
7977  my_bind[1].buffer_length= 255;
7978  rc= mysql_stmt_bind_result(stmt, my_bind);
7979  check_execute(stmt, rc);
7980 
7981  rc= mysql_stmt_fetch(stmt);
7982  check_execute(stmt, rc);
7983 
7984  if (!opt_silent)
7985  {
7986  fprintf(stdout, "id : %d\n", id);
7987  fprintf(stdout, "name : %s(%ld)\n", data, length);
7988  }
7989 
7990  DIE_UNLESS(id == 9876);
7991  DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */
7992  DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1);
7993 
7994  rc= mysql_stmt_fetch(stmt);
7995  check_execute(stmt, rc);
7996 
7997  if (!opt_silent)
7998  fprintf(stdout, "\n name : %s(%ld)", data, length);
7999 
8000  DIE_UNLESS(length == 1);
8001  DIE_UNLESS(strcmp(data, "'") == 0);
8002 
8003  rc= mysql_stmt_fetch(stmt);
8004  check_execute(stmt, rc);
8005 
8006  if (!opt_silent)
8007  fprintf(stdout, "\n name : %s(%ld)", data, length);
8008 
8009  DIE_UNLESS(length == 1);
8010  DIE_UNLESS(strcmp(data, "\"") == 0);
8011 
8012  rc= mysql_stmt_fetch(stmt);
8013  check_execute(stmt, rc);
8014 
8015  if (!opt_silent)
8016  fprintf(stdout, "\n name : %s(%ld)", data, length);
8017 
8018  DIE_UNLESS(length == 7);
8019  DIE_UNLESS(strcmp(data, "my\'sql\'") == 0);
8020 
8021  rc= mysql_stmt_fetch(stmt);
8022  check_execute(stmt, rc);
8023 
8024  if (!opt_silent)
8025  fprintf(stdout, "\n name : %s(%ld)", data, length);
8026 
8027  DIE_UNLESS(length == 7);
8028  /*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */
8029 
8030  rc= mysql_stmt_fetch(stmt);
8031  DIE_UNLESS(rc == MYSQL_NO_DATA);
8032 
8033  mysql_stmt_close(stmt);
8034 
8035  rc= mysql_query(mysql, "DROP TABLE test_logs");
8036  myquery(rc);
8037 }
8038 
8039 
8040 /* Test 'n' statements create and close */
8041 
8042 static void test_nstmts()
8043 {
8044  MYSQL_STMT *stmt;
8045  char query[255];
8046  int rc;
8047  static uint i, total_stmts= 2000;
8048  MYSQL_BIND my_bind[1];
8049 
8050  myheader("test_nstmts");
8051 
8052  mysql_autocommit(mysql, TRUE);
8053 
8054  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_nstmts");
8055  myquery(rc);
8056 
8057  rc= mysql_query(mysql, "CREATE TABLE test_nstmts(id int)");
8058  myquery(rc);
8059 
8060  /*
8061  We need to memset bind structure because mysql_stmt_bind_param checks all
8062  its members.
8063  */
8064  memset(my_bind, 0, sizeof(my_bind));
8065 
8066  my_bind[0].buffer= (void *)&i;
8067  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8068 
8069  for (i= 0; i < total_stmts; i++)
8070  {
8071  if (!opt_silent)
8072  fprintf(stdout, "\r stmt: %d", i);
8073 
8074  strmov(query, "insert into test_nstmts values(?)");
8075  stmt= mysql_simple_prepare(mysql, query);
8076  check_stmt(stmt);
8077 
8078  rc= mysql_stmt_bind_param(stmt, my_bind);
8079  check_execute(stmt, rc);
8080 
8081  rc= mysql_stmt_execute(stmt);
8082  check_execute(stmt, rc);
8083 
8084  mysql_stmt_close(stmt);
8085  }
8086 
8087  stmt= mysql_simple_prepare(mysql, " select count(*) from test_nstmts");
8088  check_stmt(stmt);
8089 
8090  rc= mysql_stmt_execute(stmt);
8091  check_execute(stmt, rc);
8092 
8093  i= 0;
8094  rc= mysql_stmt_bind_result(stmt, my_bind);
8095  check_execute(stmt, rc);
8096 
8097  rc= mysql_stmt_fetch(stmt);
8098  check_execute(stmt, rc);
8099  if (!opt_silent)
8100  fprintf(stdout, "\n total rows: %d", i);
8101  DIE_UNLESS( i == total_stmts);
8102 
8103  rc= mysql_stmt_fetch(stmt);
8104  DIE_UNLESS(rc == MYSQL_NO_DATA);
8105 
8106  mysql_stmt_close(stmt);
8107 
8108  rc= mysql_query(mysql, "DROP TABLE test_nstmts");
8109  myquery(rc);
8110 }
8111 
8112 
8113 /* Test stmt seek() functions */
8114 
8115 static void test_fetch_seek()
8116 {
8117  MYSQL_STMT *stmt;
8118  MYSQL_BIND my_bind[3];
8119  MYSQL_ROW_OFFSET row;
8120  int rc;
8121  int32 c1;
8122  char c2[11], c3[20];
8123 
8124  myheader("test_fetch_seek");
8125  rc= mysql_query(mysql, "drop table if exists t1");
8126 
8127  myquery(rc);
8128 
8129  rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
8130  myquery(rc);
8131 
8132  rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
8133  myquery(rc);
8134 
8135  stmt= mysql_simple_prepare(mysql, "select * from t1");
8136  check_stmt(stmt);
8137 
8138  memset(my_bind, 0, sizeof(my_bind));
8139  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8140  my_bind[0].buffer= (void *)&c1;
8141 
8142  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8143  my_bind[1].buffer= (void *)c2;
8144  my_bind[1].buffer_length= sizeof(c2);
8145 
8146  my_bind[2]= my_bind[1];
8147  my_bind[2].buffer= (void *)c3;
8148  my_bind[2].buffer_length= sizeof(c3);
8149 
8150  rc= mysql_stmt_execute(stmt);
8151  check_execute(stmt, rc);
8152 
8153  rc= mysql_stmt_bind_result(stmt, my_bind);
8154  check_execute(stmt, rc);
8155 
8156  rc= mysql_stmt_store_result(stmt);
8157  check_execute(stmt, rc);
8158 
8159  rc= mysql_stmt_fetch(stmt);
8160  check_execute(stmt, rc);
8161 
8162  if (!opt_silent)
8163  fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8164 
8165  row= mysql_stmt_row_tell(stmt);
8166 
8167  row= mysql_stmt_row_seek(stmt, row);
8168 
8169  rc= mysql_stmt_fetch(stmt);
8170  check_execute(stmt, rc);
8171 
8172  if (!opt_silent)
8173  fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8174 
8175  row= mysql_stmt_row_seek(stmt, row);
8176 
8177  rc= mysql_stmt_fetch(stmt);
8178  check_execute(stmt, rc);
8179 
8180  if (!opt_silent)
8181  fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8182 
8183  mysql_stmt_data_seek(stmt, 0);
8184 
8185  rc= mysql_stmt_fetch(stmt);
8186  check_execute(stmt, rc);
8187 
8188  if (!opt_silent)
8189  fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8190 
8191  rc= mysql_stmt_fetch(stmt);
8192  check_execute(stmt, rc);
8193 
8194  rc= mysql_stmt_fetch(stmt);
8195  check_execute(stmt, rc);
8196 
8197  rc= mysql_stmt_fetch(stmt);
8198  check_execute(stmt, rc);
8199 
8200  rc= mysql_stmt_fetch(stmt);
8201  DIE_UNLESS(rc == MYSQL_NO_DATA);
8202 
8203  mysql_stmt_close(stmt);
8204  myquery(mysql_query(mysql, "drop table t1"));
8205 }
8206 
8207 
8208 /* Test mysql_stmt_fetch_column() with offset */
8209 
8210 static void test_fetch_offset()
8211 {
8212  MYSQL_STMT *stmt;
8213  MYSQL_BIND my_bind[1];
8214  char data[11];
8215  ulong length;
8216  int rc;
8217  my_bool is_null;
8218 
8219 
8220  myheader("test_fetch_offset");
8221 
8222  rc= mysql_query(mysql, "drop table if exists t1");
8223  myquery(rc);
8224 
8225  rc= mysql_query(mysql, "create table t1(a char(10))");
8226  myquery(rc);
8227 
8228  rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)");
8229  myquery(rc);
8230 
8231  stmt= mysql_simple_prepare(mysql, "select * from t1");
8232  check_stmt(stmt);
8233 
8234  memset(my_bind, 0, sizeof(my_bind));
8235  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8236  my_bind[0].buffer= (void *)data;
8237  my_bind[0].buffer_length= 11;
8238  my_bind[0].is_null= &is_null;
8239  my_bind[0].length= &length;
8240 
8241  rc= mysql_stmt_execute(stmt);
8242  check_execute(stmt, rc);
8243 
8244  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8245  check_execute_r(stmt, rc);
8246 
8247  rc= mysql_stmt_execute(stmt);
8248  check_execute(stmt, rc);
8249 
8250  rc= mysql_stmt_bind_result(stmt, my_bind);
8251  check_execute(stmt, rc);
8252 
8253  rc= mysql_stmt_store_result(stmt);
8254  check_execute(stmt, rc);
8255 
8256  rc= mysql_stmt_fetch(stmt);
8257  check_execute(stmt, rc);
8258 
8259  data[0]= '\0';
8260  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8261  check_execute(stmt, rc);
8262  if (!opt_silent)
8263  fprintf(stdout, "\n col 1: %s (%ld)", data, length);
8264  DIE_UNLESS(strncmp(data, "abcd", 4) == 0 && length == 10);
8265 
8266  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5);
8267  check_execute(stmt, rc);
8268  if (!opt_silent)
8269  fprintf(stdout, "\n col 1: %s (%ld)", data, length);
8270  DIE_UNLESS(strncmp(data, "fg", 2) == 0 && length == 10);
8271 
8272  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9);
8273  check_execute(stmt, rc);
8274  if (!opt_silent)
8275  fprintf(stdout, "\n col 0: %s (%ld)", data, length);
8276  DIE_UNLESS(strncmp(data, "j", 1) == 0 && length == 10);
8277 
8278  rc= mysql_stmt_fetch(stmt);
8279  check_execute(stmt, rc);
8280 
8281  is_null= 0;
8282 
8283  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8284  check_execute(stmt, rc);
8285 
8286  DIE_UNLESS(is_null == 1);
8287 
8288  rc= mysql_stmt_fetch(stmt);
8289  DIE_UNLESS(rc == MYSQL_NO_DATA);
8290 
8291  rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8292  check_execute_r(stmt, rc);
8293 
8294  mysql_stmt_close(stmt);
8295 
8296  myquery(mysql_query(mysql, "drop table t1"));
8297 }
8298 
8299 
8300 /* Test mysql_stmt_fetch_column() */
8301 
8302 static void test_fetch_column()
8303 {
8304  MYSQL_STMT *stmt;
8305  MYSQL_BIND my_bind[2];
8306  char c2[20], bc2[20];
8307  ulong l1, l2, bl1, bl2;
8308  int rc, c1, bc1;
8309 
8310  myheader("test_fetch_column");
8311 
8312  rc= mysql_query(mysql, "drop table if exists t1");
8313  myquery(rc);
8314 
8315  rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
8316  myquery(rc);
8317 
8318  rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
8319  myquery(rc);
8320 
8321  stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc");
8322  check_stmt(stmt);
8323 
8324  memset(my_bind, 0, sizeof(my_bind));
8325  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8326  my_bind[0].buffer= (void *)&bc1;
8327  my_bind[0].buffer_length= 0;
8328  my_bind[0].is_null= 0;
8329  my_bind[0].length= &bl1;
8330  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8331  my_bind[1].buffer= (void *)bc2;
8332  my_bind[1].buffer_length= 7;
8333  my_bind[1].is_null= 0;
8334  my_bind[1].length= &bl2;
8335 
8336  rc= mysql_stmt_execute(stmt);
8337  check_execute(stmt, rc);
8338 
8339  rc= mysql_stmt_bind_result(stmt, my_bind);
8340  check_execute(stmt, rc);
8341 
8342  rc= mysql_stmt_store_result(stmt);
8343  check_execute(stmt, rc);
8344 
8345  rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */
8346  check_execute_r(stmt, rc);
8347 
8348  rc= mysql_stmt_fetch(stmt);
8349  check_execute(stmt, rc);
8350 
8351  if (!opt_silent)
8352  fprintf(stdout, "\n row 0: %d, %s", bc1, bc2);
8353 
8354  c2[0]= '\0'; l2= 0;
8355  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8356  my_bind[0].buffer= (void *)c2;
8357  my_bind[0].buffer_length= 7;
8358  my_bind[0].is_null= 0;
8359  my_bind[0].length= &l2;
8360 
8361  rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8362  check_execute(stmt, rc);
8363  if (!opt_silent)
8364  fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8365  DIE_UNLESS(strncmp(c2, "venu", 4) == 0 && l2 == 4);
8366 
8367  c2[0]= '\0'; l2= 0;
8368  rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8369  check_execute(stmt, rc);
8370  if (!opt_silent)
8371  fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8372  DIE_UNLESS(strcmp(c2, "venu") == 0 && l2 == 4);
8373 
8374  c1= 0;
8375  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8376  my_bind[0].buffer= (void *)&c1;
8377  my_bind[0].buffer_length= 0;
8378  my_bind[0].is_null= 0;
8379  my_bind[0].length= &l1;
8380 
8381  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8382  check_execute(stmt, rc);
8383  if (!opt_silent)
8384  fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
8385  DIE_UNLESS(c1 == 1 && l1 == 4);
8386 
8387  rc= mysql_stmt_fetch(stmt);
8388  check_execute(stmt, rc);
8389 
8390  if (!opt_silent)
8391  fprintf(stdout, "\n row 1: %d, %s", bc1, bc2);
8392 
8393  c2[0]= '\0'; l2= 0;
8394  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8395  my_bind[0].buffer= (void *)c2;
8396  my_bind[0].buffer_length= 7;
8397  my_bind[0].is_null= 0;
8398  my_bind[0].length= &l2;
8399 
8400  rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8401  check_execute(stmt, rc);
8402  if (!opt_silent)
8403  fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8404  DIE_UNLESS(strncmp(c2, "mysq", 4) == 0 && l2 == 5);
8405 
8406  c2[0]= '\0'; l2= 0;
8407  rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8408  check_execute(stmt, rc);
8409  if (!opt_silent)
8410  fprintf(stdout, "\n col 1: %si(%ld)", c2, l2);
8411  DIE_UNLESS(strcmp(c2, "mysql") == 0 && l2 == 5);
8412 
8413  c1= 0;
8414  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8415  my_bind[0].buffer= (void *)&c1;
8416  my_bind[0].buffer_length= 0;
8417  my_bind[0].is_null= 0;
8418  my_bind[0].length= &l1;
8419 
8420  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8421  check_execute(stmt, rc);
8422  if (!opt_silent)
8423  fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
8424  DIE_UNLESS(c1 == 2 && l1 == 4);
8425 
8426  rc= mysql_stmt_fetch(stmt);
8427  DIE_UNLESS(rc == MYSQL_NO_DATA);
8428 
8429  rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8430  check_execute_r(stmt, rc);
8431 
8432  mysql_stmt_close(stmt);
8433  myquery(mysql_query(mysql, "drop table t1"));
8434 }
8435 
8436 
8437 /* Test mysql_list_fields() */
8438 
8439 static void test_list_fields()
8440 {
8441  MYSQL_RES *result;
8442  int rc;
8443  myheader("test_list_fields");
8444 
8445  rc= mysql_query(mysql, "drop table if exists t1");
8446  myquery(rc);
8447 
8448  rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10) default 'mysql')");
8449  myquery(rc);
8450 
8451  result= mysql_list_fields(mysql, "t1", NULL);
8452  mytest(result);
8453 
8454  rc= my_process_result_set(result);
8455  DIE_UNLESS(rc == 0);
8456 
8457  verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_LONG,
8458  "t1", "t1",
8459  current_db, 11, "0");
8460 
8461  verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_STRING,
8462  "t1", "t1",
8463  current_db, 10, "mysql");
8464 
8465  mysql_free_result(result);
8466  myquery(mysql_query(mysql, "drop table t1"));
8467 }
8468 
8469 
8470 static void test_bug19671()
8471 {
8472  MYSQL_RES *result;
8473  int rc;
8474  myheader("test_bug19671");
8475 
8476  mysql_query(mysql, "set sql_mode=''");
8477  rc= mysql_query(mysql, "drop table if exists t1");
8478  myquery(rc);
8479 
8480  rc= mysql_query(mysql, "drop view if exists v1");
8481  myquery(rc);
8482 
8483  rc= mysql_query(mysql, "create table t1(f1 int)");
8484  myquery(rc);
8485 
8486  rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
8487  myquery(rc);
8488 
8489  result= mysql_list_fields(mysql, "v1", NULL);
8490  mytest(result);
8491 
8492  rc= my_process_result_set(result);
8493  DIE_UNLESS(rc == 0);
8494 
8495  verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
8496  "v1", "v1", current_db, 11, "0");
8497 
8498  mysql_free_result(result);
8499  myquery(mysql_query(mysql, "drop view v1"));
8500  myquery(mysql_query(mysql, "drop table t1"));
8501 }
8502 
8503 
8504 /* Test a memory ovverun bug */
8505 
8506 static void test_mem_overun()
8507 {
8508  char buffer[10000], field[10];
8509  MYSQL_STMT *stmt;
8510  MYSQL_RES *field_res;
8511  int rc, i, length;
8512 
8513  myheader("test_mem_overun");
8514 
8515  /*
8516  Test a memory ovverun bug when a table had 1000 fields with
8517  a row of data
8518  */
8519  rc= mysql_query(mysql, "drop table if exists t_mem_overun");
8520  myquery(rc);
8521 
8522  strxmov(buffer, "create table t_mem_overun(", NullS);
8523  for (i= 0; i < 1000; i++)
8524  {
8525  sprintf(field, "c%d int", i);
8526  strxmov(buffer, buffer, field, ", ", NullS);
8527  }
8528  length= strlen(buffer);
8529  buffer[length-2]= ')';
8530  buffer[--length]= '\0';
8531 
8532  rc= mysql_real_query(mysql, buffer, length);
8533  myquery(rc);
8534 
8535  strxmov(buffer, "insert into t_mem_overun values(", NullS);
8536  for (i= 0; i < 1000; i++)
8537  {
8538  strxmov(buffer, buffer, "1, ", NullS);
8539  }
8540  length= strlen(buffer);
8541  buffer[length-2]= ')';
8542  buffer[--length]= '\0';
8543 
8544  rc= mysql_real_query(mysql, buffer, length);
8545  myquery(rc);
8546 
8547  rc= mysql_query(mysql, "select * from t_mem_overun");
8548  myquery(rc);
8549 
8550  rc= my_process_result(mysql);
8551  DIE_UNLESS(rc == 1);
8552 
8553  stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun");
8554  check_stmt(stmt);
8555 
8556  rc= mysql_stmt_execute(stmt);
8557  check_execute(stmt, rc);
8558 
8559  field_res= mysql_stmt_result_metadata(stmt);
8560  mytest(field_res);
8561 
8562  if (!opt_silent)
8563  fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
8564  DIE_UNLESS( 1000 == mysql_num_fields(field_res));
8565 
8566  rc= mysql_stmt_store_result(stmt);
8567  check_execute(stmt, rc);
8568 
8569  rc= mysql_stmt_fetch(stmt);
8570  check_execute(stmt, rc);
8571 
8572  rc= mysql_stmt_fetch(stmt);
8573  DIE_UNLESS(rc == MYSQL_NO_DATA);
8574 
8575  mysql_free_result(field_res);
8576 
8577  mysql_stmt_close(stmt);
8578 }
8579 
8580 
8581 /* Test mysql_stmt_free_result() */
8582 
8583 static void test_free_result()
8584 {
8585  MYSQL_STMT *stmt;
8586  MYSQL_BIND my_bind[1];
8587  char c2[5];
8588  ulong bl1, l2;
8589  int rc, c1, bc1;
8590 
8591  myheader("test_free_result");
8592 
8593  rc= mysql_query(mysql, "drop table if exists test_free_result");
8594  myquery(rc);
8595 
8596  rc= mysql_query(mysql, "create table test_free_result("
8597  "c1 int primary key auto_increment)");
8598  myquery(rc);
8599 
8600  rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8601  myquery(rc);
8602 
8603  stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8604  check_stmt(stmt);
8605 
8606  memset(my_bind, 0, sizeof(my_bind));
8607  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8608  my_bind[0].buffer= (void *)&bc1;
8609  my_bind[0].length= &bl1;
8610 
8611  rc= mysql_stmt_execute(stmt);
8612  check_execute(stmt, rc);
8613 
8614  rc= mysql_stmt_bind_result(stmt, my_bind);
8615  check_execute(stmt, rc);
8616 
8617  rc= mysql_stmt_fetch(stmt);
8618  check_execute(stmt, rc);
8619 
8620  c2[0]= '\0'; l2= 0;
8621  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8622  my_bind[0].buffer= (void *)c2;
8623  my_bind[0].buffer_length= 7;
8624  my_bind[0].is_null= 0;
8625  my_bind[0].length= &l2;
8626 
8627  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8628  check_execute(stmt, rc);
8629  if (!opt_silent)
8630  fprintf(stdout, "\n col 0: %s(%ld)", c2, l2);
8631  DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8632 
8633  rc= mysql_stmt_fetch(stmt);
8634  check_execute(stmt, rc);
8635 
8636  c1= 0, l2= 0;
8637  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8638  my_bind[0].buffer= (void *)&c1;
8639  my_bind[0].buffer_length= 0;
8640  my_bind[0].is_null= 0;
8641  my_bind[0].length= &l2;
8642 
8643  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8644  check_execute(stmt, rc);
8645  if (!opt_silent)
8646  fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8647  DIE_UNLESS(c1 == 2 && l2 == 4);
8648 
8649  rc= mysql_query(mysql, "drop table test_free_result");
8650  myquery_r(rc); /* error should be, COMMANDS OUT OF SYNC */
8651 
8652  rc= mysql_stmt_free_result(stmt);
8653  check_execute(stmt, rc);
8654 
8655  rc= mysql_query(mysql, "drop table test_free_result");
8656  myquery(rc); /* should be successful */
8657 
8658  mysql_stmt_close(stmt);
8659 }
8660 
8661 
8662 /* Test mysql_stmt_store_result() */
8663 
8664 static void test_free_store_result()
8665 {
8666  MYSQL_STMT *stmt;
8667  MYSQL_BIND my_bind[1];
8668  char c2[5];
8669  ulong bl1, l2;
8670  int rc, c1, bc1;
8671 
8672  myheader("test_free_store_result");
8673 
8674  rc= mysql_query(mysql, "drop table if exists test_free_result");
8675  myquery(rc);
8676 
8677  rc= mysql_query(mysql, "create table test_free_result(c1 int primary key auto_increment)");
8678  myquery(rc);
8679 
8680  rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8681  myquery(rc);
8682 
8683  stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8684  check_stmt(stmt);
8685 
8686  memset(my_bind, 0, sizeof(my_bind));
8687  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8688  my_bind[0].buffer= (void *)&bc1;
8689  my_bind[0].buffer_length= 0;
8690  my_bind[0].is_null= 0;
8691  my_bind[0].length= &bl1;
8692 
8693  rc= mysql_stmt_execute(stmt);
8694  check_execute(stmt, rc);
8695 
8696  rc= mysql_stmt_bind_result(stmt, my_bind);
8697  check_execute(stmt, rc);
8698 
8699  rc= mysql_stmt_store_result(stmt);
8700  check_execute(stmt, rc);
8701 
8702  rc= mysql_stmt_fetch(stmt);
8703  check_execute(stmt, rc);
8704 
8705  c2[0]= '\0'; l2= 0;
8706  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8707  my_bind[0].buffer= (void *)c2;
8708  my_bind[0].buffer_length= 7;
8709  my_bind[0].is_null= 0;
8710  my_bind[0].length= &l2;
8711 
8712  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8713  check_execute(stmt, rc);
8714  if (!opt_silent)
8715  fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8716  DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8717 
8718  rc= mysql_stmt_fetch(stmt);
8719  check_execute(stmt, rc);
8720 
8721  c1= 0, l2= 0;
8722  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8723  my_bind[0].buffer= (void *)&c1;
8724  my_bind[0].buffer_length= 0;
8725  my_bind[0].is_null= 0;
8726  my_bind[0].length= &l2;
8727 
8728  rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8729  check_execute(stmt, rc);
8730  if (!opt_silent)
8731  fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8732  DIE_UNLESS(c1 == 2 && l2 == 4);
8733 
8734  rc= mysql_stmt_free_result(stmt);
8735  check_execute(stmt, rc);
8736 
8737  rc= mysql_query(mysql, "drop table test_free_result");
8738  myquery(rc);
8739 
8740  mysql_stmt_close(stmt);
8741 }
8742 
8743 
8744 /* Test SQLmode */
8745 
8746 static void test_sqlmode()
8747 {
8748  MYSQL_STMT *stmt;
8749  MYSQL_BIND my_bind[2];
8750  char c1[5], c2[5];
8751  int rc;
8752  char query[MAX_TEST_QUERY_LENGTH];
8753 
8754  myheader("test_sqlmode");
8755 
8756  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping");
8757  myquery(rc);
8758 
8759  rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))");
8760  myquery(rc);
8761 
8762  /* PIPES_AS_CONCAT */
8763  strmov(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
8764  if (!opt_silent)
8765  fprintf(stdout, "\n With %s", query);
8766  rc= mysql_query(mysql, query);
8767  myquery(rc);
8768 
8769  strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8770  if (!opt_silent)
8771  fprintf(stdout, "\n query: %s", query);
8772  stmt= mysql_simple_prepare(mysql, query);
8773  check_stmt(stmt);
8774 
8775  if (!opt_silent)
8776  fprintf(stdout, "\n total parameters: %ld", mysql_stmt_param_count(stmt));
8777 
8778  /*
8779  We need to memset bind structure because mysql_stmt_bind_param checks all
8780  its members.
8781  */
8782  memset(my_bind, 0, sizeof(my_bind));
8783 
8784  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8785  my_bind[0].buffer= (void *)c1;
8786  my_bind[0].buffer_length= 2;
8787 
8788  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8789  my_bind[1].buffer= (void *)c2;
8790  my_bind[1].buffer_length= 3;
8791 
8792  rc= mysql_stmt_bind_param(stmt, my_bind);
8793  check_execute(stmt, rc);
8794 
8795  strmov(c1, "My"); strmov(c2, "SQL");
8796  rc= mysql_stmt_execute(stmt);
8797  check_execute(stmt, rc);
8798  mysql_stmt_close(stmt);
8799 
8800  verify_col_data("test_piping", "name", "MySQL");
8801 
8802  rc= mysql_query(mysql, "DELETE FROM test_piping");
8803  myquery(rc);
8804 
8805  strmov(query, "SELECT connection_id ()");
8806  if (!opt_silent)
8807  fprintf(stdout, "\n query: %s", query);
8808  stmt= mysql_simple_prepare(mysql, query);
8809  check_stmt(stmt);
8810  mysql_stmt_close(stmt);
8811 
8812  /* ANSI */
8813  strmov(query, "SET SQL_MODE= \"ANSI\"");
8814  if (!opt_silent)
8815  fprintf(stdout, "\n With %s", query);
8816  rc= mysql_query(mysql, query);
8817  myquery(rc);
8818 
8819  strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8820  if (!opt_silent)
8821  fprintf(stdout, "\n query: %s", query);
8822  stmt= mysql_simple_prepare(mysql, query);
8823  check_stmt(stmt);
8824  if (!opt_silent)
8825  fprintf(stdout, "\n total parameters: %ld", mysql_stmt_param_count(stmt));
8826 
8827  rc= mysql_stmt_bind_param(stmt, my_bind);
8828  check_execute(stmt, rc);
8829 
8830  strmov(c1, "My"); strmov(c2, "SQL");
8831  rc= mysql_stmt_execute(stmt);
8832  check_execute(stmt, rc);
8833 
8834  mysql_stmt_close(stmt);
8835  verify_col_data("test_piping", "name", "MySQL");
8836 
8837  /* ANSI mode spaces ... */
8838  strmov(query, "SELECT connection_id ()");
8839  if (!opt_silent)
8840  fprintf(stdout, "\n query: %s", query);
8841  stmt= mysql_simple_prepare(mysql, query);
8842  check_stmt(stmt);
8843 
8844  rc= mysql_stmt_execute(stmt);
8845  check_execute(stmt, rc);
8846 
8847  rc= mysql_stmt_fetch(stmt);
8848  check_execute(stmt, rc);
8849 
8850  rc= mysql_stmt_fetch(stmt);
8851  DIE_UNLESS(rc == MYSQL_NO_DATA);
8852  if (!opt_silent)
8853  fprintf(stdout, "\n returned 1 row\n");
8854 
8855  mysql_stmt_close(stmt);
8856 
8857  /* IGNORE SPACE MODE */
8858  strmov(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
8859  if (!opt_silent)
8860  fprintf(stdout, "\n With %s", query);
8861  rc= mysql_query(mysql, query);
8862  myquery(rc);
8863 
8864  strmov(query, "SELECT connection_id ()");
8865  if (!opt_silent)
8866  fprintf(stdout, "\n query: %s", query);
8867  stmt= mysql_simple_prepare(mysql, query);
8868  check_stmt(stmt);
8869 
8870  rc= mysql_stmt_execute(stmt);
8871  check_execute(stmt, rc);
8872 
8873  rc= mysql_stmt_fetch(stmt);
8874  check_execute(stmt, rc);
8875 
8876  rc= mysql_stmt_fetch(stmt);
8877  DIE_UNLESS(rc == MYSQL_NO_DATA);
8878  if (!opt_silent)
8879  fprintf(stdout, "\n returned 1 row");
8880 
8881  mysql_stmt_close(stmt);
8882 }
8883 
8884 
8885 /* Test for timestamp handling */
8886 
8887 static void test_ts()
8888 {
8889  MYSQL_STMT *stmt;
8890  MYSQL_BIND my_bind[6];
8891  MYSQL_TIME ts;
8892  MYSQL_RES *prep_res;
8893  char strts[30];
8894  ulong length;
8895  int rc, field_count;
8896  char name;
8897  char query[MAX_TEST_QUERY_LENGTH];
8898  const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
8899  "SELECT a, b, c FROM test_ts WHERE %c=?",
8900  "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
8901  myheader("test_ts");
8902 
8903  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts");
8904  myquery(rc);
8905 
8906  rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)");
8907  myquery(rc);
8908 
8909  stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)");
8910  check_stmt(stmt);
8911 
8912  ts.year= 2003;
8913  ts.month= 07;
8914  ts.day= 12;
8915  ts.hour= 21;
8916  ts.minute= 07;
8917  ts.second= 46;
8918  ts.second_part= 0;
8919  length= (long)(strmov(strts, "2003-07-12 21:07:46") - strts);
8920 
8921  /*
8922  We need to memset bind structure because mysql_stmt_bind_param checks all
8923  its members.
8924  */
8925  memset(my_bind, 0, sizeof(my_bind));
8926 
8927  my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
8928  my_bind[0].buffer= (void *)&ts;
8929  my_bind[0].buffer_length= sizeof(ts);
8930 
8931  my_bind[2]= my_bind[1]= my_bind[0];
8932 
8933  my_bind[3].buffer_type= MYSQL_TYPE_STRING;
8934  my_bind[3].buffer= (void *)strts;
8935  my_bind[3].buffer_length= sizeof(strts);
8936  my_bind[3].length= &length;
8937 
8938  my_bind[5]= my_bind[4]= my_bind[3];
8939 
8940  rc= mysql_stmt_bind_param(stmt, my_bind);
8941  check_execute(stmt, rc);
8942 
8943  rc= mysql_stmt_execute(stmt);
8944  check_execute(stmt, rc);
8945 
8946  mysql_stmt_close(stmt);
8947 
8948  verify_col_data("test_ts", "a", "2003-07-12");
8949  verify_col_data("test_ts", "b", "21:07:46");
8950  verify_col_data("test_ts", "c", "2003-07-12 21:07:46");
8951 
8952  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts");
8953  check_stmt(stmt);
8954 
8955  prep_res= mysql_stmt_result_metadata(stmt);
8956  mytest(prep_res);
8957 
8958  rc= mysql_stmt_execute(stmt);
8959  check_execute(stmt, rc);
8960 
8961  rc= my_process_stmt_result(stmt);
8962  DIE_UNLESS(rc == 2);
8963  field_count= mysql_num_fields(prep_res);
8964 
8965  mysql_free_result(prep_res);
8966  mysql_stmt_close(stmt);
8967 
8968  for (name= 'a'; field_count--; name++)
8969  {
8970  int row_count= 0;
8971 
8972  sprintf(query, queries[field_count], name);
8973 
8974  if (!opt_silent)
8975  fprintf(stdout, "\n %s", query);
8976  stmt= mysql_simple_prepare(mysql, query);
8977  check_stmt(stmt);
8978 
8979  rc= mysql_stmt_bind_param(stmt, my_bind);
8980  check_execute(stmt, rc);
8981 
8982  rc= mysql_stmt_execute(stmt);
8983  check_execute(stmt, rc);
8984 
8985  while (mysql_stmt_fetch(stmt) == 0)
8986  row_count++;
8987 
8988  if (!opt_silent)
8989  fprintf(stdout, "\n returned '%d' rows", row_count);
8990  DIE_UNLESS(row_count == 2);
8991  mysql_stmt_close(stmt);
8992  }
8993 }
8994 
8995 
8996 /* Test for bug #1500. */
8997 
8998 static void test_bug1500()
8999 {
9000  MYSQL_STMT *stmt;
9001  MYSQL_BIND my_bind[3];
9002  int rc;
9003  int32 int_data[3]= {2, 3, 4};
9004  const char *data;
9005 
9006  myheader("test_bug1500");
9007 
9008  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
9009  myquery(rc);
9010 
9011  rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (i INT)");
9012  myquery(rc);
9013 
9014  rc= mysql_query(mysql, "INSERT INTO test_bg1500 VALUES (1), (2)");
9015  myquery(rc);
9016 
9017  rc= mysql_commit(mysql);
9018  myquery(rc);
9019 
9020  stmt= mysql_simple_prepare(mysql, "SELECT i FROM test_bg1500 WHERE i IN (?, ?, ?)");
9021  check_stmt(stmt);
9022  verify_param_count(stmt, 3);
9023 
9024  /*
9025  We need to memset bind structure because mysql_stmt_bind_param checks all
9026  its members.
9027  */
9028  memset(my_bind, 0, sizeof(my_bind));
9029 
9030  my_bind[0].buffer= (void *)int_data;
9031  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9032  my_bind[2]= my_bind[1]= my_bind[0];
9033  my_bind[1].buffer= (void *)(int_data + 1);
9034  my_bind[2].buffer= (void *)(int_data + 2);
9035 
9036  rc= mysql_stmt_bind_param(stmt, my_bind);
9037  check_execute(stmt, rc);
9038 
9039  rc= mysql_stmt_execute(stmt);
9040  check_execute(stmt, rc);
9041 
9042  rc= my_process_stmt_result(stmt);
9043  DIE_UNLESS(rc == 1);
9044 
9045  mysql_stmt_close(stmt);
9046 
9047  rc= mysql_query(mysql, "DROP TABLE test_bg1500");
9048  myquery(rc);
9049 
9050  rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM");
9051  myquery(rc);
9052 
9053  rc= mysql_query(mysql,
9054  "INSERT INTO test_bg1500 VALUES ('Gravedigger'), ('Greed'), ('Hollow Dogs')");
9055  myquery(rc);
9056 
9057  rc= mysql_commit(mysql);
9058  myquery(rc);
9059 
9060  stmt= mysql_simple_prepare(mysql,
9061  "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)");
9062  check_stmt(stmt);
9063 
9064  verify_param_count(stmt, 1);
9065 
9066  data= "Dogs";
9067  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9068  my_bind[0].buffer= (void *) data;
9069  my_bind[0].buffer_length= strlen(data);
9070  my_bind[0].is_null= 0;
9071  my_bind[0].length= 0;
9072 
9073  rc= mysql_stmt_bind_param(stmt, my_bind);
9074  check_execute(stmt, rc);
9075 
9076  rc= mysql_stmt_execute(stmt);
9077  check_execute(stmt, rc);
9078 
9079  rc= my_process_stmt_result(stmt);
9080  DIE_UNLESS(rc == 1);
9081 
9082  mysql_stmt_close(stmt);
9083 
9084  /* This should work too */
9085  stmt= mysql_simple_prepare(mysql,
9086  "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?, 'digger'))");
9087  check_stmt(stmt);
9088 
9089  verify_param_count(stmt, 1);
9090 
9091  data= "Grave";
9092  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9093  my_bind[0].buffer= (void *) data;
9094  my_bind[0].buffer_length= strlen(data);
9095 
9096  rc= mysql_stmt_bind_param(stmt, my_bind);
9097  check_execute(stmt, rc);
9098 
9099  rc= mysql_stmt_execute(stmt);
9100  check_execute(stmt, rc);
9101 
9102  rc= my_process_stmt_result(stmt);
9103  DIE_UNLESS(rc == 1);
9104 
9105  mysql_stmt_close(stmt);
9106 }
9107 
9108 
9109 static void test_bug1946()
9110 {
9111  MYSQL_STMT *stmt;
9112  int rc;
9113  const char *query= "INSERT INTO prepare_command VALUES (?)";
9114 
9115  myheader("test_bug1946");
9116 
9117  rc= mysql_query(mysql, "DROP TABLE IF EXISTS prepare_command");
9118  myquery(rc);
9119 
9120  rc= mysql_query(mysql, "CREATE TABLE prepare_command(ID INT)");
9121  myquery(rc);
9122 
9123  stmt= mysql_simple_prepare(mysql, query);
9124  check_stmt(stmt);
9125  rc= mysql_real_query(mysql, query, strlen(query));
9126  DIE_UNLESS(rc != 0);
9127  if (!opt_silent)
9128  fprintf(stdout, "Got error (as expected):\n");
9129  myerror(NULL);
9130 
9131  mysql_stmt_close(stmt);
9132  rc= mysql_query(mysql, "DROP TABLE prepare_command");
9133 }
9134 
9135 
9136 static void test_parse_error_and_bad_length()
9137 {
9138  MYSQL_STMT *stmt;
9139  int rc;
9140 
9141  /* check that we get 4 syntax errors over the 4 calls */
9142  myheader("test_parse_error_and_bad_length");
9143 
9144  rc= mysql_query(mysql, "SHOW DATABAAAA");
9145  DIE_UNLESS(rc);
9146  if (!opt_silent)
9147  fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9148  rc= mysql_real_query(mysql, "SHOW DATABASES", 12); // Incorrect length.
9149  DIE_UNLESS(rc);
9150  if (!opt_silent)
9151  fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9152 
9153  stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA");
9154  DIE_UNLESS(!stmt);
9155  if (!opt_silent)
9156  fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9157  stmt= mysql_stmt_init(mysql);
9158  DIE_UNLESS(stmt);
9159  rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 12); // Incorrect length.
9160  DIE_UNLESS(rc != 0);
9161  if (!opt_silent)
9162  fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
9163  mysql_stmt_close(stmt);
9164 }
9165 
9166 
9167 static void test_bug2247()
9168 {
9169  MYSQL_STMT *stmt;
9170  MYSQL_RES *res;
9171  int rc;
9172  int i;
9173  const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)";
9174  const char *insert= "INSERT INTO bug2247 VALUES (NULL)";
9175  const char *SELECT= "SELECT id FROM bug2247";
9176  const char *update= "UPDATE bug2247 SET id=id+10";
9177  const char *drop= "DROP TABLE IF EXISTS bug2247";
9178  ulonglong exp_count;
9179  enum { NUM_ROWS= 5 };
9180 
9181  myheader("test_bug2247");
9182 
9183  if (!opt_silent)
9184  fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
9185  "mysql_query ... ");
9186  /* create table and insert few rows */
9187  rc= mysql_query(mysql, drop);
9188  myquery(rc);
9189 
9190  rc= mysql_query(mysql, create);
9191  myquery(rc);
9192 
9193  stmt= mysql_simple_prepare(mysql, insert);
9194  check_stmt(stmt);
9195  for (i= 0; i < NUM_ROWS; ++i)
9196  {
9197  rc= mysql_stmt_execute(stmt);
9198  check_execute(stmt, rc);
9199  }
9200  exp_count= mysql_stmt_affected_rows(stmt);
9201  DIE_UNLESS(exp_count == 1);
9202 
9203  rc= mysql_query(mysql, SELECT);
9204  myquery(rc);
9205  /*
9206  mysql_store_result overwrites mysql->affected_rows. Check that
9207  mysql_stmt_affected_rows() returns the same value, whereas
9208  mysql_affected_rows() value is correct.
9209  */
9210  res= mysql_store_result(mysql);
9211  mytest(res);
9212 
9213  DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9214  DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9215 
9216  rc= mysql_query(mysql, update);
9217  myquery(rc);
9218  DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9219  DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9220 
9221  mysql_free_result(res);
9222  mysql_stmt_close(stmt);
9223 
9224  /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */
9225  stmt= mysql_simple_prepare(mysql, SELECT);
9226  check_stmt(stmt);
9227 
9228  rc= mysql_stmt_execute(stmt);
9229  check_execute(stmt, rc);
9230  rc= mysql_stmt_store_result(stmt);
9231  check_execute(stmt, rc);
9232  exp_count= mysql_stmt_affected_rows(stmt);
9233  DIE_UNLESS(exp_count == NUM_ROWS);
9234 
9235  rc= mysql_query(mysql, insert);
9236  myquery(rc);
9237  DIE_UNLESS(mysql_affected_rows(mysql) == 1);
9238  DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count);
9239 
9240  mysql_stmt_close(stmt);
9241  if (!opt_silent)
9242  fprintf(stdout, "OK");
9243 }
9244 
9245 
9246 static void test_subqueries()
9247 {
9248  MYSQL_STMT *stmt;
9249  int rc, i;
9250  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";
9251 
9252  myheader("test_subqueries");
9253 
9254  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9255  myquery(rc);
9256 
9257  rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9258  myquery(rc);
9259 
9260  rc= mysql_query(mysql,
9261  "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9262  myquery(rc);
9263 
9264  rc= mysql_query(mysql, "create table t2 select * from t1;");
9265  myquery(rc);
9266 
9267  stmt= mysql_simple_prepare(mysql, query);
9268  check_stmt(stmt);
9269  for (i= 0; i < 3; i++)
9270  {
9271  rc= mysql_stmt_execute(stmt);
9272  check_execute(stmt, rc);
9273  rc= my_process_stmt_result(stmt);
9274  DIE_UNLESS(rc == 5);
9275  }
9276  mysql_stmt_close(stmt);
9277 
9278  rc= mysql_query(mysql, "DROP TABLE t1, t2");
9279  myquery(rc);
9280 }
9281 
9282 
9283 static void test_bad_union()
9284 {
9285  MYSQL_STMT *stmt;
9286  const char *query= "SELECT 1, 2 union SELECT 1";
9287 
9288  myheader("test_bad_union");
9289 
9290  stmt= mysql_simple_prepare(mysql, query);
9291  DIE_UNLESS(stmt == 0);
9292  myerror(NULL);
9293 }
9294 
9295 
9296 static void test_distinct()
9297 {
9298  MYSQL_STMT *stmt;
9299  int rc, i;
9300  const char *query=
9301  "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a";
9302 
9303  myheader("test_distinct");
9304 
9305  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9306  myquery(rc);
9307 
9308  rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9309  myquery(rc);
9310 
9311  rc= mysql_query(mysql,
9312  "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), \
9313 (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);");
9314  myquery(rc);
9315 
9316  for (i= 0; i < 3; i++)
9317  {
9318  stmt= mysql_simple_prepare(mysql, query);
9319  check_stmt(stmt);
9320  rc= mysql_stmt_execute(stmt);
9321  check_execute(stmt, rc);
9322  rc= my_process_stmt_result(stmt);
9323  DIE_UNLESS(rc == 5);
9324  mysql_stmt_close(stmt);
9325  }
9326 
9327  rc= mysql_query(mysql, "DROP TABLE t1");
9328  myquery(rc);
9329 }
9330 
9331 
9332 /*
9333  Test for bug#2248 "mysql_fetch without prior mysql_stmt_execute hangs"
9334 */
9335 
9336 static void test_bug2248()
9337 {
9338  MYSQL_STMT *stmt;
9339  int rc;
9340  const char *query1= "SELECT DATABASE()";
9341  const char *query2= "INSERT INTO test_bug2248 VALUES (10)";
9342 
9343  myheader("test_bug2248");
9344 
9345  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248");
9346  myquery(rc);
9347 
9348  rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)");
9349  myquery(rc);
9350 
9351  stmt= mysql_simple_prepare(mysql, query1);
9352  check_stmt(stmt);
9353 
9354  /* This should not hang */
9355  rc= mysql_stmt_fetch(stmt);
9356  check_execute_r(stmt, rc);
9357 
9358  /* And this too */
9359  rc= mysql_stmt_store_result(stmt);
9360  check_execute_r(stmt, rc);
9361 
9362  mysql_stmt_close(stmt);
9363 
9364  stmt= mysql_simple_prepare(mysql, query2);
9365  check_stmt(stmt);
9366 
9367  rc= mysql_stmt_execute(stmt);
9368  check_execute(stmt, rc);
9369 
9370  /* This too should not hang but should return proper error */
9371  rc= mysql_stmt_fetch(stmt);
9372  DIE_UNLESS(rc == 1);
9373 
9374  /* This too should not hang but should not bark */
9375  rc= mysql_stmt_store_result(stmt);
9376  check_execute(stmt, rc);
9377 
9378  /* This should return proper error */
9379  rc= mysql_stmt_fetch(stmt);
9380  check_execute_r(stmt, rc);
9381  DIE_UNLESS(rc == 1);
9382 
9383  mysql_stmt_close(stmt);
9384 
9385  rc= mysql_query(mysql, "DROP TABLE test_bug2248");
9386  myquery(rc);
9387 }
9388 
9389 
9390 static void test_subqueries_ref()
9391 {
9392  MYSQL_STMT *stmt;
9393  int rc, i;
9394  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)";
9395 
9396  myheader("test_subqueries_ref");
9397 
9398  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9399  myquery(rc);
9400 
9401  rc= mysql_query(mysql, "CREATE TABLE t1 (a int);");
9402  myquery(rc);
9403 
9404  rc= mysql_query(mysql,
9405  "insert into t1 values (1), (2), (3), (4), (5);");
9406  myquery(rc);
9407 
9408  stmt= mysql_simple_prepare(mysql, query);
9409  check_stmt(stmt);
9410  for (i= 0; i < 3; i++)
9411  {
9412  rc= mysql_stmt_execute(stmt);
9413  check_execute(stmt, rc);
9414  rc= my_process_stmt_result(stmt);
9415  DIE_UNLESS(rc == 1);
9416  }
9417  mysql_stmt_close(stmt);
9418 
9419  rc= mysql_query(mysql, "DROP TABLE t1");
9420  myquery(rc);
9421 }
9422 
9423 
9424 static void test_union()
9425 {
9426  MYSQL_STMT *stmt;
9427  int rc;
9428 
9429  myheader("test_union");
9430 
9431  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9432  myquery(rc);
9433 
9434  rc= mysql_query(mysql,
9435  "CREATE TABLE t1 "
9436  "(id INTEGER NOT NULL PRIMARY KEY, "
9437  " name VARCHAR(20) NOT NULL)");
9438  myquery(rc);
9439  rc= mysql_query(mysql,
9440  "INSERT INTO t1 (id, name) VALUES "
9441  "(2, 'Ja'), (3, 'Ede'), "
9442  "(4, 'Haag'), (5, 'Kabul'), "
9443  "(6, 'Almere'), (7, 'Utrecht'), "
9444  "(8, 'Qandahar'), (9, 'Amsterdam'), "
9445  "(10, 'Amersfoort'), (11, 'Constantine')");
9446  myquery(rc);
9447  rc= mysql_query(mysql,
9448  "CREATE TABLE t2 "
9449  "(id INTEGER NOT NULL PRIMARY KEY, "
9450  " name VARCHAR(20) NOT NULL)");
9451  myquery(rc);
9452  rc= mysql_query(mysql,
9453  "INSERT INTO t2 (id, name) VALUES "
9454  "(4, 'Guam'), (5, 'Aruba'), "
9455  "(6, 'Angola'), (7, 'Albania'), "
9456  "(8, 'Anguilla'), (9, 'Argentina'), "
9457  "(10, 'Azerbaijan'), (11, 'Afghanistan'), "
9458  "(12, 'Burkina Faso'), (13, 'Faroe Islands')");
9459  myquery(rc);
9460 
9461  stmt= mysql_simple_prepare(mysql,
9462  "SELECT t1.name FROM t1 UNION "
9463  "SELECT t2.name FROM t2");
9464  check_stmt(stmt);
9465 
9466  rc= mysql_stmt_execute(stmt);
9467  check_execute(stmt, rc);
9468  rc= my_process_stmt_result(stmt);
9469  DIE_UNLESS(rc == 20);
9470  mysql_stmt_close(stmt);
9471 
9472  rc= mysql_query(mysql, "DROP TABLE t1, t2");
9473  myquery(rc);
9474 }
9475 
9476 
9477 static void test_bug3117()
9478 {
9479  MYSQL_STMT *stmt;
9480  MYSQL_BIND buffer;
9481  longlong lii;
9482  ulong length;
9483  my_bool is_null;
9484  int rc;
9485 
9486  myheader("test_bug3117");
9487 
9488  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9489  myquery(rc);
9490 
9491  rc= mysql_query(mysql, "CREATE TABLE t1 (id int auto_increment primary key)");
9492  myquery(rc);
9493 
9494  stmt= mysql_simple_prepare(mysql, "SELECT LAST_INSERT_ID()");
9495  check_stmt(stmt);
9496 
9497  rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9498  myquery(rc);
9499 
9500  rc= mysql_stmt_execute(stmt);
9501  check_execute(stmt, rc);
9502 
9503  memset(&buffer, 0, sizeof(buffer));
9504  buffer.buffer_type= MYSQL_TYPE_LONGLONG;
9505  buffer.buffer_length= sizeof(lii);
9506  buffer.buffer= (void *)&lii;
9507  buffer.length= &length;
9508  buffer.is_null= &is_null;
9509 
9510  rc= mysql_stmt_bind_result(stmt, &buffer);
9511  check_execute(stmt, rc);
9512 
9513  rc= mysql_stmt_store_result(stmt);
9514  check_execute(stmt, rc);
9515 
9516  rc= mysql_stmt_fetch(stmt);
9517  check_execute(stmt, rc);
9518 
9519  DIE_UNLESS(is_null == 0 && lii == 1);
9520  if (!opt_silent)
9521  fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
9522 
9523  rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9524  myquery(rc);
9525 
9526  rc= mysql_stmt_execute(stmt);
9527  check_execute(stmt, rc);
9528 
9529  rc= mysql_stmt_fetch(stmt);
9530  check_execute(stmt, rc);
9531 
9532  DIE_UNLESS(is_null == 0 && lii == 2);
9533  if (!opt_silent)
9534  fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
9535 
9536  mysql_stmt_close(stmt);
9537 
9538  rc= mysql_query(mysql, "DROP TABLE t1");
9539  myquery(rc);
9540 }
9541 
9542 
9543 static void test_join()
9544 {
9545  MYSQL_STMT *stmt;
9546  int rc, i, j;
9547  const char *query[]= {"SELECT * FROM t2 join t1 on (t1.a=t2.a)",
9548  "SELECT * FROM t2 natural join t1",
9549  "SELECT * FROM t2 join t1 using(a)",
9550  "SELECT * FROM t2 left join t1 on(t1.a=t2.a)",
9551  "SELECT * FROM t2 natural left join t1",
9552  "SELECT * FROM t2 left join t1 using(a)",
9553  "SELECT * FROM t2 right join t1 on(t1.a=t2.a)",
9554  "SELECT * FROM t2 natural right join t1",
9555  "SELECT * FROM t2 right join t1 using(a)"};
9556 
9557  myheader("test_join");
9558 
9559  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9560  myquery(rc);
9561 
9562  rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9563  myquery(rc);
9564 
9565  rc= mysql_query(mysql,
9566  "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9567  myquery(rc);
9568 
9569  rc= mysql_query(mysql, "CREATE TABLE t2 (a int , c int);");
9570  myquery(rc);
9571 
9572  rc= mysql_query(mysql,
9573  "insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9574  myquery(rc);
9575 
9576  for (j= 0; j < 9; j++)
9577  {
9578  stmt= mysql_simple_prepare(mysql, query[j]);
9579  check_stmt(stmt);
9580  for (i= 0; i < 3; i++)
9581  {
9582  rc= mysql_stmt_execute(stmt);
9583  check_execute(stmt, rc);
9584  rc= my_process_stmt_result(stmt);
9585  DIE_UNLESS(rc == 5);
9586  }
9587  mysql_stmt_close(stmt);
9588  }
9589 
9590  rc= mysql_query(mysql, "DROP TABLE t1, t2");
9591  myquery(rc);
9592 }
9593 
9594 
9595 static void test_selecttmp()
9596 {
9597  MYSQL_STMT *stmt;
9598  int rc, i;
9599  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";
9600 
9601  myheader("test_select_tmp");
9602 
9603  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3");
9604  myquery(rc);
9605 
9606  rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9607  myquery(rc);
9608 
9609  rc= mysql_query(mysql, "create table t2 (a int, b int);");
9610  myquery(rc);
9611 
9612  rc= mysql_query(mysql, "create table t3 (a int, b int);");
9613  myquery(rc);
9614 
9615  rc= mysql_query(mysql,
9616  "insert into t1 values (0, 100), (1, 2), (1, 3), (2, 2), (2, 7), \
9617 (2, -1), (3, 10);");
9618  myquery(rc);
9619  rc= mysql_query(mysql,
9620  "insert into t2 values (0, 0), (1, 1), (2, 1), (3, 1), (4, 1);");
9621  myquery(rc);
9622  rc= mysql_query(mysql,
9623  "insert into t3 values (3, 3), (2, 2), (1, 1);");
9624  myquery(rc);
9625 
9626  stmt= mysql_simple_prepare(mysql, query);
9627  check_stmt(stmt);
9628  for (i= 0; i < 3; i++)
9629  {
9630  rc= mysql_stmt_execute(stmt);
9631  check_execute(stmt, rc);
9632  rc= my_process_stmt_result(stmt);
9633  DIE_UNLESS(rc == 3);
9634  }
9635  mysql_stmt_close(stmt);
9636 
9637  rc= mysql_query(mysql, "DROP TABLE t1, t2, t3");
9638  myquery(rc);
9639 }
9640 
9641 
9642 static void test_create_drop()
9643 {
9644  MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select;
9645  char *query;
9646  int rc, i;
9647  myheader("test_table_manipulation");
9648 
9649  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9650  myquery(rc);
9651 
9652  rc= mysql_query(mysql, "create table t2 (a int);");
9653  myquery(rc);
9654 
9655  rc= mysql_query(mysql, "create table t1 (a int);");
9656  myquery(rc);
9657 
9658  rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);");
9659  myquery(rc);
9660 
9661  query= (char*)"create table t1 (a int)";
9662  stmt_create= mysql_simple_prepare(mysql, query);
9663  check_stmt(stmt_create);
9664 
9665  query= (char*)"drop table t1";
9666  stmt_drop= mysql_simple_prepare(mysql, query);
9667  check_stmt(stmt_drop);
9668 
9669  query= (char*)"select a in (select a from t2) from t1";
9670  stmt_select= mysql_simple_prepare(mysql, query);
9671  check_stmt(stmt_select);
9672 
9673  rc= mysql_query(mysql, "DROP TABLE t1");
9674  myquery(rc);
9675 
9676  query= (char*)"create table t1 select a from t2";
9677  stmt_create_select= mysql_simple_prepare(mysql, query);
9678  check_stmt(stmt_create_select);
9679 
9680  for (i= 0; i < 3; i++)
9681  {
9682  rc= mysql_stmt_execute(stmt_create);
9683  check_execute(stmt_create, rc);
9684  if (!opt_silent)
9685  fprintf(stdout, "created %i\n", i);
9686 
9687  rc= mysql_stmt_execute(stmt_select);
9688  check_execute(stmt_select, rc);
9689  rc= my_process_stmt_result(stmt_select);
9690  DIE_UNLESS(rc == 0);
9691 
9692  rc= mysql_stmt_execute(stmt_drop);
9693  check_execute(stmt_drop, rc);
9694  if (!opt_silent)
9695  fprintf(stdout, "dropped %i\n", i);
9696 
9697  rc= mysql_stmt_execute(stmt_create_select);
9698  check_execute(stmt_create, rc);
9699  if (!opt_silent)
9700  fprintf(stdout, "created select %i\n", i);
9701 
9702  rc= mysql_stmt_execute(stmt_select);
9703  check_execute(stmt_select, rc);
9704  rc= my_process_stmt_result(stmt_select);
9705  DIE_UNLESS(rc == 3);
9706 
9707  rc= mysql_stmt_execute(stmt_drop);
9708  check_execute(stmt_drop, rc);
9709  if (!opt_silent)
9710  fprintf(stdout, "dropped %i\n", i);
9711  }
9712 
9713  mysql_stmt_close(stmt_create);
9714  mysql_stmt_close(stmt_drop);
9715  mysql_stmt_close(stmt_select);
9716  mysql_stmt_close(stmt_create_select);
9717 
9718  rc= mysql_query(mysql, "DROP TABLE t2");
9719  myquery(rc);
9720 }
9721 
9722 
9723 static void test_rename()
9724 {
9725  MYSQL_STMT *stmt;
9726  const char *query= "rename table t1 to t2, t3 to t4";
9727  int rc;
9728  myheader("test_table_rename");
9729 
9730  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
9731  myquery(rc);
9732 
9733  stmt= mysql_simple_prepare(mysql, query);
9734  check_stmt(stmt);
9735 
9736  rc= mysql_query(mysql, "create table t1 (a int)");
9737  myquery(rc);
9738 
9739  rc= mysql_stmt_execute(stmt);
9740  check_execute_r(stmt, rc);
9741  if (!opt_silent)
9742  fprintf(stdout, "rename without t3\n");
9743 
9744  rc= mysql_query(mysql, "create table t3 (a int)");
9745  myquery(rc);
9746 
9747  rc= mysql_stmt_execute(stmt);
9748  check_execute(stmt, rc);
9749  if (!opt_silent)
9750  fprintf(stdout, "rename with t3\n");
9751 
9752  rc= mysql_stmt_execute(stmt);
9753  check_execute_r(stmt, rc);
9754  if (!opt_silent)
9755  fprintf(stdout, "rename renamed\n");
9756 
9757  rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3");
9758  myquery(rc);
9759 
9760  rc= mysql_stmt_execute(stmt);
9761  check_execute(stmt, rc);
9762  if (!opt_silent)
9763  fprintf(stdout, "rename reverted\n");
9764 
9765  mysql_stmt_close(stmt);
9766 
9767  rc= mysql_query(mysql, "DROP TABLE t2, t4");
9768  myquery(rc);
9769 }
9770 
9771 
9772 static void test_do_set()
9773 {
9774  MYSQL_STMT *stmt_do, *stmt_set;
9775  char *query;
9776  int rc, i;
9777  myheader("test_do_set");
9778 
9779  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9780  myquery(rc);
9781 
9782  rc= mysql_query(mysql, "create table t1 (a int)");
9783  myquery(rc);
9784 
9785  query= (char*)"do @var:=(1 in (select * from t1))";
9786  stmt_do= mysql_simple_prepare(mysql, query);
9787  check_stmt(stmt_do);
9788 
9789  query= (char*)"set @var=(1 in (select * from t1))";
9790  stmt_set= mysql_simple_prepare(mysql, query);
9791  check_stmt(stmt_set);
9792 
9793  for (i= 0; i < 3; i++)
9794  {
9795  rc= mysql_stmt_execute(stmt_do);
9796  check_execute(stmt_do, rc);
9797  if (!opt_silent)
9798  fprintf(stdout, "do %i\n", i);
9799  rc= mysql_stmt_execute(stmt_set);
9800  check_execute(stmt_set, rc);
9801  if (!opt_silent)
9802  fprintf(stdout, "set %i\n", i);
9803  }
9804 
9805  mysql_stmt_close(stmt_do);
9806  mysql_stmt_close(stmt_set);
9807 }
9808 
9809 
9810 static void test_multi()
9811 {
9812  MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2;
9813  char *query;
9814  MYSQL_BIND my_bind[1];
9815  int rc, i;
9816  int32 param= 1;
9817  ulong length= 1;
9818  myheader("test_multi");
9819 
9820  /*
9821  We need to memset bind structure because mysql_stmt_bind_param checks all
9822  its members.
9823  */
9824  memset(my_bind, 0, sizeof(my_bind));
9825 
9826  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9827  my_bind[0].buffer= (void *)&param;
9828  my_bind[0].length= &length;
9829 
9830  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9831  myquery(rc);
9832 
9833  rc= mysql_query(mysql, "create table t1 (a int, b int)");
9834  myquery(rc);
9835 
9836  rc= mysql_query(mysql, "create table t2 (a int, b int)");
9837  myquery(rc);
9838 
9839  rc= mysql_query(mysql, "insert into t1 values (3, 3), (2, 2), (1, 1)");
9840  myquery(rc);
9841 
9842  rc= mysql_query(mysql, "insert into t2 values (3, 3), (2, 2), (1, 1)");
9843  myquery(rc);
9844 
9845  query= (char*)"delete t1, t2 from t1, t2 where t1.a=t2.a and t1.b=10";
9846  stmt_delete= mysql_simple_prepare(mysql, query);
9847  check_stmt(stmt_delete);
9848 
9849  query= (char*)"update t1, t2 set t1.b=10, t2.b=10 where t1.a=t2.a and t1.b=?";
9850  stmt_update= mysql_simple_prepare(mysql, query);
9851  check_stmt(stmt_update);
9852 
9853  query= (char*)"select * from t1";
9854  stmt_select1= mysql_simple_prepare(mysql, query);
9855  check_stmt(stmt_select1);
9856 
9857  query= (char*)"select * from t2";
9858  stmt_select2= mysql_simple_prepare(mysql, query);
9859  check_stmt(stmt_select2);
9860 
9861  for(i= 0; i < 3; i++)
9862  {
9863  rc= mysql_stmt_bind_param(stmt_update, my_bind);
9864  check_execute(stmt_update, rc);
9865 
9866  rc= mysql_stmt_execute(stmt_update);
9867  check_execute(stmt_update, rc);
9868  if (!opt_silent)
9869  fprintf(stdout, "update %ld\n", (long) param);
9870 
9871  rc= mysql_stmt_execute(stmt_delete);
9872  check_execute(stmt_delete, rc);
9873  if (!opt_silent)
9874  fprintf(stdout, "delete %ld\n", (long) param);
9875 
9876  rc= mysql_stmt_execute(stmt_select1);
9877  check_execute(stmt_select1, rc);
9878  rc= my_process_stmt_result(stmt_select1);
9879  DIE_UNLESS(rc == 3-param);
9880 
9881  rc= mysql_stmt_execute(stmt_select2);
9882  check_execute(stmt_select2, rc);
9883  rc= my_process_stmt_result(stmt_select2);
9884  DIE_UNLESS(rc == 3-param);
9885 
9886  param++;
9887  }
9888 
9889  mysql_stmt_close(stmt_delete);
9890  mysql_stmt_close(stmt_update);
9891  mysql_stmt_close(stmt_select1);
9892  mysql_stmt_close(stmt_select2);
9893  rc= mysql_query(mysql, "drop table t1, t2");
9894  myquery(rc);
9895 }
9896 
9897 
9898 static void test_insert_select()
9899 {
9900  MYSQL_STMT *stmt_insert, *stmt_select;
9901  char *query;
9902  int rc;
9903  uint i;
9904  myheader("test_insert_select");
9905 
9906  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9907  myquery(rc);
9908 
9909  rc= mysql_query(mysql, "create table t1 (a int)");
9910  myquery(rc);
9911 
9912  rc= mysql_query(mysql, "create table t2 (a int)");
9913  myquery(rc);
9914 
9915  rc= mysql_query(mysql, "insert into t2 values (1)");
9916  myquery(rc);
9917 
9918  query= (char*)"insert into t1 select a from t2";
9919  stmt_insert= mysql_simple_prepare(mysql, query);
9920  check_stmt(stmt_insert);
9921 
9922  query= (char*)"select * from t1";
9923  stmt_select= mysql_simple_prepare(mysql, query);
9924  check_stmt(stmt_select);
9925 
9926  for(i= 0; i < 3; i++)
9927  {
9928  rc= mysql_stmt_execute(stmt_insert);
9929  check_execute(stmt_insert, rc);
9930  if (!opt_silent)
9931  fprintf(stdout, "insert %u\n", i);
9932 
9933  rc= mysql_stmt_execute(stmt_select);
9934  check_execute(stmt_select, rc);
9935  rc= my_process_stmt_result(stmt_select);
9936  DIE_UNLESS(rc == (int)(i+1));
9937  }
9938 
9939  mysql_stmt_close(stmt_insert);
9940  mysql_stmt_close(stmt_select);
9941  rc= mysql_query(mysql, "drop table t1, t2");
9942  myquery(rc);
9943 }
9944 
9945 
9946 static void test_bind_nagative()
9947 {
9948  MYSQL_STMT *stmt_insert;
9949  char *query;
9950  int rc;
9951  MYSQL_BIND my_bind[1];
9952  int32 my_val= 0;
9953  ulong my_length= 0L;
9954  my_bool my_null= FALSE;
9955  myheader("test_insert_select");
9956 
9957  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9958  myquery(rc);
9959 
9960  rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)");
9961  myquery(rc);
9962 
9963  rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)");
9964  myquery(rc);
9965 
9966  query= (char*)"INSERT INTO t1 VALUES (?)";
9967  stmt_insert= mysql_simple_prepare(mysql, query);
9968  check_stmt(stmt_insert);
9969 
9970  /* bind parameters */
9971  memset(my_bind, 0, sizeof(my_bind));
9972 
9973  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9974  my_bind[0].buffer= (void *)&my_val;
9975  my_bind[0].length= &my_length;
9976  my_bind[0].is_null= (char*)&my_null;
9977 
9978  rc= mysql_stmt_bind_param(stmt_insert, my_bind);
9979  check_execute(stmt_insert, rc);
9980 
9981  my_val= -1;
9982  rc= mysql_stmt_execute(stmt_insert);
9983  check_execute(stmt_insert, rc);
9984 
9985  mysql_stmt_close(stmt_insert);
9986  rc= mysql_query(mysql, "drop table t1");
9987  myquery(rc);
9988 }
9989 
9990 
9991 static void test_derived()
9992 {
9993  MYSQL_STMT *stmt;
9994  int rc, i;
9995  MYSQL_BIND my_bind[1];
9996  int32 my_val= 0;
9997  ulong my_length= 0L;
9998  my_bool my_null= FALSE;
9999  const char *query=
10000  "select count(1) from (select f.id from t1 f where f.id=?) as x";
10001 
10002  myheader("test_derived");
10003 
10004  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10005  myquery(rc);
10006 
10007  rc= mysql_query(mysql, "create table t1 (id int(8), primary key (id)) \
10008 ENGINE=InnoDB DEFAULT CHARSET=utf8");
10009  myquery(rc);
10010 
10011  rc= mysql_query(mysql, "insert into t1 values (1)");
10012  myquery(rc);
10013 
10014  stmt= mysql_simple_prepare(mysql, query);
10015  check_stmt(stmt);
10016  /*
10017  We need to memset bind structure because mysql_stmt_bind_param checks all
10018  its members.
10019  */
10020  memset(my_bind, 0, sizeof(my_bind));
10021 
10022  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10023  my_bind[0].buffer= (void *)&my_val;
10024  my_bind[0].length= &my_length;
10025  my_bind[0].is_null= (char*)&my_null;
10026  my_val= 1;
10027  rc= mysql_stmt_bind_param(stmt, my_bind);
10028  check_execute(stmt, rc);
10029 
10030  for (i= 0; i < 3; i++)
10031  {
10032  rc= mysql_stmt_execute(stmt);
10033  check_execute(stmt, rc);
10034  rc= my_process_stmt_result(stmt);
10035  DIE_UNLESS(rc == 1);
10036  }
10037  mysql_stmt_close(stmt);
10038 
10039  rc= mysql_query(mysql, "DROP TABLE t1");
10040  myquery(rc);
10041 }
10042 
10043 
10044 static void test_xjoin()
10045 {
10046  MYSQL_STMT *stmt;
10047  int rc, i;
10048  const char *query=
10049  "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";
10050 
10051  myheader("test_xjoin");
10052 
10053  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
10054  myquery(rc);
10055 
10056  rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10057  myquery(rc);
10058 
10059  rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10060  myquery(rc);
10061 
10062  rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
10063  myquery(rc);
10064 
10065  rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10066  myquery(rc);
10067 
10068  rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)");
10069  myquery(rc);
10070 
10071  rc= mysql_query(mysql, "insert into t1 values (1, 1, 'aaa'), (2, null, 'bbb')");
10072  myquery(rc);
10073 
10074  rc= mysql_query(mysql, "insert into t2 values (1, 2, 'ccc')");
10075  myquery(rc);
10076 
10077  rc= mysql_query(mysql, "insert into t4 values (1, 'Name1'), (2, null)");
10078  myquery(rc);
10079 
10080  stmt= mysql_simple_prepare(mysql, query);
10081  check_stmt(stmt);
10082 
10083  for (i= 0; i < 3; i++)
10084  {
10085  rc= mysql_stmt_execute(stmt);
10086  check_execute(stmt, rc);
10087  rc= my_process_stmt_result(stmt);
10088  DIE_UNLESS(rc == 1);
10089  }
10090  mysql_stmt_close(stmt);
10091 
10092  rc= mysql_query(mysql, "DROP TABLE t1, t2, t3, t4");
10093  myquery(rc);
10094 }
10095 
10096 
10097 static void test_bug3035()
10098 {
10099  MYSQL_STMT *stmt;
10100  int rc;
10101  MYSQL_BIND bind_array[12], *my_bind= bind_array, *bind_end= my_bind + 12;
10102  int8 int8_val;
10103  uint8 uint8_val;
10104  int16 int16_val;
10105  uint16 uint16_val;
10106  int32 int32_val;
10107  uint32 uint32_val;
10108  longlong int64_val;
10109  ulonglong uint64_val;
10110  double double_val, udouble_val, double_tmp;
10111  char longlong_as_string[22], ulonglong_as_string[22];
10112 
10113  /* mins and maxes */
10114  const int8 int8_min= -128;
10115  const int8 int8_max= 127;
10116  const uint8 uint8_min= 0;
10117  const uint8 uint8_max= 255;
10118 
10119  const int16 int16_min= -32768;
10120  const int16 int16_max= 32767;
10121  const uint16 uint16_min= 0;
10122  const uint16 uint16_max= 65535;
10123 
10124  const int32 int32_max= 2147483647L;
10125  const int32 int32_min= -int32_max - 1;
10126  const uint32 uint32_min= 0;
10127  const uint32 uint32_max= 4294967295U;
10128 
10129  /* it might not work okay everyplace */
10130  const longlong int64_max= LL(9223372036854775807);
10131  const longlong int64_min= -int64_max - 1;
10132 
10133  const ulonglong uint64_min= 0U;
10134  const ulonglong uint64_max= ULL(18446744073709551615);
10135 
10136  const char *stmt_text;
10137 
10138  myheader("test_bug3035");
10139 
10140  stmt_text= "DROP TABLE IF EXISTS t1";
10141  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10142  myquery(rc);
10143 
10144  stmt_text= "CREATE TABLE t1 (i8 TINYINT, ui8 TINYINT UNSIGNED, "
10145  "i16 SMALLINT, ui16 SMALLINT UNSIGNED, "
10146  "i32 INT, ui32 INT UNSIGNED, "
10147  "i64 BIGINT, ui64 BIGINT UNSIGNED, "
10148  "id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT)";
10149  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10150  myquery(rc);
10151 
10152  memset(bind_array, 0, sizeof(bind_array));
10153 
10154  for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10155  my_bind->error= &my_bind->error_value;
10156 
10157  bind_array[0].buffer_type= MYSQL_TYPE_TINY;
10158  bind_array[0].buffer= (void *) &int8_val;
10159 
10160  bind_array[1].buffer_type= MYSQL_TYPE_TINY;
10161  bind_array[1].buffer= (void *) &uint8_val;
10162  bind_array[1].is_unsigned= 1;
10163 
10164  bind_array[2].buffer_type= MYSQL_TYPE_SHORT;
10165  bind_array[2].buffer= (void *) &int16_val;
10166 
10167  bind_array[3].buffer_type= MYSQL_TYPE_SHORT;
10168  bind_array[3].buffer= (void *) &uint16_val;
10169  bind_array[3].is_unsigned= 1;
10170 
10171  bind_array[4].buffer_type= MYSQL_TYPE_LONG;
10172  bind_array[4].buffer= (void *) &int32_val;
10173 
10174  bind_array[5].buffer_type= MYSQL_TYPE_LONG;
10175  bind_array[5].buffer= (void *) &uint32_val;
10176  bind_array[5].is_unsigned= 1;
10177 
10178  bind_array[6].buffer_type= MYSQL_TYPE_LONGLONG;
10179  bind_array[6].buffer= (void *) &int64_val;
10180 
10181  bind_array[7].buffer_type= MYSQL_TYPE_LONGLONG;
10182  bind_array[7].buffer= (void *) &uint64_val;
10183  bind_array[7].is_unsigned= 1;
10184 
10185  stmt= mysql_stmt_init(mysql);
10186  check_stmt(stmt);
10187 
10188  stmt_text= "INSERT INTO t1 (i8, ui8, i16, ui16, i32, ui32, i64, ui64) "
10189  "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
10190  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10191  check_execute(stmt, rc);
10192 
10193  mysql_stmt_bind_param(stmt, bind_array);
10194 
10195  int8_val= int8_min;
10196  uint8_val= uint8_min;
10197  int16_val= int16_min;
10198  uint16_val= uint16_min;
10199  int32_val= int32_min;
10200  uint32_val= uint32_min;
10201  int64_val= int64_min;
10202  uint64_val= uint64_min;
10203 
10204  rc= mysql_stmt_execute(stmt);
10205  check_execute(stmt, rc);
10206 
10207  int8_val= int8_max;
10208  uint8_val= uint8_max;
10209  int16_val= int16_max;
10210  uint16_val= uint16_max;
10211  int32_val= int32_max;
10212  uint32_val= uint32_max;
10213  int64_val= int64_max;
10214  uint64_val= uint64_max;
10215 
10216  rc= mysql_stmt_execute(stmt);
10217  check_execute(stmt, rc);
10218 
10219  stmt_text= "SELECT i8, ui8, i16, ui16, i32, ui32, i64, ui64, ui64, "
10220  "cast(ui64 as signed), ui64, cast(ui64 as signed)"
10221  "FROM t1 ORDER BY id ASC";
10222 
10223  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10224  check_execute(stmt, rc);
10225 
10226  rc= mysql_stmt_execute(stmt);
10227  check_execute(stmt, rc);
10228 
10229  bind_array[8].buffer_type= MYSQL_TYPE_DOUBLE;
10230  bind_array[8].buffer= (void *) &udouble_val;
10231 
10232  bind_array[9].buffer_type= MYSQL_TYPE_DOUBLE;
10233  bind_array[9].buffer= (void *) &double_val;
10234 
10235  bind_array[10].buffer_type= MYSQL_TYPE_STRING;
10236  bind_array[10].buffer= (void *) &ulonglong_as_string;
10237  bind_array[10].buffer_length= sizeof(ulonglong_as_string);
10238 
10239  bind_array[11].buffer_type= MYSQL_TYPE_STRING;
10240  bind_array[11].buffer= (void *) &longlong_as_string;
10241  bind_array[11].buffer_length= sizeof(longlong_as_string);
10242 
10243  mysql_stmt_bind_result(stmt, bind_array);
10244 
10245  rc= mysql_stmt_fetch(stmt);
10246  check_execute(stmt, rc);
10247 
10248  DIE_UNLESS(int8_val == int8_min);
10249  DIE_UNLESS(uint8_val == uint8_min);
10250  DIE_UNLESS(int16_val == int16_min);
10251  DIE_UNLESS(uint16_val == uint16_min);
10252  DIE_UNLESS(int32_val == int32_min);
10253  DIE_UNLESS(uint32_val == uint32_min);
10254  DIE_UNLESS(int64_val == int64_min);
10255  DIE_UNLESS(uint64_val == uint64_min);
10256  DIE_UNLESS(double_val == (longlong) uint64_min);
10257  double_tmp= ulonglong2double(uint64_val);
10258  DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10259  DIE_UNLESS(!strcmp(longlong_as_string, "0"));
10260  DIE_UNLESS(!strcmp(ulonglong_as_string, "0"));
10261 
10262  rc= mysql_stmt_fetch(stmt);
10263 
10264  if (!opt_silent)
10265  {
10266  printf("Truncation mask: ");
10267  for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10268  printf("%d", (int) my_bind->error_value);
10269  printf("\n");
10270  }
10271  DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0);
10272 
10273  DIE_UNLESS(int8_val == int8_max);
10274  DIE_UNLESS(uint8_val == uint8_max);
10275  DIE_UNLESS(int16_val == int16_max);
10276  DIE_UNLESS(uint16_val == uint16_max);
10277  DIE_UNLESS(int32_val == int32_max);
10278  DIE_UNLESS(uint32_val == uint32_max);
10279  DIE_UNLESS(int64_val == int64_max);
10280  DIE_UNLESS(uint64_val == uint64_max);
10281  DIE_UNLESS(double_val == (longlong) uint64_val);
10282  double_tmp= ulonglong2double(uint64_val);
10283  DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10284  DIE_UNLESS(!strcmp(longlong_as_string, "-1"));
10285  DIE_UNLESS(!strcmp(ulonglong_as_string, "18446744073709551615"));
10286 
10287  rc= mysql_stmt_fetch(stmt);
10288  DIE_UNLESS(rc == MYSQL_NO_DATA);
10289 
10290  mysql_stmt_close(stmt);
10291 
10292  stmt_text= "DROP TABLE t1";
10293  mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10294 }
10295 
10296 
10297 static void test_union2()
10298 {
10299  MYSQL_STMT *stmt;
10300  int rc, i;
10301 
10302  myheader("test_union2");
10303 
10304  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10305  myquery(rc);
10306 
10307  rc= mysql_query(mysql, "CREATE TABLE t1(col1 INT, \
10308  col2 VARCHAR(40), \
10309  col3 SMALLINT, \
10310  col4 TIMESTAMP)");
10311  myquery(rc);
10312 
10313  stmt= mysql_simple_prepare(mysql,
10314  "select col1 FROM t1 where col1=1 union distinct "
10315  "select col1 FROM t1 where col1=2");
10316  check_stmt(stmt);
10317 
10318  for (i= 0; i < 3; i++)
10319  {
10320  rc= mysql_stmt_execute(stmt);
10321  check_execute(stmt, rc);
10322  rc= my_process_stmt_result(stmt);
10323  DIE_UNLESS(rc == 0);
10324  }
10325 
10326  mysql_stmt_close(stmt);
10327 
10328  rc= mysql_query(mysql, "DROP TABLE t1");
10329  myquery(rc);
10330 }
10331 
10332 
10333 /*
10334  This tests for various mysql_stmt_send_long_data bugs described in #1664
10335 */
10336 
10337 static void test_bug1664()
10338 {
10339  MYSQL_STMT *stmt;
10340  int rc, int_data;
10341  const char *data;
10342  const char *str_data= "Simple string";
10343  MYSQL_BIND my_bind[2];
10344  const char *query= "INSERT INTO test_long_data(col2, col1) VALUES(?, ?)";
10345 
10346  myheader("test_bug1664");
10347 
10348  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
10349  myquery(rc);
10350 
10351  rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, col2 long varchar)");
10352  myquery(rc);
10353 
10354  stmt= mysql_stmt_init(mysql);
10355  check_stmt(stmt);
10356  rc= mysql_stmt_prepare(stmt, query, strlen(query));
10357  check_execute(stmt, rc);
10358 
10359  verify_param_count(stmt, 2);
10360 
10361  memset(my_bind, 0, sizeof(my_bind));
10362 
10363  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10364  my_bind[0].buffer= (void *)str_data;
10365  my_bind[0].buffer_length= strlen(str_data);
10366 
10367  my_bind[1].buffer= (void *)&int_data;
10368  my_bind[1].buffer_type= MYSQL_TYPE_LONG;
10369 
10370  rc= mysql_stmt_bind_param(stmt, my_bind);
10371  check_execute(stmt, rc);
10372 
10373  int_data= 1;
10374 
10375  /*
10376  Let us supply empty long_data. This should work and should
10377  not break following execution.
10378  */
10379  data= "";
10380  rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10381  check_execute(stmt, rc);
10382 
10383  rc= mysql_stmt_execute(stmt);
10384  check_execute(stmt, rc);
10385 
10386  verify_col_data("test_long_data", "col1", "1");
10387  verify_col_data("test_long_data", "col2", "");
10388 
10389  rc= mysql_query(mysql, "DELETE FROM test_long_data");
10390  myquery(rc);
10391 
10392  /* This should pass OK */
10393  data= (char *)"Data";
10394  rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10395  check_execute(stmt, rc);
10396 
10397  rc= mysql_stmt_execute(stmt);
10398  check_execute(stmt, rc);
10399 
10400  verify_col_data("test_long_data", "col1", "1");
10401  verify_col_data("test_long_data", "col2", "Data");
10402 
10403  /* clean up */
10404  rc= mysql_query(mysql, "DELETE FROM test_long_data");
10405  myquery(rc);
10406 
10407  /*
10408  Now we are changing int parameter and don't do anything
10409  with first parameter. Second mysql_stmt_execute() should run
10410  OK treating this first parameter as string parameter.
10411  */
10412 
10413  int_data= 2;
10414  /* execute */
10415  rc= mysql_stmt_execute(stmt);
10416  check_execute(stmt, rc);
10417 
10418  verify_col_data("test_long_data", "col1", "2");
10419  verify_col_data("test_long_data", "col2", str_data);
10420 
10421  /* clean up */
10422  rc= mysql_query(mysql, "DELETE FROM test_long_data");
10423  myquery(rc);
10424 
10425  /*
10426  Now we are sending other long data. It should not be
10427  concatened to previous.
10428  */
10429 
10430  data= (char *)"SomeOtherData";
10431  rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10432  check_execute(stmt, rc);
10433 
10434  rc= mysql_stmt_execute(stmt);
10435  check_execute(stmt, rc);
10436 
10437  verify_col_data("test_long_data", "col1", "2");
10438  verify_col_data("test_long_data", "col2", "SomeOtherData");
10439 
10440  mysql_stmt_close(stmt);
10441 
10442  /* clean up */
10443  rc= mysql_query(mysql, "DELETE FROM test_long_data");
10444  myquery(rc);
10445 
10446  /* Now let us test how mysql_stmt_reset works. */
10447  stmt= mysql_stmt_init(mysql);
10448  check_stmt(stmt);
10449  rc= mysql_stmt_prepare(stmt, query, strlen(query));
10450  check_execute(stmt, rc);
10451  rc= mysql_stmt_bind_param(stmt, my_bind);
10452  check_execute(stmt, rc);
10453 
10454  data= (char *)"SomeData";
10455  rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10456  check_execute(stmt, rc);
10457 
10458  rc= mysql_stmt_reset(stmt);
10459  check_execute(stmt, rc);
10460 
10461  rc= mysql_stmt_execute(stmt);
10462  check_execute(stmt, rc);
10463 
10464  verify_col_data("test_long_data", "col1", "2");
10465  verify_col_data("test_long_data", "col2", str_data);
10466 
10467  mysql_stmt_close(stmt);
10468 
10469  /* Final clean up */
10470  rc= mysql_query(mysql, "DROP TABLE test_long_data");
10471  myquery(rc);
10472 }
10473 
10474 
10475 static void test_order_param()
10476 {
10477  MYSQL_STMT *stmt;
10478  int rc;
10479 
10480  myheader("test_order_param");
10481 
10482  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10483  myquery(rc);
10484 
10485  rc= mysql_query(mysql, "CREATE TABLE t1(a INT, b char(10))");
10486  myquery(rc);
10487 
10488  stmt= mysql_simple_prepare(mysql,
10489  "select sum(a) + 200, 1 from t1 "
10490  " union distinct "
10491  "select sum(a) + 200, 1 from t1 group by b ");
10492  check_stmt(stmt);
10493  mysql_stmt_close(stmt);
10494 
10495  stmt= mysql_simple_prepare(mysql,
10496  "select sum(a) + 200, ? from t1 group by b "
10497  " union distinct "
10498  "select sum(a) + 200, 1 from t1 group by b ");
10499  check_stmt(stmt);
10500  mysql_stmt_close(stmt);
10501 
10502  stmt= mysql_simple_prepare(mysql,
10503  "select sum(a) + 200, ? from t1 "
10504  " union distinct "
10505  "select sum(a) + 200, 1 from t1 group by b ");
10506  check_stmt(stmt);
10507  mysql_stmt_close(stmt);
10508 
10509  rc= mysql_query(mysql, "DROP TABLE t1");
10510  myquery(rc);
10511 }
10512 
10513 
10514 static void test_union_param()
10515 {
10516  MYSQL_STMT *stmt;
10517  char *query;
10518  int rc, i;
10519  MYSQL_BIND my_bind[2];
10520  char my_val[4];
10521  ulong my_length= 3L;
10522  my_bool my_null= FALSE;
10523  myheader("test_union_param");
10524 
10525  strmov(my_val, "abc");
10526 
10527  query= (char*)"select ? as my_col union distinct select ?";
10528  stmt= mysql_simple_prepare(mysql, query);
10529  check_stmt(stmt);
10530 
10531  /*
10532  We need to memset bind structure because mysql_stmt_bind_param checks all
10533  its members.
10534  */
10535  memset(my_bind, 0, sizeof(my_bind));
10536 
10537  /* bind parameters */
10538  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10539  my_bind[0].buffer= (char*) &my_val;
10540  my_bind[0].buffer_length= 4;
10541  my_bind[0].length= &my_length;
10542  my_bind[0].is_null= (char*)&my_null;
10543  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
10544  my_bind[1].buffer= (char*) &my_val;
10545  my_bind[1].buffer_length= 4;
10546  my_bind[1].length= &my_length;
10547  my_bind[1].is_null= (char*)&my_null;
10548 
10549  rc= mysql_stmt_bind_param(stmt, my_bind);
10550  check_execute(stmt, rc);
10551 
10552  for (i= 0; i < 3; i++)
10553  {
10554  rc= mysql_stmt_execute(stmt);
10555  check_execute(stmt, rc);
10556  rc= my_process_stmt_result(stmt);
10557  DIE_UNLESS(rc == 1);
10558  }
10559 
10560  mysql_stmt_close(stmt);
10561 }
10562 
10563 
10564 static void test_ps_i18n()
10565 {
10566  MYSQL_STMT *stmt;
10567  int rc;
10568  const char *stmt_text;
10569  MYSQL_BIND bind_array[2];
10570 
10571  /* Represented as numbers to keep UTF8 tools from clobbering them. */
10572  const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
10573  const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
10574  char buf1[16], buf2[16];
10575  ulong buf1_len, buf2_len;
10576 
10577 
10578  myheader("test_ps_i18n");
10579 
10580  stmt_text= "DROP TABLE IF EXISTS t1";
10581  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10582  myquery(rc);
10583 
10584  /*
10585  Create table with binary columns, set session character set to cp1251,
10586  client character set to koi8, and make sure that there is conversion
10587  on insert and no conversion on select
10588  */
10589 
10590  stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
10591 
10592  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10593  myquery(rc);
10594 
10595  stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
10596  "CHARACTER_SET_CONNECTION=cp1251, "
10597  "CHARACTER_SET_RESULTS=koi8r";
10598 
10599  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10600  myquery(rc);
10601 
10602  memset(bind_array, 0, sizeof(bind_array));
10603 
10604  bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10605  bind_array[0].buffer= (void *) koi8;
10606  bind_array[0].buffer_length= strlen(koi8);
10607 
10608  bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10609  bind_array[1].buffer= (void *) koi8;
10610  bind_array[1].buffer_length= strlen(koi8);
10611 
10612  stmt= mysql_stmt_init(mysql);
10613  check_stmt(stmt);
10614 
10615  stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10616 
10617  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10618  check_execute(stmt, rc);
10619 
10620  mysql_stmt_bind_param(stmt, bind_array);
10621 
10622  mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10623 
10624  rc= mysql_stmt_execute(stmt);
10625  check_execute(stmt, rc);
10626 
10627  stmt_text= "SELECT c1, c2 FROM t1";
10628 
10629  /* c1 and c2 are binary so no conversion will be done on select */
10630  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10631  check_execute(stmt, rc);
10632 
10633  rc= mysql_stmt_execute(stmt);
10634  check_execute(stmt, rc);
10635 
10636  bind_array[0].buffer= buf1;
10637  bind_array[0].buffer_length= sizeof(buf1);
10638  bind_array[0].length= &buf1_len;
10639 
10640  bind_array[1].buffer= buf2;
10641  bind_array[1].buffer_length= sizeof(buf2);
10642  bind_array[1].length= &buf2_len;
10643 
10644  mysql_stmt_bind_result(stmt, bind_array);
10645 
10646  rc= mysql_stmt_fetch(stmt);
10647  check_execute(stmt, rc);
10648 
10649  DIE_UNLESS(buf1_len == strlen(cp1251));
10650  DIE_UNLESS(buf2_len == strlen(cp1251));
10651  DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
10652  DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
10653 
10654  rc= mysql_stmt_fetch(stmt);
10655  DIE_UNLESS(rc == MYSQL_NO_DATA);
10656 
10657  stmt_text= "DROP TABLE IF EXISTS t1";
10658  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10659  myquery(rc);
10660 
10661  /*
10662  Now create table with two cp1251 columns, set client character
10663  set to koi8 and supply columns of one row as string and another as
10664  binary data. Binary data must not be converted on insert, and both
10665  columns must be converted to client character set on select.
10666  */
10667 
10668  stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
10669  "c2 VARCHAR(255) CHARACTER SET cp1251)";
10670 
10671  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10672  myquery(rc);
10673 
10674  stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10675 
10676  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10677  check_execute(stmt, rc);
10678 
10679  /* this data must be converted */
10680  bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10681  bind_array[0].buffer= (void *) koi8;
10682  bind_array[0].buffer_length= strlen(koi8);
10683 
10684  bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10685  bind_array[1].buffer= (void *) koi8;
10686  bind_array[1].buffer_length= strlen(koi8);
10687 
10688  mysql_stmt_bind_param(stmt, bind_array);
10689 
10690  mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10691 
10692  rc= mysql_stmt_execute(stmt);
10693  check_execute(stmt, rc);
10694 
10695  /* this data must not be converted */
10696  bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
10697  bind_array[0].buffer= (void *) cp1251;
10698  bind_array[0].buffer_length= strlen(cp1251);
10699 
10700  bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
10701  bind_array[1].buffer= (void *) cp1251;
10702  bind_array[1].buffer_length= strlen(cp1251);
10703 
10704  mysql_stmt_bind_param(stmt, bind_array);
10705 
10706  mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251));
10707 
10708  rc= mysql_stmt_execute(stmt);
10709  check_execute(stmt, rc);
10710 
10711  /* Fetch data and verify that rows are in koi8 */
10712 
10713  stmt_text= "SELECT c1, c2 FROM t1";
10714 
10715  /* c1 and c2 are binary so no conversion will be done on select */
10716  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10717  check_execute(stmt, rc);
10718 
10719  rc= mysql_stmt_execute(stmt);
10720  check_execute(stmt, rc);
10721 
10722  bind_array[0].buffer= buf1;
10723  bind_array[0].buffer_length= sizeof(buf1);
10724  bind_array[0].length= &buf1_len;
10725 
10726  bind_array[1].buffer= buf2;
10727  bind_array[1].buffer_length= sizeof(buf2);
10728  bind_array[1].length= &buf2_len;
10729 
10730  mysql_stmt_bind_result(stmt, bind_array);
10731 
10732  while ((rc= mysql_stmt_fetch(stmt)) == 0)
10733  {
10734  DIE_UNLESS(buf1_len == strlen(koi8));
10735  DIE_UNLESS(buf2_len == strlen(koi8));
10736  DIE_UNLESS(!memcmp(buf1, koi8, buf1_len));
10737  DIE_UNLESS(!memcmp(buf2, koi8, buf1_len));
10738  }
10739  DIE_UNLESS(rc == MYSQL_NO_DATA);
10740  mysql_stmt_close(stmt);
10741 
10742  stmt_text= "DROP TABLE t1";
10743  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10744  myquery(rc);
10745  stmt_text= "SET NAMES DEFAULT";
10746  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10747  myquery(rc);
10748 }
10749 
10750 
10751 static void test_bug3796()
10752 {
10753  MYSQL_STMT *stmt;
10754  MYSQL_BIND my_bind[1];
10755  const char *concat_arg0= "concat_with_";
10756  enum { OUT_BUFF_SIZE= 30 };
10757  char out_buff[OUT_BUFF_SIZE];
10758  char canonical_buff[OUT_BUFF_SIZE];
10759  ulong out_length;
10760  const char *stmt_text;
10761  int rc;
10762 
10763  myheader("test_bug3796");
10764 
10765  /* Create and fill test table */
10766  stmt_text= "DROP TABLE IF EXISTS t1";
10767  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10768  myquery(rc);
10769 
10770  stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))";
10771  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10772  myquery(rc);
10773 
10774  stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')";
10775  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10776  myquery(rc);
10777 
10778  /* Create statement handle and prepare it with select */
10779  stmt= mysql_stmt_init(mysql);
10780  stmt_text= "SELECT concat(?, b) FROM t1";
10781 
10782  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10783  check_execute(stmt, rc);
10784 
10785  /* Bind input buffers */
10786  memset(my_bind, 0, sizeof(my_bind));
10787 
10788  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10789  my_bind[0].buffer= (void *) concat_arg0;
10790  my_bind[0].buffer_length= strlen(concat_arg0);
10791 
10792  mysql_stmt_bind_param(stmt, my_bind);
10793 
10794  /* Execute the select statement */
10795  rc= mysql_stmt_execute(stmt);
10796  check_execute(stmt, rc);
10797 
10798  my_bind[0].buffer= (void *) out_buff;
10799  my_bind[0].buffer_length= OUT_BUFF_SIZE;
10800  my_bind[0].length= &out_length;
10801 
10802  mysql_stmt_bind_result(stmt, my_bind);
10803 
10804  rc= mysql_stmt_fetch(stmt);
10805  if (!opt_silent)
10806  printf("Concat result: '%s'\n", out_buff);
10807  check_execute(stmt, rc);
10808  strmov(canonical_buff, concat_arg0);
10809  strcat(canonical_buff, "ONE");
10810  DIE_UNLESS(strlen(canonical_buff) == out_length &&
10811  strncmp(out_buff, canonical_buff, out_length) == 0);
10812 
10813  rc= mysql_stmt_fetch(stmt);
10814  check_execute(stmt, rc);
10815  strmov(canonical_buff + strlen(concat_arg0), "TWO");
10816  DIE_UNLESS(strlen(canonical_buff) == out_length &&
10817  strncmp(out_buff, canonical_buff, out_length) == 0);
10818  if (!opt_silent)
10819  printf("Concat result: '%s'\n", out_buff);
10820 
10821  rc= mysql_stmt_fetch(stmt);
10822  DIE_UNLESS(rc == MYSQL_NO_DATA);
10823 
10824  mysql_stmt_close(stmt);
10825 
10826  stmt_text= "DROP TABLE IF EXISTS t1";
10827  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10828  myquery(rc);
10829 }
10830 
10831 
10832 static void test_bug4026()
10833 {
10834  MYSQL_STMT *stmt;
10835  MYSQL_BIND my_bind[2];
10836  MYSQL_TIME time_in, time_out;
10837  MYSQL_TIME datetime_in, datetime_out;
10838  const char *stmt_text;
10839  int rc;
10840 
10841  myheader("test_bug4026");
10842 
10843  /* Check that microseconds are inserted and selected successfully */
10844 
10845  /* Create a statement handle and prepare it with select */
10846  stmt= mysql_stmt_init(mysql);
10847  stmt_text= "SELECT ?, ?";
10848 
10849  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10850  check_execute(stmt, rc);
10851 
10852  /* Bind input buffers */
10853  memset(my_bind, 0, sizeof(my_bind));
10854  memset(&time_in, 0, sizeof(time_in));
10855  memset(&time_out, 0, sizeof(time_out));
10856  memset(&datetime_in, 0, sizeof(datetime_in));
10857  memset(&datetime_out, 0, sizeof(datetime_out));
10858 
10859  my_bind[0].buffer_type= MYSQL_TYPE_TIME;
10860  my_bind[0].buffer= (void *) &time_in;
10861  my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
10862  my_bind[1].buffer= (void *) &datetime_in;
10863 
10864  time_in.hour= 23;
10865  time_in.minute= 59;
10866  time_in.second= 59;
10867  time_in.second_part= 123456;
10868  /*
10869  This is not necessary, just to make DIE_UNLESS below work: this field
10870  is filled in when time is received from server
10871  */
10872  time_in.time_type= MYSQL_TIMESTAMP_TIME;
10873 
10874  datetime_in= time_in;
10875  datetime_in.year= 2003;
10876  datetime_in.month= 12;
10877  datetime_in.day= 31;
10878  datetime_in.time_type= MYSQL_TIMESTAMP_DATETIME;
10879 
10880  mysql_stmt_bind_param(stmt, my_bind);
10881 
10882  /* Execute the select statement */
10883  rc= mysql_stmt_execute(stmt);
10884  check_execute(stmt, rc);
10885 
10886  my_bind[0].buffer= (void *) &time_out;
10887  my_bind[1].buffer= (void *) &datetime_out;
10888 
10889  mysql_stmt_bind_result(stmt, my_bind);
10890 
10891  rc= mysql_stmt_fetch(stmt);
10892  DIE_UNLESS(rc == 0);
10893  if (!opt_silent)
10894  {
10895  printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
10896  time_out.second_part);
10897  printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
10898  datetime_out.day, datetime_out.hour,
10899  datetime_out.minute, datetime_out.second,
10900  datetime_out.second_part);
10901  }
10902  DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0);
10903  DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0);
10904  mysql_stmt_close(stmt);
10905 }
10906 
10907 
10908 static void test_bug4079()
10909 {
10910  MYSQL_STMT *stmt;
10911  MYSQL_BIND my_bind[1];
10912  const char *stmt_text;
10913  uint32 res;
10914  int rc;
10915 
10916  myheader("test_bug4079");
10917 
10918  /* Create and fill table */
10919  mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10920  mysql_query(mysql, "CREATE TABLE t1 (a int)");
10921  mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2)");
10922 
10923  /* Prepare erroneous statement */
10924  stmt= mysql_stmt_init(mysql);
10925  stmt_text= "SELECT 1 < (SELECT a FROM t1)";
10926 
10927  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10928  check_execute(stmt, rc);
10929 
10930  /* Execute the select statement */
10931  rc= mysql_stmt_execute(stmt);
10932  check_execute(stmt, rc);
10933 
10934  /* Bind input buffers */
10935  memset(my_bind, 0, sizeof(my_bind));
10936 
10937  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10938  my_bind[0].buffer= (void *) &res;
10939 
10940  mysql_stmt_bind_result(stmt, my_bind);
10941 
10942  rc= mysql_stmt_fetch(stmt);
10943  DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA);
10944  if (!opt_silent)
10945  printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
10946  mysql_stmt_error(stmt));
10947  /* buggy version of libmysql hanged up here */
10948  mysql_stmt_close(stmt);
10949 }
10950 
10951 
10952 static void test_bug4236()
10953 {
10954  MYSQL_STMT *stmt;
10955  const char *stmt_text;
10956  int rc;
10957  MYSQL_STMT backup;
10958 
10959  myheader("test_bug4236");
10960 
10961  stmt= mysql_stmt_init(mysql);
10962 
10963  /* mysql_stmt_execute() of statement with statement id= 0 crashed server */
10964  stmt_text= "SELECT 1";
10965  /* We need to prepare statement to pass by possible check in libmysql */
10966  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10967  check_execute(stmt, rc);
10968  /* Hack to check that server works OK if statement wasn't found */
10969  backup.stmt_id= stmt->stmt_id;
10970  stmt->stmt_id= 0;
10971  rc= mysql_stmt_execute(stmt);
10972  DIE_UNLESS(rc);
10973  /* Restore original statement id to be able to reprepare it */
10974  stmt->stmt_id= backup.stmt_id;
10975 
10976  mysql_stmt_close(stmt);
10977 }
10978 
10979 
10980 static void test_bug4030()
10981 {
10982  MYSQL_STMT *stmt;
10983  MYSQL_BIND my_bind[3];
10984  MYSQL_TIME time_canonical, time_out;
10985  MYSQL_TIME date_canonical, date_out;
10986  MYSQL_TIME datetime_canonical, datetime_out;
10987  const char *stmt_text;
10988  int rc;
10989 
10990  myheader("test_bug4030");
10991 
10992  /* Check that microseconds are inserted and selected successfully */
10993 
10994  /* Execute a query with time values in prepared mode */
10995  stmt= mysql_stmt_init(mysql);
10996  stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
10997  "'2003-12-31 23:59:59.123456'";
10998  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10999  check_execute(stmt, rc);
11000  rc= mysql_stmt_execute(stmt);
11001  check_execute(stmt, rc);
11002 
11003  /* Bind output buffers */
11004  memset(my_bind, 0, sizeof(my_bind));
11005  memset(&time_canonical, 0, sizeof(time_canonical));
11006  memset(&time_out, 0, sizeof(time_out));
11007  memset(&date_canonical, 0, sizeof(date_canonical));
11008  memset(&date_out, 0, sizeof(date_out));
11009  memset(&datetime_canonical, 0, sizeof(datetime_canonical));
11010  memset(&datetime_out, 0, sizeof(datetime_out));
11011 
11012  my_bind[0].buffer_type= MYSQL_TYPE_TIME;
11013  my_bind[0].buffer= (void *) &time_out;
11014  my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11015  my_bind[1].buffer= (void *) &date_out;
11016  my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
11017  my_bind[2].buffer= (void *) &datetime_out;
11018 
11019  time_canonical.hour= 23;
11020  time_canonical.minute= 59;
11021  time_canonical.second= 59;
11022  time_canonical.second_part= 123456;
11023  time_canonical.time_type= MYSQL_TIMESTAMP_TIME;
11024 
11025  date_canonical.year= 2003;
11026  date_canonical.month= 12;
11027  date_canonical.day= 31;
11028  date_canonical.time_type= MYSQL_TIMESTAMP_DATE;
11029 
11030  datetime_canonical= time_canonical;
11031  datetime_canonical.year= 2003;
11032  datetime_canonical.month= 12;
11033  datetime_canonical.day= 31;
11034  datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME;
11035 
11036  mysql_stmt_bind_result(stmt, my_bind);
11037 
11038  rc= mysql_stmt_fetch(stmt);
11039  DIE_UNLESS(rc == 0);
11040  if (!opt_silent)
11041  {
11042  printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
11043  time_out.second_part);
11044  printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
11045  printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
11046  datetime_out.day, datetime_out.hour,
11047  datetime_out.minute, datetime_out.second,
11048  datetime_out.second_part);
11049  }
11050  DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
11051  DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
11052  DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
11053  mysql_stmt_close(stmt);
11054 }
11055 
11056 static void test_view()
11057 {
11058  MYSQL_STMT *stmt;
11059  int rc, i;
11060  MYSQL_BIND my_bind[1];
11061  char str_data[50];
11062  ulong length = 0L;
11063  long is_null = 0L;
11064  const char *query=
11065  "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
11066 
11067  myheader("test_view");
11068 
11069  rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
11070  myquery(rc);
11071 
11072  rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
11073  myquery(rc);
11074  rc= mysql_query(mysql,"CREATE TABLE t1 ("
11075  " SERVERGRP varchar(20) NOT NULL default '', "
11076  " DBINSTANCE varchar(20) NOT NULL default '', "
11077  " PRIMARY KEY (SERVERGRP)) "
11078  " CHARSET=latin1 collate=latin1_bin");
11079  myquery(rc);
11080  rc= mysql_query(mysql,"CREATE TABLE t2 ("
11081  " SERVERNAME varchar(20) NOT NULL, "
11082  " SERVERGRP varchar(20) NOT NULL, "
11083  " PRIMARY KEY (SERVERNAME)) "
11084  " CHARSET=latin1 COLLATE latin1_bin");
11085  myquery(rc);
11086  rc= mysql_query(mysql,
11087  "CREATE TABLE t3 ("
11088  " SERVERGRP varchar(20) BINARY NOT NULL, "
11089  " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
11090  " ACTSTATE char(1) NOT NULL , "
11091  " LOCAL_NAME varchar(30) NOT NULL, "
11092  " CHG_DATE varchar(8) NOT NULL default '00000000', "
11093  " CHG_TIME varchar(6) NOT NULL default '000000', "
11094  " MXUSER varchar(12) NOT NULL default '', "
11095  " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
11096  " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
11097  myquery(rc);
11098  rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
11099  " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
11100  " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
11101  " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
11102  " ((T0002.SERVERGRP = T0001.SERVERGRP) and"
11103  " (T0002.SERVERGRP = T0003.SERVERGRP)"
11104  " and (T0003.MAPSTATE = _latin1'A') and"
11105  " (T0003.ACTSTATE = _latin1' '))");
11106  myquery(rc);
11107 
11108  stmt= mysql_stmt_init(mysql);
11109  rc= mysql_stmt_prepare(stmt, query, strlen(query));
11110  check_execute(stmt, rc);
11111 
11112  strmov(str_data, "TEST");
11113  memset(my_bind, 0, sizeof(my_bind));
11114  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
11115  my_bind[0].buffer= (char *)&str_data;
11116  my_bind[0].buffer_length= 50;
11117  my_bind[0].length= &length;
11118  length= 4;
11119  my_bind[0].is_null= (char*)&is_null;
11120  rc= mysql_stmt_bind_param(stmt, my_bind);
11121  check_execute(stmt,rc);
11122 
11123  for (i= 0; i < 3; i++)
11124  {
11125  rc= mysql_stmt_execute(stmt);
11126  check_execute(stmt, rc);
11127  rc= my_process_stmt_result(stmt);
11128  DIE_UNLESS(1 == rc);
11129  }
11130  mysql_stmt_close(stmt);
11131 
11132  rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
11133  myquery(rc);
11134  rc= mysql_query(mysql, "DROP VIEW v1");
11135  myquery(rc);
11136 }
11137 
11138 
11139 static void test_view_where()
11140 {
11141  MYSQL_STMT *stmt;
11142  int rc, i;
11143  const char *query=
11144  "select v1.c,v2.c from v1, v2";
11145 
11146  myheader("test_view_where");
11147 
11148  rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2");
11149  myquery(rc);
11150 
11151  rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1");
11152  myquery(rc);
11153  rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)");
11154  myquery(rc);
11155  rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)");
11156  myquery(rc);
11157  rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3");
11158  myquery(rc);
11159  rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3");
11160  myquery(rc);
11161 
11162  stmt= mysql_stmt_init(mysql);
11163  rc= mysql_stmt_prepare(stmt, query, strlen(query));
11164  check_execute(stmt, rc);
11165 
11166  for (i= 0; i < 3; i++)
11167  {
11168  rc= mysql_stmt_execute(stmt);
11169  check_execute(stmt, rc);
11170  rc= my_process_stmt_result(stmt);
11171  DIE_UNLESS(4 == rc);
11172  }
11173  mysql_stmt_close(stmt);
11174 
11175  rc= mysql_query(mysql, "DROP TABLE t1");
11176  myquery(rc);
11177  rc= mysql_query(mysql, "DROP VIEW v1, v2");
11178  myquery(rc);
11179 }
11180 
11181 
11182 static void test_view_2where()
11183 {
11184  MYSQL_STMT *stmt;
11185  int rc, i;
11186  MYSQL_BIND my_bind[8];
11187  char parms[8][100];
11188  ulong length[8];
11189  const char *query=
11190  "select relid, report, handle, log_group, username, variant, type, "
11191  "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
11192  "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
11193  "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";
11194 
11195  myheader("test_view_2where");
11196 
11197  rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
11198  myquery(rc);
11199  rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
11200  myquery(rc);
11201  rc= mysql_query(mysql,
11202  "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
11203  " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
11204  " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
11205  " USERNAME varchar(12) NOT NULL,"
11206  " VARIANT varchar(12) NOT NULL,"
11207  " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
11208  " VERSION varchar(6) NOT NULL default '000000',"
11209  " ERFDAT varchar(8) NOT NULL default '00000000',"
11210  " ERFTIME varchar(6) NOT NULL default '000000',"
11211  " ERFNAME varchar(12) NOT NULL,"
11212  " AEDAT varchar(8) NOT NULL default '00000000',"
11213  " AETIME varchar(6) NOT NULL default '000000',"
11214  " AENAME varchar(12) NOT NULL,"
11215  " DEPENDVARS varchar(10) NOT NULL,"
11216  " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
11217  " CLUSTD blob,"
11218  " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
11219  "USERNAME, VARIANT, TYPE, SRTF2))"
11220  " CHARSET=latin1 COLLATE latin1_bin");
11221  myquery(rc);
11222  rc= mysql_query(mysql,
11223  "CREATE VIEW V_LTDX AS select T0001.MANDT AS "
11224  " MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
11225  " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
11226  " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
11227  " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
11228  " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
11229  " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
11230  " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
11231  " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
11232  " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
11233  myquery(rc);
11234  memset(my_bind, 0, sizeof(my_bind));
11235  for (i=0; i < 8; i++) {
11236  strmov(parms[i], "1");
11237  my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11238  my_bind[i].buffer = (char *)&parms[i];
11239  my_bind[i].buffer_length = 100;
11240  my_bind[i].is_null = 0;
11241  my_bind[i].length = &length[i];
11242  length[i] = 1;
11243  }
11244  stmt= mysql_stmt_init(mysql);
11245  rc= mysql_stmt_prepare(stmt, query, strlen(query));
11246  check_execute(stmt, rc);
11247 
11248  rc= mysql_stmt_bind_param(stmt, my_bind);
11249  check_execute(stmt,rc);
11250 
11251  rc= mysql_stmt_execute(stmt);
11252  check_execute(stmt, rc);
11253  rc= my_process_stmt_result(stmt);
11254  DIE_UNLESS(0 == rc);
11255 
11256  mysql_stmt_close(stmt);
11257 
11258  rc= mysql_query(mysql, "DROP VIEW V_LTDX");
11259  myquery(rc);
11260  rc= mysql_query(mysql, "DROP TABLE LTDX");
11261  myquery(rc);
11262 }
11263 
11264 
11265 static void test_view_star()
11266 {
11267  MYSQL_STMT *stmt;
11268  int rc, i;
11269  MYSQL_BIND my_bind[8];
11270  char parms[8][100];
11271  ulong length[8];
11272  const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)";
11273 
11274  myheader("test_view_star");
11275 
11276  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1");
11277  myquery(rc);
11278  rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1");
11279  myquery(rc);
11280  rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
11281  myquery(rc);
11282  rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1");
11283  myquery(rc);
11284  memset(my_bind, 0, sizeof(my_bind));
11285  for (i= 0; i < 2; i++) {
11286  sprintf((char *)&parms[i], "%d", i);
11287  my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11288  my_bind[i].buffer = (char *)&parms[i];
11289  my_bind[i].buffer_length = 100;
11290  my_bind[i].is_null = 0;
11291  my_bind[i].length = &length[i];
11292  length[i] = 1;
11293  }
11294 
11295  stmt= mysql_stmt_init(mysql);
11296  rc= mysql_stmt_prepare(stmt, query, strlen(query));
11297  check_execute(stmt, rc);
11298 
11299  rc= mysql_stmt_bind_param(stmt, my_bind);
11300  check_execute(stmt,rc);
11301 
11302  for (i= 0; i < 3; i++)
11303  {
11304  rc= mysql_stmt_execute(stmt);
11305  check_execute(stmt, rc);
11306  rc= my_process_stmt_result(stmt);
11307  DIE_UNLESS(0 == rc);
11308  }
11309 
11310  mysql_stmt_close(stmt);
11311 
11312  rc= mysql_query(mysql, "DROP TABLE t1");
11313  myquery(rc);
11314  rc= mysql_query(mysql, "DROP VIEW vt1");
11315  myquery(rc);
11316 }
11317 
11318 
11319 static void test_view_insert()
11320 {
11321  MYSQL_STMT *insert_stmt, *select_stmt;
11322  int rc, i;
11323  MYSQL_BIND my_bind[1];
11324  int my_val = 0;
11325  ulong my_length = 0L;
11326  long my_null = 0L;
11327  const char *query=
11328  "insert into v1 values (?)";
11329 
11330  myheader("test_view_insert");
11331 
11332  rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11333  myquery(rc);
11334  rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1");
11335  myquery(rc);
11336 
11337  rc= mysql_query(mysql,"create table t1 (a int, primary key (a))");
11338  myquery(rc);
11339 
11340  rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1");
11341  myquery(rc);
11342 
11343  insert_stmt= mysql_stmt_init(mysql);
11344  rc= mysql_stmt_prepare(insert_stmt, query, strlen(query));
11345  check_execute(insert_stmt, rc);
11346  query= "select * from t1";
11347  select_stmt= mysql_stmt_init(mysql);
11348  rc= mysql_stmt_prepare(select_stmt, query, strlen(query));
11349  check_execute(select_stmt, rc);
11350 
11351  memset(my_bind, 0, sizeof(my_bind));
11352  my_bind[0].buffer_type = MYSQL_TYPE_LONG;
11353  my_bind[0].buffer = (char *)&my_val;
11354  my_bind[0].length = &my_length;
11355  my_bind[0].is_null = (char*)&my_null;
11356  rc= mysql_stmt_bind_param(insert_stmt, my_bind);
11357  check_execute(insert_stmt, rc);
11358 
11359  for (i= 0; i < 3; i++)
11360  {
11361  int rowcount= 0;
11362  my_val= i;
11363 
11364  rc= mysql_stmt_execute(insert_stmt);
11365  check_execute(insert_stmt, rc);
11366 
11367  rc= mysql_stmt_execute(select_stmt);
11368  check_execute(select_stmt, rc);
11369  rowcount= (int)my_process_stmt_result(select_stmt);
11370  DIE_UNLESS((i+1) == rowcount);
11371  }
11372  mysql_stmt_close(insert_stmt);
11373  mysql_stmt_close(select_stmt);
11374 
11375  rc= mysql_query(mysql, "DROP VIEW v1");
11376  myquery(rc);
11377  rc= mysql_query(mysql, "DROP TABLE t1");
11378  myquery(rc);
11379 }
11380 
11381 
11382 static void test_left_join_view()
11383 {
11384  MYSQL_STMT *stmt;
11385  int rc, i;
11386  const char *query=
11387  "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);";
11388 
11389  myheader("test_left_join_view");
11390 
11391  rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11392  myquery(rc);
11393 
11394  rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1");
11395  myquery(rc);
11396  rc= mysql_query(mysql,"CREATE TABLE t1 (a int)");
11397  myquery(rc);
11398  rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)");
11399  myquery(rc);
11400  rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1");
11401  myquery(rc);
11402  stmt= mysql_stmt_init(mysql);
11403  rc= mysql_stmt_prepare(stmt, query, strlen(query));
11404  check_execute(stmt, rc);
11405 
11406  for (i= 0; i < 3; i++)
11407  {
11408  rc= mysql_stmt_execute(stmt);
11409  check_execute(stmt, rc);
11410  rc= my_process_stmt_result(stmt);
11411  DIE_UNLESS(3 == rc);
11412  }
11413  mysql_stmt_close(stmt);
11414 
11415  rc= mysql_query(mysql, "DROP VIEW v1");
11416  myquery(rc);
11417  rc= mysql_query(mysql, "DROP TABLE t1");
11418  myquery(rc);
11419 }
11420 
11421 
11422 static void test_view_insert_fields()
11423 {
11424  MYSQL_STMT *stmt;
11425  char parm[11][1000];
11426  ulong l[11];
11427  int rc, i;
11428  MYSQL_BIND my_bind[11];
11429  const char *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";
11430 
11431  myheader("test_view_insert_fields");
11432 
11433  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
11434  myquery(rc);
11435  rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
11436  myquery(rc);
11437  rc= mysql_query(mysql,
11438  "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
11439  "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
11440  "K4N4 varchar(4) NOT NULL default '0000',"
11441  "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
11442  "F3N5 varchar(5) NOT NULL default '00000',"
11443  "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
11444  "F6N4 varchar(4) NOT NULL default '0000',"
11445  "F7F8 double NOT NULL default '0',"
11446  "F8F8 double NOT NULL default '0',"
11447  "F9D8 decimal(8,2) NOT NULL default '0.00',"
11448  "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
11449  "CHARSET=latin1 COLLATE latin1_bin");
11450  myquery(rc);
11451  rc= mysql_query(mysql,
11452  "CREATE VIEW v1 AS select sql_no_cache "
11453  " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
11454  " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
11455  " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
11456  " from t1 T0001");
11457 
11458  memset(my_bind, 0, sizeof(my_bind));
11459  for (i= 0; i < 11; i++)
11460  {
11461  l[i]= 20;
11462  my_bind[i].buffer_type= MYSQL_TYPE_STRING;
11463  my_bind[i].is_null= 0;
11464  my_bind[i].buffer= (char *)&parm[i];
11465 
11466  strmov(parm[i], "1");
11467  my_bind[i].buffer_length= 2;
11468  my_bind[i].length= &l[i];
11469  }
11470  stmt= mysql_stmt_init(mysql);
11471  rc= mysql_stmt_prepare(stmt, query, strlen(query));
11472  check_execute(stmt, rc);
11473  rc= mysql_stmt_bind_param(stmt, my_bind);
11474  check_execute(stmt, rc);
11475 
11476  rc= mysql_stmt_execute(stmt);
11477  check_execute(stmt, rc);
11478  mysql_stmt_close(stmt);
11479 
11480  query= "select * from t1";
11481  stmt= mysql_stmt_init(mysql);
11482  rc= mysql_stmt_prepare(stmt, query, strlen(query));
11483  check_execute(stmt, rc);
11484  rc= mysql_stmt_execute(stmt);
11485  check_execute(stmt, rc);
11486  rc= my_process_stmt_result(stmt);
11487  DIE_UNLESS(1 == rc);
11488 
11489  mysql_stmt_close(stmt);
11490  rc= mysql_query(mysql, "DROP VIEW v1");
11491  myquery(rc);
11492  rc= mysql_query(mysql, "DROP TABLE t1");
11493  myquery(rc);
11494 
11495 }
11496 
11497 static void test_bug5126()
11498 {
11499  MYSQL_STMT *stmt;
11500  MYSQL_BIND my_bind[2];
11501  int32 c1, c2;
11502  const char *stmt_text;
11503  int rc;
11504 
11505  myheader("test_bug5126");
11506 
11507  stmt_text= "DROP TABLE IF EXISTS t1";
11508  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11509  myquery(rc);
11510 
11511  stmt_text= "CREATE TABLE t1 (a mediumint, b int)";
11512  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11513  myquery(rc);
11514 
11515  stmt_text= "INSERT INTO t1 VALUES (8386608, 1)";
11516  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11517  myquery(rc);
11518 
11519  stmt= mysql_stmt_init(mysql);
11520  stmt_text= "SELECT a, b FROM t1";
11521  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11522  check_execute(stmt, rc);
11523  rc= mysql_stmt_execute(stmt);
11524  check_execute(stmt, rc);
11525 
11526  /* Bind output buffers */
11527  memset(my_bind, 0, sizeof(my_bind));
11528 
11529  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11530  my_bind[0].buffer= &c1;
11531  my_bind[1].buffer_type= MYSQL_TYPE_LONG;
11532  my_bind[1].buffer= &c2;
11533 
11534  mysql_stmt_bind_result(stmt, my_bind);
11535 
11536  rc= mysql_stmt_fetch(stmt);
11537  DIE_UNLESS(rc == 0);
11538  DIE_UNLESS(c1 == 8386608 && c2 == 1);
11539  if (!opt_silent)
11540  printf("%ld, %ld\n", (long) c1, (long) c2);
11541  mysql_stmt_close(stmt);
11542 }
11543 
11544 
11545 static void test_bug4231()
11546 {
11547  MYSQL_STMT *stmt;
11548  MYSQL_BIND my_bind[2];
11549  MYSQL_TIME tm[2];
11550  const char *stmt_text;
11551  int rc;
11552 
11553  myheader("test_bug4231");
11554 
11555  stmt_text= "DROP TABLE IF EXISTS t1";
11556  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11557  myquery(rc);
11558 
11559  stmt_text= "CREATE TABLE t1 (a int)";
11560  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11561  myquery(rc);
11562 
11563  stmt_text= "INSERT INTO t1 VALUES (1)";
11564  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11565  myquery(rc);
11566 
11567  stmt= mysql_stmt_init(mysql);
11568  stmt_text= "SELECT a FROM t1 WHERE ? = ?";
11569  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11570  check_execute(stmt, rc);
11571 
11572  /* Bind input buffers */
11573  memset(my_bind, 0, sizeof(my_bind));
11574  memset(tm, 0, sizeof(tm));
11575 
11576  my_bind[0].buffer_type= MYSQL_TYPE_DATE;
11577  my_bind[0].buffer= &tm[0];
11578  my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11579  my_bind[1].buffer= &tm[1];
11580 
11581  mysql_stmt_bind_param(stmt, my_bind);
11582  check_execute(stmt, rc);
11583 
11584  /*
11585  First set server-side params to some non-zero non-equal values:
11586  then we will check that they are not used when client sends
11587  new (zero) times.
11588  */
11589  tm[0].time_type = MYSQL_TIMESTAMP_DATE;
11590  tm[0].year = 2000;
11591  tm[0].month = 1;
11592  tm[0].day = 1;
11593  tm[1]= tm[0];
11594  --tm[1].year; /* tm[0] != tm[1] */
11595 
11596  rc= mysql_stmt_execute(stmt);
11597  check_execute(stmt, rc);
11598 
11599  rc= mysql_stmt_fetch(stmt);
11600 
11601  /* binds are unequal, no rows should be returned */
11602  DIE_UNLESS(rc == MYSQL_NO_DATA);
11603 
11604  /* Set one of the dates to zero */
11605  tm[0].year= tm[0].month= tm[0].day= 0;
11606  tm[1]= tm[0];
11607  mysql_stmt_execute(stmt);
11608  rc= mysql_stmt_fetch(stmt);
11609  DIE_UNLESS(rc == 0);
11610 
11611  mysql_stmt_close(stmt);
11612  stmt_text= "DROP TABLE t1";
11613  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11614  myquery(rc);
11615 }
11616 
11617 
11618 static void test_bug5399()
11619 {
11620  /*
11621  Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
11622  statement id hash in the server uses binary collation.
11623  */
11624 #define NUM_OF_USED_STMT 97
11625  MYSQL_STMT *stmt_list[NUM_OF_USED_STMT];
11626  MYSQL_STMT **stmt;
11627  MYSQL_BIND my_bind[1];
11628  char buff[600];
11629  int rc;
11630  int32 no;
11631 
11632  myheader("test_bug5399");
11633 
11634  memset(my_bind, 0, sizeof(my_bind));
11635  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11636  my_bind[0].buffer= &no;
11637 
11638  for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11639  {
11640  sprintf(buff, "select %d", (int) (stmt - stmt_list));
11641  *stmt= mysql_stmt_init(mysql);
11642  rc= mysql_stmt_prepare(*stmt, buff, strlen(buff));
11643  check_execute(*stmt, rc);
11644  mysql_stmt_bind_result(*stmt, my_bind);
11645  }
11646  if (!opt_silent)
11647  printf("%d statements prepared.\n", NUM_OF_USED_STMT);
11648 
11649  for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11650  {
11651  rc= mysql_stmt_execute(*stmt);
11652  check_execute(*stmt, rc);
11653  rc= mysql_stmt_store_result(*stmt);
11654  check_execute(*stmt, rc);
11655  rc= mysql_stmt_fetch(*stmt);
11656  DIE_UNLESS(rc == 0);
11657  DIE_UNLESS((int32) (stmt - stmt_list) == no);
11658  }
11659 
11660  for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11661  mysql_stmt_close(*stmt);
11662 #undef NUM_OF_USED_STMT
11663 }
11664 
11665 
11666 static void test_bug5194()
11667 {
11668  MYSQL_STMT *stmt;
11669  MYSQL_BIND *my_bind;
11670  char *query;
11671  char *param_str;
11672  int param_str_length;
11673  const char *stmt_text;
11674  int rc;
11675  float float_array[250] =
11676  {
11677  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11678  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11679  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11680  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11681  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11682  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11683  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11684  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11685  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11686  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11687  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11688  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11689  0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
11690  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11691  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11692  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11693  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11694  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11695  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11696  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11697  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11698  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11699  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11700  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
11701  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25
11702  };
11703  float *fa_ptr= float_array;
11704  /* Number of columns per row */
11705  const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array);
11706  /* Number of rows per bulk insert to start with */
11707  const int MIN_ROWS_PER_INSERT= 262;
11708  /* Max number of rows per bulk insert to end with */
11709  const int MAX_ROWS_PER_INSERT= 300;
11710  const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT;
11711  const char *query_template= "insert into t1 values %s";
11712  const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */
11713  const int uint16_max= 65535;
11714  int nrows, i;
11715 
11716  myheader("test_bug5194");
11717 
11718  stmt_text= "drop table if exists t1";
11719  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11720 
11721  stmt_text= "create table if not exists t1"
11722  "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, "
11723  "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, "
11724  "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, "
11725  "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, "
11726  "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, "
11727  "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, "
11728  "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, "
11729  "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, "
11730  "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, "
11731  "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, "
11732  "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, "
11733  "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, "
11734  "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, "
11735  "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, "
11736  "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, "
11737  "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, "
11738  "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, "
11739  "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, "
11740  "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, "
11741  "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, "
11742  "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, "
11743  "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, "
11744  "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, "
11745  "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, "
11746  "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, "
11747  "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, "
11748  "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, "
11749  "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, "
11750  "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, "
11751  "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, "
11752  "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, "
11753  "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, "
11754  "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, "
11755  "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, "
11756  "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, "
11757  "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, "
11758  "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, "
11759  "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, "
11760  "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, "
11761  "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, "
11762  "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, "
11763  "c247 float, c248 float, c249 float, c250 float)";
11764  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11765  myquery(rc);
11766 
11767  my_bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11768  query= (char*) malloc(strlen(query_template) +
11769  MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
11770  param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
11771 
11772  if (my_bind == 0 || query == 0 || param_str == 0)
11773  {
11774  fprintf(stderr, "Can't allocate enough memory for query structs\n");
11775  if (my_bind)
11776  free(my_bind);
11777  if (query)
11778  free(query);
11779  if (param_str)
11780  free(param_str);
11781  return;
11782  }
11783 
11784  stmt= mysql_stmt_init(mysql);
11785 
11786  /* setup a template for one row of parameters */
11787  sprintf(param_str, "(");
11788  for (i= 1; i < COLUMN_COUNT; ++i)
11789  strcat(param_str, "?, ");
11790  strcat(param_str, "?)");
11791  param_str_length= strlen(param_str);
11792 
11793  /* setup bind array */
11794  memset(my_bind, 0, MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11795  for (i= 0; i < MAX_PARAM_COUNT; ++i)
11796  {
11797  my_bind[i].buffer_type= MYSQL_TYPE_FLOAT;
11798  my_bind[i].buffer= fa_ptr;
11799  if (++fa_ptr == float_array + COLUMN_COUNT)
11800  fa_ptr= float_array;
11801  }
11802 
11803  /*
11804  Test each number of rows per bulk insert, so that we can see where
11805  MySQL fails.
11806  */
11807  for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows)
11808  {
11809  char *query_ptr;
11810  /* Create statement text for current number of rows */
11811  sprintf(query, query_template, param_str);
11812  query_ptr= query + strlen(query);
11813  for (i= 1; i < nrows; ++i)
11814  {
11815  memcpy(query_ptr, ", ", 2);
11816  query_ptr+= 2;
11817  memcpy(query_ptr, param_str, param_str_length);
11818  query_ptr+= param_str_length;
11819  }
11820  *query_ptr= '\0';
11821 
11822  rc= mysql_stmt_prepare(stmt, query, query_ptr - query);
11823  if (rc && nrows * COLUMN_COUNT > uint16_max)
11824  {
11825  if (!opt_silent)
11826  printf("Failed to prepare a statement with %d placeholders "
11827  "(as expected).\n", nrows * COLUMN_COUNT);
11828  break;
11829  }
11830  else
11831  check_execute(stmt, rc);
11832 
11833  if (!opt_silent)
11834  printf("Insert: query length= %d, row count= %d, param count= %lu\n",
11835  (int) strlen(query), nrows, mysql_stmt_param_count(stmt));
11836 
11837  /* bind the parameter array and execute the query */
11838  rc= mysql_stmt_bind_param(stmt, my_bind);
11839  check_execute(stmt, rc);
11840 
11841  rc= mysql_stmt_execute(stmt);
11842  check_execute(stmt, rc);
11843  mysql_stmt_reset(stmt);
11844  }
11845 
11846  mysql_stmt_close(stmt);
11847  free(my_bind);
11848  free(query);
11849  free(param_str);
11850  stmt_text= "drop table t1";
11851  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11852  myquery(rc);
11853 }
11854 
11855 
11856 static void test_bug5315()
11857 {
11858  MYSQL_STMT *stmt;
11859  const char *stmt_text;
11860  int rc;
11861 
11862  myheader("test_bug5315");
11863 
11864  stmt_text= "SELECT 1";
11865  stmt= mysql_stmt_init(mysql);
11866  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11867  DIE_UNLESS(rc == 0);
11868  if (!opt_silent)
11869  printf("Excuting mysql_change_user\n");
11870  mysql_change_user(mysql, opt_user, opt_password, current_db);
11871  if (!opt_silent)
11872  printf("Excuting mysql_stmt_execute\n");
11873  rc= mysql_stmt_execute(stmt);
11874  DIE_UNLESS(rc != 0);
11875  if (rc)
11876  {
11877  if (!opt_silent)
11878  printf("Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
11879  }
11880  /* check that connection is OK */
11881  if (!opt_silent)
11882  printf("Excuting mysql_stmt_close\n");
11883  mysql_stmt_close(stmt);
11884  if (!opt_silent)
11885  printf("Excuting mysql_stmt_init\n");
11886  stmt= mysql_stmt_init(mysql);
11887  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11888  DIE_UNLESS(rc == 0);
11889  rc= mysql_stmt_execute(stmt);
11890  DIE_UNLESS(rc == 0);
11891  mysql_stmt_close(stmt);
11892 }
11893 
11894 
11895 static void test_bug6049()
11896 {
11897  MYSQL_STMT *stmt;
11898  MYSQL_BIND my_bind[1];
11899  MYSQL_RES *res;
11900  MYSQL_ROW row;
11901  const char *stmt_text;
11902  char buffer[30];
11903  ulong length;
11904  int rc;
11905 
11906  myheader("test_bug6049");
11907 
11908  stmt_text= "SELECT MAKETIME(-25, 12, 12)";
11909 
11910  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11911  myquery(rc);
11912  res= mysql_store_result(mysql);
11913  row= mysql_fetch_row(res);
11914 
11915  stmt= mysql_stmt_init(mysql);
11916  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11917  check_execute(stmt, rc);
11918  rc= mysql_stmt_execute(stmt);
11919  check_execute(stmt, rc);
11920 
11921  memset(my_bind, 0, sizeof(my_bind));
11922  my_bind[0].buffer_type = MYSQL_TYPE_STRING;
11923  my_bind[0].buffer = &buffer;
11924  my_bind[0].buffer_length = sizeof(buffer);
11925  my_bind[0].length = &length;
11926 
11927  mysql_stmt_bind_result(stmt, my_bind);
11928  rc= mysql_stmt_fetch(stmt);
11929  DIE_UNLESS(rc == 0);
11930 
11931  if (!opt_silent)
11932  {
11933  printf("Result from query: %s\n", row[0]);
11934  printf("Result from prepared statement: %s\n", (char*) buffer);
11935  }
11936 
11937  DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);
11938 
11939  mysql_free_result(res);
11940  mysql_stmt_close(stmt);
11941 }
11942 
11943 
11944 static void test_bug6058()
11945 {
11946  MYSQL_STMT *stmt;
11947  MYSQL_BIND my_bind[1];
11948  MYSQL_RES *res;
11949  MYSQL_ROW row;
11950  const char *stmt_text;
11951  char buffer[30];
11952  ulong length;
11953  int rc;
11954 
11955  myheader("test_bug6058");
11956 
11957  rc= mysql_query(mysql, "SET SQL_MODE=''");
11958  myquery(rc);
11959 
11960  stmt_text= "SELECT CAST('0000-00-00' AS DATE)";
11961 
11962  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11963  myquery(rc);
11964  res= mysql_store_result(mysql);
11965  row= mysql_fetch_row(res);
11966 
11967  stmt= mysql_stmt_init(mysql);
11968  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11969  check_execute(stmt, rc);
11970  rc= mysql_stmt_execute(stmt);
11971  check_execute(stmt, rc);
11972 
11973  memset(my_bind, 0, sizeof(my_bind));
11974  my_bind[0].buffer_type = MYSQL_TYPE_STRING;
11975  my_bind[0].buffer = &buffer;
11976  my_bind[0].buffer_length = sizeof(buffer);
11977  my_bind[0].length = &length;
11978 
11979  mysql_stmt_bind_result(stmt, my_bind);
11980  rc= mysql_stmt_fetch(stmt);
11981  DIE_UNLESS(rc == 0);
11982 
11983  if (!opt_silent)
11984  {
11985  printf("Result from query: %s\n", row[0]);
11986  printf("Result from prepared statement: %s\n", buffer);
11987  }
11988 
11989  DIE_UNLESS(strcmp(row[0], buffer) == 0);
11990 
11991  mysql_free_result(res);
11992  mysql_stmt_close(stmt);
11993 }
11994 
11995 
11996 static void test_bug6059()
11997 {
11998  MYSQL_STMT *stmt;
11999  const char *stmt_text;
12000 
12001  myheader("test_bug6059");
12002 
12003  stmt_text= "SELECT 'foo' INTO OUTFILE 'x.3'";
12004 
12005  stmt= mysql_stmt_init(mysql);
12006  (void) mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12007  DIE_UNLESS(mysql_stmt_field_count(stmt) == 0);
12008  mysql_stmt_close(stmt);
12009 }
12010 
12011 
12012 static void test_bug6046()
12013 {
12014  MYSQL_STMT *stmt;
12015  const char *stmt_text;
12016  int rc;
12017  short b= 1;
12018  MYSQL_BIND my_bind[1];
12019 
12020  myheader("test_bug6046");
12021 
12022  stmt_text= "DROP TABLE IF EXISTS t1";
12023  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12024  myquery(rc);
12025  stmt_text= "CREATE TABLE t1 (a int, b int)";
12026  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12027  myquery(rc);
12028  stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)";
12029  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12030  myquery(rc);
12031 
12032  stmt= mysql_stmt_init(mysql);
12033 
12034  stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 "
12035  "WHERE t1.b > ? ORDER BY t1.a";
12036 
12037  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12038  check_execute(stmt, rc);
12039 
12040  b= 1;
12041  memset(my_bind, 0, sizeof(my_bind));
12042  my_bind[0].buffer= &b;
12043  my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
12044 
12045  mysql_stmt_bind_param(stmt, my_bind);
12046 
12047  rc= mysql_stmt_execute(stmt);
12048  check_execute(stmt, rc);
12049  mysql_stmt_store_result(stmt);
12050 
12051  rc= mysql_stmt_execute(stmt);
12052  check_execute(stmt, rc);
12053 
12054  mysql_stmt_close(stmt);
12055 }
12056 
12057 
12058 
12059 static void test_basic_cursors()
12060 {
12061  const char *basic_tables[]=
12062  {
12063  "DROP TABLE IF EXISTS t1, t2",
12064 
12065  "CREATE TABLE t1 "
12066  "(id INTEGER NOT NULL PRIMARY KEY, "
12067  " name VARCHAR(20) NOT NULL)",
12068 
12069  "INSERT INTO t1 (id, name) VALUES "
12070  " (2, 'Ja'), (3, 'Ede'), "
12071  " (4, 'Haag'), (5, 'Kabul'), "
12072  " (6, 'Almere'), (7, 'Utrecht'), "
12073  " (8, 'Qandahar'), (9, 'Amsterdam'), "
12074  " (10, 'Amersfoort'), (11, 'Constantine')",
12075 
12076  "CREATE TABLE t2 "
12077  "(id INTEGER NOT NULL PRIMARY KEY, "
12078  " name VARCHAR(20) NOT NULL)",
12079 
12080  "INSERT INTO t2 (id, name) VALUES "
12081  " (4, 'Guam'), (5, 'Aruba'), "
12082  " (6, 'Angola'), (7, 'Albania'), "
12083  " (8, 'Anguilla'), (9, 'Argentina'), "
12084  " (10, 'Azerbaijan'), (11, 'Afghanistan'), "
12085  " (12, 'Burkina Faso'), (13, 'Faroe Islands')"
12086  };
12087  const char *queries[]=
12088  {
12089  "SELECT * FROM t1",
12090  "SELECT * FROM t2"
12091  };
12092 
12093  DBUG_ENTER("test_basic_cursors");
12094  myheader("test_basic_cursors");
12095 
12096  fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
12097 
12098  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12099  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12100  DBUG_VOID_RETURN;
12101 }
12102 
12103 
12104 static void test_cursors_with_union()
12105 {
12106  const char *queries[]=
12107  {
12108  "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2",
12109  "SELECT t1.id FROM t1 WHERE t1.id < 5"
12110  };
12111  myheader("test_cursors_with_union");
12112  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12113  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12114 }
12115 
12116 
12117 static void test_cursors_with_procedure()
12118 {
12119  const char *queries[]=
12120  {
12121  "SELECT * FROM t1 procedure analyse()"
12122  };
12123  myheader("test_cursors_with_procedure");
12124  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12125  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12126 }
12127 
12128 
12129 /*
12130  Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
12131  should not crash server and should not hang in case of errors.
12132 
12133  Since those functions can't be seen in modern API (unless client library
12134  was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro.
12135 */
12136 static void test_bug6081()
12137 {
12138  int rc;
12139  myheader("test_bug6081");
12140 
12141  rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12142  (ulong)strlen(current_db), 0);
12143  if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12144  {
12145  myerror(NULL); /* purecov: inspected */
12146  die(__FILE__, __LINE__, "COM_DROP_DB failed"); /* purecov: inspected */
12147  }
12148  rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12149  (ulong)strlen(current_db), 0);
12150  myquery_r(rc);
12151  rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12152  (ulong)strlen(current_db), 0);
12153  if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12154  {
12155  myerror(NULL); /* purecov: inspected */
12156  die(__FILE__, __LINE__, "COM_CREATE_DB failed"); /* purecov: inspected */
12157  }
12158  rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12159  (ulong)strlen(current_db), 0);
12160  myquery_r(rc);
12161  rc= mysql_select_db(mysql, current_db);
12162  myquery(rc);
12163 }
12164 
12165 
12166 static void test_bug6096()
12167 {
12168  MYSQL_STMT *stmt;
12169  MYSQL_RES *query_result, *stmt_metadata;
12170  const char *stmt_text;
12171  MYSQL_BIND my_bind[12];
12172  MYSQL_FIELD *query_field_list, *stmt_field_list;
12173  ulong query_field_count, stmt_field_count;
12174  int rc;
12175  my_bool update_max_length= TRUE;
12176  uint i;
12177 
12178  myheader("test_bug6096");
12179 
12180  stmt_text= "drop table if exists t1";
12181  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12182  myquery(rc);
12183 
12184  mysql_query(mysql, "set sql_mode=''");
12185  stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, "
12186  " c_mediumint mediumint, c_int int, "
12187  " c_bigint bigint, c_float float, "
12188  " c_double double, c_varchar varchar(20), "
12189  " c_char char(20), c_time time, c_date date, "
12190  " c_datetime datetime)";
12191  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12192  myquery(rc);
12193  stmt_text= "insert into t1 values (-100, -20000, 30000000, 4, 8, 1.0, "
12194  "2.0, 'abc', 'def', now(), now(), now())";
12195  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12196  myquery(rc);
12197 
12198  stmt_text= "select * from t1";
12199 
12200  /* Run select in prepared and non-prepared mode and compare metadata */
12201  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12202  myquery(rc);
12203  query_result= mysql_store_result(mysql);
12204  query_field_list= mysql_fetch_fields(query_result);
12205  query_field_count= mysql_num_fields(query_result);
12206 
12207  stmt= mysql_stmt_init(mysql);
12208  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12209  check_execute(stmt, rc);
12210  rc= mysql_stmt_execute(stmt);
12211  check_execute(stmt, rc);
12212  mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
12213  (void*) &update_max_length);
12214  mysql_stmt_store_result(stmt);
12215  stmt_metadata= mysql_stmt_result_metadata(stmt);
12216  stmt_field_list= mysql_fetch_fields(stmt_metadata);
12217  stmt_field_count= mysql_num_fields(stmt_metadata);
12218  DIE_UNLESS(stmt_field_count == query_field_count);
12219 
12220  /* Print out and check the metadata */
12221 
12222  if (!opt_silent)
12223  {
12224  printf(" ------------------------------------------------------------\n");
12225  printf(" | Metadata \n");
12226  printf(" ------------------------------------------------------------\n");
12227  printf(" | Query | Prepared statement \n");
12228  printf(" ------------------------------------------------------------\n");
12229  printf(" field name | length | max_length | length | max_length\n");
12230  printf(" ------------------------------------------------------------\n");
12231 
12232  for (i= 0; i < query_field_count; ++i)
12233  {
12234  MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
12235  printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
12236  f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
12237  DIE_UNLESS(f1->length == f2->length);
12238  }
12239  printf(" ---------------------------------------------------------------\n");
12240  }
12241 
12242  /* Bind and fetch the data */
12243 
12244  memset(my_bind, 0, sizeof(my_bind));
12245  for (i= 0; i < stmt_field_count; ++i)
12246  {
12247  my_bind[i].buffer_type= MYSQL_TYPE_STRING;
12248  my_bind[i].buffer_length= stmt_field_list[i].max_length + 1;
12249  my_bind[i].buffer= malloc(my_bind[i].buffer_length);
12250  }
12251  mysql_stmt_bind_result(stmt, my_bind);
12252  rc= mysql_stmt_fetch(stmt);
12253  check_execute(stmt, rc);
12254  rc= mysql_stmt_fetch(stmt);
12255  DIE_UNLESS(rc == MYSQL_NO_DATA);
12256 
12257  /* Clean up */
12258 
12259  for (i= 0; i < stmt_field_count; ++i)
12260  free(my_bind[i].buffer);
12261  mysql_stmt_close(stmt);
12262  mysql_free_result(query_result);
12263  mysql_free_result(stmt_metadata);
12264  stmt_text= "drop table t1";
12265  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12266  myquery(rc);
12267 }
12268 
12269 
12270 /*
12271  Test of basic checks that are performed in server for components
12272  of MYSQL_TIME parameters.
12273 */
12274 
12275 static void test_datetime_ranges()
12276 {
12277  const char *stmt_text;
12278  int rc, i;
12279  MYSQL_STMT *stmt;
12280  MYSQL_BIND my_bind[6];
12281  MYSQL_TIME tm[6];
12282 
12283  myheader("test_datetime_ranges");
12284 
12285  stmt_text= "drop table if exists t1";
12286  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12287  myquery(rc);
12288 
12289  stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
12290  "hour datetime, min datetime, sec datetime)";
12291  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12292  myquery(rc);
12293 
12294  stmt= mysql_simple_prepare(mysql,
12295  "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
12296  check_stmt(stmt);
12297  verify_param_count(stmt, 6);
12298 
12299  memset(my_bind, 0, sizeof(my_bind));
12300  for (i= 0; i < 6; i++)
12301  {
12302  my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12303  my_bind[i].buffer= &tm[i];
12304  }
12305  rc= mysql_stmt_bind_param(stmt, my_bind);
12306  check_execute(stmt, rc);
12307 
12308  tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
12309  tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12310  tm[0].second_part= 0; tm[0].neg= 0;
12311 
12312  tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12313  tm[0].year= 10000; tm[1].month= 13; tm[2].day= 32;
12314  tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;
12315 
12316  rc= mysql_stmt_execute(stmt);
12317  check_execute(stmt, rc);
12318  my_process_warnings(mysql, 12);
12319 
12320  verify_col_data("t1", "year", "0000-00-00 00:00:00");
12321  verify_col_data("t1", "month", "0000-00-00 00:00:00");
12322  verify_col_data("t1", "day", "0000-00-00 00:00:00");
12323  verify_col_data("t1", "hour", "0000-00-00 00:00:00");
12324  verify_col_data("t1", "min", "0000-00-00 00:00:00");
12325  verify_col_data("t1", "sec", "0000-00-00 00:00:00");
12326 
12327  mysql_stmt_close(stmt);
12328 
12329  stmt_text= "delete from t1";
12330  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12331  myquery(rc);
12332 
12333  stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
12334  "VALUES (?, ?, ?)");
12335  check_stmt(stmt);
12336  verify_param_count(stmt, 3);
12337 
12338  /*
12339  We reuse contents of bind and tm arrays left from previous part of test.
12340  */
12341  for (i= 0; i < 3; i++)
12342  my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12343 
12344  rc= mysql_stmt_bind_param(stmt, my_bind);
12345  check_execute(stmt, rc);
12346 
12347  rc= mysql_stmt_execute(stmt);
12348  check_execute(stmt, rc);
12349  my_process_warnings(mysql, 6);
12350 
12351  verify_col_data("t1", "year", "0000-00-00 00:00:00");
12352  verify_col_data("t1", "month", "0000-00-00 00:00:00");
12353  verify_col_data("t1", "day", "0000-00-00 00:00:00");
12354 
12355  mysql_stmt_close(stmt);
12356 
12357  stmt_text= "drop table t1";
12358  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12359  myquery(rc);
12360 
12361  stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
12362  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12363  myquery(rc);
12364 
12365  stmt= mysql_simple_prepare(mysql,
12366  "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
12367  check_stmt(stmt);
12368  verify_param_count(stmt, 5);
12369 
12370  /*
12371  Again we reuse what we can from previous part of test.
12372  */
12373  for (i= 0; i < 5; i++)
12374  my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12375 
12376  rc= mysql_stmt_bind_param(stmt, my_bind);
12377  check_execute(stmt, rc);
12378 
12379  tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
12380  tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12381  tm[0].second_part= 0; tm[0].neg= 0;
12382 
12383  tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12384  tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;
12385 
12386  rc= mysql_stmt_execute(stmt);
12387  check_execute(stmt, rc);
12388  my_process_warnings(mysql, 2);
12389 
12390  verify_col_data("t1", "day_ovfl", "838:59:59");
12391  verify_col_data("t1", "day", "828:30:30");
12392  verify_col_data("t1", "hour", "270:30:30");
12393  verify_col_data("t1", "min", "00:00:00");
12394  verify_col_data("t1", "sec", "00:00:00");
12395 
12396  mysql_stmt_close(stmt);
12397 
12398  stmt_text= "drop table t1";
12399  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12400  myquery(rc);
12401 }
12402 
12403 
12404 static void test_bug4172()
12405 {
12406  MYSQL_STMT *stmt;
12407  MYSQL_BIND my_bind[3];
12408  const char *stmt_text;
12409  MYSQL_RES *res;
12410  MYSQL_ROW row;
12411  int rc;
12412  char f[100], d[100], e[100];
12413  ulong f_len, d_len, e_len;
12414 
12415  myheader("test_bug4172");
12416 
12417  mysql_query(mysql, "DROP TABLE IF EXISTS t1");
12418  mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))");
12419  mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, "
12420  "123456.1234)");
12421 
12422  stmt= mysql_stmt_init(mysql);
12423  stmt_text= "SELECT f, d, e FROM t1";
12424 
12425  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12426  check_execute(stmt, rc);
12427  rc= mysql_stmt_execute(stmt);
12428  check_execute(stmt, rc);
12429 
12430  memset(my_bind, 0, sizeof(my_bind));
12431  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12432  my_bind[0].buffer= f;
12433  my_bind[0].buffer_length= sizeof(f);
12434  my_bind[0].length= &f_len;
12435  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
12436  my_bind[1].buffer= d;
12437  my_bind[1].buffer_length= sizeof(d);
12438  my_bind[1].length= &d_len;
12439  my_bind[2].buffer_type= MYSQL_TYPE_STRING;
12440  my_bind[2].buffer= e;
12441  my_bind[2].buffer_length= sizeof(e);
12442  my_bind[2].length= &e_len;
12443 
12444  mysql_stmt_bind_result(stmt, my_bind);
12445 
12446  mysql_stmt_store_result(stmt);
12447  rc= mysql_stmt_fetch(stmt);
12448  check_execute(stmt, rc);
12449 
12450  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12451  myquery(rc);
12452  res= mysql_store_result(mysql);
12453  row= mysql_fetch_row(res);
12454 
12455  if (!opt_silent)
12456  {
12457  printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n",
12458  f, d, e);
12459  printf("Text protocol: float=%s, double=%s, decimal(10,4)=%s\n",
12460  row[0], row[1], row[2]);
12461  }
12462  DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]));
12463 
12464  mysql_free_result(res);
12465  mysql_stmt_close(stmt);
12466 }
12467 
12468 
12469 static void test_conversion()
12470 {
12471  MYSQL_STMT *stmt;
12472  const char *stmt_text;
12473  int rc;
12474  MYSQL_BIND my_bind[1];
12475  char buff[4];
12476  ulong length;
12477 
12478  myheader("test_conversion");
12479 
12480  stmt_text= "DROP TABLE IF EXISTS t1";
12481  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12482  myquery(rc);
12483  stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
12484  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12485  myquery(rc);
12486  stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
12487  " character_set_results=latin1";
12488  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12489  myquery(rc);
12490 
12491  stmt= mysql_stmt_init(mysql);
12492 
12493  stmt_text= "INSERT INTO t1 (a) VALUES (?)";
12494  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12495  check_execute(stmt, rc);
12496 
12497  memset(my_bind, 0, sizeof(my_bind));
12498  my_bind[0].buffer= buff;
12499  my_bind[0].length= &length;
12500  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12501 
12502  mysql_stmt_bind_param(stmt, my_bind);
12503 
12504  buff[0]= (uchar) 0xC3;
12505  buff[1]= (uchar) 0xA0;
12506  length= 2;
12507 
12508  rc= mysql_stmt_execute(stmt);
12509  check_execute(stmt, rc);
12510 
12511  stmt_text= "SELECT a FROM t1";
12512  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12513  check_execute(stmt, rc);
12514  rc= mysql_stmt_execute(stmt);
12515  check_execute(stmt, rc);
12516 
12517  my_bind[0].buffer_length= sizeof(buff);
12518  mysql_stmt_bind_result(stmt, my_bind);
12519 
12520  rc= mysql_stmt_fetch(stmt);
12521  DIE_UNLESS(rc == 0);
12522  DIE_UNLESS(length == 1);
12523  DIE_UNLESS((uchar) buff[0] == 0xE0);
12524  rc= mysql_stmt_fetch(stmt);
12525  DIE_UNLESS(rc == MYSQL_NO_DATA);
12526 
12527  mysql_stmt_close(stmt);
12528  stmt_text= "DROP TABLE t1";
12529  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12530  myquery(rc);
12531  stmt_text= "SET NAMES DEFAULT";
12532  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12533  myquery(rc);
12534 }
12535 
12536 static void test_rewind(void)
12537 {
12538  MYSQL_STMT *stmt;
12539  MYSQL_BIND my_bind;
12540  int rc = 0;
12541  const char *stmt_text;
12542  long unsigned int length=4, Data=0;
12543  my_bool isnull=0;
12544 
12545  myheader("test_rewind");
12546 
12547  stmt_text= "CREATE TABLE t1 (a int)";
12548  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12549  myquery(rc);
12550  stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)";
12551  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12552  myquery(rc);
12553 
12554  stmt= mysql_stmt_init(mysql);
12555 
12556  stmt_text= "SELECT * FROM t1";
12557  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12558  check_execute(stmt, rc);
12559 
12560  memset(&my_bind, 0, sizeof(MYSQL_BIND));
12561  my_bind.buffer_type= MYSQL_TYPE_LONG;
12562  my_bind.buffer= (void *)&Data; /* this buffer won't be altered */
12563  my_bind.length= &length;
12564  my_bind.is_null= &isnull;
12565 
12566  rc= mysql_stmt_execute(stmt);
12567  check_execute(stmt, rc);
12568 
12569  rc= mysql_stmt_store_result(stmt);
12570  DIE_UNLESS(rc == 0);
12571 
12572  rc= mysql_stmt_bind_result(stmt, &my_bind);
12573  DIE_UNLESS(rc == 0);
12574 
12575  /* retreive all result sets till we are at the end */
12576  while(!mysql_stmt_fetch(stmt))
12577  if (!opt_silent)
12578  printf("fetched result:%ld\n", Data);
12579 
12580  DIE_UNLESS(rc != MYSQL_NO_DATA);
12581 
12582  /* seek to the first row */
12583  mysql_stmt_data_seek(stmt, 0);
12584 
12585  /* now we should be able to fetch the results again */
12586  /* but mysql_stmt_fetch returns MYSQL_NO_DATA */
12587  while(!(rc= mysql_stmt_fetch(stmt)))
12588  if (!opt_silent)
12589  printf("fetched result after seek:%ld\n", Data);
12590 
12591  DIE_UNLESS(rc == MYSQL_NO_DATA);
12592 
12593  stmt_text= "DROP TABLE t1";
12594  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12595  myquery(rc);
12596  rc= mysql_stmt_free_result(stmt);
12597  rc= mysql_stmt_close(stmt);
12598 }
12599 
12600 
12601 static void test_truncation()
12602 {
12603  MYSQL_STMT *stmt;
12604  const char *stmt_text;
12605  int rc;
12606  uint bind_count;
12607  MYSQL_BIND *bind_array, *my_bind;
12608 
12609  myheader("test_truncation");
12610 
12611  /* Prepare the test table */
12612  rc= mysql_query(mysql, "drop table if exists t1");
12613  myquery(rc);
12614 
12615  stmt_text= "create table t1 ("
12616  "i8 tinyint, ui8 tinyint unsigned, "
12617  "i16 smallint, i16_1 smallint, "
12618  "ui16 smallint unsigned, i32 int, i32_1 int, "
12619  "d double, d_1 double, ch char(30), ch_1 char(30), "
12620  "tx text, tx_1 text, ch_2 char(30) "
12621  ")";
12622  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12623  myquery(rc);
12624 
12625  {
12626  const char insert_text[]=
12627  "insert into t1 VALUES ("
12628  "-10, " /* i8 */
12629  "200, " /* ui8 */
12630  "32000, " /* i16 */
12631  "-32767, " /* i16_1 */
12632  "64000, " /* ui16 */
12633  "1073741824, " /* i32 */
12634  "1073741825, " /* i32_1 */
12635  "123.456, " /* d */
12636  "-12345678910, " /* d_1 */
12637  "'111111111111111111111111111111',"/* ch */
12638  "'abcdef', " /* ch_1 */
12639  "'12345 ', " /* tx */
12640  "'12345.67 ', " /* tx_1 */
12641  "'12345.67abc'" /* ch_2 */
12642  ")";
12643  rc= mysql_real_query(mysql, insert_text, strlen(insert_text));
12644  myquery(rc);
12645  }
12646 
12647  stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, "
12648  " i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, "
12649  " d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, "
12650  " tx_1 c17, ch_2 c18 "
12651  "from t1";
12652 
12653  stmt= mysql_stmt_init(mysql);
12654  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12655  check_execute(stmt, rc);
12656  rc= mysql_stmt_execute(stmt);
12657  check_execute(stmt, rc);
12658  bind_count= (uint) mysql_stmt_field_count(stmt);
12659 
12660  /*************** Fill in the bind structure and bind it **************/
12661  bind_array= malloc(sizeof(MYSQL_BIND) * bind_count);
12662  memset(bind_array, 0, sizeof(MYSQL_BIND) * bind_count);
12663  for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12664  my_bind->error= &my_bind->error_value;
12665  my_bind= bind_array;
12666 
12667  my_bind->buffer= malloc(sizeof(uint8));
12668  my_bind->buffer_type= MYSQL_TYPE_TINY;
12669  my_bind->is_unsigned= TRUE;
12670 
12671  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12672  my_bind->buffer= malloc(sizeof(uint32));
12673  my_bind->buffer_type= MYSQL_TYPE_LONG;
12674  my_bind->is_unsigned= TRUE;
12675 
12676  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12677  my_bind->buffer= malloc(sizeof(int8));
12678  my_bind->buffer_type= MYSQL_TYPE_TINY;
12679 
12680  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12681  my_bind->buffer= malloc(sizeof(uint16));
12682  my_bind->buffer_type= MYSQL_TYPE_SHORT;
12683  my_bind->is_unsigned= TRUE;
12684 
12685  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12686  my_bind->buffer= malloc(sizeof(int16));
12687  my_bind->buffer_type= MYSQL_TYPE_SHORT;
12688 
12689  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12690  my_bind->buffer= malloc(sizeof(uint16));
12691  my_bind->buffer_type= MYSQL_TYPE_SHORT;
12692  my_bind->is_unsigned= TRUE;
12693 
12694  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12695  my_bind->buffer= malloc(sizeof(int8));
12696  my_bind->buffer_type= MYSQL_TYPE_TINY;
12697  my_bind->is_unsigned= TRUE;
12698 
12699  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12700  my_bind->buffer= malloc(sizeof(float));
12701  my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12702 
12703  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12704  my_bind->buffer= malloc(sizeof(float));
12705  my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12706 
12707  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12708  my_bind->buffer= malloc(sizeof(double));
12709  my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12710 
12711  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12712  my_bind->buffer= malloc(sizeof(longlong));
12713  my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12714 
12715  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12716  my_bind->buffer= malloc(sizeof(ulonglong));
12717  my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12718  my_bind->is_unsigned= TRUE;
12719 
12720  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12721  my_bind->buffer= malloc(sizeof(longlong));
12722  my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12723 
12724  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12725  my_bind->buffer= malloc(sizeof(longlong));
12726  my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12727 
12728  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12729  my_bind->buffer= malloc(sizeof(longlong));
12730  my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12731 
12732  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12733  my_bind->buffer= malloc(sizeof(longlong));
12734  my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12735 
12736  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12737  my_bind->buffer= malloc(sizeof(double));
12738  my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12739 
12740  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12741  my_bind->buffer= malloc(sizeof(double));
12742  my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12743 
12744  rc= mysql_stmt_bind_result(stmt, bind_array);
12745  check_execute(stmt, rc);
12746  rc= mysql_stmt_fetch(stmt);
12747  DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12748 
12749  /*************** Verify truncation results ***************************/
12750  my_bind= bind_array;
12751 
12752  /* signed tiny -> tiny */
12753  DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == -10);
12754 
12755  /* signed tiny -> uint32 */
12756  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12757  DIE_UNLESS(*my_bind->error && * (int32*) my_bind->buffer == -10);
12758 
12759  /* unsigned tiny -> tiny */
12760  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12761  DIE_UNLESS(*my_bind->error && * (uint8*) my_bind->buffer == 200);
12762 
12763  /* short -> ushort */
12764  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12765  DIE_UNLESS(*my_bind->error && * (int16*) my_bind->buffer == -32767);
12766 
12767  /* ushort -> short */
12768  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12769  DIE_UNLESS(*my_bind->error && * (uint16*) my_bind->buffer == 64000);
12770 
12771  /* short -> ushort (no truncation, data is in the range of target type) */
12772  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12773  DIE_UNLESS(! *my_bind->error && * (uint16*) my_bind->buffer == 32000);
12774 
12775  /* ushort -> utiny */
12776  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12777  DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == 0);
12778 
12779  /* int -> float: no truncation, the number is a power of two */
12780  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12781  DIE_UNLESS(! *my_bind->error && * (float*) my_bind->buffer == 1073741824);
12782 
12783  /* int -> float: truncation, not enough bits in float */
12784  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12785  DIE_UNLESS(*my_bind->error);
12786 
12787  /* int -> double: no truncation */
12788  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12789  DIE_UNLESS(! *my_bind->error && * (double*) my_bind->buffer == 1073741825);
12790 
12791  /* double -> longlong: fractional part is lost */
12792  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12793 
12794  /* double -> ulonglong, negative fp number to unsigned integer */
12795  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12796  /* Value in the buffer is not defined: don't test it */
12797  DIE_UNLESS(*my_bind->error);
12798 
12799  /* double -> longlong, negative fp number to signed integer: no loss */
12800  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12801  DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == LL(-12345678910));
12802 
12803  /* big numeric string -> number */
12804  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12805  DIE_UNLESS(*my_bind->error);
12806 
12807  /* junk string -> number */
12808  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12809  DIE_UNLESS(*my_bind->error && *(longlong*) my_bind->buffer == 0);
12810 
12811  /* string with trailing spaces -> number */
12812  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12813  DIE_UNLESS(! *my_bind->error && *(longlong*) my_bind->buffer == 12345);
12814 
12815  /* string with trailing spaces -> double */
12816  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12817  DIE_UNLESS(! *my_bind->error && *(double*) my_bind->buffer == 12345.67);
12818 
12819  /* string with trailing junk -> double */
12820  DIE_UNLESS(my_bind++ < bind_array + bind_count);
12821  /*
12822  XXX: There must be a truncation error: but it's not the way the server
12823  behaves, so let's leave it for now.
12824  */
12825  DIE_UNLESS(*(double*) my_bind->buffer == 12345.67);
12826  /*
12827  TODO: string -> double, double -> time, double -> string (truncation
12828  errors are not supported here yet)
12829  longlong -> time/date/datetime
12830  date -> time, date -> timestamp, date -> number
12831  time -> string, time -> date, time -> timestamp,
12832  number -> date string -> date
12833  */
12834  /*************** Cleanup *********************************************/
12835 
12836  mysql_stmt_close(stmt);
12837 
12838  for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12839  free(my_bind->buffer);
12840  free(bind_array);
12841 
12842  rc= mysql_query(mysql, "drop table t1");
12843  myquery(rc);
12844 }
12845 
12846 static void test_truncation_option()
12847 {
12848  MYSQL_STMT *stmt;
12849  const char *stmt_text;
12850  int rc;
12851  uint8 buf;
12852  my_bool option= 0;
12853  my_bool error;
12854  MYSQL_BIND my_bind;
12855 
12856  myheader("test_truncation_option");
12857 
12858  /* Prepare the test table */
12859  stmt_text= "select -1";
12860 
12861  stmt= mysql_stmt_init(mysql);
12862  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12863  check_execute(stmt, rc);
12864  rc= mysql_stmt_execute(stmt);
12865  check_execute(stmt, rc);
12866 
12867  memset(&my_bind, 0, sizeof(my_bind));
12868 
12869  my_bind.buffer= (void*) &buf;
12870  my_bind.buffer_type= MYSQL_TYPE_TINY;
12871  my_bind.is_unsigned= TRUE;
12872  my_bind.error= &error;
12873 
12874  rc= mysql_stmt_bind_result(stmt, &my_bind);
12875  check_execute(stmt, rc);
12876  rc= mysql_stmt_fetch(stmt);
12877  DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12878  DIE_UNLESS(error);
12879  rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
12880  myquery(rc);
12881  /* need to rebind for the new setting to take effect */
12882  rc= mysql_stmt_bind_result(stmt, &my_bind);
12883  check_execute(stmt, rc);
12884  rc= mysql_stmt_execute(stmt);
12885  check_execute(stmt, rc);
12886  rc= mysql_stmt_fetch(stmt);
12887  check_execute(stmt, rc);
12888  /* The only change is rc - error pointers are still filled in */
12889  DIE_UNLESS(error == 1);
12890  /* restore back the defaults */
12891  option= 1;
12892  mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
12893 
12894  mysql_stmt_close(stmt);
12895 }
12896 
12897 
12898 /* Bug#6761 - mysql_list_fields doesn't work */
12899 
12900 static void test_bug6761(void)
12901 {
12902  const char *stmt_text;
12903  MYSQL_RES *res;
12904  int rc;
12905  myheader("test_bug6761");
12906 
12907  stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
12908  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12909  myquery(rc);
12910 
12911  res= mysql_list_fields(mysql, "t1", "%");
12912  DIE_UNLESS(res && mysql_num_fields(res) == 3);
12913  mysql_free_result(res);
12914 
12915  stmt_text= "DROP TABLE t1";
12916  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12917  myquery(rc);
12918 }
12919 
12920 
12921 /* Bug#8330 - mysql_stmt_execute crashes (libmysql) */
12922 
12923 static void test_bug8330()
12924 {
12925  const char *stmt_text;
12926  MYSQL_STMT *stmt[2];
12927  int i, rc;
12928  const char *query= "select a,b from t1 where a=?";
12929  MYSQL_BIND my_bind[2];
12930  long lval[2];
12931 
12932  myheader("test_bug8330");
12933 
12934  stmt_text= "drop table if exists t1";
12935  /* in case some previos test failed */
12936  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12937  myquery(rc);
12938  stmt_text= "create table t1 (a int, b int)";
12939  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12940  myquery(rc);
12941 
12942  memset(my_bind, 0, sizeof(my_bind));
12943  for (i=0; i < 2; i++)
12944  {
12945  stmt[i]= mysql_stmt_init(mysql);
12946  rc= mysql_stmt_prepare(stmt[i], query, strlen(query));
12947  check_execute(stmt[i], rc);
12948 
12949  my_bind[i].buffer_type= MYSQL_TYPE_LONG;
12950  my_bind[i].buffer= (void*) &lval[i];
12951  my_bind[i].is_null= 0;
12952  mysql_stmt_bind_param(stmt[i], &my_bind[i]);
12953  }
12954 
12955  rc= mysql_stmt_execute(stmt[0]);
12956  check_execute(stmt[0], rc);
12957 
12958  rc= mysql_stmt_execute(stmt[1]);
12959  DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
12960  rc= mysql_stmt_execute(stmt[0]);
12961  check_execute(stmt[0], rc);
12962 
12963  mysql_stmt_close(stmt[0]);
12964  mysql_stmt_close(stmt[1]);
12965 
12966  stmt_text= "drop table t1";
12967  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12968  myquery(rc);
12969 }
12970 
12971 
12972 /* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */
12973 
12974 static void test_bug7990()
12975 {
12976  MYSQL_STMT *stmt;
12977  int rc;
12978  myheader("test_bug7990");
12979 
12980  stmt= mysql_stmt_init(mysql);
12981  rc= mysql_stmt_prepare(stmt, "foo", 3);
12982  /*
12983  XXX: the fact that we store errno both in STMT and in
12984  MYSQL is not documented and is subject to change in 5.0
12985  */
12986  DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql));
12987  mysql_stmt_close(stmt);
12988  DIE_UNLESS(!mysql_errno(mysql));
12989 }
12990 
12991 /*
12992  Bug #15518 - Reusing a stmt that has failed during prepare
12993  does not clear error
12994 */
12995 
12996 static void test_bug15518()
12997 {
12998  MYSQL_STMT *stmt;
12999  MYSQL* mysql1;
13000  int rc;
13001  myheader("test_bug15518");
13002 
13003  mysql1= mysql_client_init(NULL);
13004 
13005  if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13006  opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13007  CLIENT_MULTI_STATEMENTS))
13008  {
13009  fprintf(stderr, "Failed to connect to the database\n");
13010  DIE_UNLESS(0);
13011  }
13012 
13013  stmt= mysql_stmt_init(mysql1);
13014 
13015  /*
13016  The prepare of foo should fail with errno 1064 since
13017  it's not a valid query
13018  */
13019  rc= mysql_stmt_prepare(stmt, "foo", 3);
13020  if (!opt_silent)
13021  fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13022  rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13023  DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13024 
13025  /*
13026  Use the same stmt and reprepare with another query that
13027  suceeds
13028  */
13029  rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13030  if (!opt_silent)
13031  fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13032  rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13033  DIE_UNLESS(!rc || mysql_stmt_errno(stmt) || mysql_errno(mysql1));
13034 
13035  mysql_stmt_close(stmt);
13036  DIE_UNLESS(!mysql_errno(mysql1));
13037 
13038  /*
13039  part2, when connection to server has been closed
13040  after first prepare
13041  */
13042  stmt= mysql_stmt_init(mysql1);
13043  rc= mysql_stmt_prepare(stmt, "foo", 3);
13044  if (!opt_silent)
13045  fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13046  rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13047  DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13048 
13049  /* Close connection to server */
13050  mysql_close(mysql1);
13051 
13052  /*
13053  Use the same stmt and reprepare with another query that
13054  suceeds. The prepare should fail with error 2013 since
13055  connection to server has been closed.
13056  */
13057  rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13058  if (!opt_silent)
13059  fprintf(stdout, "rc: %d, mysql_stmt_errno: %d\n",
13060  rc, mysql_stmt_errno(stmt));
13061  DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13062 
13063  mysql_stmt_close(stmt);
13064 }
13065 
13066 
13067 static void disable_query_logs()
13068 {
13069  int rc;
13070  rc= mysql_query(mysql, "set @@global.general_log=off");
13071  myquery(rc);
13072  rc= mysql_query(mysql, "set @@global.slow_query_log=off");
13073  myquery(rc);
13074 }
13075 
13076 
13077 static void enable_query_logs(int truncate)
13078 {
13079  int rc;
13080 
13081  rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
13082  myquery(rc);
13083 
13084  rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log");
13085  myquery(rc);
13086 
13087  rc= mysql_query(mysql, "set @@global.general_log=on");
13088  myquery(rc);
13089 
13090  rc= mysql_query(mysql, "set @@global.slow_query_log=on");
13091  myquery(rc);
13092 
13093 
13094  if (truncate)
13095  {
13096  rc= mysql_query(mysql, "truncate mysql.general_log");
13097  myquery(rc);
13098 
13099  rc= mysql_query(mysql, "truncate mysql.slow_log");
13100  myquery(rc);
13101  }
13102 }
13103 
13104 
13105 static void restore_query_logs()
13106 {
13107  int rc;
13108  rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
13109  myquery(rc);
13110 
13111  rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log");
13112  myquery(rc);
13113 }
13114 
13115 
13116 static void test_view_sp_list_fields()
13117 {
13118  int rc;
13119  MYSQL_RES *res;
13120 
13121  myheader("test_view_sp_list_fields");
13122 
13123  rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
13124  myquery(rc);
13125  rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
13126  myquery(rc);
13127  rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
13128  myquery(rc);
13129  rc= mysql_query(mysql, "create function f1 () returns int return 5");
13130  myquery(rc);
13131  rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
13132  myquery(rc);
13133  rc= mysql_query(mysql, "create table t2 (s1 int);");
13134  myquery(rc);
13135  rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
13136 count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
13137 from t2);");
13138  myquery(rc);
13139  res= mysql_list_fields(mysql, "v1", NullS);
13140  DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0);
13141  rc= mysql_query(mysql, "DROP FUNCTION f1");
13142  myquery(rc);
13143  rc= mysql_query(mysql, "DROP VIEW v1");
13144  myquery(rc);
13145  rc= mysql_query(mysql, "DROP TABLE t1, t2");
13146  mysql_free_result(res);
13147  myquery(rc);
13148 
13149 }
13150 
13151 
13152 /*
13153  Test mysql_real_escape_string() with gbk charset
13154 
13155  The important part is that 0x27 (') is the second-byte in a invalid
13156  two-byte GBK character here. But 0xbf5c is a valid GBK character, so
13157  it needs to be escaped as 0x5cbf27
13158 */
13159 #define TEST_BUG8378_IN "\xef\xbb\xbf\x27\xbf\x10"
13160 #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
13161 
13162 static void test_bug8378()
13163 {
13164 #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
13165  MYSQL *lmysql;
13166  char out[9]; /* strlen(TEST_BUG8378)*2+1 */
13167  char buf[256];
13168  int len, rc;
13169 
13170  myheader("test_bug8378");
13171 
13172  if (!opt_silent)
13173  fprintf(stdout, "\n Establishing a test connection ...");
13174  if (!(lmysql= mysql_client_init(NULL)))
13175  {
13176  myerror("mysql_client_init() failed");
13177  exit(1);
13178  }
13179  if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
13180  {
13181  myerror("mysql_options() failed");
13182  exit(1);
13183  }
13184  if (!(mysql_real_connect(lmysql, opt_host, opt_user,
13185  opt_password, current_db, opt_port,
13186  opt_unix_socket, 0)))
13187  {
13188  myerror("connection failed");
13189  exit(1);
13190  }
13191  if (!opt_silent)
13192  fprintf(stdout, "OK");
13193 
13194  rc= mysql_query(lmysql, "SET SQL_MODE=''");
13195  myquery(rc);
13196 
13197  len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4);
13198 
13199  /* No escaping should have actually happened. */
13200  DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
13201 
13202  sprintf(buf, "SELECT '%s'", out);
13203 
13204  rc=mysql_real_query(lmysql, buf, strlen(buf));
13205  myquery(rc);
13206 
13207  mysql_close(lmysql);
13208 #endif
13209 }
13210 
13211 
13212 static void test_bug8722()
13213 {
13214  MYSQL_STMT *stmt;
13215  int rc;
13216  const char *stmt_text;
13217 
13218  myheader("test_bug8722");
13219  /* Prepare test data */
13220  stmt_text= "drop table if exists t1, v1";
13221  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13222  myquery(rc);
13223  stmt_text= "CREATE TABLE t1 (c1 varchar(10), c2 varchar(10), c3 varchar(10),"
13224  " c4 varchar(10), c5 varchar(10), c6 varchar(10),"
13225  " c7 varchar(10), c8 varchar(10), c9 varchar(10),"
13226  "c10 varchar(10))";
13227  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13228  myquery(rc);
13229  stmt_text= "INSERT INTO t1 VALUES (1,2,3,4,5,6,7,8,9,10)";
13230  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13231  myquery(rc);
13232  stmt_text= "CREATE VIEW v1 AS SELECT * FROM t1";
13233  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13234  myquery(rc);
13235  /* Note: if you uncomment following block everything works fine */
13236 /*
13237  rc= mysql_query(mysql, "sellect * from v1");
13238  myquery(rc);
13239  mysql_free_result(mysql_store_result(mysql));
13240 */
13241 
13242  stmt= mysql_stmt_init(mysql);
13243  stmt_text= "select * from v1";
13244  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13245  check_execute(stmt, rc);
13246  mysql_stmt_close(stmt);
13247  stmt_text= "drop table if exists t1, v1";
13248  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13249  myquery(rc);
13250 }
13251 
13252 
13253 MYSQL_STMT *open_cursor(const char *query)
13254 {
13255  int rc;
13256  const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
13257 
13258  MYSQL_STMT *stmt= mysql_stmt_init(mysql);
13259  rc= mysql_stmt_prepare(stmt, query, strlen(query));
13260  check_execute(stmt, rc);
13261 
13262  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13263  return stmt;
13264 }
13265 
13266 
13267 static void test_bug8880()
13268 {
13269  MYSQL_STMT *stmt_list[2], **stmt;
13270  MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
13271  int rc;
13272 
13273  myheader("test_bug8880");
13274 
13275  mysql_query(mysql, "drop table if exists t1");
13276  mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13277  rc= mysql_query(mysql, "insert into t1 values (1,1)");
13278  myquery(rc); /* one check is enough */
13279  /*
13280  when inserting 2 rows everything works well
13281  mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
13282  */
13283  for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13284  *stmt= open_cursor("select a from t1");
13285  for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13286  {
13287  rc= mysql_stmt_execute(*stmt);
13288  check_execute(*stmt, rc);
13289  }
13290  for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13291  mysql_stmt_close(*stmt);
13292 }
13293 
13294 
13295 static void test_bug9159()
13296 {
13297  MYSQL_STMT *stmt;
13298  int rc;
13299  const char *stmt_text= "select a, b from t1";
13300  const unsigned long type= CURSOR_TYPE_READ_ONLY;
13301 
13302  myheader("test_bug9159");
13303 
13304  mysql_query(mysql, "drop table if exists t1");
13305  mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13306  rc= mysql_query(mysql, "insert into t1 values (1,1)");
13307  myquery(rc);
13308 
13309  stmt= mysql_stmt_init(mysql);
13310  mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13311  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
13312 
13313  mysql_stmt_execute(stmt);
13314  mysql_stmt_close(stmt);
13315  rc= mysql_query(mysql, "drop table if exists t1");
13316  myquery(rc);
13317 }
13318 
13319 
13320 /* Crash when opening a cursor to a query with DISTICNT and no key */
13321 
13322 static void test_bug9520()
13323 {
13324  MYSQL_STMT *stmt;
13325  MYSQL_BIND my_bind[1];
13326  char a[6];
13327  ulong a_len;
13328  int rc, row_count= 0;
13329 
13330  myheader("test_bug9520");
13331 
13332  mysql_query(mysql, "drop table if exists t1");
13333  mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
13334  " primary key (a, b, c))");
13335  rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
13336  " ('a', 'b', 'c'), ('k', 'l', 'm')");
13337  myquery(rc);
13338 
13339  stmt= open_cursor("select distinct b from t1");
13340 
13341  /*
13342  Not crashes with:
13343  stmt= open_cursor("select distinct a from t1");
13344  */
13345 
13346  rc= mysql_stmt_execute(stmt);
13347  check_execute(stmt, rc);
13348 
13349  memset(my_bind, 0, sizeof(my_bind));
13350  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13351  my_bind[0].buffer= (char*) a;
13352  my_bind[0].buffer_length= sizeof(a);
13353  my_bind[0].length= &a_len;
13354 
13355  mysql_stmt_bind_result(stmt, my_bind);
13356 
13357  while (!(rc= mysql_stmt_fetch(stmt)))
13358  row_count++;
13359 
13360  DIE_UNLESS(rc == MYSQL_NO_DATA);
13361 
13362  if (!opt_silent)
13363  printf("Fetched %d rows\n", row_count);
13364  DBUG_ASSERT(row_count == 3);
13365 
13366  mysql_stmt_close(stmt);
13367 
13368  rc= mysql_query(mysql, "drop table t1");
13369  myquery(rc);
13370 }
13371 
13372 
13373 /*
13374  We can't have more than one cursor open for a prepared statement.
13375  Test re-executions of a PS with cursor; mysql_stmt_reset must close
13376  the cursor attached to the statement, if there is one.
13377 */
13378 
13379 static void test_bug9478()
13380 {
13381  MYSQL_STMT *stmt;
13382  MYSQL_BIND my_bind[1];
13383  char a[6];
13384  ulong a_len;
13385  int rc, i;
13386  DBUG_ENTER("test_bug9478");
13387 
13388  myheader("test_bug9478");
13389 
13390  mysql_query(mysql, "drop table if exists t1");
13391  mysql_query(mysql, "create table t1 (id integer not null primary key, "
13392  " name varchar(20) not null)");
13393  rc= mysql_query(mysql, "insert into t1 (id, name) values "
13394  " (1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13395  myquery(rc);
13396 
13397  stmt= open_cursor("select name from t1 where id=2");
13398 
13399  memset(my_bind, 0, sizeof(my_bind));
13400  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13401  my_bind[0].buffer= (char*) a;
13402  my_bind[0].buffer_length= sizeof(a);
13403  my_bind[0].length= &a_len;
13404  mysql_stmt_bind_result(stmt, my_bind);
13405 
13406  for (i= 0; i < 5; i++)
13407  {
13408  rc= mysql_stmt_execute(stmt);
13409  check_execute(stmt, rc);
13410  rc= mysql_stmt_fetch(stmt);
13411  check_execute(stmt, rc);
13412  if (!opt_silent && i == 0)
13413  printf("Fetched row: %s\n", a);
13414 
13415  /*
13416  The query above is a one-row result set. Therefore, there is no
13417  cursor associated with it, as the server won't bother with opening
13418  a cursor for a one-row result set. The first row was read from the
13419  server in the fetch above. But there is eof packet pending in the
13420  network. mysql_stmt_execute will flush the packet and successfully
13421  execute the statement.
13422  */
13423 
13424  rc= mysql_stmt_execute(stmt);
13425  check_execute(stmt, rc);
13426 
13427  rc= mysql_stmt_fetch(stmt);
13428  check_execute(stmt, rc);
13429  if (!opt_silent && i == 0)
13430  printf("Fetched row: %s\n", a);
13431  rc= mysql_stmt_fetch(stmt);
13432  DIE_UNLESS(rc == MYSQL_NO_DATA);
13433 
13434  {
13435  char buff[8];
13436  /* Fill in the fetch packet */
13437  int4store(buff, stmt->stmt_id);
13438  buff[4]= 1; /* prefetch rows */
13439  rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
13440  (uchar*) buff,
13441  sizeof(buff), 0,0,1,NULL) ||
13442  (*mysql->methods->read_query_result)(mysql));
13443  DIE_UNLESS(rc);
13444  if (!opt_silent && i == 0)
13445  printf("Got error (as expected): %s\n", mysql_error(mysql));
13446  }
13447 
13448  rc= mysql_stmt_execute(stmt);
13449  check_execute(stmt, rc);
13450 
13451  rc= mysql_stmt_fetch(stmt);
13452  check_execute(stmt, rc);
13453  if (!opt_silent && i == 0)
13454  printf("Fetched row: %s\n", a);
13455 
13456  rc= mysql_stmt_reset(stmt);
13457  check_execute(stmt, rc);
13458  rc= mysql_stmt_fetch(stmt);
13459  DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13460  if (!opt_silent && i == 0)
13461  printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13462  }
13463  rc= mysql_stmt_close(stmt);
13464  DIE_UNLESS(rc == 0);
13465 
13466  /* Test the case with a server side cursor */
13467  stmt= open_cursor("select name from t1");
13468 
13469  mysql_stmt_bind_result(stmt, my_bind);
13470 
13471  for (i= 0; i < 5; i++)
13472  {
13473  DBUG_PRINT("loop",("i: %d", i));
13474  rc= mysql_stmt_execute(stmt);
13475  check_execute(stmt, rc);
13476  rc= mysql_stmt_fetch(stmt);
13477  check_execute(stmt, rc);
13478  if (!opt_silent && i == 0)
13479  printf("Fetched row: %s\n", a);
13480  rc= mysql_stmt_execute(stmt);
13481  check_execute(stmt, rc);
13482 
13483  while (! (rc= mysql_stmt_fetch(stmt)))
13484  {
13485  if (!opt_silent && i == 0)
13486  printf("Fetched row: %s\n", a);
13487  }
13488  DIE_UNLESS(rc == MYSQL_NO_DATA);
13489 
13490  rc= mysql_stmt_execute(stmt);
13491  check_execute(stmt, rc);
13492 
13493  rc= mysql_stmt_fetch(stmt);
13494  check_execute(stmt, rc);
13495  if (!opt_silent && i == 0)
13496  printf("Fetched row: %s\n", a);
13497 
13498  rc= mysql_stmt_reset(stmt);
13499  check_execute(stmt, rc);
13500  rc= mysql_stmt_fetch(stmt);
13501  DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13502  if (!opt_silent && i == 0)
13503  printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13504  }
13505 
13506  rc= mysql_stmt_close(stmt);
13507  DIE_UNLESS(rc == 0);
13508 
13509  rc= mysql_query(mysql, "drop table t1");
13510  myquery(rc);
13511  DBUG_VOID_RETURN;
13512 }
13513 
13514 
13515 /*
13516  Error message is returned for unsupported features.
13517  Test also cursors with non-default PREFETCH_ROWS
13518 */
13519 
13520 static void test_bug9643()
13521 {
13522  MYSQL_STMT *stmt;
13523  MYSQL_BIND my_bind[1];
13524  int32 a;
13525  int rc;
13526  const char *stmt_text;
13527  int num_rows= 0;
13528  ulong type;
13529  ulong prefetch_rows= 5;
13530 
13531  myheader("test_bug9643");
13532 
13533  mysql_query(mysql, "drop table if exists t1");
13534  mysql_query(mysql, "create table t1 (id integer not null primary key)");
13535  rc= mysql_query(mysql, "insert into t1 (id) values "
13536  " (1), (2), (3), (4), (5), (6), (7), (8), (9)");
13537  myquery(rc);
13538 
13539  stmt= mysql_stmt_init(mysql);
13540  /* Not implemented in 5.0 */
13541  type= (ulong) CURSOR_TYPE_SCROLLABLE;
13542  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13543  DIE_UNLESS(rc);
13544  if (! opt_silent)
13545  printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13546 
13547  type= (ulong) CURSOR_TYPE_READ_ONLY;
13548  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13549  check_execute(stmt, rc);
13550  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
13551  (void*) &prefetch_rows);
13552  check_execute(stmt, rc);
13553  stmt_text= "select * from t1";
13554  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13555  check_execute(stmt, rc);
13556 
13557  memset(my_bind, 0, sizeof(my_bind));
13558  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13559  my_bind[0].buffer= (void*) &a;
13560  my_bind[0].buffer_length= sizeof(a);
13561  mysql_stmt_bind_result(stmt, my_bind);
13562 
13563  rc= mysql_stmt_execute(stmt);
13564  check_execute(stmt, rc);
13565 
13566  while ((rc= mysql_stmt_fetch(stmt)) == 0)
13567  ++num_rows;
13568  DIE_UNLESS(num_rows == 9);
13569 
13570  rc= mysql_stmt_close(stmt);
13571  DIE_UNLESS(rc == 0);
13572 
13573  rc= mysql_query(mysql, "drop table t1");
13574  myquery(rc);
13575 }
13576 
13577 /*
13578  Bug#11111: fetch from view returns wrong data
13579 */
13580 
13581 static void test_bug11111()
13582 {
13583  MYSQL_STMT *stmt;
13584  MYSQL_BIND my_bind[2];
13585  char buf[2][20];
13586  ulong len[2];
13587  int i;
13588  int rc;
13589  const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
13590 
13591  myheader("test_bug11111");
13592 
13593  rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
13594  myquery(rc);
13595  rc= mysql_query(mysql, "drop view if exists t1, t2, v1");
13596  myquery(rc);
13597  rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)");
13598  myquery(rc);
13599  rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)");
13600  myquery(rc);
13601  rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1");
13602  myquery(rc);
13603  rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)");
13604  myquery(rc);
13605  rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
13606  myquery(rc);
13607 
13608  stmt= mysql_stmt_init(mysql);
13609 
13610  mysql_stmt_prepare(stmt, query, strlen(query));
13611  mysql_stmt_execute(stmt);
13612 
13613  memset(my_bind, 0, sizeof(my_bind));
13614  for (i=0; i < 2; i++)
13615  {
13616  my_bind[i].buffer_type= MYSQL_TYPE_STRING;
13617  my_bind[i].buffer= (uchar* *)&buf[i];
13618  my_bind[i].buffer_length= 20;
13619  my_bind[i].length= &len[i];
13620  }
13621 
13622  rc= mysql_stmt_bind_result(stmt, my_bind);
13623  check_execute(stmt, rc);
13624 
13625  rc= mysql_stmt_fetch(stmt);
13626  check_execute(stmt, rc);
13627  if (!opt_silent)
13628  printf("return: %s", buf[1]);
13629  DIE_UNLESS(!strcmp(buf[1],"1"));
13630  mysql_stmt_close(stmt);
13631  rc= mysql_query(mysql, "drop view v1");
13632  myquery(rc);
13633  rc= mysql_query(mysql, "drop table t1, t2");
13634  myquery(rc);
13635 }
13636 
13637 /*
13638  Check that proper cleanups are done for prepared statement when
13639  fetching thorugh a cursor.
13640 */
13641 
13642 static void test_bug10729()
13643 {
13644  MYSQL_STMT *stmt;
13645  MYSQL_BIND my_bind[1];
13646  char a[21];
13647  int rc;
13648  const char *stmt_text;
13649  int i= 0;
13650  const char *name_array[3]= { "aaa", "bbb", "ccc" };
13651  ulong type;
13652 
13653  myheader("test_bug10729");
13654 
13655  mysql_query(mysql, "drop table if exists t1");
13656  mysql_query(mysql, "create table t1 (id integer not null primary key,"
13657  "name VARCHAR(20) NOT NULL)");
13658  rc= mysql_query(mysql, "insert into t1 (id, name) values "
13659  "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13660  myquery(rc);
13661 
13662  stmt= mysql_stmt_init(mysql);
13663 
13664  type= (ulong) CURSOR_TYPE_READ_ONLY;
13665  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13666  check_execute(stmt, rc);
13667  stmt_text= "select name from t1";
13668  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13669  check_execute(stmt, rc);
13670 
13671  memset(my_bind, 0, sizeof(my_bind));
13672  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13673  my_bind[0].buffer= (void*) a;
13674  my_bind[0].buffer_length= sizeof(a);
13675  mysql_stmt_bind_result(stmt, my_bind);
13676 
13677  for (i= 0; i < 3; i++)
13678  {
13679  int row_no= 0;
13680  rc= mysql_stmt_execute(stmt);
13681  check_execute(stmt, rc);
13682  while ((rc= mysql_stmt_fetch(stmt)) == 0)
13683  {
13684  DIE_UNLESS(strcmp(a, name_array[row_no]) == 0);
13685  if (!opt_silent)
13686  printf("%d: %s\n", row_no, a);
13687  ++row_no;
13688  }
13689  DIE_UNLESS(rc == MYSQL_NO_DATA);
13690  }
13691  rc= mysql_stmt_close(stmt);
13692  DIE_UNLESS(rc == 0);
13693 
13694  rc= mysql_query(mysql, "drop table t1");
13695  myquery(rc);
13696 }
13697 
13698 
13699 /*
13700  Check that mysql_next_result works properly in case when one of
13701  the statements used in a multi-statement query is erroneous
13702 */
13703 
13704 static void test_bug9992()
13705 {
13706  MYSQL *mysql1;
13707  MYSQL_RES* res ;
13708  int rc;
13709 
13710  myheader("test_bug9992");
13711 
13712  if (!opt_silent)
13713  printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
13714 
13715  mysql1= mysql_client_init(NULL);
13716 
13717  if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13718  opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13719  CLIENT_MULTI_STATEMENTS))
13720  {
13721  fprintf(stderr, "Failed to connect to the database\n");
13722  DIE_UNLESS(0);
13723  }
13724 
13725 
13726  /* Sic: SHOW DATABASE is incorrect syntax. */
13727  rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;");
13728 
13729  if (rc)
13730  {
13731  fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1));
13732  DIE_UNLESS(0);
13733  }
13734 
13735  if (!opt_silent)
13736  printf("Testing mysql_store_result/mysql_next_result..\n");
13737 
13738  res= mysql_store_result(mysql1);
13739  DIE_UNLESS(res);
13740  mysql_free_result(res);
13741  rc= mysql_next_result(mysql1);
13742  DIE_UNLESS(rc == 1); /* Got errors, as expected */
13743 
13744  if (!opt_silent)
13745  fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
13746  mysql_errno(mysql1), mysql_error(mysql1));
13747 
13748  mysql_close(mysql1);
13749 }
13750 
13751 /* Bug#10736: cursors and subqueries, memroot management */
13752 
13753 static void test_bug10736()
13754 {
13755  MYSQL_STMT *stmt;
13756  MYSQL_BIND my_bind[1];
13757  char a[21];
13758  int rc;
13759  const char *stmt_text;
13760  int i= 0;
13761  ulong type;
13762 
13763  myheader("test_bug10736");
13764 
13765  mysql_query(mysql, "drop table if exists t1");
13766  mysql_query(mysql, "create table t1 (id integer not null primary key,"
13767  "name VARCHAR(20) NOT NULL)");
13768  rc= mysql_query(mysql, "insert into t1 (id, name) values "
13769  "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13770  myquery(rc);
13771 
13772  stmt= mysql_stmt_init(mysql);
13773 
13774  type= (ulong) CURSOR_TYPE_READ_ONLY;
13775  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13776  check_execute(stmt, rc);
13777  stmt_text= "select name from t1 where name=(select name from t1 where id=2)";
13778  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13779  check_execute(stmt, rc);
13780 
13781  memset(my_bind, 0, sizeof(my_bind));
13782  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13783  my_bind[0].buffer= (void*) a;
13784  my_bind[0].buffer_length= sizeof(a);
13785  mysql_stmt_bind_result(stmt, my_bind);
13786 
13787  for (i= 0; i < 3; i++)
13788  {
13789  int row_no= 0;
13790  rc= mysql_stmt_execute(stmt);
13791  check_execute(stmt, rc);
13792  while ((rc= mysql_stmt_fetch(stmt)) == 0)
13793  {
13794  if (!opt_silent)
13795  printf("%d: %s\n", row_no, a);
13796  ++row_no;
13797  }
13798  DIE_UNLESS(rc == MYSQL_NO_DATA);
13799  }
13800  rc= mysql_stmt_close(stmt);
13801  DIE_UNLESS(rc == 0);
13802 
13803  rc= mysql_query(mysql, "drop table t1");
13804  myquery(rc);
13805 }
13806 
13807 /* Bug#10794: cursors, packets out of order */
13808 
13809 static void test_bug10794()
13810 {
13811  MYSQL_STMT *stmt, *stmt1;
13812  MYSQL_BIND my_bind[2];
13813  char a[21];
13814  int id_val;
13815  ulong a_len;
13816  int rc;
13817  const char *stmt_text;
13818  int i= 0;
13819  ulong type;
13820 
13821  myheader("test_bug10794");
13822 
13823  mysql_query(mysql, "drop table if exists t1");
13824  mysql_query(mysql, "create table t1 (id integer not null primary key,"
13825  "name varchar(20) not null)");
13826  stmt= mysql_stmt_init(mysql);
13827  stmt_text= "insert into t1 (id, name) values (?, ?)";
13828  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13829  check_execute(stmt, rc);
13830  memset(my_bind, 0, sizeof(my_bind));
13831  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
13832  my_bind[0].buffer= (void*) &id_val;
13833  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
13834  my_bind[1].buffer= (void*) a;
13835  my_bind[1].length= &a_len;
13836  rc= mysql_stmt_bind_param(stmt, my_bind);
13837  check_execute(stmt, rc);
13838  for (i= 0; i < 42; i++)
13839  {
13840  id_val= (i+1)*10;
13841  sprintf(a, "a%d", i);
13842  a_len= strlen(a); /* safety against broken sprintf */
13843  rc= mysql_stmt_execute(stmt);
13844  check_execute(stmt, rc);
13845  }
13846  stmt_text= "select name from t1";
13847  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13848  type= (ulong) CURSOR_TYPE_READ_ONLY;
13849  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13850  stmt1= mysql_stmt_init(mysql);
13851  mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13852  memset(my_bind, 0, sizeof(my_bind));
13853  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13854  my_bind[0].buffer= (void*) a;
13855  my_bind[0].buffer_length= sizeof(a);
13856  my_bind[0].length= &a_len;
13857  rc= mysql_stmt_bind_result(stmt, my_bind);
13858  check_execute(stmt, rc);
13859  rc= mysql_stmt_execute(stmt);
13860  check_execute(stmt, rc);
13861  rc= mysql_stmt_fetch(stmt);
13862  check_execute(stmt, rc);
13863  if (!opt_silent)
13864  printf("Fetched row from stmt: %s\n", a);
13865  /* Don't optimize: an attribute of the original test case */
13866  mysql_stmt_free_result(stmt);
13867  mysql_stmt_reset(stmt);
13868  stmt_text= "select name from t1 where id=10";
13869  rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
13870  check_execute(stmt1, rc);
13871  rc= mysql_stmt_bind_result(stmt1, my_bind);
13872  check_execute(stmt1, rc);
13873  rc= mysql_stmt_execute(stmt1);
13874  while (1)
13875  {
13876  rc= mysql_stmt_fetch(stmt1);
13877  if (rc == MYSQL_NO_DATA)
13878  {
13879  if (!opt_silent)
13880  printf("End of data in stmt1\n");
13881  break;
13882  }
13883  check_execute(stmt1, rc);
13884  if (!opt_silent)
13885  printf("Fetched row from stmt1: %s\n", a);
13886  }
13887  mysql_stmt_close(stmt);
13888  mysql_stmt_close(stmt1);
13889 
13890  rc= mysql_query(mysql, "drop table t1");
13891  myquery(rc);
13892 }
13893 
13894 
13895 /* Bug#11172: cursors, crash on a fetch from a datetime column */
13896 
13897 static void test_bug11172()
13898 {
13899  MYSQL_STMT *stmt;
13900  MYSQL_BIND bind_in[1], bind_out[2];
13901  MYSQL_TIME hired;
13902  int rc;
13903  const char *stmt_text;
13904  int i= 0, id;
13905  ulong type;
13906 
13907  myheader("test_bug11172");
13908 
13909  mysql_query(mysql, "drop table if exists t1");
13910  mysql_query(mysql, "create table t1 (id integer not null primary key,"
13911  "hired date not null)");
13912  rc= mysql_query(mysql,
13913  "insert into t1 (id, hired) values (1, '1933-08-24'), "
13914  "(2, '1965-01-01'), (3, '1949-08-17'), (4, '1945-07-07'), "
13915  "(5, '1941-05-15'), (6, '1978-09-15'), (7, '1936-03-28')");
13916  myquery(rc);
13917  stmt= mysql_stmt_init(mysql);
13918  stmt_text= "SELECT id, hired FROM t1 WHERE hired=?";
13919  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13920  check_execute(stmt, rc);
13921 
13922  type= (ulong) CURSOR_TYPE_READ_ONLY;
13923  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13924 
13925  memset(bind_in, 0, sizeof(bind_in));
13926  memset(bind_out, 0, sizeof(bind_out));
13927  memset(&hired, 0, sizeof(hired));
13928  hired.year= 1965;
13929  hired.month= 1;
13930  hired.day= 1;
13931  bind_in[0].buffer_type= MYSQL_TYPE_DATE;
13932  bind_in[0].buffer= (void*) &hired;
13933  bind_in[0].buffer_length= sizeof(hired);
13934  bind_out[0].buffer_type= MYSQL_TYPE_LONG;
13935  bind_out[0].buffer= (void*) &id;
13936  bind_out[1]= bind_in[0];
13937 
13938  for (i= 0; i < 3; i++)
13939  {
13940  rc= mysql_stmt_bind_param(stmt, bind_in);
13941  check_execute(stmt, rc);
13942  rc= mysql_stmt_bind_result(stmt, bind_out);
13943  check_execute(stmt, rc);
13944  rc= mysql_stmt_execute(stmt);
13945  check_execute(stmt, rc);
13946  while ((rc= mysql_stmt_fetch(stmt)) == 0)
13947  {
13948  if (!opt_silent)
13949  printf("fetched data %d:%d-%d-%d\n", id,
13950  hired.year, hired.month, hired.day);
13951  }
13952  DIE_UNLESS(rc == MYSQL_NO_DATA);
13953  if (!mysql_stmt_free_result(stmt))
13954  mysql_stmt_reset(stmt);
13955  }
13956  mysql_stmt_close(stmt);
13957  mysql_rollback(mysql);
13958  mysql_rollback(mysql);
13959 
13960  rc= mysql_query(mysql, "drop table t1");
13961  myquery(rc);
13962 }
13963 
13964 
13965 /* Bug#11656: cursors, crash on a fetch from a query with distinct. */
13966 
13967 static void test_bug11656()
13968 {
13969  MYSQL_STMT *stmt;
13970  MYSQL_BIND my_bind[2];
13971  int rc;
13972  const char *stmt_text;
13973  char buf[2][20];
13974  int i= 0;
13975  ulong type;
13976 
13977  myheader("test_bug11656");
13978 
13979  mysql_query(mysql, "drop table if exists t1");
13980 
13981  rc= mysql_query(mysql, "create table t1 ("
13982  "server varchar(40) not null, "
13983  "test_kind varchar(1) not null, "
13984  "test_id varchar(30) not null , "
13985  "primary key (server,test_kind,test_id))");
13986  myquery(rc);
13987 
13988  stmt_text= "select distinct test_kind, test_id from t1 "
13989  "where server in (?, ?)";
13990  stmt= mysql_stmt_init(mysql);
13991  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13992  check_execute(stmt, rc);
13993  type= (ulong) CURSOR_TYPE_READ_ONLY;
13994  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
13995 
13996  memset(my_bind, 0, sizeof(my_bind));
13997  strmov(buf[0], "pcint502_MY2");
13998  strmov(buf[1], "*");
13999  for (i=0; i < 2; i++)
14000  {
14001  my_bind[i].buffer_type= MYSQL_TYPE_STRING;
14002  my_bind[i].buffer= (uchar* *)&buf[i];
14003  my_bind[i].buffer_length= strlen(buf[i]);
14004  }
14005  mysql_stmt_bind_param(stmt, my_bind);
14006 
14007  rc= mysql_stmt_execute(stmt);
14008  check_execute(stmt, rc);
14009 
14010  rc= mysql_stmt_fetch(stmt);
14011  DIE_UNLESS(rc == MYSQL_NO_DATA);
14012 
14013  mysql_stmt_close(stmt);
14014  rc= mysql_query(mysql, "drop table t1");
14015  myquery(rc);
14016 }
14017 
14018 
14019 /*
14020  Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
14021  and mysql_real_escape_string() does the right thing as a result.
14022 */
14023 
14024 static void test_bug10214()
14025 {
14026  int len;
14027  char out[8];
14028 
14029  myheader("test_bug10214");
14030 
14031  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
14032 
14033  len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14034  DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14035 
14036  mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
14037  DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
14038 
14039  len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14040  DIE_UNLESS(memcmp(out, "a''b\\c", len) == 0);
14041 
14042  mysql_query(mysql, "set sql_mode=''");
14043 }
14044 
14045 static void test_client_character_set()
14046 {
14047  MY_CHARSET_INFO cs;
14048  char *csname= (char*) "utf8";
14049  char *csdefault= (char*)mysql_character_set_name(mysql);
14050  int rc;
14051 
14052  myheader("test_client_character_set");
14053 
14054  rc= mysql_set_character_set(mysql, csname);
14055  DIE_UNLESS(rc == 0);
14056 
14057  mysql_get_character_set_info(mysql, &cs);
14058  DIE_UNLESS(!strcmp(cs.csname, "utf8"));
14059  DIE_UNLESS(!strcmp(cs.name, "utf8_general_ci"));
14060  /* Restore the default character set */
14061  rc= mysql_set_character_set(mysql, csdefault);
14062  myquery(rc);
14063 }
14064 
14065 /* Test correct max length for MEDIUMTEXT and LONGTEXT columns */
14066 
14067 static void test_bug9735()
14068 {
14069  MYSQL_RES *res;
14070  int rc;
14071 
14072  myheader("test_bug9735");
14073 
14074  rc= mysql_query(mysql, "drop table if exists t1");
14075  myquery(rc);
14076  rc= mysql_query(mysql, "create table t1 (a mediumtext, b longtext) "
14077  "character set latin1");
14078  myquery(rc);
14079  rc= mysql_query(mysql, "select * from t1");
14080  myquery(rc);
14081  res= mysql_store_result(mysql);
14082  verify_prepare_field(res, 0, "a", "a", MYSQL_TYPE_BLOB,
14083  "t1", "t1", current_db, (1U << 24)-1, 0);
14084  verify_prepare_field(res, 1, "b", "b", MYSQL_TYPE_BLOB,
14085  "t1", "t1", current_db, ~0U, 0);
14086  mysql_free_result(res);
14087  rc= mysql_query(mysql, "drop table t1");
14088  myquery(rc);
14089 }
14090 
14091 
14092 /* Bug#11183 "mysql_stmt_reset() doesn't reset information about error" */
14093 
14094 static void test_bug11183()
14095 {
14096  int rc;
14097  MYSQL_STMT *stmt;
14098  char bug_statement[]= "insert into t1 values (1)";
14099 
14100  myheader("test_bug11183");
14101 
14102  mysql_query(mysql, "drop table t1 if exists");
14103  mysql_query(mysql, "create table t1 (a int)");
14104 
14105  stmt= mysql_stmt_init(mysql);
14106  DIE_UNLESS(stmt != 0);
14107 
14108  rc= mysql_stmt_prepare(stmt, bug_statement, strlen(bug_statement));
14109  check_execute(stmt, rc);
14110 
14111  rc= mysql_query(mysql, "drop table t1");
14112  myquery(rc);
14113 
14114  /* Trying to execute statement that should fail on execute stage */
14115  rc= mysql_stmt_execute(stmt);
14116  DIE_UNLESS(rc);
14117 
14118  mysql_stmt_reset(stmt);
14119  DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14120 
14121  mysql_query(mysql, "create table t1 (a int)");
14122 
14123  /* Trying to execute statement that should pass ok */
14124  if (mysql_stmt_execute(stmt))
14125  {
14126  mysql_stmt_reset(stmt);
14127  DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14128  }
14129 
14130  mysql_stmt_close(stmt);
14131 
14132  rc= mysql_query(mysql, "drop table t1");
14133  myquery(rc);
14134 }
14135 
14136 static void test_bug11037()
14137 {
14138  MYSQL_STMT *stmt;
14139  int rc;
14140  const char *stmt_text;
14141 
14142  myheader("test_bug11037");
14143 
14144  mysql_query(mysql, "drop table if exists t1");
14145 
14146  rc= mysql_query(mysql, "create table t1 (id int not null)");
14147  myquery(rc);
14148 
14149  rc= mysql_query(mysql, "insert into t1 values (1)");
14150  myquery(rc);
14151 
14152  stmt_text= "select id FROM t1";
14153  stmt= mysql_stmt_init(mysql);
14154  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14155 
14156  /* expected error */
14157  rc = mysql_stmt_fetch(stmt);
14158  DIE_UNLESS(rc==1);
14159  if (!opt_silent)
14160  fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
14161  mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
14162 
14163  rc= mysql_stmt_execute(stmt);
14164  check_execute(stmt, rc);
14165 
14166  rc= mysql_stmt_fetch(stmt);
14167  DIE_UNLESS(rc==0);
14168 
14169  rc= mysql_stmt_fetch(stmt);
14170  DIE_UNLESS(rc==MYSQL_NO_DATA);
14171 
14172  rc= mysql_stmt_fetch(stmt);
14173  DIE_UNLESS(rc==MYSQL_NO_DATA);
14174 
14175  mysql_stmt_close(stmt);
14176  rc= mysql_query(mysql, "drop table t1");
14177  myquery(rc);
14178 }
14179 
14180 /* Bug#10760: cursors, crash in a fetch after rollback. */
14181 
14182 static void test_bug10760()
14183 {
14184  MYSQL_STMT *stmt;
14185  MYSQL_BIND my_bind[1];
14186  int rc;
14187  const char *stmt_text;
14188  char id_buf[20];
14189  ulong id_len;
14190  int i= 0;
14191  ulong type;
14192 
14193  myheader("test_bug10760");
14194 
14195  mysql_query(mysql, "drop table if exists t1, t2");
14196 
14197  /* create tables */
14198  rc= mysql_query(mysql, "create table t1 (id integer not null primary key)"
14199  " engine=MyISAM");
14200  myquery(rc);
14201  for (; i < 42; ++i)
14202  {
14203  char buf[100];
14204  sprintf(buf, "insert into t1 (id) values (%d)", i+1);
14205  rc= mysql_query(mysql, buf);
14206  myquery(rc);
14207  }
14208  mysql_autocommit(mysql, FALSE);
14209  /* create statement */
14210  stmt= mysql_stmt_init(mysql);
14211  type= (ulong) CURSOR_TYPE_READ_ONLY;
14212  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14213 
14214  /*
14215  1: check that a deadlock within the same connection
14216  is resolved and an error is returned. The deadlock is modelled
14217  as follows:
14218  con1: open cursor for select * from t1;
14219  con1: insert into t1 (id) values (1)
14220  */
14221  stmt_text= "select id from t1 order by 1";
14222  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14223  check_execute(stmt, rc);
14224  rc= mysql_stmt_execute(stmt);
14225  check_execute(stmt, rc);
14226  rc= mysql_query(mysql, "update t1 set id=id+100");
14227  /*
14228  If cursors are not materialized, the update will return an error;
14229  we mainly test that it won't deadlock.
14230  */
14231  if (rc && !opt_silent)
14232  printf("Got error (as expected): %s\n", mysql_error(mysql));
14233  /*
14234  2: check that MyISAM tables used in cursors survive
14235  COMMIT/ROLLBACK.
14236  */
14237  rc= mysql_rollback(mysql); /* should not close the cursor */
14238  myquery(rc);
14239  rc= mysql_stmt_fetch(stmt);
14240  check_execute(stmt, rc);
14241 
14242  /*
14243  3: check that cursors to InnoDB tables are closed (for now) by
14244  COMMIT/ROLLBACK.
14245  */
14246  if (! have_innodb)
14247  {
14248  if (!opt_silent)
14249  printf("Testing that cursors are closed at COMMIT/ROLLBACK requires "
14250  "InnoDB.\n");
14251  }
14252  else
14253  {
14254  stmt_text= "select id from t1 order by 1";
14255  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14256  check_execute(stmt, rc);
14257 
14258  rc= mysql_query(mysql, "alter table t1 engine=InnoDB");
14259  myquery(rc);
14260 
14261  memset(my_bind, 0, sizeof(my_bind));
14262  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14263  my_bind[0].buffer= (void*) id_buf;
14264  my_bind[0].buffer_length= sizeof(id_buf);
14265  my_bind[0].length= &id_len;
14266  check_execute(stmt, rc);
14267  mysql_stmt_bind_result(stmt, my_bind);
14268 
14269  rc= mysql_stmt_execute(stmt);
14270  rc= mysql_stmt_fetch(stmt);
14271  DIE_UNLESS(rc == 0);
14272  if (!opt_silent)
14273  printf("Fetched row %s\n", id_buf);
14274  rc= mysql_rollback(mysql); /* should close the cursor */
14275  myquery(rc);
14276 #if 0
14277  rc= mysql_stmt_fetch(stmt);
14278  DIE_UNLESS(rc);
14279  if (!opt_silent)
14280  printf("Got error (as expected): %s\n", mysql_error(mysql));
14281 #endif
14282  }
14283 
14284  mysql_stmt_close(stmt);
14285  rc= mysql_query(mysql, "drop table t1");
14286  myquery(rc);
14287  mysql_autocommit(mysql, TRUE); /* restore default */
14288 }
14289 
14290 static void test_bug12001()
14291 {
14292  MYSQL *mysql_local;
14293  MYSQL_RES *result;
14294  const char *query= "DROP TABLE IF EXISTS test_table;"
14295  "CREATE TABLE test_table(id INT);"
14296  "INSERT INTO test_table VALUES(10);"
14297  "UPDATE test_table SET id=20 WHERE id=10;"
14298  "SELECT * FROM test_table;"
14299  "INSERT INTO non_existent_table VALUES(11);";
14300  int rc, res;
14301 
14302  myheader("test_bug12001");
14303 
14304  if (!(mysql_local= mysql_client_init(NULL)))
14305  {
14306  fprintf(stdout, "\n mysql_client_init() failed");
14307  exit(1);
14308  }
14309 
14310  /* Create connection that supports multi statements */
14311  if (!mysql_real_connect(mysql_local, opt_host, opt_user,
14312  opt_password, current_db, opt_port,
14313  opt_unix_socket, CLIENT_MULTI_STATEMENTS))
14314  {
14315  fprintf(stdout, "\n mysql_real_connect() failed");
14316  exit(1);
14317  }
14318 
14319  rc= mysql_query(mysql_local, query);
14320  myquery(rc);
14321 
14322  do
14323  {
14324  if (mysql_field_count(mysql_local) &&
14325  (result= mysql_use_result(mysql_local)))
14326  {
14327  mysql_free_result(result);
14328  }
14329  }
14330  while (!(res= mysql_next_result(mysql_local)));
14331 
14332  rc= mysql_query(mysql_local, "DROP TABLE IF EXISTS test_table");
14333  myquery(rc);
14334 
14335  mysql_close(mysql_local);
14336  DIE_UNLESS(res==1);
14337 }
14338 
14339 
14340 /* Bug#11909: wrong metadata if fetching from two cursors */
14341 
14342 static void test_bug11909()
14343 {
14344  MYSQL_STMT *stmt1, *stmt2;
14345  MYSQL_BIND my_bind[7];
14346  int rc;
14347  char firstname[20], midinit[20], lastname[20], workdept[20];
14348  ulong firstname_len, midinit_len, lastname_len, workdept_len;
14349  uint32 empno;
14350  double salary;
14351  float bonus;
14352  const char *stmt_text;
14353 
14354  myheader("test_bug11909");
14355 
14356  stmt_text= "drop table if exists t1";
14357  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14358  myquery(rc);
14359 
14360  stmt_text= "create table t1 ("
14361  " empno int(11) not null, firstname varchar(20) not null,"
14362  " midinit varchar(20) not null, lastname varchar(20) not null,"
14363  " workdept varchar(6) not null, salary double not null,"
14364  " bonus float not null, primary key (empno)"
14365  ") default charset=latin1 collate=latin1_bin";
14366  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14367  myquery(rc);
14368 
14369  stmt_text= "insert into t1 values "
14370  "(10, 'CHRISTINE', 'I', 'HAAS', 'A00', 52750, 1000), "
14371  "(20, 'MICHAEL', 'L', 'THOMPSON', 'B01', 41250, 800),"
14372  "(30, 'SALLY', 'A', 'KWAN', 'C01', 38250, 800),"
14373  "(50, 'JOHN', 'B', 'GEYER', 'E01', 40175, 800), "
14374  "(60, 'IRVING', 'F', 'STERN', 'D11', 32250, 500)";
14375  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14376  myquery(rc);
14377 
14378  /* ****** Begin of trace ****** */
14379 
14380  stmt1= open_cursor("SELECT empno, firstname, midinit, lastname,"
14381  "workdept, salary, bonus FROM t1");
14382 
14383  memset(my_bind, 0, sizeof(my_bind));
14384  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14385  my_bind[0].buffer= (void*) &empno;
14386 
14387  my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14388  my_bind[1].buffer= (void*) firstname;
14389  my_bind[1].buffer_length= sizeof(firstname);
14390  my_bind[1].length= &firstname_len;
14391 
14392  my_bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;
14393  my_bind[2].buffer= (void*) midinit;
14394  my_bind[2].buffer_length= sizeof(midinit);
14395  my_bind[2].length= &midinit_len;
14396 
14397  my_bind[3].buffer_type= MYSQL_TYPE_VAR_STRING;
14398  my_bind[3].buffer= (void*) lastname;
14399  my_bind[3].buffer_length= sizeof(lastname);
14400  my_bind[3].length= &lastname_len;
14401 
14402  my_bind[4].buffer_type= MYSQL_TYPE_VAR_STRING;
14403  my_bind[4].buffer= (void*) workdept;
14404  my_bind[4].buffer_length= sizeof(workdept);
14405  my_bind[4].length= &workdept_len;
14406 
14407  my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
14408  my_bind[5].buffer= (void*) &salary;
14409 
14410  my_bind[6].buffer_type= MYSQL_TYPE_FLOAT;
14411  my_bind[6].buffer= (void*) &bonus;
14412  rc= mysql_stmt_bind_result(stmt1, my_bind);
14413  check_execute(stmt1, rc);
14414 
14415  rc= mysql_stmt_execute(stmt1);
14416  check_execute(stmt1, rc);
14417 
14418  rc= mysql_stmt_fetch(stmt1);
14419  DIE_UNLESS(rc == 0);
14420  DIE_UNLESS(empno == 10);
14421  DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14422  DIE_UNLESS(strcmp(midinit, "I") == 0);
14423  DIE_UNLESS(strcmp(lastname, "HAAS") == 0);
14424  DIE_UNLESS(strcmp(workdept, "A00") == 0);
14425  DIE_UNLESS(salary == (double) 52750.0);
14426  DIE_UNLESS(bonus == (float) 1000.0);
14427 
14428  stmt2= open_cursor("SELECT empno, firstname FROM t1");
14429  rc= mysql_stmt_bind_result(stmt2, my_bind);
14430  check_execute(stmt2, rc);
14431 
14432  rc= mysql_stmt_execute(stmt2);
14433  check_execute(stmt2, rc);
14434 
14435  rc= mysql_stmt_fetch(stmt2);
14436  DIE_UNLESS(rc == 0);
14437 
14438  DIE_UNLESS(empno == 10);
14439  DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14440 
14441  rc= mysql_stmt_reset(stmt2);
14442  check_execute(stmt2, rc);
14443 
14444  /* ERROR: next statement should return 0 */
14445 
14446  rc= mysql_stmt_fetch(stmt1);
14447  DIE_UNLESS(rc == 0);
14448 
14449  mysql_stmt_close(stmt1);
14450  mysql_stmt_close(stmt2);
14451  rc= mysql_rollback(mysql);
14452  myquery(rc);
14453 
14454  rc= mysql_query(mysql, "drop table t1");
14455  myquery(rc);
14456 }
14457 
14458 /* Cursors: opening a cursor to a compilicated query with ORDER BY */
14459 
14460 static void test_bug11901()
14461 {
14462 /* MYSQL_STMT *stmt;
14463  MYSQL_BIND my_bind[2]; */
14464  int rc;
14465 /* char workdept[20];
14466  ulong workdept_len;
14467  uint32 empno; */
14468  const char *stmt_text;
14469 
14470  myheader("test_bug11901");
14471 
14472  stmt_text= "drop table if exists t1, t2";
14473  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14474  myquery(rc);
14475 
14476  stmt_text= "create table t1 ("
14477  " empno int(11) not null, firstname varchar(20) not null,"
14478  " midinit varchar(20) not null, lastname varchar(20) not null,"
14479  " workdept varchar(6) not null, salary double not null,"
14480  " bonus float not null, primary key (empno), "
14481  " unique key (workdept, empno) "
14482  ") default charset=latin1 collate=latin1_bin";
14483  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14484  myquery(rc);
14485 
14486  stmt_text= "insert into t1 values "
14487  "(10, 'CHRISTINE', 'I', 'HAAS', 'A00', 52750, 1000),"
14488  "(20, 'MICHAEL', 'L', 'THOMPSON', 'B01', 41250, 800), "
14489  "(30, 'SALLY', 'A', 'KWAN', 'C01', 38250, 800), "
14490  "(50, 'JOHN', 'B', 'GEYER', 'E01', 40175, 800), "
14491  "(60, 'IRVING', 'F', 'STERN', 'D11', 32250, 500), "
14492  "(70, 'EVA', 'D', 'PULASKI', 'D21', 36170, 700), "
14493  "(90, 'EILEEN', 'W', 'HENDERSON', 'E11', 29750, 600), "
14494  "(100, 'THEODORE', 'Q', 'SPENSER', 'E21', 26150, 500), "
14495  "(110, 'VINCENZO', 'G', 'LUCCHESSI', 'A00', 46500, 900), "
14496  "(120, 'SEAN', '', 'O\\'CONNELL', 'A00', 29250, 600), "
14497  "(130, 'DOLORES', 'M', 'QUINTANA', 'C01', 23800, 500), "
14498  "(140, 'HEATHER', 'A', 'NICHOLLS', 'C01', 28420, 600), "
14499  "(150, 'BRUCE', '', 'ADAMSON', 'D11', 25280, 500), "
14500  "(160, 'ELIZABETH', 'R', 'PIANKA', 'D11', 22250, 400), "
14501  "(170, 'MASATOSHI', 'J', 'YOSHIMURA', 'D11', 24680, 500), "
14502  "(180, 'MARILYN', 'S', 'SCOUTTEN', 'D11', 21340, 500), "
14503  "(190, 'JAMES', 'H', 'WALKER', 'D11', 20450, 400), "
14504  "(200, 'DAVID', '', 'BROWN', 'D11', 27740, 600), "
14505  "(210, 'WILLIAM', 'T', 'JONES', 'D11', 18270, 400), "
14506  "(220, 'JENNIFER', 'K', 'LUTZ', 'D11', 29840, 600), "
14507  "(230, 'JAMES', 'J', 'JEFFERSON', 'D21', 22180, 400), "
14508  "(240, 'SALVATORE', 'M', 'MARINO', 'D21', 28760, 600), "
14509  "(250, 'DANIEL', 'S', 'SMITH', 'D21', 19180, 400), "
14510  "(260, 'SYBIL', 'P', 'JOHNSON', 'D21', 17250, 300), "
14511  "(270, 'MARIA', 'L', 'PEREZ', 'D21', 27380, 500), "
14512  "(280, 'ETHEL', 'R', 'SCHNEIDER', 'E11', 26250, 500), "
14513  "(290, 'JOHN', 'R', 'PARKER', 'E11', 15340, 300), "
14514  "(300, 'PHILIP', 'X', 'SMITH', 'E11', 17750, 400), "
14515  "(310, 'MAUDE', 'F', 'SETRIGHT', 'E11', 15900, 300), "
14516  "(320, 'RAMLAL', 'V', 'MEHTA', 'E21', 19950, 400), "
14517  "(330, 'WING', '', 'LEE', 'E21', 25370, 500), "
14518  "(340, 'JASON', 'R', 'GOUNOT', 'E21', 23840, 500)";
14519 
14520  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14521  myquery(rc);
14522 
14523  stmt_text= "create table t2 ("
14524  " deptno varchar(6) not null, deptname varchar(20) not null,"
14525  " mgrno int(11) not null, location varchar(20) not null,"
14526  " admrdept varchar(6) not null, refcntd int(11) not null,"
14527  " refcntu int(11) not null, primary key (deptno)"
14528  ") default charset=latin1 collate=latin1_bin";
14529  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14530  myquery(rc);
14531 
14532  stmt_text= "insert into t2 values "
14533  "('A00', 'SPIFFY COMPUTER SERV', 10, '', 'A00', 0, 0), "
14534  "('B01', 'PLANNING', 20, '', 'A00', 0, 0), "
14535  "('C01', 'INFORMATION CENTER', 30, '', 'A00', 0, 0), "
14536  "('D01', 'DEVELOPMENT CENTER', 0, '', 'A00', 0, 0),"
14537  "('D11', 'MANUFACTURING SYSTEM', 60, '', 'D01', 0, 0), "
14538  "('D21', 'ADMINISTRATION SYSTE', 70, '', 'D01', 0, 0), "
14539  "('E01', 'SUPPORT SERVICES', 50, '', 'A00', 0, 0), "
14540  "('E11', 'OPERATIONS', 90, '', 'E01', 0, 0), "
14541  "('E21', 'SOFTWARE SUPPORT', 100,'', 'E01', 0, 0)";
14542  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14543  myquery(rc);
14544 
14545  /* ****** Begin of trace ****** */
14546 /* WL#1110 - disabled test case failure - crash. */
14547 /*
14548  stmt= open_cursor("select t1.emp, t1.workdept "
14549  "from (t1 left join t2 on t2.deptno = t1.workdept) "
14550  "where t2.deptno in "
14551  " (select t2.deptno "
14552  " from (t1 left join t2 on t2.deptno = t1.workdept) "
14553  " where t1.empno = ?) "
14554  "order by 1");
14555  memset(my_bind, 0, sizeof(my_bind));
14556 
14557  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14558  my_bind[0].buffer= &empno;
14559  rc= mysql_stmt_bind_param(stmt, my_bind);
14560  check_execute(stmt, rc);
14561 
14562  my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14563  my_bind[1].buffer= (void*) workdept;
14564  my_bind[1].buffer_length= sizeof(workdept);
14565  my_bind[1].length= &workdept_len;
14566 
14567  rc= mysql_stmt_bind_result(stmt, my_bind);
14568  check_execute(stmt, rc);
14569 
14570  empno= 10;
14571 */
14572  /* ERROR: next statement causes a server crash */
14573 /*
14574  rc= mysql_stmt_execute(stmt);
14575  check_execute(stmt, rc);
14576 
14577  mysql_stmt_close(stmt);
14578 
14579  rc= mysql_query(mysql, "drop table t1, t2");
14580  myquery(rc);
14581 */
14582 }
14583 
14584 /* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */
14585 
14586 static void test_bug11904()
14587 {
14588  MYSQL_STMT *stmt1;
14589  int rc;
14590  const char *stmt_text;
14591  const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
14592  MYSQL_BIND my_bind[2];
14593  int country_id=0;
14594  char row_data[11]= {0};
14595 
14596  myheader("test_bug11904");
14597 
14598  /* create tables */
14599  rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b");
14600  myquery(rc);
14601  rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))");
14602  myquery(rc);
14603 
14604  rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv'),"
14605  " (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg'),"
14606  " (3,'berlin'), (3, 'frankfurt')");
14607 
14608  myquery(rc);
14609  mysql_commit(mysql);
14610  /* create statement */
14611  stmt1= mysql_stmt_init(mysql);
14612  mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14613 
14614  stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id";
14615 
14616  rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14617  check_execute(stmt1, rc);
14618 
14619  memset(my_bind, 0, sizeof(my_bind));
14620  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14621  my_bind[0].buffer=& country_id;
14622  my_bind[0].buffer_length= 0;
14623  my_bind[0].length= 0;
14624 
14625  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14626  my_bind[1].buffer=& row_data;
14627  my_bind[1].buffer_length= sizeof(row_data) - 1;
14628  my_bind[1].length= 0;
14629 
14630  rc= mysql_stmt_bind_result(stmt1, my_bind);
14631  check_execute(stmt1, rc);
14632 
14633  rc= mysql_stmt_execute(stmt1);
14634  check_execute(stmt1, rc);
14635 
14636  rc= mysql_stmt_fetch(stmt1);
14637  check_execute(stmt1, rc);
14638  DIE_UNLESS(country_id == 1);
14639  DIE_UNLESS(memcmp(row_data, "plovdiv", 7) == 0);
14640 
14641  rc= mysql_stmt_fetch(stmt1);
14642  check_execute(stmt1, rc);
14643  DIE_UNLESS(country_id == 2);
14644  DIE_UNLESS(memcmp(row_data, "LA", 2) == 0);
14645 
14646  rc= mysql_stmt_fetch(stmt1);
14647  check_execute(stmt1, rc);
14648  DIE_UNLESS(country_id == 3);
14649  DIE_UNLESS(memcmp(row_data, "berlin", 6) == 0);
14650 
14651  rc= mysql_stmt_close(stmt1);
14652  check_execute(stmt1, rc);
14653 
14654  rc= mysql_query(mysql, "drop table bug11904b");
14655  myquery(rc);
14656 }
14657 
14658 
14659 /* Bug#12243: multiple cursors, crash in a fetch after commit. */
14660 
14661 static void test_bug12243()
14662 {
14663  MYSQL_STMT *stmt1, *stmt2;
14664  int rc;
14665  const char *stmt_text;
14666  ulong type;
14667 
14668  myheader("test_bug12243");
14669 
14670  if (! have_innodb)
14671  {
14672  if (!opt_silent)
14673  printf("This test requires InnoDB.\n");
14674  return;
14675  }
14676 
14677  /* create tables */
14678  mysql_query(mysql, "drop table if exists t1");
14679  mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
14680  rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
14681  myquery(rc);
14682  mysql_autocommit(mysql, FALSE);
14683  /* create statement */
14684  stmt1= mysql_stmt_init(mysql);
14685  stmt2= mysql_stmt_init(mysql);
14686  type= (ulong) CURSOR_TYPE_READ_ONLY;
14687  mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14688  mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14689 
14690  stmt_text= "select a from t1";
14691 
14692  rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14693  check_execute(stmt1, rc);
14694  rc= mysql_stmt_execute(stmt1);
14695  check_execute(stmt1, rc);
14696  rc= mysql_stmt_fetch(stmt1);
14697  check_execute(stmt1, rc);
14698 
14699  rc= mysql_stmt_prepare(stmt2, stmt_text, strlen(stmt_text));
14700  check_execute(stmt2, rc);
14701  rc= mysql_stmt_execute(stmt2);
14702  check_execute(stmt2, rc);
14703  rc= mysql_stmt_fetch(stmt2);
14704  check_execute(stmt2, rc);
14705 
14706  rc= mysql_stmt_close(stmt1);
14707  check_execute(stmt1, rc);
14708  rc= mysql_commit(mysql);
14709  myquery(rc);
14710  rc= mysql_stmt_fetch(stmt2);
14711  check_execute(stmt2, rc);
14712 
14713  mysql_stmt_close(stmt2);
14714  rc= mysql_query(mysql, "drop table t1");
14715  myquery(rc);
14716  mysql_autocommit(mysql, TRUE); /* restore default */
14717 }
14718 
14719 
14720 /*
14721  Bug#11718: query with function, join and order by returns wrong type
14722 */
14723 
14724 static void test_bug11718()
14725 {
14726  MYSQL_RES *res;
14727  int rc;
14728  const char *query= "select str_to_date(concat(f3),'%Y%m%d') from t1,t2 "
14729  "where f1=f2 order by f1";
14730 
14731  myheader("test_bug11718");
14732 
14733  rc= mysql_query(mysql, "drop table if exists t1, t2");
14734  myquery(rc);
14735  rc= mysql_query(mysql, "create table t1 (f1 int)");
14736  myquery(rc);
14737  rc= mysql_query(mysql, "create table t2 (f2 int, f3 numeric(8))");
14738  myquery(rc);
14739  rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14740  myquery(rc);
14741  rc= mysql_query(mysql, "insert into t2 values (1,20050101), (2,20050202)");
14742  myquery(rc);
14743  rc= mysql_query(mysql, query);
14744  myquery(rc);
14745  res = mysql_store_result(mysql);
14746 
14747  if (!opt_silent)
14748  printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
14749  "not DATE");
14750  DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
14751  mysql_free_result(res);
14752  rc= mysql_query(mysql, "drop table t1, t2");
14753  myquery(rc);
14754 }
14755 
14756 
14757 /*
14758  Bug #12925: Bad handling of maximum values in getopt
14759 */
14760 static void test_bug12925()
14761 {
14762  myheader("test_bug12925");
14763  if (opt_getopt_ll_test)
14764  DIE_UNLESS(opt_getopt_ll_test == LL(25600*1024*1024));
14765 }
14766 
14767 
14768 /*
14769  Bug#14210 "Simple query with > operator on large table gives server
14770  crash"
14771 */
14772 
14773 static void test_bug14210()
14774 {
14775  MYSQL_STMT *stmt;
14776  int rc, i;
14777  const char *stmt_text;
14778  ulong type;
14779 
14780  myheader("test_bug14210");
14781 
14782  mysql_query(mysql, "drop table if exists t1");
14783  /*
14784  To trigger the problem the table must be InnoDB, although the problem
14785  itself is not InnoDB related. In case the table is MyISAM this test
14786  is harmless.
14787  */
14788  mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB");
14789  rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
14790  myquery(rc);
14791  rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
14792  /* Create a big enough table (more than max_heap_table_size) */
14793  for (i= 0; i < 8; i++)
14794  {
14795  rc= mysql_query(mysql, "insert into t1 (a) select a from t1");
14796  myquery(rc);
14797  }
14798  /* create statement */
14799  stmt= mysql_stmt_init(mysql);
14800  type= (ulong) CURSOR_TYPE_READ_ONLY;
14801  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14802 
14803  stmt_text= "select a from t1";
14804 
14805  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14806  check_execute(stmt, rc);
14807  rc= mysql_stmt_execute(stmt);
14808  while ((rc= mysql_stmt_fetch(stmt)) == 0)
14809  ;
14810  DIE_UNLESS(rc == MYSQL_NO_DATA);
14811 
14812  rc= mysql_stmt_close(stmt);
14813 
14814  rc= mysql_query(mysql, "drop table t1");
14815  myquery(rc);
14816  rc= mysql_query(mysql, "set @@session.max_heap_table_size=default");
14817  myquery(rc);
14818 }
14819 
14820 /* Bug#13488: wrong column metadata when fetching from cursor */
14821 
14822 static void test_bug13488()
14823 {
14824  MYSQL_BIND my_bind[3];
14825  MYSQL_STMT *stmt1;
14826  int rc, f1, f2, f3, i;
14827  const ulong type= CURSOR_TYPE_READ_ONLY;
14828  const char *query= "select * from t1 left join t2 on f1=f2 where f1=1";
14829 
14830  myheader("test_bug13488");
14831 
14832  rc= mysql_query(mysql, "drop table if exists t1, t2");
14833  myquery(rc);
14834  rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)");
14835  myquery(rc);
14836  rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, "
14837  "f3 int not null)");
14838  myquery(rc);
14839  rc= mysql_query(mysql, "insert into t1 values (1), (2)");
14840  myquery(rc);
14841  rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)");
14842  myquery(rc);
14843 
14844  memset(my_bind, 0, sizeof(my_bind));
14845  for (i= 0; i < 3; i++)
14846  {
14847  my_bind[i].buffer_type= MYSQL_TYPE_LONG;
14848  my_bind[i].buffer_length= 4;
14849  my_bind[i].length= 0;
14850  }
14851  my_bind[0].buffer=&f1;
14852  my_bind[1].buffer=&f2;
14853  my_bind[2].buffer=&f3;
14854 
14855  stmt1= mysql_stmt_init(mysql);
14856  rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type);
14857  check_execute(stmt1, rc);
14858 
14859  rc= mysql_stmt_prepare(stmt1, query, strlen(query));
14860  check_execute(stmt1, rc);
14861 
14862  rc= mysql_stmt_execute(stmt1);
14863  check_execute(stmt1, rc);
14864 
14865  rc= mysql_stmt_bind_result(stmt1, my_bind);
14866  check_execute(stmt1, rc);
14867 
14868  rc= mysql_stmt_fetch(stmt1);
14869  check_execute(stmt1, rc);
14870 
14871  rc= mysql_stmt_free_result(stmt1);
14872  check_execute(stmt1, rc);
14873 
14874  rc= mysql_stmt_reset(stmt1);
14875  check_execute(stmt1, rc);
14876 
14877  rc= mysql_stmt_close(stmt1);
14878  check_execute(stmt1, rc);
14879 
14880  if (!opt_silent)
14881  {
14882  printf("data: f1: %d; f2: %d; f3: %d\n", f1, f2, f3);
14883  printf("data is: %s\n",
14884  (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong");
14885  }
14886  DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
14887  rc= mysql_query(mysql, "drop table t1, t2");
14888  myquery(rc);
14889 }
14890 
14891 /*
14892  Bug#13524: warnings of a previous command are not reset when fetching
14893  from a cursor.
14894 */
14895 
14896 static void test_bug13524()
14897 {
14898  MYSQL_STMT *stmt;
14899  int rc;
14900  unsigned int warning_count;
14901  const ulong type= CURSOR_TYPE_READ_ONLY;
14902  const char *query= "select * from t1";
14903 
14904  myheader("test_bug13524");
14905 
14906  rc= mysql_query(mysql, "drop table if exists t1, t2");
14907  myquery(rc);
14908  rc= mysql_query(mysql, "create table t1 (a int not null primary key)");
14909  myquery(rc);
14910  rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
14911  myquery(rc);
14912 
14913  stmt= mysql_stmt_init(mysql);
14914  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14915  check_execute(stmt, rc);
14916 
14917  rc= mysql_stmt_prepare(stmt, query, strlen(query));
14918  check_execute(stmt, rc);
14919 
14920  rc= mysql_stmt_execute(stmt);
14921  check_execute(stmt, rc);
14922 
14923  rc= mysql_stmt_fetch(stmt);
14924  check_execute(stmt, rc);
14925 
14926  warning_count= mysql_warning_count(mysql);
14927  DIE_UNLESS(warning_count == 0);
14928 
14929  /* Check that DROP TABLE produced a warning (no such table) */
14930  rc= mysql_query(mysql, "drop table if exists t2");
14931  myquery(rc);
14932  warning_count= mysql_warning_count(mysql);
14933  DIE_UNLESS(warning_count == 1);
14934 
14935  /*
14936  Check that fetch from a cursor cleared the warning from the previous
14937  command.
14938  */
14939  rc= mysql_stmt_fetch(stmt);
14940  check_execute(stmt, rc);
14941  warning_count= mysql_warning_count(mysql);
14942  DIE_UNLESS(warning_count == 0);
14943 
14944  /* Cleanup */
14945  mysql_stmt_close(stmt);
14946  rc= mysql_query(mysql, "drop table t1");
14947  myquery(rc);
14948 }
14949 
14950 /*
14951  Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
14952 */
14953 
14954 static void test_bug14845()
14955 {
14956  MYSQL_STMT *stmt;
14957  int rc;
14958  const ulong type= CURSOR_TYPE_READ_ONLY;
14959  const char *query= "select count(*) from t1 where 1 = 0";
14960 
14961  myheader("test_bug14845");
14962 
14963  rc= mysql_query(mysql, "drop table if exists t1");
14964  myquery(rc);
14965  rc= mysql_query(mysql, "create table t1 (id int(11) default null, "
14966  "name varchar(20) default null)"
14967  "engine=MyISAM DEFAULT CHARSET=utf8");
14968  myquery(rc);
14969  rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')");
14970  myquery(rc);
14971 
14972  stmt= mysql_stmt_init(mysql);
14973  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14974  check_execute(stmt, rc);
14975 
14976  rc= mysql_stmt_prepare(stmt, query, strlen(query));
14977  check_execute(stmt, rc);
14978 
14979  rc= mysql_stmt_execute(stmt);
14980  check_execute(stmt, rc);
14981 
14982  rc= mysql_stmt_fetch(stmt);
14983  DIE_UNLESS(rc == 0);
14984 
14985  rc= mysql_stmt_fetch(stmt);
14986  DIE_UNLESS(rc == MYSQL_NO_DATA);
14987 
14988  /* Cleanup */
14989  mysql_stmt_close(stmt);
14990  rc= mysql_query(mysql, "drop table t1");
14991  myquery(rc);
14992 }
14993 
14994 
14995 /*
14996  Bug #15510: mysql_warning_count returns 0 after mysql_stmt_fetch which
14997  should warn
14998 */
14999 static void test_bug15510()
15000 {
15001  MYSQL_STMT *stmt;
15002  int rc;
15003  const char *query= "select 1 from dual where 1/0";
15004 
15005  myheader("test_bug15510");
15006 
15007  rc= mysql_query(mysql, "set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'");
15008  myquery(rc);
15009 
15010  stmt= mysql_stmt_init(mysql);
15011 
15012  rc= mysql_stmt_prepare(stmt, query, strlen(query));
15013  check_execute(stmt, rc);
15014 
15015  rc= mysql_stmt_execute(stmt);
15016  check_execute(stmt, rc);
15017 
15018  rc= mysql_stmt_fetch(stmt);
15019  DIE_UNLESS(mysql_warning_count(mysql));
15020 
15021  /* Cleanup */
15022  mysql_stmt_close(stmt);
15023  rc= mysql_query(mysql, "set @@sql_mode=''");
15024  myquery(rc);
15025 }
15026 
15027 
15028 /* Test MYSQL_OPT_RECONNECT, Bug#15719 */
15029 
15030 static void test_opt_reconnect()
15031 {
15032  MYSQL *lmysql;
15033  my_bool my_true= TRUE;
15034 
15035  myheader("test_opt_reconnect");
15036 
15037  if (!(lmysql= mysql_client_init(NULL)))
15038  {
15039  myerror("mysql_client_init() failed");
15040  exit(1);
15041  }
15042 
15043  if (!opt_silent)
15044  fprintf(stdout, "reconnect before mysql_options: %d\n", lmysql->reconnect);
15045  DIE_UNLESS(lmysql->reconnect == 0);
15046 
15047  if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
15048  {
15049  myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
15050  DIE_UNLESS(0);
15051  }
15052 
15053  /* reconnect should be 1 */
15054  if (!opt_silent)
15055  fprintf(stdout, "reconnect after mysql_options: %d\n", lmysql->reconnect);
15056  DIE_UNLESS(lmysql->reconnect == 1);
15057 
15058  if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15059  opt_password, current_db, opt_port,
15060  opt_unix_socket, 0)))
15061  {
15062  myerror("connection failed");
15063  DIE_UNLESS(0);
15064  }
15065 
15066  /* reconnect should still be 1 */
15067  if (!opt_silent)
15068  fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15069  lmysql->reconnect);
15070  DIE_UNLESS(lmysql->reconnect == 1);
15071 
15072  mysql_close(lmysql);
15073 
15074  if (!(lmysql= mysql_client_init(NULL)))
15075  {
15076  myerror("mysql_client_init() failed");
15077  DIE_UNLESS(0);
15078  }
15079 
15080  if (!opt_silent)
15081  fprintf(stdout, "reconnect before mysql_real_connect: %d\n", lmysql->reconnect);
15082  DIE_UNLESS(lmysql->reconnect == 0);
15083 
15084  if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15085  opt_password, current_db, opt_port,
15086  opt_unix_socket, 0)))
15087  {
15088  myerror("connection failed");
15089  DIE_UNLESS(0);
15090  }
15091 
15092  /* reconnect should still be 0 */
15093  if (!opt_silent)
15094  fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15095  lmysql->reconnect);
15096  DIE_UNLESS(lmysql->reconnect == 0);
15097 
15098  mysql_close(lmysql);
15099 }
15100 
15101 
15102 #ifndef EMBEDDED_LIBRARY
15103 
15104 static void test_bug12744()
15105 {
15106  MYSQL_STMT *prep_stmt = NULL;
15107  MYSQL *lmysql;
15108  int rc;
15109  myheader("test_bug12744");
15110 
15111  lmysql= mysql_client_init(NULL);
15112  DIE_UNLESS(lmysql);
15113 
15114  if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
15115  current_db, opt_port, opt_unix_socket, 0))
15116  {
15117  fprintf(stderr, "Failed to connect to the database\n");
15118  DIE_UNLESS(0);
15119  }
15120 
15121  prep_stmt= mysql_stmt_init(lmysql);
15122  rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
15123  DIE_UNLESS(rc == 0);
15124 
15125  mysql_close(lmysql);
15126 
15127  rc= mysql_stmt_execute(prep_stmt);
15128  DIE_UNLESS(rc);
15129  rc= mysql_stmt_reset(prep_stmt);
15130  DIE_UNLESS(rc);
15131  rc= mysql_stmt_close(prep_stmt);
15132  DIE_UNLESS(rc == 0);
15133 }
15134 
15135 #endif /* EMBEDDED_LIBRARY */
15136 
15137 /* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
15138 
15139 static void test_bug16143()
15140 {
15141  MYSQL_STMT *stmt;
15142  myheader("test_bug16143");
15143 
15144  stmt= mysql_stmt_init(mysql);
15145  /* Check mysql_stmt_sqlstate return "no error" */
15146  DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0);
15147 
15148  mysql_stmt_close(stmt);
15149 }
15150 
15151 
15152 /* Bug #16144: mysql_stmt_attr_get type error */
15153 
15154 static void test_bug16144()
15155 {
15156  const my_bool flag_orig= (my_bool) 0xde;
15157  my_bool flag= flag_orig;
15158  MYSQL_STMT *stmt;
15159  myheader("test_bug16144");
15160 
15161  /* Check that attr_get returns correct data on little and big endian CPUs */
15162  stmt= mysql_stmt_init(mysql);
15163  mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
15164  mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
15165  DIE_UNLESS(flag == flag_orig);
15166 
15167  mysql_stmt_close(stmt);
15168 }
15169 
15170 /*
15171  Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
15172  field length"
15173 */
15174 
15175 static void test_bug15613()
15176 {
15177  MYSQL_STMT *stmt;
15178  const char *stmt_text;
15179  MYSQL_RES *metadata;
15180  MYSQL_FIELD *field;
15181  int rc;
15182  myheader("test_bug15613");
15183 
15184  /* I. Prepare the table */
15185  rc= mysql_query(mysql, "set names latin1");
15186  myquery(rc);
15187  mysql_query(mysql, "drop table if exists t1");
15188  rc= mysql_query(mysql,
15189  "create table t1 (t text character set utf8, "
15190  "tt tinytext character set utf8, "
15191  "mt mediumtext character set utf8, "
15192  "lt longtext character set utf8, "
15193  "vl varchar(255) character set latin1,"
15194  "vb varchar(255) character set binary,"
15195  "vu varchar(255) character set utf8)");
15196  myquery(rc);
15197 
15198  stmt= mysql_stmt_init(mysql);
15199 
15200  /* II. Check SELECT metadata */
15201  stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
15202  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15203  metadata= mysql_stmt_result_metadata(stmt);
15204  field= mysql_fetch_fields(metadata);
15205  if (!opt_silent)
15206  {
15207  printf("Field lengths (client character set is latin1):\n"
15208  "text character set utf8:\t\t%lu\n"
15209  "tinytext character set utf8:\t\t%lu\n"
15210  "mediumtext character set utf8:\t\t%lu\n"
15211  "longtext character set utf8:\t\t%lu\n"
15212  "varchar(255) character set latin1:\t%lu\n"
15213  "varchar(255) character set binary:\t%lu\n"
15214  "varchar(255) character set utf8:\t%lu\n",
15215  field[0].length, field[1].length, field[2].length, field[3].length,
15216  field[4].length, field[5].length, field[6].length);
15217  }
15218  DIE_UNLESS(field[0].length == 65535);
15219  DIE_UNLESS(field[1].length == 255);
15220  DIE_UNLESS(field[2].length == 16777215);
15221  DIE_UNLESS(field[3].length == 4294967295UL);
15222  DIE_UNLESS(field[4].length == 255);
15223  DIE_UNLESS(field[5].length == 255);
15224  DIE_UNLESS(field[6].length == 255);
15225  mysql_free_result(metadata);
15226  mysql_stmt_free_result(stmt);
15227 
15228  /* III. Cleanup */
15229  rc= mysql_query(mysql, "drop table t1");
15230  myquery(rc);
15231  rc= mysql_query(mysql, "set names default");
15232  myquery(rc);
15233  mysql_stmt_close(stmt);
15234 }
15235 
15236 /*
15237  Bug#17667: An attacker has the opportunity to bypass query logging.
15238 
15239  Note! Also tests Bug#21813, where prepared statements are used to
15240  run queries
15241 */
15242 static void test_bug17667()
15243 {
15244  int rc;
15245  MYSQL_STMT *stmt;
15246  enum query_type { QT_NORMAL, QT_PREPARED};
15247  struct buffer_and_length {
15248  enum query_type qt;
15249  const char *buffer;
15250  const uint length;
15251  } statements[]= {
15252  { QT_NORMAL, "drop table if exists bug17667", 29 },
15253  { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
15254  { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
15255  { QT_PREPARED,
15256  "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
15257  { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
15258  { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
15259  { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
15260  { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
15261  { QT_NORMAL, "drop table bug17667", 19 },
15262  { QT_NORMAL, NULL, 0 } };
15263 
15264  struct buffer_and_length *statement_cursor;
15265  FILE *log_file;
15266  char *master_log_filename;
15267 
15268  myheader("test_bug17667");
15269 
15270  master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1);
15271  strxmov(master_log_filename, opt_vardir, "/log/master.log", NullS);
15272  if (!opt_silent)
15273  printf("Opening '%s'\n", master_log_filename);
15274  log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0));
15275  free(master_log_filename);
15276 
15277  if (log_file == NULL)
15278  {
15279  if (!opt_silent)
15280  {
15281  printf("Could not find the log file, VARDIR/log/master.log, so "
15282  "test_bug17667 is not run.\n"
15283  "Run test from the mysql-test/mysql-test-run* program to set up "
15284  "correct environment for this test.\n\n");
15285  }
15286  return;
15287  }
15288 
15289  enable_query_logs(1);
15290 
15291  for (statement_cursor= statements; statement_cursor->buffer != NULL;
15292  statement_cursor++)
15293  {
15294  if (statement_cursor->qt == QT_NORMAL)
15295  {
15296  /* Run statement as normal query */
15297  rc= mysql_real_query(mysql, statement_cursor->buffer,
15298  statement_cursor->length);
15299  myquery(rc);
15300  }
15301  else if (statement_cursor->qt == QT_PREPARED)
15302  {
15303  /*
15304  Run as prepared statement
15305 
15306  NOTE! All these queries should be in the log twice,
15307  one time for prepare and one time for execute
15308  */
15309  stmt= mysql_stmt_init(mysql);
15310 
15311  rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
15312  statement_cursor->length);
15313  check_execute(stmt, rc);
15314 
15315  rc= mysql_stmt_execute(stmt);
15316  check_execute(stmt, rc);
15317 
15318  mysql_stmt_close(stmt);
15319  }
15320  else
15321  {
15322  DIE_UNLESS(0==1);
15323  }
15324  }
15325 
15326  /* Make sure the server has written the logs to disk before reading it */
15327  rc= mysql_query(mysql, "flush logs");
15328  myquery(rc);
15329 
15330  for (statement_cursor= statements; statement_cursor->buffer != NULL;
15331  statement_cursor++)
15332  {
15333  int expected_hits= 1, hits= 0;
15334  char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15335  /* more than enough room for the query and some marginalia. */
15336 
15337  /* Prepared statments always occurs twice in log */
15338  if (statement_cursor->qt == QT_PREPARED)
15339  expected_hits++;
15340 
15341  /* Loop until we found expected number of log entries */
15342  do {
15343  /* Loop until statement is found in log */
15344  do {
15345  memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15346 
15347  if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15348  {
15349  /* If fgets returned NULL, it indicates either error or EOF */
15350  if (feof(log_file))
15351  DIE("Found EOF before all statements where found");
15352 
15353  fprintf(stderr, "Got error %d while reading from file\n",
15354  ferror(log_file));
15355  DIE("Read error");
15356  }
15357 
15358  } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15359  statement_cursor->buffer,
15360  statement_cursor->length) == NULL);
15361  hits++;
15362  } while (hits < expected_hits);
15363 
15364  if (!opt_silent)
15365  printf("Found statement starting with \"%s\"\n",
15366  statement_cursor->buffer);
15367  }
15368 
15369  restore_query_logs();
15370 
15371  if (!opt_silent)
15372  printf("success. All queries found intact in the log.\n");
15373 
15374  my_fclose(log_file, MYF(0));
15375 }
15376 
15377 
15378 /*
15379  Bug#14169: type of group_concat() result changed to blob if tmp_table was
15380  used
15381 */
15382 static void test_bug14169()
15383 {
15384  MYSQL_STMT *stmt;
15385  const char *stmt_text;
15386  MYSQL_RES *res;
15387  MYSQL_FIELD *field;
15388  int rc;
15389 
15390  myheader("test_bug14169");
15391 
15392  rc= mysql_query(mysql, "drop table if exists t1");
15393  myquery(rc);
15394  rc= mysql_query(mysql, "set session group_concat_max_len=1024");
15395  myquery(rc);
15396  rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))");
15397  myquery(rc);
15398  rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255)),"
15399  "(2,repeat('b',255))");
15400  myquery(rc);
15401  stmt= mysql_stmt_init(mysql);
15402  stmt_text= "select f2,group_concat(f1) from t1 group by f2";
15403  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15404  myquery(rc);
15405  res= mysql_stmt_result_metadata(stmt);
15406  field= mysql_fetch_fields(res);
15407  if (!opt_silent)
15408  printf("GROUP_CONCAT() result type %i", field[1].type);
15409  DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
15410  mysql_free_result(res);
15411  mysql_stmt_free_result(stmt);
15412  mysql_stmt_close(stmt);
15413 
15414  rc= mysql_query(mysql, "drop table t1");
15415  myquery(rc);
15416 }
15417 
15418 /*
15419  Test that mysql_insert_id() behaves as documented in our manual
15420 */
15421 static void test_mysql_insert_id()
15422 {
15423  my_ulonglong res;
15424  int rc;
15425 
15426  myheader("test_mysql_insert_id");
15427 
15428  rc= mysql_query(mysql, "drop table if exists t1");
15429  myquery(rc);
15430  /* table without auto_increment column */
15431  rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
15432  myquery(rc);
15433  rc= mysql_query(mysql, "insert into t1 values (1,'a')");
15434  myquery(rc);
15435  res= mysql_insert_id(mysql);
15436  DIE_UNLESS(res == 0);
15437  rc= mysql_query(mysql, "insert into t1 values (null,'b')");
15438  myquery(rc);
15439  res= mysql_insert_id(mysql);
15440  DIE_UNLESS(res == 0);
15441  rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15442  myquery(rc);
15443  res= mysql_insert_id(mysql);
15444  DIE_UNLESS(res == 0);
15445 
15446  /*
15447  Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
15448  sporadically
15449  */
15450  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15451  myquery(rc);
15452  rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15453  myquery(rc);
15454  rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15455  myquery(rc);
15456  res= mysql_insert_id(mysql);
15457  DIE_UNLESS(res == 0);
15458  rc= mysql_query(mysql, "drop table t2");
15459  myquery(rc);
15460 
15461  rc= mysql_query(mysql, "insert into t1 select null,'d'");
15462  myquery(rc);
15463  res= mysql_insert_id(mysql);
15464  DIE_UNLESS(res == 0);
15465  rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
15466  myquery(rc);
15467  res= mysql_insert_id(mysql);
15468  DIE_UNLESS(res == 300);
15469  rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
15470  myquery(rc);
15471  res= mysql_insert_id(mysql);
15472  /*
15473  Behaviour change: old code used to return 0; but 400 is consistent
15474  with INSERT VALUES, and the manual's section of mysql_insert_id() does not
15475  say INSERT SELECT should be different.
15476  */
15477  DIE_UNLESS(res == 400);
15478 
15479  /* table with auto_increment column */
15480  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15481  myquery(rc);
15482  rc= mysql_query(mysql, "insert into t2 values (1,'a')");
15483  myquery(rc);
15484  res= mysql_insert_id(mysql);
15485  DIE_UNLESS(res == 1);
15486  /* this should not influence next INSERT if it doesn't have auto_inc */
15487  rc= mysql_query(mysql, "insert into t1 values (10,'e')");
15488  myquery(rc);
15489  res= mysql_insert_id(mysql);
15490  DIE_UNLESS(res == 0);
15491 
15492  rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15493  myquery(rc);
15494  res= mysql_insert_id(mysql);
15495  DIE_UNLESS(res == 2);
15496  rc= mysql_query(mysql, "insert into t2 select 5,'c'");
15497  myquery(rc);
15498  res= mysql_insert_id(mysql);
15499  /*
15500  Manual says that for multirow insert this should have been 5, but does not
15501  say for INSERT SELECT. This is a behaviour change: old code used to return
15502  0. We try to be consistent with INSERT VALUES.
15503  */
15504  DIE_UNLESS(res == 5);
15505  rc= mysql_query(mysql, "insert into t2 select null,'d'");
15506  myquery(rc);
15507  res= mysql_insert_id(mysql);
15508  DIE_UNLESS(res == 6);
15509  /* with more than one row */
15510  rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
15511  myquery(rc);
15512  res= mysql_insert_id(mysql);
15513  DIE_UNLESS(res == 11);
15514  rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15515  myquery(rc);
15516  res= mysql_insert_id(mysql);
15517  /*
15518  Manual says that for multirow insert this should have been 13, but does
15519  not say for INSERT SELECT. This is a behaviour change: old code used to
15520  return 0. We try to be consistent with INSERT VALUES.
15521  */
15522  DIE_UNLESS(res == 13);
15523  rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
15524  myquery(rc);
15525  res= mysql_insert_id(mysql);
15526  DIE_UNLESS(res == 14);
15527  rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
15528  myquery(rc);
15529  res= mysql_insert_id(mysql);
15530  DIE_UNLESS(res == 16);
15531  rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15532  myquery_r(rc);
15533  rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
15534  myquery(rc);
15535  res= mysql_insert_id(mysql);
15536  DIE_UNLESS(res == 0);
15537  rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
15538  myquery_r(rc);
15539  res= mysql_insert_id(mysql);
15540  DIE_UNLESS(res == 0);
15541  rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
15542  myquery(rc);
15543  res= mysql_insert_id(mysql);
15544  DIE_UNLESS(res == 0);
15545  /* mixing autogenerated and explicit values */
15546  rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
15547  myquery_r(rc);
15548  rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
15549  myquery_r(rc);
15550  rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
15551  myquery(rc);
15552  res= mysql_insert_id(mysql);
15553  /*
15554  according to the manual, this might be 20 or 300, but it looks like
15555  auto_increment column takes priority over last_insert_id().
15556  */
15557  DIE_UNLESS(res == 20);
15558  /* If first autogenerated number fails and 2nd works: */
15559  rc= mysql_query(mysql, "drop table t2");
15560  myquery(rc);
15561  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
15562  "auto_increment, f2 varchar(255), unique (f2))");
15563  myquery(rc);
15564  rc= mysql_query(mysql, "insert into t2 values (null,'e')");
15565  res= mysql_insert_id(mysql);
15566  DIE_UNLESS(res == 1);
15567  rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
15568  myquery(rc);
15569  res= mysql_insert_id(mysql);
15570  DIE_UNLESS(res == 2);
15571  /* If autogenerated fails and explicit works: */
15572  rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
15573  myquery(rc);
15574  res= mysql_insert_id(mysql);
15575  /*
15576  Behaviour change: old code returned 3 (first autogenerated, even if it
15577  fails); we now return first successful autogenerated.
15578  */
15579  DIE_UNLESS(res == 13);
15580  /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
15581  rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
15582  myquery(rc);
15583  res= mysql_insert_id(mysql);
15584  DIE_UNLESS(res == 0);
15585  rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
15586  myquery(rc);
15587  res= mysql_insert_id(mysql);
15588  DIE_UNLESS(res == 0);
15589  rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
15590  myquery(rc);
15591  res= mysql_insert_id(mysql);
15592  DIE_UNLESS(res == 372);
15593  /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
15594  rc= mysql_query(mysql, "insert into t2 values (null,'g')");
15595  myquery(rc);
15596  res= mysql_insert_id(mysql);
15597  DIE_UNLESS(res == 15);
15598  rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
15599  myquery(rc);
15600  res= mysql_insert_id(mysql);
15601  DIE_UNLESS(res == 0);
15602  /*
15603  Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
15604  mysql_insert_id() returns the id of the row, instead of not being
15605  affected.
15606  */
15607  rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
15608  "update f2=concat('we updated ',f2)");
15609  myquery(rc);
15610  res= mysql_insert_id(mysql);
15611  DIE_UNLESS(res == 15);
15612 
15613  rc= mysql_query(mysql, "drop table t1,t2");
15614  myquery(rc);
15615 }
15616 
15617 /*
15618  Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
15619 */
15620 
15621 static void test_bug20152()
15622 {
15623  MYSQL_BIND my_bind[1];
15624  MYSQL_STMT *stmt;
15625  MYSQL_TIME tm;
15626  int rc;
15627  const char *query= "INSERT INTO t1 (f1) VALUES (?)";
15628 
15629  myheader("test_bug20152");
15630 
15631  memset(my_bind, 0, sizeof(my_bind));
15632  my_bind[0].buffer_type= MYSQL_TYPE_DATE;
15633  my_bind[0].buffer= (void*)&tm;
15634 
15635  tm.year = 2006;
15636  tm.month = 6;
15637  tm.day = 18;
15638  tm.hour = 14;
15639  tm.minute = 9;
15640  tm.second = 42;
15641 
15642  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15643  myquery(rc);
15644  rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)");
15645  myquery(rc);
15646 
15647  stmt= mysql_stmt_init(mysql);
15648  rc= mysql_stmt_prepare(stmt, query, strlen(query));
15649  check_execute(stmt, rc);
15650  rc= mysql_stmt_bind_param(stmt, my_bind);
15651  check_execute(stmt, rc);
15652  rc= mysql_stmt_execute(stmt);
15653  check_execute(stmt, rc);
15654  rc= mysql_stmt_close(stmt);
15655  check_execute(stmt, rc);
15656  rc= mysql_query(mysql, "DROP TABLE t1");
15657  myquery(rc);
15658 
15659  if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) {
15660  if (!opt_silent)
15661  printf("OK!");
15662  } else {
15663  printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second);
15664  DIE_UNLESS(0==1);
15665  }
15666 }
15667 
15668 /* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
15669 
15670 static void test_bug15752()
15671 {
15672  MYSQL mysql_local;
15673  int rc, i;
15674  const int ITERATION_COUNT= 100;
15675  const char *query= "CALL p1()";
15676 
15677  myheader("test_bug15752");
15678 
15679  rc= mysql_query(mysql, "drop procedure if exists p1");
15680  myquery(rc);
15681  rc= mysql_query(mysql, "create procedure p1() select 1");
15682  myquery(rc);
15683 
15684  mysql_client_init(&mysql_local);
15685  if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
15686  opt_password, current_db, opt_port,
15687  opt_unix_socket,
15688  CLIENT_MULTI_STATEMENTS))
15689  {
15690  printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
15691  DIE_UNLESS(0);
15692  }
15693  rc= mysql_real_query(&mysql_local, query, strlen(query));
15694  myquery(rc);
15695  mysql_free_result(mysql_store_result(&mysql_local));
15696 
15697  rc= mysql_real_query(&mysql_local, query, strlen(query));
15698  DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
15699 
15700  if (! opt_silent)
15701  printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
15702 
15703  /* Check some other commands too */
15704 
15705  DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15706  mysql_free_result(mysql_store_result(&mysql_local));
15707  DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15708 
15709  /* The second problem is not reproducible: add the test case */
15710  for (i = 0; i < ITERATION_COUNT; i++)
15711  {
15712  if (mysql_real_query(&mysql_local, query, strlen(query)))
15713  {
15714  printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
15715  break;
15716  }
15717  mysql_free_result(mysql_store_result(&mysql_local));
15718  DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15719  mysql_free_result(mysql_store_result(&mysql_local));
15720  DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15721 
15722  }
15723  mysql_close(&mysql_local);
15724  rc= mysql_query(mysql, "drop procedure p1");
15725  myquery(rc);
15726 }
15727 
15728 /*
15729  Bug#21206: memory corruption when too many cursors are opened at once
15730 
15731  Memory corruption happens when more than 1024 cursors are open
15732  simultaneously.
15733 */
15734 static void test_bug21206()
15735 {
15736  const size_t cursor_count= 1025;
15737 
15738  const char *create_table[]=
15739  {
15740  "DROP TABLE IF EXISTS t1",
15741  "CREATE TABLE t1 (i INT)",
15742  "INSERT INTO t1 VALUES (1), (2), (3)"
15743  };
15744  const char *query= "SELECT * FROM t1";
15745 
15746  Stmt_fetch *fetch_array=
15747  (Stmt_fetch*) calloc(cursor_count, sizeof(Stmt_fetch));
15748 
15749  Stmt_fetch *fetch;
15750 
15751  DBUG_ENTER("test_bug21206");
15752  myheader("test_bug21206");
15753 
15754  fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
15755 
15756  for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15757  {
15758  /* Init will exit(1) in case of error */
15759  stmt_fetch_init(fetch, fetch - fetch_array, query);
15760  }
15761 
15762  for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
15763  stmt_fetch_close(fetch);
15764 
15765  free(fetch_array);
15766 
15767  DBUG_VOID_RETURN;
15768 }
15769 
15770 /*
15771  Ensure we execute the status code while testing
15772 */
15773 
15774 static void test_status()
15775 {
15776  const char *status;
15777  DBUG_ENTER("test_status");
15778  myheader("test_status");
15779 
15780  if (!(status= mysql_stat(mysql)))
15781  {
15782  myerror("mysql_stat failed"); /* purecov: inspected */
15783  die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
15784  }
15785  DBUG_VOID_RETURN;
15786 }
15787 
15788 /*
15789  Bug#21726: Incorrect result with multiple invocations of
15790  LAST_INSERT_ID
15791 
15792  Test that client gets updated value of insert_id on UPDATE that uses
15793  LAST_INSERT_ID(expr).
15794  select_query added to test for bug
15795  #26921 Problem in mysql_insert_id() Embedded C API function
15796 */
15797 static void test_bug21726()
15798 {
15799  const char *create_table[]=
15800  {
15801  "DROP TABLE IF EXISTS t1",
15802  "CREATE TABLE t1 (i INT)",
15803  "INSERT INTO t1 VALUES (1)",
15804  };
15805  const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
15806  int rc;
15807  my_ulonglong insert_id;
15808  const char *select_query= "SELECT * FROM t1";
15809  MYSQL_RES *result;
15810 
15811  DBUG_ENTER("test_bug21726");
15812  myheader("test_bug21726");
15813 
15814  fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
15815 
15816  rc= mysql_query(mysql, update_query);
15817  myquery(rc);
15818  insert_id= mysql_insert_id(mysql);
15819  DIE_UNLESS(insert_id == 2);
15820 
15821  rc= mysql_query(mysql, update_query);
15822  myquery(rc);
15823  insert_id= mysql_insert_id(mysql);
15824  DIE_UNLESS(insert_id == 3);
15825 
15826  rc= mysql_query(mysql, select_query);
15827  myquery(rc);
15828  insert_id= mysql_insert_id(mysql);
15829  DIE_UNLESS(insert_id == 3);
15830  result= mysql_store_result(mysql);
15831  mysql_free_result(result);
15832 
15833  DBUG_VOID_RETURN;
15834 }
15835 
15836 
15837 /*
15838  BUG#23383: mysql_affected_rows() returns different values than
15839  mysql_stmt_affected_rows()
15840 
15841  Test that both mysql_affected_rows() and mysql_stmt_affected_rows()
15842  return -1 on error, 0 when no rows were affected, and (positive) row
15843  count when some rows were affected.
15844 */
15845 static void test_bug23383()
15846 {
15847  const char *insert_query= "INSERT INTO t1 VALUES (1), (2)";
15848  const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3";
15849  MYSQL_STMT *stmt;
15850  my_ulonglong row_count;
15851  int rc;
15852 
15853  DBUG_ENTER("test_bug23383");
15854  myheader("test_bug23383");
15855 
15856  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15857  myquery(rc);
15858 
15859  rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)");
15860  myquery(rc);
15861 
15862  rc= mysql_query(mysql, insert_query);
15863  myquery(rc);
15864  row_count= mysql_affected_rows(mysql);
15865  DIE_UNLESS(row_count == 2);
15866 
15867  rc= mysql_query(mysql, insert_query);
15868  DIE_UNLESS(rc != 0);
15869  row_count= mysql_affected_rows(mysql);
15870  DIE_UNLESS(row_count == (my_ulonglong)-1);
15871 
15872  rc= mysql_query(mysql, update_query);
15873  myquery(rc);
15874  row_count= mysql_affected_rows(mysql);
15875  DIE_UNLESS(row_count == 0);
15876 
15877  rc= mysql_query(mysql, "DELETE FROM t1");
15878  myquery(rc);
15879 
15880  stmt= mysql_stmt_init(mysql);
15881  DIE_UNLESS(stmt != 0);
15882 
15883  rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query));
15884  check_execute(stmt, rc);
15885 
15886  rc= mysql_stmt_execute(stmt);
15887  check_execute(stmt, rc);
15888  row_count= mysql_stmt_affected_rows(stmt);
15889  DIE_UNLESS(row_count == 2);
15890 
15891  rc= mysql_stmt_execute(stmt);
15892  DIE_UNLESS(rc != 0);
15893  row_count= mysql_stmt_affected_rows(stmt);
15894  DIE_UNLESS(row_count == (my_ulonglong)-1);
15895 
15896  rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query));
15897  check_execute(stmt, rc);
15898 
15899  rc= mysql_stmt_execute(stmt);
15900  check_execute(stmt, rc);
15901  row_count= mysql_stmt_affected_rows(stmt);
15902  DIE_UNLESS(row_count == 0);
15903 
15904  rc= mysql_stmt_close(stmt);
15905  check_execute(stmt, rc);
15906 
15907  rc= mysql_query(mysql, "DROP TABLE t1");
15908  myquery(rc);
15909 
15910  DBUG_VOID_RETURN;
15911 }
15912 
15913 
15914 /*
15915  BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for
15916  expression cols
15917 
15918  Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set
15919  to either expression or its alias, and db, org_table, table,
15920  org_name fields are empty strings.
15921 */
15922 static void test_bug21635()
15923 {
15924  const char *expr[]=
15925  {
15926  "MIN(i)", "MIN(i)",
15927  "MIN(i) AS A1", "A1",
15928  "MAX(i)", "MAX(i)",
15929  "MAX(i) AS A2", "A2",
15930  "COUNT(i)", "COUNT(i)",
15931  "COUNT(i) AS A3", "A3",
15932  };
15933  char query[MAX_TEST_QUERY_LENGTH];
15934  char *query_end;
15935  MYSQL_RES *result;
15936  MYSQL_FIELD *field;
15937  unsigned int field_count, i, j;
15938  int rc;
15939 
15940  DBUG_ENTER("test_bug21635");
15941  myheader("test_bug21635");
15942 
15943  query_end= strxmov(query, "SELECT ", NullS);
15944  for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i)
15945  query_end= strxmov(query_end, expr[i * 2], ", ", NullS);
15946  query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS);
15947  DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH);
15948 
15949  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15950  myquery(rc);
15951  rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)");
15952  myquery(rc);
15953  /*
15954  We need this loop to ensure correct behavior with both constant and
15955  non-constant tables.
15956  */
15957  for (j= 0; j < 2 ; j++)
15958  {
15959  rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
15960  myquery(rc);
15961 
15962  rc= mysql_real_query(mysql, query, query_end - query);
15963  myquery(rc);
15964 
15965  result= mysql_use_result(mysql);
15966  DIE_UNLESS(result);
15967 
15968  field_count= mysql_field_count(mysql);
15969  for (i= 0; i < field_count; ++i)
15970  {
15971  field= mysql_fetch_field_direct(result, i);
15972  if (!opt_silent)
15973  if (!opt_silent)
15974  printf("%s -> %s ... ", expr[i * 2], field->name);
15975  fflush(stdout);
15976  DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
15977  field->table[0] == 0 && field->org_name[0] == 0);
15978  DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
15979  if (!opt_silent)
15980  if (!opt_silent)
15981  puts("OK");
15982  }
15983 
15984  mysql_free_result(result);
15985  }
15986  rc= mysql_query(mysql, "DROP TABLE t1");
15987  myquery(rc);
15988 
15989  DBUG_VOID_RETURN;
15990 }
15991 
15992 /*
15993  Bug#24179 "select b into $var" fails with --cursor_protocol"
15994  The failure is correct, check that the returned message is meaningful.
15995 */
15996 
15997 static void test_bug24179()
15998 {
15999  int rc;
16000  MYSQL_STMT *stmt;
16001 
16002  DBUG_ENTER("test_bug24179");
16003  myheader("test_bug24179");
16004 
16005  stmt= open_cursor("select 1 into @a");
16006  rc= mysql_stmt_execute(stmt);
16007  DIE_UNLESS(rc);
16008  if (!opt_silent)
16009  {
16010  printf("Got error (as expected): %d %s\n",
16011  mysql_stmt_errno(stmt),
16012  mysql_stmt_error(stmt));
16013  }
16014  DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
16015  mysql_stmt_close(stmt);
16016 
16017  DBUG_VOID_RETURN;
16018 }
16019 
16020 
16025 static void test_bug32265()
16026 {
16027  int rc;
16028  MYSQL_STMT *stmt;
16029  MYSQL_FIELD *field;
16030  MYSQL_RES *metadata;
16031 
16032  DBUG_ENTER("test_bug32265");
16033  myheader("test_bug32265");
16034 
16035  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16036  myquery(rc);
16037  rc= mysql_query(mysql, "CREATE TABLE t1 (a INTEGER)");
16038  myquery(rc);
16039  rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16040  myquery(rc);
16041  rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
16042  myquery(rc);
16043 
16044  stmt= open_cursor("SELECT * FROM t1");
16045  rc= mysql_stmt_execute(stmt);
16046  check_execute(stmt, rc);
16047 
16048  metadata= mysql_stmt_result_metadata(stmt);
16049  field= mysql_fetch_field(metadata);
16050  DIE_UNLESS(field);
16051  DIE_UNLESS(strcmp(field->table, "t1") == 0);
16052  DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16053  DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16054  mysql_free_result(metadata);
16055  mysql_stmt_close(stmt);
16056 
16057  stmt= open_cursor("SELECT a '' FROM t1 ``");
16058  rc= mysql_stmt_execute(stmt);
16059  check_execute(stmt, rc);
16060 
16061  metadata= mysql_stmt_result_metadata(stmt);
16062  field= mysql_fetch_field(metadata);
16063  DIE_UNLESS(strcmp(field->table, "") == 0);
16064  DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16065  DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16066  mysql_free_result(metadata);
16067  mysql_stmt_close(stmt);
16068 
16069  stmt= open_cursor("SELECT a '' FROM t1 ``");
16070  rc= mysql_stmt_execute(stmt);
16071  check_execute(stmt, rc);
16072 
16073  metadata= mysql_stmt_result_metadata(stmt);
16074  field= mysql_fetch_field(metadata);
16075  DIE_UNLESS(strcmp(field->table, "") == 0);
16076  DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16077  DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16078  mysql_free_result(metadata);
16079  mysql_stmt_close(stmt);
16080 
16081  stmt= open_cursor("SELECT * FROM v1");
16082  rc= mysql_stmt_execute(stmt);
16083  check_execute(stmt, rc);
16084 
16085  metadata= mysql_stmt_result_metadata(stmt);
16086  field= mysql_fetch_field(metadata);
16087  DIE_UNLESS(strcmp(field->table, "v1") == 0);
16088  DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16089  DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16090  mysql_free_result(metadata);
16091  mysql_stmt_close(stmt);
16092 
16093  stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
16094  rc= mysql_stmt_execute(stmt);
16095  check_execute(stmt, rc);
16096 
16097  metadata= mysql_stmt_result_metadata(stmt);
16098  field= mysql_fetch_field(metadata);
16099  DIE_UNLESS(strcmp(field->table, "v1") == 0);
16100  DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16101  DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16102  mysql_free_result(metadata);
16103  mysql_stmt_close(stmt);
16104 
16105  rc= mysql_query(mysql, "DROP VIEW v1");
16106  myquery(rc);
16107  rc= mysql_query(mysql, "DROP TABLE t1");
16108  myquery(rc);
16109 
16110  DBUG_VOID_RETURN;
16111 }
16112 
16113 /*
16114  Bug#28075 "COM_DEBUG crashes mysqld"
16115 */
16116 
16117 static void test_bug28075()
16118 {
16119  int rc;
16120 
16121  DBUG_ENTER("test_bug28075");
16122  myheader("test_bug28075");
16123 
16124  rc= mysql_dump_debug_info(mysql);
16125  DIE_UNLESS(rc == 0);
16126 
16127  rc= mysql_ping(mysql);
16128  DIE_UNLESS(rc == 0);
16129 
16130  DBUG_VOID_RETURN;
16131 }
16132 
16133 
16134 /*
16135  Bug#27876 (SF with cyrillic variable name fails during execution (regression))
16136 */
16137 
16138 static void test_bug27876()
16139 {
16140  int rc;
16141  MYSQL_RES *result;
16142 
16143  uchar utf8_func[] =
16144  {
16145  0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
16146  0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
16147  0xd0, 0xb0,
16148  0x00
16149  };
16150 
16151  uchar utf8_param[] =
16152  {
16153  0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
16154  0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
16155  0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
16156  0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
16157  0x00
16158  };
16159 
16160  char query[500];
16161 
16162  DBUG_ENTER("test_bug27876");
16163  myheader("test_bug27876");
16164 
16165  rc= mysql_query(mysql, "set names utf8");
16166  myquery(rc);
16167 
16168  rc= mysql_query(mysql, "select version()");
16169  myquery(rc);
16170  result= mysql_store_result(mysql);
16171  mytest(result);
16172  mysql_free_result(result);
16173 
16174  sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
16175  rc= mysql_query(mysql, query);
16176  myquery(rc);
16177 
16178  sprintf(query,
16179  "CREATE FUNCTION %s( %s VARCHAR(25))"
16180  " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
16181  (char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
16182  rc= mysql_query(mysql, query);
16183  myquery(rc);
16184  sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
16185  rc= mysql_query(mysql, query);
16186  myquery(rc);
16187  result= mysql_store_result(mysql);
16188  mytest(result);
16189  mysql_free_result(result);
16190 
16191  sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
16192  rc= mysql_query(mysql, query);
16193  myquery(rc);
16194 
16195  rc= mysql_query(mysql, "set names default");
16196  myquery(rc);
16197  DBUG_VOID_RETURN;
16198 }
16199 
16200 
16201 /*
16202  Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
16203  flag is set.
16204 */
16205 
16206 static void test_bug28505()
16207 {
16208  my_ulonglong res;
16209 
16210  myquery(mysql_query(mysql, "drop table if exists t1"));
16211  myquery(mysql_query(mysql, "create table t1(f1 int primary key)"));
16212  myquery(mysql_query(mysql, "insert into t1 values(1)"));
16213  myquery(mysql_query(mysql,
16214  "insert into t1 values(1) on duplicate key update f1=1"));
16215  res= mysql_affected_rows(mysql);
16216  DIE_UNLESS(!res);
16217  myquery(mysql_query(mysql, "drop table t1"));
16218 }
16219 
16220 
16221 /*
16222  Bug#28934: server crash when receiving malformed com_execute packets
16223 */
16224 
16225 static void test_bug28934()
16226 {
16227  my_bool error= 0;
16228  MYSQL_BIND bind[5];
16229  MYSQL_STMT *stmt;
16230  int cnt;
16231 
16232  myquery(mysql_query(mysql, "drop table if exists t1"));
16233  myquery(mysql_query(mysql, "create table t1(id int)"));
16234 
16235  myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)"));
16236  stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)");
16237  check_stmt(stmt);
16238 
16239  memset (&bind, 0, sizeof (bind));
16240  for (cnt= 0; cnt < 5; cnt++)
16241  {
16242  bind[cnt].buffer_type= MYSQL_TYPE_LONG;
16243  bind[cnt].buffer= (char*)&cnt;
16244  bind[cnt].buffer_length= 0;
16245  }
16246  myquery(mysql_stmt_bind_param(stmt, bind));
16247 
16248  stmt->param_count=2;
16249  error= mysql_stmt_execute(stmt);
16250  DIE_UNLESS(error != 0);
16251  myerror(NULL);
16252  mysql_stmt_close(stmt);
16253 
16254  myquery(mysql_query(mysql, "drop table t1"));
16255 }
16256 
16257 /*
16258  Test mysql_change_user() C API and COM_CHANGE_USER
16259 */
16260 
16261 static void reconnect(MYSQL **mysql)
16262 {
16263  mysql_close(*mysql);
16264  *mysql= mysql_client_init(NULL);
16265  DIE_UNLESS(*mysql != 0);
16266  *mysql= mysql_real_connect(*mysql, opt_host, opt_user,
16267  opt_password, current_db, opt_port,
16268  opt_unix_socket, 0);
16269  DIE_UNLESS(*mysql != 0);
16270 }
16271 
16272 
16273 static void test_change_user()
16274 {
16275  char buff[256];
16276  const char *user_pw= "mysqltest_pw";
16277  const char *user_no_pw= "mysqltest_no_pw";
16278  const char *pw= "password";
16279  const char *db= "mysqltest_user_test_database";
16280  int rc;
16281  MYSQL *l_mysql;
16282 
16283  DBUG_ENTER("test_change_user");
16284  myheader("test_change_user");
16285 
16286  l_mysql= mysql_client_init(NULL);
16287  DIE_UNLESS(l_mysql != NULL);
16288 
16289  l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
16290  opt_password, current_db, opt_port,
16291  opt_unix_socket, 0);
16292  DIE_UNLESS(l_mysql != 0);
16293 
16294 
16295  /* Prepare environment */
16296  sprintf(buff, "drop database if exists %s", db);
16297  rc= mysql_query(l_mysql, buff);
16298  myquery2(l_mysql, rc);
16299 
16300  sprintf(buff, "create database %s", db);
16301  rc= mysql_query(l_mysql, buff);
16302  myquery2(l_mysql, rc);
16303 
16304  sprintf(buff,
16305  "grant select on %s.* to %s@'%%' identified by '%s'",
16306  db,
16307  user_pw,
16308  pw);
16309  rc= mysql_query(l_mysql, buff);
16310  myquery2(l_mysql, rc);
16311 
16312  sprintf(buff,
16313  "grant select on %s.* to %s@'localhost' identified by '%s'",
16314  db,
16315  user_pw,
16316  pw);
16317  rc= mysql_query(l_mysql, buff);
16318  myquery2(l_mysql, rc);
16319 
16320  sprintf(buff,
16321  "grant select on %s.* to %s@'%%'",
16322  db,
16323  user_no_pw);
16324  rc= mysql_query(l_mysql, buff);
16325  myquery2(l_mysql, rc);
16326 
16327  sprintf(buff,
16328  "grant select on %s.* to %s@'localhost'",
16329  db,
16330  user_no_pw);
16331  rc= mysql_query(l_mysql, buff);
16332  myquery2(l_mysql, rc);
16333 
16334  /* Try some combinations */
16335  rc= mysql_change_user(l_mysql, NULL, NULL, NULL);
16336  DIE_UNLESS(rc);
16337  if (! opt_silent)
16338  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16339  reconnect(&l_mysql);
16340 
16341  rc= mysql_change_user(l_mysql, "", NULL, NULL);
16342  DIE_UNLESS(rc);
16343  if (! opt_silent)
16344  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16345  reconnect(&l_mysql);
16346 
16347  rc= mysql_change_user(l_mysql, "", "", NULL);
16348  DIE_UNLESS(rc);
16349  if (! opt_silent)
16350  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16351  reconnect(&l_mysql);
16352 
16353 
16354  rc= mysql_change_user(l_mysql, "", "", "");
16355  DIE_UNLESS(rc);
16356  if (! opt_silent)
16357  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16358  reconnect(&l_mysql);
16359 
16360  rc= mysql_change_user(l_mysql, NULL, "", "");
16361  DIE_UNLESS(rc);
16362  if (! opt_silent)
16363  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16364  reconnect(&l_mysql);
16365 
16366 
16367  rc= mysql_change_user(l_mysql, NULL, NULL, "");
16368  DIE_UNLESS(rc);
16369  if (! opt_silent)
16370  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16371  reconnect(&l_mysql);
16372 
16373  rc= mysql_change_user(l_mysql, "", NULL, "");
16374  DIE_UNLESS(rc);
16375  if (! opt_silent)
16376  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16377  reconnect(&l_mysql);
16378 
16379  rc= mysql_change_user(l_mysql, user_pw, NULL, "");
16380  DIE_UNLESS(rc);
16381  if (! opt_silent)
16382  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16383  reconnect(&l_mysql);
16384 
16385  rc= mysql_change_user(l_mysql, user_pw, "", "");
16386  DIE_UNLESS(rc);
16387  if (! opt_silent)
16388  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16389  reconnect(&l_mysql);
16390 
16391  rc= mysql_change_user(l_mysql, user_pw, "", NULL);
16392  DIE_UNLESS(rc);
16393  if (! opt_silent)
16394  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16395  reconnect(&l_mysql);
16396 
16397  rc= mysql_change_user(l_mysql, user_pw, NULL, NULL);
16398  DIE_UNLESS(rc);
16399  if (! opt_silent)
16400  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16401  reconnect(&l_mysql);
16402 
16403  rc= mysql_change_user(l_mysql, user_pw, "", db);
16404  DIE_UNLESS(rc);
16405  if (! opt_silent)
16406  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16407  reconnect(&l_mysql);
16408 
16409  rc= mysql_change_user(l_mysql, user_pw, NULL, db);
16410  DIE_UNLESS(rc);
16411  if (! opt_silent)
16412  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16413  reconnect(&l_mysql);
16414 
16415  rc= mysql_change_user(l_mysql, user_pw, pw, db);
16416  myquery2(l_mysql, rc);
16417 
16418  rc= mysql_change_user(l_mysql, user_pw, pw, NULL);
16419  myquery2(l_mysql, rc);
16420 
16421  rc= mysql_change_user(l_mysql, user_pw, pw, "");
16422  myquery2(l_mysql, rc);
16423 
16424  rc= mysql_change_user(l_mysql, user_no_pw, pw, db);
16425  DIE_UNLESS(rc);
16426  if (! opt_silent)
16427  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16428 
16429  rc= mysql_change_user(l_mysql, user_no_pw, pw, "");
16430  DIE_UNLESS(rc);
16431  if (! opt_silent)
16432  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16433  reconnect(&l_mysql);
16434 
16435  rc= mysql_change_user(l_mysql, user_no_pw, pw, NULL);
16436  DIE_UNLESS(rc);
16437  if (! opt_silent)
16438  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16439  reconnect(&l_mysql);
16440 
16441  rc= mysql_change_user(l_mysql, user_no_pw, "", NULL);
16442  myquery2(l_mysql, rc);
16443 
16444  rc= mysql_change_user(l_mysql, user_no_pw, "", "");
16445  myquery2(l_mysql, rc);
16446 
16447  rc= mysql_change_user(l_mysql, user_no_pw, "", db);
16448  myquery2(l_mysql, rc);
16449 
16450  rc= mysql_change_user(l_mysql, user_no_pw, NULL, db);
16451  myquery2(l_mysql, rc);
16452 
16453  rc= mysql_change_user(l_mysql, "", pw, db);
16454  DIE_UNLESS(rc);
16455  if (! opt_silent)
16456  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16457  reconnect(&l_mysql);
16458 
16459  rc= mysql_change_user(l_mysql, "", pw, "");
16460  DIE_UNLESS(rc);
16461  if (! opt_silent)
16462  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16463  reconnect(&l_mysql);
16464 
16465  rc= mysql_change_user(l_mysql, "", pw, NULL);
16466  DIE_UNLESS(rc);
16467  if (! opt_silent)
16468  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16469 
16470  rc= mysql_change_user(l_mysql, NULL, pw, NULL);
16471  DIE_UNLESS(rc);
16472  if (! opt_silent)
16473  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16474  reconnect(&l_mysql);
16475 
16476  rc= mysql_change_user(l_mysql, NULL, NULL, db);
16477  DIE_UNLESS(rc);
16478  if (! opt_silent)
16479  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16480  reconnect(&l_mysql);
16481 
16482  rc= mysql_change_user(l_mysql, NULL, "", db);
16483  DIE_UNLESS(rc);
16484  if (! opt_silent)
16485  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16486  reconnect(&l_mysql);
16487 
16488  rc= mysql_change_user(l_mysql, "", "", db);
16489  DIE_UNLESS(rc);
16490  if (! opt_silent)
16491  printf("Got error (as expected): %s\n", mysql_error(l_mysql));
16492  reconnect(&l_mysql);
16493 
16494  /* Cleanup the environment */
16495 
16496  mysql_close(l_mysql);
16497 
16498  sprintf(buff, "drop database %s", db);
16499  rc= mysql_query(mysql, buff);
16500  myquery(rc);
16501 
16502  sprintf(buff, "drop user %s@'%%'", user_pw);
16503  rc= mysql_query(mysql, buff);
16504  myquery(rc);
16505 
16506  sprintf(buff, "drop user %s@'%%'", user_no_pw);
16507  rc= mysql_query(mysql, buff);
16508  myquery(rc);
16509 
16510  sprintf(buff, "drop user %s@'localhost'", user_pw);
16511  rc= mysql_query(mysql, buff);
16512  myquery(rc);
16513 
16514  sprintf(buff, "drop user %s@'localhost'", user_no_pw);
16515  rc= mysql_query(mysql, buff);
16516  myquery(rc);
16517 
16518  DBUG_VOID_RETURN;
16519 }
16520 
16521 /*
16522  Bug#27592 (stack overrun when storing datetime value using prepared statements)
16523 */
16524 
16525 static void test_bug27592()
16526 {
16527  const int NUM_ITERATIONS= 40;
16528  int i;
16529  int rc;
16530  MYSQL_STMT *stmt= NULL;
16531  MYSQL_BIND bind[1];
16532  MYSQL_TIME time_val;
16533 
16534  DBUG_ENTER("test_bug27592");
16535  myheader("test_bug27592");
16536 
16537  mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16538  mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
16539 
16540  stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
16541  DIE_UNLESS(stmt);
16542 
16543  memset(bind, 0, sizeof(bind));
16544 
16545  bind[0].buffer_type= MYSQL_TYPE_DATETIME;
16546  bind[0].buffer= (char *) &time_val;
16547  bind[0].length= NULL;
16548 
16549  for (i= 0; i < NUM_ITERATIONS; i++)
16550  {
16551  time_val.year= 2007;
16552  time_val.month= 6;
16553  time_val.day= 7;
16554  time_val.hour= 18;
16555  time_val.minute= 41;
16556  time_val.second= 3;
16557 
16558  time_val.second_part=0;
16559  time_val.neg=0;
16560 
16561  rc= mysql_stmt_bind_param(stmt, bind);
16562  check_execute(stmt, rc);
16563 
16564  rc= mysql_stmt_execute(stmt);
16565  check_execute(stmt, rc);
16566  }
16567 
16568  mysql_stmt_close(stmt);
16569 
16570  DBUG_VOID_RETURN;
16571 }
16572 
16573 /*
16574  Bug#29687 mysql_stmt_store_result memory leak in libmysqld
16575 */
16576 
16577 static void test_bug29687()
16578 {
16579  const int NUM_ITERATIONS= 40;
16580  int i;
16581  int rc;
16582  MYSQL_STMT *stmt= NULL;
16583 
16584  DBUG_ENTER("test_bug29687");
16585  myheader("test_bug29687");
16586 
16587  stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2");
16588  DIE_UNLESS(stmt);
16589 
16590  for (i= 0; i < NUM_ITERATIONS; i++)
16591  {
16592  rc= mysql_stmt_execute(stmt);
16593  check_execute(stmt, rc);
16594  mysql_stmt_store_result(stmt);
16595  while (mysql_stmt_fetch(stmt)==0);
16596  mysql_stmt_free_result(stmt);
16597  }
16598 
16599  mysql_stmt_close(stmt);
16600  DBUG_VOID_RETURN;
16601 }
16602 
16603 
16604 /*
16605  Bug #29692 Single row inserts can incorrectly report a huge number of
16606  row insertions
16607 */
16608 
16609 static void test_bug29692()
16610 {
16611  MYSQL* conn;
16612 
16613  if (!(conn= mysql_client_init(NULL)))
16614  {
16615  myerror("test_bug29692 init failed");
16616  exit(1);
16617  }
16618 
16619  if (!(mysql_real_connect(conn, opt_host, opt_user,
16620  opt_password, opt_db ? opt_db:"test", opt_port,
16621  opt_unix_socket, CLIENT_FOUND_ROWS)))
16622  {
16623  myerror("test_bug29692 connection failed");
16624  mysql_close(mysql);
16625  exit(1);
16626  }
16627  myquery(mysql_query(conn, "drop table if exists t1"));
16628  myquery(mysql_query(conn, "create table t1(f1 int)"));
16629  myquery(mysql_query(conn, "insert into t1 values(1)"));
16630  DIE_UNLESS(1 == mysql_affected_rows(conn));
16631  myquery(mysql_query(conn, "drop table t1"));
16632  mysql_close(conn);
16633 }
16634 
16639 static void test_bug29306()
16640 {
16641  MYSQL_FIELD *field;
16642  int rc;
16643  MYSQL_RES *res;
16644 
16645  DBUG_ENTER("test_bug29306");
16646  myheader("test_bug29306");
16647 
16648  rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
16649  myquery(rc);
16650  rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
16651  myquery(rc);
16652  rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
16653  myquery(rc);
16654  rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
16655  myquery(rc);
16656  rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
16657  myquery(rc);
16658 
16659  /* Checking the view */
16660  res= mysql_list_fields(mysql, "view17557", NULL);
16661  while ((field= mysql_fetch_field(res)))
16662  {
16663  if (! opt_silent)
16664  {
16665  printf("field name %s\n", field->name);
16666  printf("field table %s\n", field->table);
16667  printf("field decimals %d\n", field->decimals);
16668  if (field->decimals < 1)
16669  printf("Error! No decimals! \n");
16670  printf("\n\n");
16671  }
16672  DIE_UNLESS(field->decimals == 1);
16673  }
16674  mysql_free_result(res);
16675 
16676  rc= mysql_query(mysql, "DROP TABLE tab17557");
16677  myquery(rc);
16678  rc= mysql_query(mysql, "DROP VIEW view17557");
16679  myquery(rc);
16680 
16681  DBUG_VOID_RETURN;
16682 }
16683 /*
16684  Bug#30472: libmysql doesn't reset charset, insert_id after succ.
16685  mysql_change_user() call row insertions.
16686 */
16687 
16688 static void bug30472_retrieve_charset_info(MYSQL *con,
16689  char *character_set_name,
16690  char *character_set_client,
16691  char *character_set_results,
16692  char *collation_connection)
16693 {
16694  MYSQL_RES *rs;
16695  MYSQL_ROW row;
16696 
16697  /* Get the cached client character set name. */
16698 
16699  strcpy(character_set_name, mysql_character_set_name(con));
16700 
16701  /* Retrieve server character set information. */
16702 
16703  DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
16704  DIE_UNLESS(rs= mysql_store_result(con));
16705  DIE_UNLESS(row= mysql_fetch_row(rs));
16706  strcpy(character_set_client, row[1]);
16707  mysql_free_result(rs);
16708 
16709  DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
16710  DIE_UNLESS(rs= mysql_store_result(con));
16711  DIE_UNLESS(row= mysql_fetch_row(rs));
16712  strcpy(character_set_results, row[1]);
16713  mysql_free_result(rs);
16714 
16715  DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
16716  DIE_UNLESS(rs= mysql_store_result(con));
16717  DIE_UNLESS(row= mysql_fetch_row(rs));
16718  strcpy(collation_connection, row[1]);
16719  mysql_free_result(rs);
16720 }
16721 
16722 static void test_bug30472()
16723 {
16724  MYSQL con;
16725 
16726  char character_set_name_1[MY_CS_NAME_SIZE];
16727  char character_set_client_1[MY_CS_NAME_SIZE];
16728  char character_set_results_1[MY_CS_NAME_SIZE];
16729  char collation_connnection_1[MY_CS_NAME_SIZE];
16730 
16731  char character_set_name_2[MY_CS_NAME_SIZE];
16732  char character_set_client_2[MY_CS_NAME_SIZE];
16733  char character_set_results_2[MY_CS_NAME_SIZE];
16734  char collation_connnection_2[MY_CS_NAME_SIZE];
16735 
16736  char character_set_name_3[MY_CS_NAME_SIZE];
16737  char character_set_client_3[MY_CS_NAME_SIZE];
16738  char character_set_results_3[MY_CS_NAME_SIZE];
16739  char collation_connnection_3[MY_CS_NAME_SIZE];
16740 
16741  char character_set_name_4[MY_CS_NAME_SIZE];
16742  char character_set_client_4[MY_CS_NAME_SIZE];
16743  char character_set_results_4[MY_CS_NAME_SIZE];
16744  char collation_connnection_4[MY_CS_NAME_SIZE];
16745 
16746  /* Create a new connection. */
16747 
16748  DIE_UNLESS(mysql_client_init(&con));
16749 
16750  DIE_UNLESS(mysql_real_connect(&con,
16751  opt_host,
16752  opt_user,
16753  opt_password,
16754  opt_db ? opt_db : "test",
16755  opt_port,
16756  opt_unix_socket,
16757  CLIENT_FOUND_ROWS));
16758 
16759  /* Retrieve character set information. */
16760 
16761  bug30472_retrieve_charset_info(&con,
16762  character_set_name_1,
16763  character_set_client_1,
16764  character_set_results_1,
16765  collation_connnection_1);
16766 
16767  /* Switch client character set. */
16768 
16769  DIE_IF(mysql_set_character_set(&con, "utf8"));
16770 
16771  /* Retrieve character set information. */
16772 
16773  bug30472_retrieve_charset_info(&con,
16774  character_set_name_2,
16775  character_set_client_2,
16776  character_set_results_2,
16777  collation_connnection_2);
16778 
16779  /*
16780  Check that
16781  1) character set has been switched and
16782  2) new character set is different from the original one.
16783  */
16784 
16785  DIE_UNLESS(strcmp(character_set_name_2, "utf8") == 0);
16786  DIE_UNLESS(strcmp(character_set_client_2, "utf8") == 0);
16787  DIE_UNLESS(strcmp(character_set_results_2, "utf8") == 0);
16788  DIE_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0);
16789 
16790  DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
16791  DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
16792  DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
16793  DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
16794 
16795  /* Call mysql_change_user() with the same username, password, database. */
16796 
16797  DIE_IF(mysql_change_user(&con,
16798  opt_user,
16799  opt_password,
16800  opt_db ? opt_db : "test"));
16801 
16802  /* Retrieve character set information. */
16803 
16804  bug30472_retrieve_charset_info(&con,
16805  character_set_name_3,
16806  character_set_client_3,
16807  character_set_results_3,
16808  collation_connnection_3);
16809 
16810  /* Check that character set information has been reset. */
16811 
16812  DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
16813  DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
16814  DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
16815  DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
16816 
16817  /* Change connection-default character set in the client. */
16818 
16819  mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8");
16820 
16821  /*
16822  Call mysql_change_user() in order to check that new connection will
16823  have UTF8 character set on the client and on the server.
16824  */
16825 
16826  DIE_IF(mysql_change_user(&con,
16827  opt_user,
16828  opt_password,
16829  opt_db ? opt_db : "test"));
16830 
16831  /* Retrieve character set information. */
16832 
16833  bug30472_retrieve_charset_info(&con,
16834  character_set_name_4,
16835  character_set_client_4,
16836  character_set_results_4,
16837  collation_connnection_4);
16838 
16839  /* Check that we have UTF8 on the server and on the client. */
16840 
16841  DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
16842  DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
16843  DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
16844  DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
16845 
16846  /* That's it. Cleanup. */
16847 
16848  mysql_close(&con);
16849 }
16850 
16851 static void bug20023_change_user(MYSQL *con)
16852 {
16853  DIE_IF(mysql_change_user(con,
16854  opt_user,
16855  opt_password,
16856  opt_db ? opt_db : "test"));
16857 }
16858 
16859 static my_bool query_str_variable(MYSQL *con,
16860  const char *var_name,
16861  char *str,
16862  size_t len)
16863 {
16864  MYSQL_RES *rs;
16865  MYSQL_ROW row;
16866 
16867  char query_buffer[MAX_TEST_QUERY_LENGTH];
16868 
16869  my_bool is_null;
16870 
16871  my_snprintf(query_buffer, sizeof (query_buffer),
16872  "SELECT %s", var_name);
16873 
16874  DIE_IF(mysql_query(con, query_buffer));
16875  DIE_UNLESS(rs= mysql_store_result(con));
16876  DIE_UNLESS(row= mysql_fetch_row(rs));
16877 
16878  is_null= row[0] == NULL;
16879 
16880  if (!is_null)
16881  my_snprintf(str, len, "%s", row[0]);
16882 
16883  mysql_free_result(rs);
16884 
16885  return is_null;
16886 }
16887 
16888 static my_bool query_int_variable(MYSQL *con,
16889  const char *var_name,
16890  int *var_value)
16891 {
16892  char str[32];
16893  my_bool is_null= query_str_variable(con, var_name, str, sizeof(str));
16894 
16895  if (!is_null)
16896  *var_value= atoi(str);
16897 
16898  return is_null;
16899 }
16900 
16901 static void test_bug20023()
16902 {
16903  MYSQL con;
16904 
16905  int sql_big_selects_orig= 0;
16906  /*
16907  Type of max_join_size is ha_rows, which might be ulong or off_t
16908  depending on the platform or configure options. Preserve the string
16909  to avoid type overflow pitfalls.
16910  */
16911  char max_join_size_orig[32];
16912 
16913  int sql_big_selects_2= 0;
16914  int sql_big_selects_3= 0;
16915  int sql_big_selects_4= 0;
16916  int sql_big_selects_5= 0;
16917 
16918  char query_buffer[MAX_TEST_QUERY_LENGTH];
16919 
16920  /* Create a new connection. */
16921 
16922  DIE_UNLESS(mysql_client_init(&con));
16923 
16924  DIE_UNLESS(mysql_real_connect(&con,
16925  opt_host,
16926  opt_user,
16927  opt_password,
16928  opt_db ? opt_db : "test",
16929  opt_port,
16930  opt_unix_socket,
16931  CLIENT_FOUND_ROWS));
16932 
16933  /***********************************************************************
16934  Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
16935  ***********************************************************************/
16936 
16937  query_int_variable(&con,
16938  "@@session.sql_big_selects",
16939  &sql_big_selects_orig);
16940 
16941  query_str_variable(&con,
16942  "@@global.max_join_size",
16943  max_join_size_orig,
16944  sizeof(max_join_size_orig));
16945 
16946  /***********************************************************************
16947  Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
16948  ***********************************************************************/
16949 
16950  /* Issue COM_CHANGE_USER. */
16951 
16952  bug20023_change_user(&con);
16953 
16954  /* Query SQL_BIG_SELECTS. */
16955 
16956  query_int_variable(&con,
16957  "@@session.sql_big_selects",
16958  &sql_big_selects_2);
16959 
16960  /* Check that SQL_BIG_SELECTS is reset properly. */
16961 
16962  DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2);
16963 
16964  /***********************************************************************
16965  Test that if MAX_JOIN_SIZE set to non-default value,
16966  SQL_BIG_SELECTS will be 0.
16967  ***********************************************************************/
16968 
16969  /* Set MAX_JOIN_SIZE to some non-default value. */
16970 
16971  DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000"));
16972  DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
16973 
16974  /* Issue COM_CHANGE_USER. */
16975 
16976  bug20023_change_user(&con);
16977 
16978  /* Query SQL_BIG_SELECTS. */
16979 
16980  query_int_variable(&con,
16981  "@@session.sql_big_selects",
16982  &sql_big_selects_3);
16983 
16984  /* Check that SQL_BIG_SELECTS is 0. */
16985 
16986  DIE_UNLESS(sql_big_selects_3 == 0);
16987 
16988  /***********************************************************************
16989  Test that if MAX_JOIN_SIZE set to default value,
16990  SQL_BIG_SELECTS will be 1.
16991  ***********************************************************************/
16992 
16993  /* Set MAX_JOIN_SIZE to the default value (2^64-1). */
16994 
16995  DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
16996  DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
16997 
16998  /* Issue COM_CHANGE_USER. */
16999 
17000  bug20023_change_user(&con);
17001 
17002  /* Query SQL_BIG_SELECTS. */
17003 
17004  query_int_variable(&con,
17005  "@@session.sql_big_selects",
17006  &sql_big_selects_4);
17007 
17008  /* Check that SQL_BIG_SELECTS is 1. */
17009 
17010  DIE_UNLESS(sql_big_selects_4 == 1);
17011 
17012  /***********************************************************************
17013  Restore MAX_JOIN_SIZE.
17014  Check that SQL_BIG_SELECTS will be the original one.
17015  ***********************************************************************/
17016 
17017  /* Restore MAX_JOIN_SIZE. */
17018 
17019  my_snprintf(query_buffer,
17020  sizeof (query_buffer),
17021  "SET @@global.max_join_size = %s",
17022  max_join_size_orig);
17023 
17024  DIE_IF(mysql_query(&con, query_buffer));
17025 
17026  DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17027  DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17028 
17029  /* Issue COM_CHANGE_USER. */
17030 
17031  bug20023_change_user(&con);
17032 
17033  /* Query SQL_BIG_SELECTS. */
17034 
17035  query_int_variable(&con,
17036  "@@session.sql_big_selects",
17037  &sql_big_selects_5);
17038 
17039  /* Check that SQL_BIG_SELECTS is 1. */
17040 
17041  DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig);
17042 
17043  /***********************************************************************
17044  That's it. Cleanup.
17045  ***********************************************************************/
17046 
17047  mysql_close(&con);
17048 }
17049 
17050 static void bug31418_impl()
17051 {
17052  MYSQL con;
17053 
17054  my_bool is_null;
17055  int rc= 0;
17056 
17057  /* Create a new connection. */
17058 
17059  DIE_UNLESS(mysql_client_init(&con));
17060 
17061  DIE_UNLESS(mysql_real_connect(&con,
17062  opt_host,
17063  opt_user,
17064  opt_password,
17065  opt_db ? opt_db : "test",
17066  opt_port,
17067  opt_unix_socket,
17068  CLIENT_FOUND_ROWS));
17069 
17070  /***********************************************************************
17071  Check that lock is free:
17072  - IS_FREE_LOCK() should return 1;
17073  - IS_USED_LOCK() should return NULL;
17074  ***********************************************************************/
17075 
17076  is_null= query_int_variable(&con,
17077  "IS_FREE_LOCK('bug31418')",
17078  &rc);
17079  DIE_UNLESS(!is_null && rc);
17080 
17081  is_null= query_int_variable(&con,
17082  "IS_USED_LOCK('bug31418')",
17083  &rc);
17084  DIE_UNLESS(is_null);
17085 
17086  /***********************************************************************
17087  Acquire lock and check the lock status (the lock must be in use):
17088  - IS_FREE_LOCK() should return 0;
17089  - IS_USED_LOCK() should return non-zero thread id;
17090  ***********************************************************************/
17091 
17092  query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
17093  DIE_UNLESS(rc);
17094 
17095  is_null= query_int_variable(&con,
17096  "IS_FREE_LOCK('bug31418')",
17097  &rc);
17098  DIE_UNLESS(!is_null && !rc);
17099 
17100  is_null= query_int_variable(&con,
17101  "IS_USED_LOCK('bug31418')",
17102  &rc);
17103  DIE_UNLESS(!is_null && rc);
17104 
17105  /***********************************************************************
17106  Issue COM_CHANGE_USER command and check the lock status
17107  (the lock must be free):
17108  - IS_FREE_LOCK() should return 1;
17109  - IS_USED_LOCK() should return NULL;
17110  **********************************************************************/
17111 
17112  bug20023_change_user(&con);
17113 
17114  is_null= query_int_variable(&con,
17115  "IS_FREE_LOCK('bug31418')",
17116  &rc);
17117  DIE_UNLESS(!is_null && rc);
17118 
17119  is_null= query_int_variable(&con,
17120  "IS_USED_LOCK('bug31418')",
17121  &rc);
17122  DIE_UNLESS(is_null);
17123 
17124  /***********************************************************************
17125  That's it. Cleanup.
17126  ***********************************************************************/
17127 
17128  mysql_close(&con);
17129 }
17130 
17131 static void test_bug31418()
17132 {
17133  /* Run test case for BUG#31418 for three different connections. */
17134 
17135  bug31418_impl();
17136 
17137  bug31418_impl();
17138 
17139  bug31418_impl();
17140 }
17141 
17142 
17143 
17148 #define LARGE_BUFFER_SIZE 2048
17149 
17150 static void test_bug31669()
17151 {
17152  int rc;
17153  static char buff[LARGE_BUFFER_SIZE+1];
17154 #ifndef EMBEDDED_LIBRARY
17155  static char user[USERNAME_CHAR_LENGTH+1];
17156  static char db[NAME_CHAR_LEN+1];
17157  static char query[LARGE_BUFFER_SIZE*2];
17158 #endif
17159  MYSQL *l_mysql;
17160 
17161 
17162  DBUG_ENTER("test_bug31669");
17163  myheader("test_bug31669");
17164 
17165  l_mysql= mysql_client_init(NULL);
17166  DIE_UNLESS(l_mysql != NULL);
17167 
17168  l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
17169  opt_password, current_db, opt_port,
17170  opt_unix_socket, 0);
17171  DIE_UNLESS(l_mysql != 0);
17172 
17173 
17174  rc= mysql_change_user(l_mysql, NULL, NULL, NULL);
17175  DIE_UNLESS(rc);
17176 
17177  reconnect(&l_mysql);
17178 
17179  rc= mysql_change_user(l_mysql, "", "", "");
17180  DIE_UNLESS(rc);
17181  reconnect(&l_mysql);
17182 
17183  memset(buff, 'a', sizeof(buff));
17184  buff[sizeof(buff) - 1] = '\0';
17185 
17186  rc= mysql_change_user(l_mysql, buff, buff, buff);
17187  DIE_UNLESS(rc);
17188  reconnect(&l_mysql);
17189 
17190  rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
17191  DIE_UNLESS(!rc);
17192 
17193 #ifndef EMBEDDED_LIBRARY
17194  memset(db, 'a', sizeof(db));
17195  db[NAME_CHAR_LEN]= 0;
17196  strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
17197  rc= mysql_query(mysql, query);
17198  myquery(rc);
17199 
17200  memset(user, 'b', sizeof(user));
17201  user[USERNAME_CHAR_LENGTH]= 0;
17202  memset(buff, 'c', sizeof(buff));
17203  buff[LARGE_BUFFER_SIZE]= 0;
17204  strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
17205  "'", buff, "' WITH GRANT OPTION", NullS);
17206  rc= mysql_query(mysql, query);
17207  myquery(rc);
17208 
17209  strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY "
17210  "'", buff, "' WITH GRANT OPTION", NullS);
17211  rc= mysql_query(mysql, query);
17212  myquery(rc);
17213 
17214  rc= mysql_query(mysql, "FLUSH PRIVILEGES");
17215  myquery(rc);
17216 
17217  rc= mysql_change_user(l_mysql, user, buff, db);
17218  DIE_UNLESS(!rc);
17219 
17220  user[USERNAME_CHAR_LENGTH-1]= 'a';
17221  rc= mysql_change_user(l_mysql, user, buff, db);
17222  DIE_UNLESS(rc);
17223  reconnect(&l_mysql);
17224 
17225  user[USERNAME_CHAR_LENGTH-1]= 'b';
17226  buff[LARGE_BUFFER_SIZE-1]= 'd';
17227  rc= mysql_change_user(l_mysql, user, buff, db);
17228  DIE_UNLESS(rc);
17229  reconnect(&l_mysql);
17230 
17231  buff[LARGE_BUFFER_SIZE-1]= 'c';
17232  db[NAME_CHAR_LEN-1]= 'e';
17233  rc= mysql_change_user(l_mysql, user, buff, db);
17234  DIE_UNLESS(rc);
17235  reconnect(&l_mysql);
17236 
17237  db[NAME_CHAR_LEN-1]= 'a';
17238  rc= mysql_change_user(l_mysql, user, buff, db);
17239  DIE_UNLESS(!rc);
17240 
17241  rc= mysql_change_user(l_mysql, user + 1, buff + 1, db + 1);
17242  DIE_UNLESS(rc);
17243  reconnect(&l_mysql);
17244 
17245  rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
17246  DIE_UNLESS(!rc);
17247 
17248  strxmov(query, "DROP DATABASE ", db, NullS);
17249  rc= mysql_query(mysql, query);
17250  myquery(rc);
17251 
17252  strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
17253  rc= mysql_query(mysql, query);
17254  myquery(rc);
17255  DIE_UNLESS(mysql_affected_rows(mysql) == 2);
17256 
17257  mysql_close(l_mysql);
17258 #endif
17259 
17260  DBUG_VOID_RETURN;
17261 }
17262 
17263 
17268 static void test_bug28386()
17269 {
17270  int rc;
17271  MYSQL_STMT *stmt;
17272  MYSQL_RES *result;
17273  MYSQL_ROW row;
17274  MYSQL_BIND bind;
17275  const char hello[]= "hello world!";
17276 
17277  DBUG_ENTER("test_bug28386");
17278  myheader("test_bug28386");
17279 
17280  rc= mysql_query(mysql, "select @@global.log_output");
17281  myquery(rc);
17282 
17283  result= mysql_store_result(mysql);
17284  DIE_UNLESS(result);
17285 
17286  row= mysql_fetch_row(result);
17287  if (! strstr(row[0], "TABLE"))
17288  {
17289  mysql_free_result(result);
17290  if (! opt_silent)
17291  printf("Skipping the test since logging to tables is not enabled\n");
17292  /* Log output is not to tables */
17293  return;
17294  }
17295  mysql_free_result(result);
17296 
17297  enable_query_logs(1);
17298 
17299  stmt= mysql_simple_prepare(mysql, "SELECT ?");
17300  check_stmt(stmt);
17301 
17302  memset(&bind, 0, sizeof(bind));
17303 
17304  bind.buffer_type= MYSQL_TYPE_STRING;
17305  bind.buffer= (void *) hello;
17306  bind.buffer_length= sizeof(hello);
17307 
17308  mysql_stmt_bind_param(stmt, &bind);
17309  mysql_stmt_send_long_data(stmt, 0, hello, sizeof(hello));
17310 
17311  rc= mysql_stmt_execute(stmt);
17312  check_execute(stmt, rc);
17313 
17314  rc= my_process_stmt_result(stmt);
17315  DIE_UNLESS(rc == 1);
17316 
17317  rc= mysql_stmt_reset(stmt);
17318  check_execute(stmt, rc);
17319 
17320  rc= mysql_stmt_close(stmt);
17321  DIE_UNLESS(!rc);
17322 
17323  rc= mysql_query(mysql, "select * from mysql.general_log where "
17324  "command_type='Close stmt' or "
17325  "command_type='Reset stmt' or "
17326  "command_type='Long Data'");
17327  myquery(rc);
17328 
17329  result= mysql_store_result(mysql);
17330  mytest(result);
17331 
17332  DIE_UNLESS(mysql_num_rows(result) == 3);
17333 
17334  mysql_free_result(result);
17335 
17336  restore_query_logs();
17337 
17338  DBUG_VOID_RETURN;
17339 }
17340 
17341 
17342 static void test_wl4166_1()
17343 {
17344  MYSQL_STMT *stmt;
17345  int int_data;
17346  char str_data[50];
17347  char tiny_data;
17348  short small_data;
17349  longlong big_data;
17350  float real_data;
17351  double double_data;
17352  ulong length[7];
17353  my_bool is_null[7];
17354  MYSQL_BIND my_bind[7];
17355  int rc;
17356  int i;
17357 
17358  myheader("test_wl4166_1");
17359 
17360  rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
17361  myquery(rc);
17362 
17363  rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
17364  "col2 varchar(15), col3 int, "
17365  "col4 smallint, col5 bigint, "
17366  "col6 float, col7 double, "
17367  "colX varchar(10) default NULL)");
17368  myquery(rc);
17369 
17370  stmt= mysql_simple_prepare(mysql,
17371  "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
17372  "VALUES(?, ?, ?, ?, ?, ?, ?)");
17373  check_stmt(stmt);
17374 
17375  verify_param_count(stmt, 7);
17376 
17377  memset(my_bind, 0, sizeof(my_bind));
17378  /* tinyint */
17379  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
17380  my_bind[0].buffer= (void *)&tiny_data;
17381  /* string */
17382  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
17383  my_bind[1].buffer= (void *)str_data;
17384  my_bind[1].buffer_length= 1000; /* Max string length */
17385  /* integer */
17386  my_bind[2].buffer_type= MYSQL_TYPE_LONG;
17387  my_bind[2].buffer= (void *)&int_data;
17388  /* short */
17389  my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
17390  my_bind[3].buffer= (void *)&small_data;
17391  /* bigint */
17392  my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
17393  my_bind[4].buffer= (void *)&big_data;
17394  /* float */
17395  my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
17396  my_bind[5].buffer= (void *)&real_data;
17397  /* double */
17398  my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
17399  my_bind[6].buffer= (void *)&double_data;
17400 
17401  for (i= 0; i < (int) array_elements(my_bind); i++)
17402  {
17403  my_bind[i].length= &length[i];
17404  my_bind[i].is_null= &is_null[i];
17405  is_null[i]= 0;
17406  }
17407 
17408  rc= mysql_stmt_bind_param(stmt, my_bind);
17409  check_execute(stmt, rc);
17410 
17411  int_data= 320;
17412  small_data= 1867;
17413  big_data= 1000;
17414  real_data= 2;
17415  double_data= 6578.001;
17416 
17417  /* now, execute the prepared statement to insert 10 records.. */
17418  for (tiny_data= 0; tiny_data < 10; tiny_data++)
17419  {
17420  length[1]= sprintf(str_data, "MySQL%d", int_data);
17421  rc= mysql_stmt_execute(stmt);
17422  check_execute(stmt, rc);
17423  int_data += 25;
17424  small_data += 10;
17425  big_data += 100;
17426  real_data += 1;
17427  double_data += 10.09;
17428  }
17429 
17430  /* force a re-prepare with some DDL */
17431 
17432  rc= mysql_query(mysql,
17433  "ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
17434  myquery(rc);
17435 
17436  /*
17437  execute the prepared statement again,
17438  without changing the types of parameters already bound.
17439  */
17440 
17441  for (tiny_data= 50; tiny_data < 60; tiny_data++)
17442  {
17443  length[1]= sprintf(str_data, "MySQL%d", int_data);
17444  rc= mysql_stmt_execute(stmt);
17445  check_execute(stmt, rc);
17446  int_data += 25;
17447  small_data += 10;
17448  big_data += 100;
17449  real_data += 1;
17450  double_data += 10.09;
17451  }
17452 
17453  mysql_stmt_close(stmt);
17454 
17455  rc= mysql_query(mysql, "DROP TABLE table_4166");
17456  myquery(rc);
17457 }
17458 
17459 
17460 static void test_wl4166_2()
17461 {
17462  MYSQL_STMT *stmt;
17463  int c_int;
17464  MYSQL_TIME d_date;
17465  MYSQL_BIND bind_out[2];
17466  int rc;
17467 
17468  myheader("test_wl4166_2");
17469 
17470  rc= mysql_query(mysql, "SET SQL_MODE=''");
17471  myquery(rc);
17472 
17473  rc= mysql_query(mysql, "drop table if exists t1");
17474  myquery(rc);
17475  rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
17476  myquery(rc);
17477  rc= mysql_query(mysql,
17478  "insert into t1 (c_int, d_date) values (42, '1948-05-15')");
17479  myquery(rc);
17480 
17481  stmt= mysql_simple_prepare(mysql, "select * from t1");
17482  check_stmt(stmt);
17483 
17484  memset(bind_out, 0, sizeof(bind_out));
17485  bind_out[0].buffer_type= MYSQL_TYPE_LONG;
17486  bind_out[0].buffer= (void*) &c_int;
17487 
17488  bind_out[1].buffer_type= MYSQL_TYPE_DATE;
17489  bind_out[1].buffer= (void*) &d_date;
17490 
17491  rc= mysql_stmt_bind_result(stmt, bind_out);
17492  check_execute(stmt, rc);
17493 
17494  /* int -> varchar transition */
17495 
17496  rc= mysql_query(mysql,
17497  "alter table t1 change column c_int c_int varchar(11)");
17498  myquery(rc);
17499 
17500  rc= mysql_stmt_execute(stmt);
17501  check_execute(stmt, rc);
17502 
17503  rc= mysql_stmt_fetch(stmt);
17504  check_execute(stmt, rc);
17505 
17506  DIE_UNLESS(c_int == 42);
17507  DIE_UNLESS(d_date.year == 1948);
17508  DIE_UNLESS(d_date.month == 5);
17509  DIE_UNLESS(d_date.day == 15);
17510 
17511  rc= mysql_stmt_fetch(stmt);
17512  DIE_UNLESS(rc == MYSQL_NO_DATA);
17513 
17514  /* varchar to int retrieval with truncation */
17515 
17516  rc= mysql_query(mysql, "update t1 set c_int='abcde'");
17517  myquery(rc);
17518 
17519  rc= mysql_stmt_execute(stmt);
17520  check_execute(stmt, rc);
17521 
17522  rc= mysql_stmt_fetch(stmt);
17523  check_execute_r(stmt, rc);
17524 
17525  DIE_UNLESS(c_int == 0);
17526 
17527  rc= mysql_stmt_fetch(stmt);
17528  DIE_UNLESS(rc == MYSQL_NO_DATA);
17529 
17530  /* alter table and increase the number of columns */
17531  rc= mysql_query(mysql, "alter table t1 add column d_int int");
17532  myquery(rc);
17533 
17534  rc= mysql_stmt_execute(stmt);
17535  check_execute_r(stmt, rc);
17536 
17537  rc= mysql_stmt_reset(stmt);
17538  check_execute(stmt, rc);
17539 
17540  /* decrease the number of columns */
17541  rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
17542  myquery(rc);
17543 
17544  rc= mysql_stmt_execute(stmt);
17545  check_execute_r(stmt, rc);
17546 
17547  mysql_stmt_close(stmt);
17548  rc= mysql_query(mysql, "drop table t1");
17549  myquery(rc);
17550 
17551 }
17552 
17553 
17559 static void test_wl4166_3()
17560 {
17561  int rc;
17562  MYSQL_STMT *stmt;
17563  MYSQL_BIND my_bind[1];
17564  MYSQL_TIME tm[1];
17565 
17566  myheader("test_wl4166_3");
17567 
17568  rc= mysql_query(mysql, "drop table if exists t1");
17569  myquery(rc);
17570 
17571  rc= mysql_query(mysql, "create table t1 (year datetime)");
17572  myquery(rc);
17573 
17574  stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)");
17575  check_stmt(stmt);
17576  verify_param_count(stmt, 1);
17577 
17578  memset(my_bind, 0, sizeof(my_bind));
17579  my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17580  my_bind[0].buffer= &tm[0];
17581 
17582  rc= mysql_stmt_bind_param(stmt, my_bind);
17583  check_execute(stmt, rc);
17584 
17585  tm[0].year= 10000;
17586  tm[0].month= 1; tm[0].day= 1;
17587  tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
17588  tm[0].second_part= 0; tm[0].neg= 0;
17589 
17590  /* Cause a statement reprepare */
17591  rc= mysql_query(mysql, "alter table t1 add column c int");
17592  myquery(rc);
17593 
17594  rc= mysql_stmt_execute(stmt);
17595  check_execute(stmt, rc);
17596  /*
17597  Sic: only one warning, instead of two. The warning
17598  about data truncation when assigning a parameter is lost.
17599  This is a bug.
17600  */
17601  my_process_warnings(mysql, 1);
17602 
17603  verify_col_data("t1", "year", "0000-00-00 00:00:00");
17604 
17605  mysql_stmt_close(stmt);
17606 
17607  rc= mysql_query(mysql, "drop table t1");
17608  myquery(rc);
17609 }
17610 
17611 
17618 static void test_wl4166_4()
17619 {
17620  MYSQL_STMT *stmt;
17621  int rc;
17622  const char *stmt_text;
17623  MYSQL_BIND bind_array[2];
17624 
17625  /* Represented as numbers to keep UTF8 tools from clobbering them. */
17626  const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
17627  const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
17628  char buf1[16], buf2[16];
17629  ulong buf1_len, buf2_len;
17630 
17631  myheader("test_wl4166_4");
17632 
17633  rc= mysql_query(mysql, "drop table if exists t1");
17634  myquery(rc);
17635 
17636  /*
17637  Create table with binary columns, set session character set to cp1251,
17638  client character set to koi8, and make sure that there is conversion
17639  on insert and no conversion on select
17640  */
17641  rc= mysql_query(mysql,
17642  "create table t1 (c1 varbinary(255), c2 varbinary(255))");
17643  myquery(rc);
17644  rc= mysql_query(mysql, "set character_set_client=koi8r, "
17645  "character_set_connection=cp1251, "
17646  "character_set_results=koi8r");
17647  myquery(rc);
17648 
17649  memset(bind_array, 0, sizeof(bind_array));
17650 
17651  bind_array[0].buffer_type= MYSQL_TYPE_STRING;
17652 
17653  bind_array[1].buffer_type= MYSQL_TYPE_STRING;
17654  bind_array[1].buffer= (void *) koi8;
17655  bind_array[1].buffer_length= strlen(koi8);
17656 
17657  stmt= mysql_stmt_init(mysql);
17658  check_stmt(stmt);
17659 
17660  stmt_text= "insert into t1 (c1, c2) values (?, ?)";
17661 
17662  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17663  check_execute(stmt, rc);
17664 
17665  mysql_stmt_bind_param(stmt, bind_array);
17666 
17667  mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
17668 
17669  /* Cause a reprepare at statement execute */
17670  rc= mysql_query(mysql, "alter table t1 add column d int");
17671  myquery(rc);
17672 
17673  rc= mysql_stmt_execute(stmt);
17674  check_execute(stmt, rc);
17675 
17676  stmt_text= "select c1, c2 from t1";
17677 
17678  /* c1 and c2 are binary so no conversion will be done on select */
17679  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17680  check_execute(stmt, rc);
17681 
17682  rc= mysql_stmt_execute(stmt);
17683  check_execute(stmt, rc);
17684 
17685  bind_array[0].buffer= buf1;
17686  bind_array[0].buffer_length= sizeof(buf1);
17687  bind_array[0].length= &buf1_len;
17688 
17689  bind_array[1].buffer= buf2;
17690  bind_array[1].buffer_length= sizeof(buf2);
17691  bind_array[1].length= &buf2_len;
17692 
17693  mysql_stmt_bind_result(stmt, bind_array);
17694 
17695  rc= mysql_stmt_fetch(stmt);
17696  check_execute(stmt, rc);
17697 
17698  DIE_UNLESS(buf1_len == strlen(cp1251));
17699  DIE_UNLESS(buf2_len == strlen(cp1251));
17700  DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
17701  DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
17702 
17703  rc= mysql_stmt_fetch(stmt);
17704  DIE_UNLESS(rc == MYSQL_NO_DATA);
17705 
17706  mysql_stmt_close(stmt);
17707 
17708  rc= mysql_query(mysql, "drop table t1");
17709  myquery(rc);
17710  rc= mysql_query(mysql, "set names default");
17711  myquery(rc);
17712 }
17713 
17718 static void test_bug36004()
17719 {
17720  int rc, warning_count= 0;
17721  MYSQL_STMT *stmt;
17722 
17723  DBUG_ENTER("test_bug36004");
17724  myheader("test_bug36004");
17725 
17726  rc= mysql_query(mysql, "drop table if exists inexistant");
17727  myquery(rc);
17728 
17729  DIE_UNLESS(mysql_warning_count(mysql) == 1);
17730  query_int_variable(mysql, "@@warning_count", &warning_count);
17731  DIE_UNLESS(warning_count);
17732 
17733  stmt= mysql_simple_prepare(mysql, "select 1");
17734  check_stmt(stmt);
17735 
17736  DIE_UNLESS(mysql_warning_count(mysql) == 0);
17737  query_int_variable(mysql, "@@warning_count", &warning_count);
17738  DIE_UNLESS(warning_count);
17739 
17740  rc= mysql_stmt_execute(stmt);
17741  check_execute(stmt, rc);
17742 
17743  DIE_UNLESS(mysql_warning_count(mysql) == 0);
17744  mysql_stmt_close(stmt);
17745 
17746  query_int_variable(mysql, "@@warning_count", &warning_count);
17747  DIE_UNLESS(warning_count);
17748 
17749  stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
17750  check_stmt(stmt);
17751 
17752  query_int_variable(mysql, "@@warning_count", &warning_count);
17753  DIE_UNLESS(warning_count == 0);
17754  mysql_stmt_close(stmt);
17755 
17756  DBUG_VOID_RETURN;
17757 }
17758 
17763 static void test_wl4284_1()
17764 {
17765  int rc;
17766  MYSQL_ROW row;
17767  MYSQL_RES *result;
17768 
17769  DBUG_ENTER("test_wl4284_1");
17770  myheader("test_wl4284_1");
17771 
17772  /* set AUTOCOMMIT to OFF */
17773  rc= mysql_autocommit(mysql, FALSE);
17774  myquery(rc);
17775 
17776  rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
17777  myquery(rc);
17778 
17779  rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
17780  myquery(rc);
17781 
17782  rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
17783  myquery(rc);
17784 
17785  rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
17786  myquery(rc);
17787 
17788  rc= mysql_rollback(mysql);
17789  myquery(rc);
17790 
17791  rc= mysql_query(mysql, "SELECT * FROM trans");
17792  myquery(rc);
17793 
17794  result= mysql_use_result(mysql);
17795  mytest(result);
17796 
17797  row= mysql_fetch_row(result);
17798  mytest(row);
17799 
17800  mysql_free_result(result);
17801 
17802  /* set AUTOCOMMIT to ON */
17803  rc= mysql_autocommit(mysql, TRUE);
17804  myquery(rc);
17805 
17806  rc= mysql_query(mysql, "DROP TABLE trans");
17807  myquery(rc);
17808 
17809  DBUG_VOID_RETURN;
17810 }
17811 
17812 
17813 static void test_bug38486(void)
17814 {
17815  MYSQL_STMT *stmt;
17816  const char *stmt_text;
17817  unsigned long type= CURSOR_TYPE_READ_ONLY;
17818 
17819  DBUG_ENTER("test_bug38486");
17820  myheader("test_bug38486");
17821 
17822  stmt= mysql_stmt_init(mysql);
17823  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
17824  stmt_text= "CREATE TABLE t1 (a INT)";
17825  mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17826  mysql_stmt_execute(stmt);
17827  mysql_stmt_close(stmt);
17828 
17829  stmt= mysql_stmt_init(mysql);
17830  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
17831  stmt_text= "INSERT INTO t1 VALUES (1)";
17832  mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17833  mysql_stmt_execute(stmt);
17834  mysql_stmt_close(stmt);
17835 
17836  DBUG_VOID_RETURN;
17837 }
17838 
17839 
17845 static void test_bug33831(void)
17846 {
17847  MYSQL *l_mysql;
17848 
17849  DBUG_ENTER("test_bug33831");
17850 
17851  if (!(l_mysql= mysql_client_init(NULL)))
17852  {
17853  myerror("mysql_client_init() failed");
17854  DIE_UNLESS(0);
17855  }
17856  if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
17857  opt_password, current_db, opt_port,
17858  opt_unix_socket, 0)))
17859  {
17860  myerror("connection failed");
17861  DIE_UNLESS(0);
17862  }
17863 
17864  if (mysql_real_connect(l_mysql, opt_host, opt_user,
17865  opt_password, current_db, opt_port,
17866  opt_unix_socket, 0))
17867  {
17868  myerror("connection should have failed");
17869  DIE_UNLESS(0);
17870  }
17871 
17872  mysql_close(l_mysql);
17873 
17874  DBUG_VOID_RETURN;
17875 }
17876 
17877 
17878 static void test_bug40365(void)
17879 {
17880  uint rc, i;
17881  MYSQL_STMT *stmt= 0;
17882  MYSQL_BIND my_bind[2];
17883  my_bool is_null[2]= {0};
17884  MYSQL_TIME tm[2];
17885 
17886  DBUG_ENTER("test_bug40365");
17887 
17888  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
17889  myquery(rc);
17890  rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \
17891  c2 DATE)");
17892  myquery(rc);
17893 
17894  stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)");
17895  check_stmt(stmt);
17896  verify_param_count(stmt, 2);
17897 
17898  memset(my_bind, 0, sizeof(my_bind));
17899  my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17900  my_bind[1].buffer_type= MYSQL_TYPE_DATE;
17901  for (i= 0; i < (int) array_elements(my_bind); i++)
17902  {
17903  my_bind[i].buffer= (void *) &tm[i];
17904  my_bind[i].is_null= &is_null[i];
17905  }
17906 
17907  rc= mysql_stmt_bind_param(stmt, my_bind);
17908  check_execute(stmt, rc);
17909 
17910  for (i= 0; i < (int) array_elements(my_bind); i++)
17911  {
17912  tm[i].neg= 0;
17913  tm[i].second_part= 0;
17914  tm[i].year= 2009;
17915  tm[i].month= 2;
17916  tm[i].day= 29;
17917  tm[i].hour= 0;
17918  tm[i].minute= 0;
17919  tm[i].second= 0;
17920  }
17921  rc= mysql_stmt_execute(stmt);
17922  check_execute(stmt, rc);
17923 
17924  rc= mysql_commit(mysql);
17925  myquery(rc);
17926  mysql_stmt_close(stmt);
17927 
17928  stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1");
17929  check_stmt(stmt);
17930 
17931  rc= mysql_stmt_bind_result(stmt, my_bind);
17932  check_execute(stmt, rc);
17933 
17934  rc= mysql_stmt_execute(stmt);
17935  check_execute(stmt, rc);
17936 
17937  rc= mysql_stmt_store_result(stmt);
17938  check_execute(stmt, rc);
17939 
17940  rc= mysql_stmt_fetch(stmt);
17941  check_execute(stmt, rc);
17942 
17943  if (!opt_silent)
17944  fprintf(stdout, "\n");
17945 
17946  for (i= 0; i < array_elements(my_bind); i++)
17947  {
17948  if (!opt_silent)
17949  fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d ",
17950  i, tm[i].year, tm[i].month, tm[i].day);
17951  DIE_UNLESS(tm[i].year == 0);
17952  DIE_UNLESS(tm[i].month == 0);
17953  DIE_UNLESS(tm[i].day == 0);
17954  }
17955  mysql_stmt_close(stmt);
17956  rc= mysql_commit(mysql);
17957  myquery(rc);
17958 
17959  DBUG_VOID_RETURN;
17960 }
17961 
17962 
17972 static void test_bug43560(void)
17973 {
17974  MYSQL* conn;
17975  uint rc;
17976  MYSQL_STMT *stmt= 0;
17977  MYSQL_BIND bind;
17978  my_bool is_null= 0;
17979  char buffer[256];
17980  const uint BUFSIZE= sizeof(buffer);
17981  const char* values[] = {"eins", "zwei", "drei", "viele", NULL};
17982  const char insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
17983  unsigned long length;
17984  const unsigned int drop_db= opt_drop_db;
17985 
17986  DBUG_ENTER("test_bug43560");
17987  myheader("test_bug43560");
17988 
17989  /* Make sure we only run against a debug server. */
17990  if (!strstr(mysql->server_version, "debug"))
17991  {
17992  fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
17993  DBUG_VOID_RETURN;
17994  }
17995 
17996  /*
17997  Set up a separate connection for this test to avoid messing up the
17998  general MYSQL object used in other subtests. Use TCP protocol to avoid
17999  problems with the buffer semantics of AF_UNIX, and turn off auto reconnect.
18000  */
18001  conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
18002 
18003  rc= mysql_query(conn, "DROP TABLE IF EXISTS t1");
18004  myquery(rc);
18005  rc= mysql_query(conn,
18006  "CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))");
18007  myquery(rc);
18008 
18009  stmt= mysql_stmt_init(conn);
18010  check_stmt(stmt);
18011  rc= mysql_stmt_prepare(stmt, insert_str, strlen(insert_str));
18012  check_execute(stmt, rc);
18013 
18014  memset(&bind, 0, sizeof(bind));
18015  bind.buffer_type= MYSQL_TYPE_STRING;
18016  bind.buffer_length= BUFSIZE;
18017  bind.buffer= buffer;
18018  bind.is_null= &is_null;
18019  bind.length= &length;
18020  rc= mysql_stmt_bind_param(stmt, &bind);
18021  check_execute(stmt, rc);
18022 
18023  /* First execute; should succeed. */
18024  strncpy(buffer, values[0], BUFSIZE);
18025  length= strlen(buffer);
18026  rc= mysql_stmt_execute(stmt);
18027  check_execute(stmt, rc);
18028 
18029  /*
18030  Set up the server to close this session's server-side socket after
18031  next execution of prep statement.
18032  */
18033  rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'");
18034  myquery(rc);
18035 
18036  /* Second execute; should fail due to socket closed during execution. */
18037  strncpy(buffer, values[1], BUFSIZE);
18038  length= strlen(buffer);
18039  rc= mysql_stmt_execute(stmt);
18040  DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18041 
18042  /*
18043  Third execute; should fail (connection already closed), or SIGSEGV in
18044  case of a Bug#43560 type regression in which case the whole test fails.
18045  */
18046  strncpy(buffer, values[2], BUFSIZE);
18047  length= strlen(buffer);
18048  rc= mysql_stmt_execute(stmt);
18049  DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18050 
18051  mysql_stmt_close(stmt);
18052 
18053  opt_drop_db= 0;
18054  client_disconnect(conn);
18055  rc= mysql_query(mysql, "DROP TABLE t1");
18056  myquery(rc);
18057  opt_drop_db= drop_db;
18058 
18059  DBUG_VOID_RETURN;
18060 }
18061 
18062 
18067 #ifdef HAVE_QUERY_CACHE
18068 
18069 static void test_bug36326()
18070 {
18071  int rc;
18072 
18073  DBUG_ENTER("test_bug36326");
18074  myheader("test_bug36326");
18075 
18076  rc= mysql_autocommit(mysql, TRUE);
18077  myquery(rc);
18078  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18079  myquery(rc);
18080  rc= mysql_query(mysql, "CREATE TABLE t1 (a INTEGER)");
18081  myquery(rc);
18082  rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
18083  myquery(rc);
18084  rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
18085  myquery(rc);
18086  rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576");
18087  myquery(rc);
18088  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18089  DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
18090  rc= mysql_query(mysql, "BEGIN");
18091  myquery(rc);
18092  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
18093  rc= mysql_query(mysql, "SELECT * FROM t1");
18094  myquery(rc);
18095  rc= my_process_result(mysql);
18096  DIE_UNLESS(rc == 1);
18097  rc= mysql_rollback(mysql);
18098  myquery(rc);
18099  rc= mysql_query(mysql, "ROLLBACK");
18100  myquery(rc);
18101  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18102  rc= mysql_query(mysql, "SELECT * FROM t1");
18103  myquery(rc);
18104  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18105  rc= my_process_result(mysql);
18106  DIE_UNLESS(rc == 1);
18107  rc= mysql_query(mysql, "DROP TABLE t1");
18108  myquery(rc);
18109  rc= mysql_query(mysql, "SET GLOBAL query_cache_size = DEFAULT");
18110  myquery(rc);
18111 
18112  DBUG_VOID_RETURN;
18113 }
18114 
18115 #endif
18116 
18122 static void test_bug41078(void)
18123 {
18124  uint rc;
18125  MYSQL_STMT *stmt= 0;
18126  MYSQL_BIND param, result;
18127  ulong cursor_type= CURSOR_TYPE_READ_ONLY;
18128  ulong len;
18129  char str[64];
18130  const char param_str[]= "abcdefghijklmn";
18131  my_bool is_null, error;
18132 
18133  DBUG_ENTER("test_bug41078");
18134 
18135  rc= mysql_query(mysql, "SET NAMES UTF8");
18136  myquery(rc);
18137 
18138  stmt= mysql_simple_prepare(mysql, "SELECT ?");
18139  check_stmt(stmt);
18140  verify_param_count(stmt, 1);
18141 
18142  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type);
18143  check_execute(stmt, rc);
18144 
18145  memset(&param, 0, sizeof(param));
18146  param.buffer_type= MYSQL_TYPE_STRING;
18147  param.buffer= (void *) param_str;
18148  len= sizeof(param_str) - 1;
18149  param.length= &len;
18150 
18151  rc= mysql_stmt_bind_param(stmt, &param);
18152  check_execute(stmt, rc);
18153 
18154  rc= mysql_stmt_execute(stmt);
18155  check_execute(stmt, rc);
18156 
18157  memset(&result, 0, sizeof(result));
18158  result.buffer_type= MYSQL_TYPE_STRING;
18159  result.buffer= str;
18160  result.buffer_length= sizeof(str);
18161  result.is_null= &is_null;
18162  result.length= &len;
18163  result.error= &error;
18164 
18165  rc= mysql_stmt_bind_result(stmt, &result);
18166  check_execute(stmt, rc);
18167 
18168  rc= mysql_stmt_store_result(stmt);
18169  check_execute(stmt, rc);
18170 
18171  rc= mysql_stmt_fetch(stmt);
18172  check_execute(stmt, rc);
18173 
18174  DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str));
18175 
18176  mysql_stmt_close(stmt);
18177 
18178  DBUG_VOID_RETURN;
18179 }
18180 
18184 static void test_bug45010()
18185 {
18186  int rc;
18187  const char query1[]= "select a.\x80",
18188  query2[]= "describe `table\xef";
18189 
18190  DBUG_ENTER("test_bug45010");
18191  myheader("test_bug45010");
18192 
18193  rc= mysql_query(mysql, "set names utf8");
18194  myquery(rc);
18195 
18196  /* \x80 (-128) could be used as a index of ident_map. */
18197  rc= mysql_real_query(mysql, query1, sizeof(query1) - 1);
18198  DIE_UNLESS(rc);
18199 
18200  /* \xef (-17) could be used to skip 3 bytes past the buffer end. */
18201  rc= mysql_real_query(mysql, query2, sizeof(query2) - 1);
18202  DIE_UNLESS(rc);
18203 
18204  rc= mysql_query(mysql, "set names default");
18205  myquery(rc);
18206 
18207  DBUG_VOID_RETURN;
18208 }
18209 
18215 static void test_bug44495()
18216 {
18217  int rc;
18218  MYSQL con;
18219  MYSQL_STMT *stmt;
18220 
18221  DBUG_ENTER("test_bug44495");
18222  myheader("test_44495");
18223 
18224  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18225  myquery(rc);
18226 
18227  rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN arg VARCHAR(25))"
18228  " BEGIN SET @stmt = CONCAT('SELECT \"', arg, '\"');"
18229  " PREPARE ps1 FROM @stmt;"
18230  " EXECUTE ps1;"
18231  " DROP PREPARE ps1;"
18232  "END;");
18233  myquery(rc);
18234 
18235  DIE_UNLESS(mysql_client_init(&con));
18236 
18237  DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18238  current_db, opt_port, opt_unix_socket,
18239  CLIENT_MULTI_RESULTS));
18240 
18241  stmt= mysql_simple_prepare(&con, "CALL p1('abc')");
18242  check_stmt(stmt);
18243 
18244  rc= mysql_stmt_execute(stmt);
18245  check_execute(stmt, rc);
18246 
18247  rc= my_process_stmt_result(stmt);
18248  DIE_UNLESS(rc == 1);
18249 
18250  mysql_stmt_close(stmt);
18251 
18252  mysql_close(&con);
18253 
18254  rc= mysql_query(mysql, "DROP PROCEDURE p1");
18255  myquery(rc);
18256 
18257  DBUG_VOID_RETURN;
18258 }
18259 
18260 static void test_bug53371()
18261 {
18262  int rc;
18263  MYSQL_RES *result;
18264 
18265  myheader("test_bug53371");
18266 
18267  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18268  myquery(rc);
18269  rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
18270  myquery(rc);
18271  rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18272 
18273  rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18274  myquery(rc);
18275  rc= mysql_query(mysql, "CREATE DATABASE bug53371");
18276  myquery(rc);
18277  rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
18278  myquery(rc);
18279 
18280  rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
18281  myquery(rc);
18282 
18283  rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
18284  DIE_UNLESS(rc);
18285  DIE_UNLESS(mysql_errno(mysql) == 1142);
18286 
18287  result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
18288  DIE_IF(result);
18289 
18290  result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
18291  DIE_IF(result);
18292 
18293  rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
18294  myquery(rc);
18295  rc= mysql_query(mysql, "DROP TABLE t1");
18296  myquery(rc);
18297  rc= mysql_query(mysql, "DROP DATABASE bug53371");
18298  myquery(rc);
18299  rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18300  myquery(rc);
18301 }
18302 
18303 
18304 
18308 static void test_bug42373()
18309 {
18310  int rc;
18311  MYSQL con;
18312  MYSQL_STMT *stmt;
18313 
18314  DBUG_ENTER("test_bug42373");
18315  myheader("test_42373");
18316 
18317  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18318  myquery(rc);
18319 
18320  rc= mysql_query(mysql, "CREATE PROCEDURE p1()"
18321  " BEGIN"
18322  " SELECT 1;"
18323  " INSERT INTO t1 VALUES (2);"
18324  "END;");
18325  myquery(rc);
18326 
18327  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18328  myquery(rc);
18329 
18330  rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18331  myquery(rc);
18332 
18333  /* Try with a stored procedure. */
18334  DIE_UNLESS(mysql_client_init(&con));
18335 
18336  mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()");
18337 
18338  DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18339  current_db, opt_port, opt_unix_socket,
18340  CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18341 
18342  stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18343  check_stmt(stmt);
18344 
18345  rc= mysql_stmt_execute(stmt);
18346  check_execute(stmt, rc);
18347 
18348  rc= my_process_stmt_result(stmt);
18349  DIE_UNLESS(rc == 1);
18350 
18351  mysql_stmt_close(stmt);
18352  mysql_close(&con);
18353 
18354  /* Now try with a multi-statement. */
18355  DIE_UNLESS(mysql_client_init(&con));
18356 
18357  mysql_options(&con, MYSQL_INIT_COMMAND,
18358  "SELECT 3; INSERT INTO t1 VALUES (4)");
18359 
18360  DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18361  current_db, opt_port, opt_unix_socket,
18362  CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18363 
18364  stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18365  check_stmt(stmt);
18366 
18367  rc= mysql_stmt_execute(stmt);
18368  check_execute(stmt, rc);
18369 
18370  rc= my_process_stmt_result(stmt);
18371  DIE_UNLESS(rc == 2);
18372 
18373  mysql_stmt_close(stmt);
18374  mysql_close(&con);
18375 
18376  rc= mysql_query(mysql, "DROP TABLE t1");
18377  myquery(rc);
18378 
18379  rc= mysql_query(mysql, "DROP PROCEDURE p1");
18380  myquery(rc);
18381 
18382  DBUG_VOID_RETURN;
18383 }
18384 
18385 
18390 static void test_bug54041_impl()
18391 {
18392  int rc;
18393  MYSQL_STMT *stmt;
18394  MYSQL_BIND bind;
18395 
18396  DBUG_ENTER("test_bug54041");
18397  myheader("test_bug54041");
18398 
18399  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18400  myquery(rc);
18401 
18402  rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18403  myquery(rc);
18404 
18405  stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?");
18406  check_stmt(stmt);
18407  verify_param_count(stmt, 1);
18408 
18409  memset(&bind, 0, sizeof(bind));
18410 
18411  /* Any type that does not support long data handling. */
18412  bind.buffer_type= MYSQL_TYPE_LONG;
18413 
18414  rc= mysql_stmt_bind_param(stmt, &bind);
18415  check_execute(stmt, rc);
18416 
18417  /*
18418  Trick the client API into sending a long data packet for
18419  the parameter. Long data is only supported for string and
18420  binary types.
18421  */
18422  stmt->params[0].buffer_type= MYSQL_TYPE_STRING;
18423 
18424  rc= mysql_stmt_send_long_data(stmt, 0, "data", 5);
18425  check_execute(stmt, rc);
18426 
18427  /* Undo API violation. */
18428  stmt->params[0].buffer_type= MYSQL_TYPE_LONG;
18429 
18430  rc= mysql_stmt_execute(stmt);
18431  /* Incorrect arguments. */
18432  check_execute_r(stmt, rc);
18433 
18434  mysql_stmt_close(stmt);
18435 
18436  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18437  myquery(rc);
18438 
18439  DBUG_VOID_RETURN;
18440 }
18441 
18442 
18447 static void test_bug54041()
18448 {
18449  enable_query_logs(0);
18450  test_bug54041_impl();
18451  disable_query_logs();
18452  test_bug54041_impl();
18453  restore_query_logs();
18454 }
18455 
18456 
18460 static void test_bug47485()
18461 {
18462  MYSQL_STMT *stmt;
18463  MYSQL_RES *res;
18464  MYSQL_BIND bind[2];
18465  int rc;
18466  const char* sql_select = "SELECT 1, 'a'";
18467  int int_data;
18468  char str_data[16];
18469  my_bool is_null[2];
18470  my_bool error[2];
18471  unsigned long length[2];
18472 
18473  DBUG_ENTER("test_bug47485");
18474  myheader("test_bug47485");
18475 
18476  stmt= mysql_stmt_init(mysql);
18477  check_stmt(stmt);
18478  rc= mysql_stmt_prepare(stmt, sql_select, strlen(sql_select));
18479  check_execute(stmt, rc);
18480 
18481  rc= mysql_stmt_execute(stmt);
18482  check_execute(stmt, rc);
18483 
18484  res = mysql_store_result(mysql);
18485  DIE_UNLESS(res == NULL);
18486 
18487  mysql_stmt_reset(stmt);
18488 
18489  rc= mysql_stmt_execute(stmt);
18490  check_execute(stmt, rc);
18491 
18492  res = mysql_use_result(mysql);
18493  DIE_UNLESS(res == NULL);
18494 
18495  mysql_stmt_reset(stmt);
18496 
18497  memset(bind, 0, sizeof(bind));
18498  bind[0].buffer_type= MYSQL_TYPE_LONG;
18499  bind[0].buffer= (char *)&int_data;
18500  bind[0].is_null= &is_null[0];
18501  bind[0].length= &length[0];
18502  bind[0].error= &error[0];
18503 
18504  bind[1].buffer_type= MYSQL_TYPE_STRING;
18505  bind[1].buffer= (char *)str_data;
18506  bind[1].buffer_length= sizeof(str_data);
18507  bind[1].is_null= &is_null[1];
18508  bind[1].length= &length[1];
18509  bind[1].error= &error[1];
18510 
18511  rc= mysql_stmt_bind_result(stmt, bind);
18512  check_execute(stmt, rc);
18513 
18514  rc= mysql_stmt_execute(stmt);
18515  check_execute(stmt, rc);
18516 
18517  rc= mysql_stmt_store_result(stmt);
18518  check_execute(stmt, rc);
18519 
18520  while (!(rc= mysql_stmt_fetch(stmt)))
18521  ;
18522 
18523  DIE_UNLESS(rc == MYSQL_NO_DATA);
18524 
18525  mysql_stmt_reset(stmt);
18526 
18527  memset(bind, 0, sizeof(bind));
18528  bind[0].buffer_type= MYSQL_TYPE_LONG;
18529  bind[0].buffer= (char *)&int_data;
18530  bind[0].is_null= &is_null[0];
18531  bind[0].length= &length[0];
18532  bind[0].error= &error[0];
18533 
18534  bind[1].buffer_type= MYSQL_TYPE_STRING;
18535  bind[1].buffer= (char *)str_data;
18536  bind[1].buffer_length= sizeof(str_data);
18537  bind[1].is_null= &is_null[1];
18538  bind[1].length= &length[1];
18539  bind[1].error= &error[1];
18540 
18541  rc= mysql_stmt_bind_result(stmt, bind);
18542  check_execute(stmt, rc);
18543 
18544  rc= mysql_stmt_execute(stmt);
18545  check_execute(stmt, rc);
18546 
18547  while (!(rc= mysql_stmt_fetch(stmt)))
18548  ;
18549 
18550  DIE_UNLESS(rc == MYSQL_NO_DATA);
18551 
18552  mysql_stmt_close(stmt);
18553 
18554  DBUG_VOID_RETURN;
18555 }
18556 
18557 
18558 /*
18559  Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server
18560 */
18561 static void test_bug58036()
18562 {
18563  MYSQL *conn;
18564  DBUG_ENTER("test_bug47485");
18565  myheader("test_bug58036");
18566 
18567  /* Part1: try to connect with ucs2 client character set */
18568  conn= mysql_client_init(NULL);
18569  mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18570  if (mysql_real_connect(conn, opt_host, opt_user,
18571  opt_password, opt_db ? opt_db : "test",
18572  opt_port, opt_unix_socket, 0))
18573  {
18574  if (!opt_silent)
18575  printf("mysql_real_connect() succeeded (failure expected)\n");
18576  mysql_close(conn);
18577  DIE("");
18578  }
18579 
18580  if (!opt_silent)
18581  printf("Got mysql_real_connect() error (expected): %s (%d)\n",
18582  mysql_error(conn), mysql_errno(conn));
18583  DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR);
18584  mysql_close(conn);
18585 
18586 
18587  /*
18588  Part2:
18589  - connect with latin1
18590  - then change client character set to ucs2
18591  - then try mysql_change_user()
18592  */
18593  conn= mysql_client_init(NULL);
18594  mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1");
18595  if (!mysql_real_connect(conn, opt_host, opt_user,
18596  opt_password, opt_db ? opt_db : "test",
18597  opt_port, opt_unix_socket, 0))
18598  {
18599  if (!opt_silent)
18600  printf("mysql_real_connect() failed: %s (%d)\n",
18601  mysql_error(conn), mysql_errno(conn));
18602  mysql_close(conn);
18603  DIE("");
18604  }
18605 
18606  mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18607  if (!mysql_change_user(conn, opt_user, opt_password, NULL))
18608  {
18609  if (!opt_silent)
18610  printf("mysql_change_user() succedded, error expected!");
18611  mysql_close(conn);
18612  DIE("");
18613  }
18614 
18615  if (!opt_silent)
18616  printf("Got mysql_change_user() error (expected): %s (%d)\n",
18617  mysql_error(conn), mysql_errno(conn));
18618  mysql_close(conn);
18619 
18620  DBUG_VOID_RETURN;
18621 }
18622 
18623 
18624 /*
18625  Bug#49972: Crash in prepared statements.
18626 
18627  The following case lead to a server crash:
18628  - Use binary protocol;
18629  - Prepare a statement with OUT-parameter;
18630  - Execute the statement;
18631  - Cause re-prepare of the statement (change dependencies);
18632  - Execute the statement again -- crash here.
18633 */
18634 
18635 static void test_bug49972()
18636 {
18637  int rc;
18638  MYSQL_STMT *stmt;
18639 
18640  MYSQL_BIND in_param_bind;
18641  MYSQL_BIND out_param_bind;
18642  int int_data;
18643  my_bool is_null;
18644 
18645  DBUG_ENTER("test_bug49972");
18646  myheader("test_bug49972");
18647 
18648  rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
18649  myquery(rc);
18650 
18651  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18652  myquery(rc);
18653 
18654  rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18655  myquery(rc);
18656 
18657  rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a");
18658  myquery(rc);
18659 
18660  stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)");
18661  check_stmt(stmt);
18662 
18663  memset(&in_param_bind, 0, sizeof (in_param_bind));
18664 
18665  in_param_bind.buffer_type= MYSQL_TYPE_LONG;
18666  in_param_bind.buffer= (char *) &int_data;
18667  in_param_bind.length= 0;
18668  in_param_bind.is_null= 0;
18669 
18670  rc= mysql_stmt_bind_param(stmt, &in_param_bind);
18671 
18672  rc= mysql_stmt_execute(stmt);
18673  check_execute(stmt, rc);
18674 
18675  {
18676  memset(&out_param_bind, 0, sizeof (out_param_bind));
18677 
18678  out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18679  out_param_bind.is_null= &is_null;
18680  out_param_bind.buffer= &int_data;
18681  out_param_bind.buffer_length= sizeof (int_data);
18682 
18683  rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18684  check_execute(stmt, rc);
18685 
18686  rc= mysql_stmt_fetch(stmt);
18687  rc= mysql_stmt_fetch(stmt);
18688  DBUG_ASSERT(rc == MYSQL_NO_DATA);
18689 
18690  mysql_stmt_next_result(stmt);
18691  mysql_stmt_fetch(stmt);
18692  }
18693 
18694  rc= mysql_query(mysql, "DROP FUNCTION f1");
18695  myquery(rc);
18696 
18697  rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18698  myquery(rc);
18699 
18700  rc= mysql_stmt_execute(stmt);
18701  check_execute(stmt, rc);
18702 
18703  {
18704  memset(&out_param_bind, 0, sizeof (out_param_bind));
18705 
18706  out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18707  out_param_bind.is_null= &is_null;
18708  out_param_bind.buffer= &int_data;
18709  out_param_bind.buffer_length= sizeof (int_data);
18710 
18711  rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18712  check_execute(stmt, rc);
18713 
18714  rc= mysql_stmt_fetch(stmt);
18715  rc= mysql_stmt_fetch(stmt);
18716  DBUG_ASSERT(rc == MYSQL_NO_DATA);
18717 
18718  mysql_stmt_next_result(stmt);
18719  mysql_stmt_fetch(stmt);
18720  }
18721 
18722  mysql_stmt_close(stmt);
18723 
18724  rc= mysql_query(mysql, "DROP PROCEDURE p1");
18725  myquery(rc);
18726 
18727  rc= mysql_query(mysql, "DROP FUNCTION f1");
18728  myquery(rc);
18729 
18730  DBUG_VOID_RETURN;
18731 }
18732 
18733 
18734 /*
18735  Bug #56976: Severe Denial Of Service in prepared statements
18736 */
18737 static void test_bug56976()
18738 {
18739  MYSQL_STMT *stmt;
18740  MYSQL_BIND bind[1];
18741  int rc;
18742  const char* query = "SELECT LENGTH(?)";
18743  char *long_buffer;
18744  unsigned long i, packet_len = 256 * 1024L;
18745  unsigned long dos_len = 8 * 1024 * 1024L;
18746 
18747  DBUG_ENTER("test_bug56976");
18748  myheader("test_bug56976");
18749 
18750  stmt= mysql_stmt_init(mysql);
18751  check_stmt(stmt);
18752 
18753  rc= mysql_stmt_prepare(stmt, query, strlen(query));
18754  check_execute(stmt, rc);
18755 
18756  memset(bind, 0, sizeof(bind));
18757  bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;
18758 
18759  rc= mysql_stmt_bind_param(stmt, bind);
18760  check_execute(stmt, rc);
18761 
18762  long_buffer= (char*) my_malloc(packet_len, MYF(0));
18763  DIE_UNLESS(long_buffer);
18764 
18765  memset(long_buffer, 'a', packet_len);
18766 
18767  for (i= 0; i < dos_len / packet_len; i++)
18768  {
18769  rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len);
18770  check_execute(stmt, rc);
18771  }
18772 
18773  my_free(long_buffer);
18774  rc= mysql_stmt_execute(stmt);
18775 
18776  DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);
18777 
18778  mysql_stmt_close(stmt);
18779 
18780  DBUG_VOID_RETURN;
18781 }
18782 
18783 
18788 static void test_bug57058()
18789 {
18790  MYSQL_RES *res;
18791  int rc;
18792 
18793  DBUG_ENTER("test_bug57058");
18794  myheader("test_bug57058");
18795 
18796  rc= mysql_query(mysql, "set @@session.long_query_time=0.1");
18797  myquery(rc);
18798 
18799  DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW));
18800 
18801  rc= mysql_query(mysql, "select sleep(1)");
18802  myquery(rc);
18803 
18804  /*
18805  Important: the flag is sent in the last EOF packet of
18806  the query, the one which ends the result. Read the
18807  result to see the "slow" status.
18808  */
18809  res= mysql_store_result(mysql);
18810 
18811  DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW);
18812 
18813  mysql_free_result(res);
18814 
18815  rc= mysql_query(mysql, "set @@session.long_query_time=default");
18816  myquery(rc);
18817 
18818  DBUG_VOID_RETURN;
18819 }
18820 
18821 
18826 static void test_bug11766854()
18827 {
18828  struct st_mysql_client_plugin *plugin;
18829 
18830  DBUG_ENTER("test_bug11766854");
18831  myheader("test_bug11766854");
18832 
18833  plugin= mysql_load_plugin(mysql, "foo", -1, 0);
18834  DIE_UNLESS(plugin == 0);
18835 
18836  plugin= mysql_load_plugin(mysql, "qa_auth_client", -1, 0);
18837  DIE_UNLESS(plugin != 0);
18838  DIE_IF(mysql_errno(mysql));
18839 
18840  DBUG_VOID_RETURN;
18841 }
18842 
18847 static void test_bug12337762()
18848 {
18849  int rc,i=0;
18850  MYSQL_RES *result;
18851  MYSQL_FIELD *field;
18852  unsigned int tab_charsetnr[3]= {0};
18853 
18854  DBUG_ENTER("test_bug12337762");
18855  myheader("test_bug12337762");
18856 
18857  /*
18858  Creating table with specific charset.
18859  */
18860  rc= mysql_query(mysql, "drop table if exists charset_tab");
18861  rc= mysql_query(mysql, "create table charset_tab("\
18862  "txt1 varchar(32) character set Latin1,"\
18863  "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
18864  "txt3 varchar(32) character set utf8 collate utf8_bin"\
18865  ")");
18866 
18867  DIE_UNLESS(rc == 0);
18868  DIE_IF(mysql_errno(mysql));
18869 
18870  /*
18871  Creating view from table created earlier.
18872  */
18873  rc= mysql_query(mysql, "drop view if exists charset_view");
18874  rc= mysql_query(mysql, "create view charset_view as "\
18875  "select * from charset_tab;");
18876  DIE_UNLESS(rc == 0);
18877  DIE_IF(mysql_errno(mysql));
18878 
18879  /*
18880  Checking field information for table.
18881  */
18882  result= mysql_list_fields(mysql, "charset_tab", NULL);
18883  DIE_IF(mysql_errno(mysql));
18884  i=0;
18885  while((field= mysql_fetch_field(result)))
18886  {
18887  printf("field name %s\n", field->name);
18888  printf("field table %s\n", field->table);
18889  printf("field type %d\n", field->type);
18890  printf("field charset %d\n", field->charsetnr);
18891  tab_charsetnr[i++]= field->charsetnr;
18892  printf("\n");
18893  }
18894  mysql_free_result(result);
18895 
18896  /*
18897  Checking field information for view.
18898  */
18899  result= mysql_list_fields(mysql, "charset_view", NULL);
18900  DIE_IF(mysql_errno(mysql));
18901  i=0;
18902  while((field= mysql_fetch_field(result)))
18903  {
18904  printf("field name %s\n", field->name);
18905  printf("field table %s\n", field->table);
18906  printf("field type %d\n", field->type);
18907  printf("field charset %d\n", field->charsetnr);
18908  printf("\n");
18909  /*
18910  charset value for field must be same for both, view and table.
18911  */
18912  DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
18913  }
18914  mysql_free_result(result);
18915 
18916  DBUG_VOID_RETURN;
18917 }
18918 
18923 static void test_bug54790()
18924 {
18925  int rc;
18926  MYSQL *lmysql;
18927  uint timeout= 2;
18928 
18929  DBUG_ENTER("test_bug54790");
18930  myheader("test_bug54790");
18931 
18932  lmysql= mysql_client_init(NULL);
18933  DIE_UNLESS(lmysql);
18934 
18935  rc= mysql_options(lmysql, MYSQL_OPT_READ_TIMEOUT, &timeout);
18936  DIE_UNLESS(!rc);
18937 
18938  if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
18939  opt_db ? opt_db : "test", opt_port,
18940  opt_unix_socket, 0))
18941  {
18942  mysql= lmysql;
18943  myerror("mysql_real_connect failed");
18944  mysql_close(lmysql);
18945  exit(1);
18946  }
18947 
18948  rc= mysql_query(lmysql, "SELECT SLEEP(100);");
18949  myquery_r(rc);
18950 
18951  /* A timeout error (ER_NET_READ_INTERRUPTED) would be more appropriate. */
18952  DIE_UNLESS(mysql_errno(lmysql) == CR_SERVER_LOST);
18953 
18954  mysql_close(lmysql);
18955 
18956  DBUG_VOID_RETURN;
18957 }
18958 
18959 
18960 /*
18961  BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
18962 */
18963 
18964 static void test_bug11754979()
18965 {
18966  MYSQL* conn;
18967  DBUG_ENTER("test_bug11754979");
18968 
18969  myheader("test_bug11754979");
18970  DIE_UNLESS((conn= mysql_client_init(NULL)));
18971  DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
18972  opt_password, opt_db ? opt_db:"test", opt_port,
18973  opt_unix_socket, CLIENT_FOUND_ROWS));
18974  myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
18975  myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
18976  myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
18977  myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
18978  "ON DUPLICATE KEY UPDATE id = 4"));
18979  DIE_UNLESS(mysql_affected_rows(conn) == 2);
18980  myquery(mysql_query(conn, "DROP TABLE t1"));
18981  mysql_close(conn);
18982 
18983  DBUG_VOID_RETURN;
18984 }
18985 
18986 
18987 /*
18988  Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
18989 */
18990 static void test_bug13001491()
18991 {
18992  int rc;
18993  char query[MAX_TEST_QUERY_LENGTH];
18994  MYSQL *c;
18995 
18996  myheader("test_bug13001491");
18997 
18998  my_snprintf(query, MAX_TEST_QUERY_LENGTH,
18999  "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
19000  opt_host ? opt_host : "'localhost'");
19001 
19002  rc= mysql_query(mysql, query);
19003  myquery(rc);
19004 
19005  my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19006  "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
19007  opt_host ? opt_host : "'localhost'");
19008 
19009  rc= mysql_query(mysql, query);
19010  myquery(rc);
19011 
19012  c= mysql_client_init(NULL);
19013 
19014  DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
19015  current_db, opt_port, opt_unix_socket,
19016  CLIENT_MULTI_STATEMENTS |
19017  CLIENT_MULTI_RESULTS));
19018 
19019  rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
19020  myquery(rc);
19021 
19022  rc= mysql_query(c,
19023  "CREATE PROCEDURE p1() "
19024  "BEGIN "
19025  " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
19026  " SELECT COUNT(*) "
19027  " FROM INFORMATION_SCHEMA.PROCESSLIST "
19028  " GROUP BY user "
19029  " ORDER BY NULL "
19030  " INTO @a; "
19031  "END");
19032  myquery(rc);
19033 
19034  rc= mysql_query(c, "CALL p1()");
19035  myquery(rc);
19036 
19037  mysql_free_result(mysql_store_result(c));
19038 
19039  /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
19040  rc= mysql_refresh(c, REFRESH_GRANT |
19041  REFRESH_TABLES | REFRESH_HOSTS |
19042  REFRESH_STATUS | REFRESH_THREADS);
19043  myquery(rc);
19044 
19045  /*
19046  Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
19047  fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
19048  location.
19049  */
19050  mysql_refresh(c, REFRESH_LOG);
19051 
19052  rc= mysql_query(c, "DROP PROCEDURE p1");
19053  myquery(rc);
19054 
19055  mysql_close(c);
19056  c= NULL;
19057 
19058  my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19059  "DROP USER mysqltest_u1@%s",
19060  opt_host ? opt_host : "'localhost'");
19061 
19062  rc= mysql_query(mysql, query);
19063  myquery(rc);
19064 }
19065 
19066 
19067 /*
19068  WL#5968: Implement START TRANSACTION READ (WRITE|ONLY);
19069  Check that the SERVER_STATUS_IN_TRANS_READONLY flag is set properly.
19070 */
19071 static void test_wl5968()
19072 {
19073  int rc;
19074 
19075  myheader("test_wl5968");
19076 
19077  rc= mysql_query(mysql, "START TRANSACTION");
19078  myquery(rc);
19079  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19080  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19081  rc= mysql_query(mysql, "COMMIT");
19082  myquery(rc);
19083  rc= mysql_query(mysql, "START TRANSACTION READ ONLY");
19084  myquery(rc);
19085  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19086  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY);
19087  rc= mysql_query(mysql, "COMMIT");
19088  myquery(rc);
19089  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
19090  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19091  rc= mysql_query(mysql, "START TRANSACTION");
19092  myquery(rc);
19093  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
19094  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
19095  rc= mysql_query(mysql, "COMMIT");
19096  myquery(rc);
19097 }
19098 
19099 
19100 /*
19101  WL#5924: Add connect string processing to mysql
19102 */
19103 static void test_wl5924()
19104 {
19105  int rc;
19106  MYSQL *l_mysql;
19107  MYSQL_RES *res;
19108  MYSQL_ROW row;
19109 
19110  myheader("test_wl5924");
19111  l_mysql= mysql_client_init(NULL);
19112  DIE_UNLESS(l_mysql != NULL);
19113 
19114  /* we want a non-default character set */
19115  rc= mysql_set_character_set(l_mysql, "cp1251");
19116  DIE_UNLESS(rc == 0);
19117 
19118  /* put in an attr */
19119  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19120  "key1", "value1");
19121  DIE_UNLESS(rc == 0);
19122 
19123  /* put a second attr */
19124  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19125  "key2", "value2");
19126  DIE_UNLESS(rc == 0);
19127 
19128  /* put the second attr again : should fail */
19129  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19130  "key2", "value2");
19131  DIE_UNLESS(rc != 0);
19132 
19133  /* delete the second attr */
19134  rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
19135  "key2");
19136  DIE_UNLESS(rc == 0);
19137 
19138  /* put the second attr again : should pass */
19139  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19140  "key2", "value2");
19141  DIE_UNLESS(rc == 0);
19142 
19143  /* full reset */
19144  rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_RESET, NULL);
19145  DIE_UNLESS(rc == 0);
19146 
19147  /* put the second attr again : should pass */
19148  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19149  "key2", "value2");
19150  DIE_UNLESS(rc == 0);
19151 
19152  /* full reset */
19153  rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_RESET, NULL);
19154  DIE_UNLESS(rc == 0);
19155 
19156  /* add a third attr */
19157  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19158  "key3", "value3");
19159  DIE_UNLESS(rc == 0);
19160 
19161  /* add a fourth attr */
19162  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19163  "key4", "value4");
19164  DIE_UNLESS(rc == 0);
19165 
19166  /* add a non-ascii attr */
19167  /* note : this is Георги, Кодинов in windows-1251 */
19168  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
19169  "\xc3\xe5\xee\xf0\xe3\xe8",
19170  "\xca\xee\xe4\xe8\xed\xee\xe2");
19171  DIE_UNLESS(rc == 0);
19172 
19173  l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
19174  opt_password, current_db, opt_port,
19175  opt_unix_socket, 0);
19176  DIE_UNLESS(l_mysql != 0);
19177 
19178  rc= mysql_query(l_mysql,
19179  "SELECT ATTR_NAME, ATTR_VALUE "
19180  " FROM performance_schema.session_account_connect_attrs"
19181  " WHERE ATTR_NAME IN ('key1','key2','key3','key4',"
19182  " '\xc3\xe5\xee\xf0\xe3\xe8') AND"
19183  " PROCESSLIST_ID = CONNECTION_ID() ORDER BY ATTR_NAME");
19184  myquery2(l_mysql,rc);
19185  res= mysql_use_result(l_mysql);
19186  DIE_UNLESS(res);
19187 
19188  row= mysql_fetch_row(res);
19189  DIE_UNLESS(row);
19190  DIE_UNLESS(0 == strcmp(row[0], "key3"));
19191  DIE_UNLESS(0 == strcmp(row[1], "value3"));
19192 
19193  row= mysql_fetch_row(res);
19194  DIE_UNLESS(row);
19195  DIE_UNLESS(0 == strcmp(row[0], "key4"));
19196  DIE_UNLESS(0 == strcmp(row[1], "value4"));
19197 
19198  row= mysql_fetch_row(res);
19199  DIE_UNLESS(row);
19200  DIE_UNLESS(0 == strcmp(row[0], "\xc3\xe5\xee\xf0\xe3\xe8"));
19201  DIE_UNLESS(0 == strcmp(row[1], "\xca\xee\xe4\xe8\xed\xee\xe2"));
19202 
19203  mysql_free_result(res);
19204 
19205  l_mysql->reconnect= 1;
19206  rc= mysql_reconnect(l_mysql);
19207  myquery2(l_mysql,rc);
19208 
19209  mysql_close(l_mysql);
19210 }
19211 
19212 
19213 /*
19214  WL#56587: Protocol support for password expiration
19215 */
19216 static void test_wl6587()
19217 {
19218  int rc;
19219  MYSQL *l_mysql;
19220  my_bool can;
19221 
19222  myheader("test_wl6587");
19223 
19224  /* initialize the server user */
19225  rc= mysql_query(mysql,
19226  "CREATE USER wl6587_cli@localhost IDENTIFIED BY 'wl6587'");
19227  myquery(rc);
19228  rc= mysql_query(mysql, "ALTER USER wl6587_cli@localhost PASSWORD EXPIRE");
19229  myquery(rc);
19230 
19231  /* prepare the connection */
19232  l_mysql= mysql_client_init(NULL);
19233  DIE_UNLESS(l_mysql != NULL);
19234 
19235  /* connect must fail : the flag is off by default */
19236  l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19237  "wl6587", "test", opt_port,
19238  opt_unix_socket, 0);
19239  DIE_UNLESS(l_mysql == 0);
19240 
19241  l_mysql= mysql_client_init(NULL);
19242  DIE_UNLESS(l_mysql != NULL);
19243 
19244  /* try the last argument. should work */
19245  l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19246  "wl6587", "test", opt_port,
19247  opt_unix_socket,
19248  CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS);
19249  DIE_UNLESS(l_mysql != 0);
19250 
19251  /* must fail : sandbox mode */
19252  rc= mysql_query(l_mysql, "SELECT USER()");
19253  myerror2(l_mysql,NULL);
19254  DIE_UNLESS(rc != 0);
19255 
19256  mysql_close(l_mysql);
19257 
19258  /* try setting the option */
19259 
19260  l_mysql= mysql_client_init(NULL);
19261  DIE_UNLESS(l_mysql != NULL);
19262 
19263  can= TRUE;
19264  rc= mysql_options(l_mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &can);
19265  DIE_UNLESS(rc == 0);
19266 
19267  l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
19268  "wl6587", "test", opt_port,
19269  opt_unix_socket, 0);
19270  DIE_UNLESS(l_mysql != 0);
19271 
19272  /* must fail : sandbox mode */
19273  rc= mysql_query(l_mysql, "SELECT USER()");
19274  myerror2(l_mysql,NULL);
19275  DIE_UNLESS(rc != 0);
19276 
19277  mysql_close(l_mysql);
19278 
19279  /* try change user against an expired account */
19280 
19281  l_mysql= mysql_client_init(NULL);
19282  DIE_UNLESS(l_mysql != NULL);
19283 
19284  can= FALSE;
19285  rc= mysql_options(l_mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &can);
19286  DIE_UNLESS(rc == 0);
19287 
19288 
19289  l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
19290  opt_password, current_db, opt_port,
19291  opt_unix_socket, 0);
19292  DIE_UNLESS(l_mysql != 0);
19293 
19294  rc= mysql_change_user(l_mysql, "wl6587_cli", "wl6587", "test");
19295  DIE_UNLESS(rc == TRUE);
19296 
19297  mysql_close(l_mysql);
19298 
19299  /* cleanup */
19300  rc= mysql_query(mysql, "DROP USER wl6587_cli@localhost");
19301  myquery(rc);
19302 }
19303 
19304 
19305 static struct my_tests_st my_tests[]= {
19306  { "disable_query_logs", disable_query_logs },
19307  { "test_view_sp_list_fields", test_view_sp_list_fields },
19308  { "client_query", client_query },
19309  { "test_prepare_insert_update", test_prepare_insert_update},
19310 #if NOT_YET_WORKING
19311  { "test_drop_temp", test_drop_temp },
19312 #endif
19313  { "test_fetch_seek", test_fetch_seek },
19314  { "test_fetch_nobuffs", test_fetch_nobuffs },
19315  { "test_open_direct", test_open_direct },
19316  { "test_fetch_null", test_fetch_null },
19317  { "test_ps_null_param", test_ps_null_param },
19318  { "test_fetch_date", test_fetch_date },
19319  { "test_fetch_str", test_fetch_str },
19320  { "test_fetch_long", test_fetch_long },
19321  { "test_fetch_short", test_fetch_short },
19322  { "test_fetch_tiny", test_fetch_tiny },
19323  { "test_fetch_bigint", test_fetch_bigint },
19324  { "test_fetch_float", test_fetch_float },
19325  { "test_fetch_double", test_fetch_double },
19326  { "test_bind_result_ext", test_bind_result_ext },
19327  { "test_bind_result_ext1", test_bind_result_ext1 },
19328  { "test_select_direct", test_select_direct },
19329  { "test_select_prepare", test_select_prepare },
19330  { "test_select", test_select },
19331  { "test_select_version", test_select_version },
19332  { "test_ps_conj_select", test_ps_conj_select },
19333  { "test_select_show_table", test_select_show_table },
19334  { "test_func_fields", test_func_fields },
19335  { "test_long_data", test_long_data },
19336  { "test_insert", test_insert },
19337  { "test_set_variable", test_set_variable },
19338  { "test_select_show", test_select_show },
19339  { "test_prepare_noparam", test_prepare_noparam },
19340  { "test_bind_result", test_bind_result },
19341  { "test_prepare_simple", test_prepare_simple },
19342  { "test_prepare", test_prepare },
19343  { "test_null", test_null },
19344  { "test_debug_example", test_debug_example },
19345  { "test_update", test_update },
19346  { "test_simple_update", test_simple_update },
19347  { "test_simple_delete", test_simple_delete },
19348  { "test_double_compare", test_double_compare },
19349  { "client_store_result", client_store_result },
19350  { "client_use_result", client_use_result },
19351  { "test_tran_bdb", test_tran_bdb },
19352  { "test_tran_innodb", test_tran_innodb },
19353  { "test_prepare_ext", test_prepare_ext },
19354  { "test_prepare_syntax", test_prepare_syntax },
19355  { "test_field_names", test_field_names },
19356  { "test_field_flags", test_field_flags },
19357  { "test_long_data_str", test_long_data_str },
19358  { "test_long_data_str1", test_long_data_str1 },
19359  { "test_long_data_bin", test_long_data_bin },
19360  { "test_warnings", test_warnings },
19361  { "test_errors", test_errors },
19362  { "test_prepare_resultset", test_prepare_resultset },
19363  { "test_stmt_close", test_stmt_close },
19364  { "test_prepare_field_result", test_prepare_field_result },
19365  { "test_multi_stmt", test_multi_stmt },
19366  { "test_multi_statements", test_multi_statements },
19367  { "test_prepare_multi_statements", test_prepare_multi_statements },
19368  { "test_store_result", test_store_result },
19369  { "test_store_result1", test_store_result1 },
19370  { "test_store_result2", test_store_result2 },
19371  { "test_subselect", test_subselect },
19372  { "test_date", test_date },
19373  { "test_date_frac", test_date_frac },
19374  { "test_temporal_param", test_temporal_param },
19375  { "test_date_date", test_date_date },
19376  { "test_date_time", test_date_time },
19377  { "test_date_ts", test_date_ts },
19378  { "test_date_dt", test_date_dt },
19379  { "test_prepare_alter", test_prepare_alter },
19380  { "test_manual_sample", test_manual_sample },
19381  { "test_pure_coverage", test_pure_coverage },
19382  { "test_buffers", test_buffers },
19383  { "test_ushort_bug", test_ushort_bug },
19384  { "test_sshort_bug", test_sshort_bug },
19385  { "test_stiny_bug", test_stiny_bug },
19386  { "test_field_misc", test_field_misc },
19387  { "test_set_option", test_set_option },
19388 #ifdef EMBEDDED_LIBRARY
19389  { "test_embedded_start_stop", test_embedded_start_stop },
19390 #endif
19391 #ifndef EMBEDDED_LIBRARY
19392  { "test_prepare_grant", test_prepare_grant },
19393 #endif
19394  { "test_frm_bug", test_frm_bug },
19395  { "test_explain_bug", test_explain_bug },
19396  { "test_decimal_bug", test_decimal_bug },
19397  { "test_nstmts", test_nstmts },
19398  { "test_logs;", test_logs },
19399  { "test_cuted_rows", test_cuted_rows },
19400  { "test_fetch_offset", test_fetch_offset },
19401  { "test_fetch_column", test_fetch_column },
19402  { "test_mem_overun", test_mem_overun },
19403  { "test_list_fields", test_list_fields },
19404  { "test_free_result", test_free_result },
19405  { "test_free_store_result", test_free_store_result },
19406  { "test_sqlmode", test_sqlmode },
19407  { "test_ts", test_ts },
19408  { "test_bug1115", test_bug1115 },
19409  { "test_bug1180", test_bug1180 },
19410  { "test_bug1500", test_bug1500 },
19411  { "test_bug1644", test_bug1644 },
19412  { "test_bug1946", test_bug1946 },
19413  { "test_bug2248", test_bug2248 },
19414  { "test_parse_error_and_bad_length", test_parse_error_and_bad_length },
19415  { "test_bug2247", test_bug2247 },
19416  { "test_subqueries", test_subqueries },
19417  { "test_bad_union", test_bad_union },
19418  { "test_distinct", test_distinct },
19419  { "test_subqueries_ref", test_subqueries_ref },
19420  { "test_union", test_union },
19421  { "test_bug3117", test_bug3117 },
19422  { "test_join", test_join },
19423  { "test_selecttmp", test_selecttmp },
19424  { "test_create_drop", test_create_drop },
19425  { "test_rename", test_rename },
19426  { "test_do_set", test_do_set },
19427  { "test_multi", test_multi },
19428  { "test_insert_select", test_insert_select },
19429  { "test_bind_nagative", test_bind_nagative },
19430  { "test_derived", test_derived },
19431  { "test_xjoin", test_xjoin },
19432  { "test_bug3035", test_bug3035 },
19433  { "test_union2", test_union2 },
19434  { "test_bug1664", test_bug1664 },
19435  { "test_union_param", test_union_param },
19436  { "test_order_param", test_order_param },
19437  { "test_ps_i18n", test_ps_i18n },
19438  { "test_bug3796", test_bug3796 },
19439  { "test_bug4026", test_bug4026 },
19440  { "test_bug4079", test_bug4079 },
19441  { "test_bug4236", test_bug4236 },
19442  { "test_bug4030", test_bug4030 },
19443  { "test_bug5126", test_bug5126 },
19444  { "test_bug4231", test_bug4231 },
19445  { "test_bug5399", test_bug5399 },
19446  { "test_bug5194", test_bug5194 },
19447  { "test_bug5315", test_bug5315 },
19448  { "test_bug6049", test_bug6049 },
19449  { "test_bug6058", test_bug6058 },
19450  { "test_bug6059", test_bug6059 },
19451  { "test_bug6046", test_bug6046 },
19452  { "test_bug6081", test_bug6081 },
19453  { "test_bug6096", test_bug6096 },
19454  { "test_datetime_ranges", test_datetime_ranges },
19455  { "test_bug4172", test_bug4172 },
19456  { "test_conversion", test_conversion },
19457  { "test_rewind", test_rewind },
19458  { "test_bug6761", test_bug6761 },
19459  { "test_view", test_view },
19460  { "test_view_where", test_view_where },
19461  { "test_view_2where", test_view_2where },
19462  { "test_view_star", test_view_star },
19463  { "test_view_insert", test_view_insert },
19464  { "test_left_join_view", test_left_join_view },
19465  { "test_view_insert_fields", test_view_insert_fields },
19466  { "test_basic_cursors", test_basic_cursors },
19467  { "test_cursors_with_union", test_cursors_with_union },
19468  { "test_cursors_with_procedure", test_cursors_with_procedure },
19469  { "test_truncation", test_truncation },
19470  { "test_truncation_option", test_truncation_option },
19471  { "test_client_character_set", test_client_character_set },
19472  { "test_bug8330", test_bug8330 },
19473  { "test_bug7990", test_bug7990 },
19474  { "test_bug8378", test_bug8378 },
19475  { "test_bug8722", test_bug8722 },
19476  { "test_bug8880", test_bug8880 },
19477  { "test_bug9159", test_bug9159 },
19478  { "test_bug9520", test_bug9520 },
19479  { "test_bug9478", test_bug9478 },
19480  { "test_bug9643", test_bug9643 },
19481  { "test_bug10729", test_bug10729 },
19482  { "test_bug11111", test_bug11111 },
19483  { "test_bug9992", test_bug9992 },
19484  { "test_bug10736", test_bug10736 },
19485  { "test_bug10794", test_bug10794 },
19486  { "test_bug11172", test_bug11172 },
19487  { "test_bug11656", test_bug11656 },
19488  { "test_bug10214", test_bug10214 },
19489  { "test_bug9735", test_bug9735 },
19490  { "test_bug11183", test_bug11183 },
19491  { "test_bug11037", test_bug11037 },
19492  { "test_bug10760", test_bug10760 },
19493  { "test_bug12001", test_bug12001 },
19494  { "test_bug11718", test_bug11718 },
19495  { "test_bug12925", test_bug12925 },
19496  { "test_bug11909", test_bug11909 },
19497  { "test_bug11901", test_bug11901 },
19498  { "test_bug11904", test_bug11904 },
19499  { "test_bug12243", test_bug12243 },
19500  { "test_bug14210", test_bug14210 },
19501  { "test_bug13488", test_bug13488 },
19502  { "test_bug13524", test_bug13524 },
19503  { "test_bug14845", test_bug14845 },
19504  { "test_opt_reconnect", test_opt_reconnect },
19505  { "test_bug15510", test_bug15510},
19506 #ifndef EMBEDDED_LIBRARY
19507  { "test_bug12744", test_bug12744 },
19508 #endif
19509  { "test_bug16143", test_bug16143 },
19510  { "test_bug16144", test_bug16144 },
19511  { "test_bug15613", test_bug15613 },
19512  { "test_bug20152", test_bug20152 },
19513  { "test_bug14169", test_bug14169 },
19514  { "test_bug17667", test_bug17667 },
19515  { "test_bug15752", test_bug15752 },
19516  { "test_mysql_insert_id", test_mysql_insert_id },
19517  { "test_bug19671", test_bug19671 },
19518  { "test_bug21206", test_bug21206 },
19519  { "test_bug21726", test_bug21726 },
19520  { "test_bug15518", test_bug15518 },
19521  { "test_bug23383", test_bug23383 },
19522  { "test_bug32265", test_bug32265 },
19523  { "test_bug21635", test_bug21635 },
19524  { "test_status", test_status },
19525  { "test_bug24179", test_bug24179 },
19526  { "test_ps_query_cache", test_ps_query_cache },
19527  { "test_bug28075", test_bug28075 },
19528  { "test_bug27876", test_bug27876 },
19529  { "test_bug28505", test_bug28505 },
19530  { "test_bug28934", test_bug28934 },
19531  { "test_bug27592", test_bug27592 },
19532  { "test_bug29687", test_bug29687 },
19533  { "test_bug29692", test_bug29692 },
19534  { "test_bug29306", test_bug29306 },
19535  { "test_change_user", test_change_user },
19536  { "test_bug30472", test_bug30472 },
19537  { "test_bug20023", test_bug20023 },
19538  { "test_bug45010", test_bug45010 },
19539  { "test_bug53371", test_bug53371 },
19540  { "test_bug31418", test_bug31418 },
19541  { "test_bug31669", test_bug31669 },
19542  { "test_bug28386", test_bug28386 },
19543  { "test_wl4166_1", test_wl4166_1 },
19544  { "test_wl4166_2", test_wl4166_2 },
19545  { "test_wl4166_3", test_wl4166_3 },
19546  { "test_wl4166_4", test_wl4166_4 },
19547  { "test_bug36004", test_bug36004 },
19548  { "test_wl4284_1", test_wl4284_1 },
19549  { "test_wl4435", test_wl4435 },
19550  { "test_wl4435_2", test_wl4435_2 },
19551  { "test_wl4435_3", test_wl4435_3 },
19552  { "test_bug38486", test_bug38486 },
19553  { "test_bug33831", test_bug33831 },
19554  { "test_bug40365", test_bug40365 },
19555  { "test_bug43560", test_bug43560 },
19556 #ifdef HAVE_QUERY_CACHE
19557  { "test_bug36326", test_bug36326 },
19558 #endif
19559  { "test_bug41078", test_bug41078 },
19560  { "test_bug44495", test_bug44495 },
19561  { "test_bug49972", test_bug49972 },
19562  { "test_bug42373", test_bug42373 },
19563  { "test_bug54041", test_bug54041 },
19564  { "test_bug47485", test_bug47485 },
19565  { "test_bug58036", test_bug58036 },
19566  { "test_bug57058", test_bug57058 },
19567  { "test_bug56976", test_bug56976 },
19568  { "test_bug11766854", test_bug11766854 },
19569  { "test_bug54790", test_bug54790 },
19570  { "test_bug12337762", test_bug12337762 },
19571  { "test_bug11754979", test_bug11754979 },
19572  { "test_bug13001491", test_bug13001491 },
19573  { "test_wl5968", test_wl5968 },
19574  { "test_wl5924", test_wl5924 },
19575  { "test_wl6587", test_wl6587 },
19576  { 0, 0 }
19577 };
19578 
19579 
19580 static struct my_tests_st *get_my_tests() { return my_tests; }