Commit message: BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST()

Analysis:
---------
Invalid memory access maybe observed when using prepared statements if:
a) The mysql client connection is lost after statement preparation
   is complete and
b) There is at least one statement which is in initialized state but
   not prepared yet.

When the client detects a closed connection, it calls end_server()
to shutdown the connection. As part of the clean up, the
mysql_prune_stmt_list() removes the statements which has transitioned
beyond the initialized state and retains only the statements which
are in a initialized state. During this processing, the initialized
statements are moved from 'mysql->stmts' to a temporary 'pruned_list'.
When moving the first 'INIT_DONE' element to the pruned_list,
'element->next' is set to NULL. Hence the rest of the list is never
traversed and the statements which have transitioned beyond the
initialized state are never invalidated.

When the mysql_stmt_close() is called for the statement which is not
invalidated; the statements list is updated in order to remove the
statement. This would end up accessing freed memory(freed by the
mysql_stmt_close() for a previous statement in the list).

Fix:
---
mysql_prune_stmt_list() called list_add() incorrectly to create a
temporary list. The use case of list_add() is to add a single
element to the front of the doubly linked list.
mysql_prune_stmt_list() called list_add() by passing an entire
list as the 'element'.

mysql_prune_stmt_list() now uses list_delete() to remove the
statement which has transitioned beyond the initialized phase.
Thus the statement list would contain only elements where the
the state of the statement is initialized.

Note: Run the test with valgrind-mysqltest and leak-check=full
option to see the invalid memory access.
CVE: CVE-2017-3302
CWE: CWE-416
Vulnerability description: Crash in libmysqlclient.so in Oracle MySQL before 5.6.21 and 5.7.x before 5.7.5 and MariaDB through 5.5.54, 10.0.x through 10.0.29, 10.1.x through 10.1.21, and 10.2.x through 10.2.3.

Project: mysql-server
File: mysql_client_test.c

static void test_long_data_str()
{
  MYSQL_STMT *stmt;
  int        rc, i;
  char       data[255];
  long       length;
  ulong      length1;
  MYSQL_RES  *result;
  MYSQL_BIND my_bind[2];
  my_bool    is_null[2];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_long_data_str");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(id int, longstr long varchar)");
  myquery(rc);

  strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer= (void *)&length;
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
  my_bind[0].is_null= &is_null[0];
  is_null[0]= 0;
  length= 0;

  my_bind[1].buffer= data;                          /* string data */
  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
  my_bind[1].length= &length1;
  my_bind[1].is_null= &is_null[1];
  is_null[1]= 0;
  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  length= 40;
  strmov(data, "MySQL AB");

  /* supply data in pieces */
  for(i= 0; i < 4; i++)
  {
    rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 5);
    check_execute(stmt, rc);
  }
  /* execute */
  rc= mysql_stmt_execute(stmt);
  if (!opt_silent)
    fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);

  rc= mysql_commit(mysql);
  myquery(rc);

  /* now fetch the results ..*/
  rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr FROM test_long_data_str");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 1);
  mysql_free_result(result);

  sprintf(data, "%d", i*5);
  verify_col_data("test_long_data_str", "LENGTH(longstr)", data);
  data[0]= '\0';
  while (i--)
   strxmov(data, data, "MySQL", NullS);
  verify_col_data("test_long_data_str", "longstr", data);

  rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_double_compare()
{
  MYSQL_STMT *stmt;
  int        rc;
  char       real_data[10], tiny_data;
  double     double_data;
  MYSQL_RES  *result;
  MYSQL_BIND my_bind[3];
  ulong      length[3];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_double_compare");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_double_compare");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_double_compare(col1 tinyint, "
                         " col2 float, col3 double )");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO test_double_compare "
                         "VALUES (1, 10.2, 34.5)");
  myquery(rc);

  strmov(query, "UPDATE test_double_compare SET col1=100 "
                "WHERE col1 = ? AND col2 = ? AND COL3 = ?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 3);

  /* Always memset bind array because there can be internal members */
  memset(my_bind, 0, sizeof(my_bind));

  /* tinyint */
  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
  my_bind[0].buffer= (void *)&tiny_data;

  /* string->float */
  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
  my_bind[1].buffer= (void *)&real_data;
  my_bind[1].buffer_length= sizeof(real_data);
  my_bind[1].length= &length[1];
  length[1]= 10;

  /* double */
  my_bind[2].buffer_type= MYSQL_TYPE_DOUBLE;
  my_bind[2].buffer= (void *)&double_data;

  tiny_data= 1;
  strmov(real_data, "10.2");
  double_data= 34.5;
  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  verify_affected_rows(0);

  mysql_stmt_close(stmt);

  /* now fetch the results ..*/
  rc= mysql_commit(mysql);
  myquery(rc);

  /* test the results now, only one row should exist */
  rc= mysql_query(mysql, "SELECT * FROM test_double_compare");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS((int)tiny_data == rc);
  mysql_free_result(result);
}

Project: mysql-server
File: mysql_client_test.c

static void test_wl6587()
{
  int rc;
  MYSQL *l_mysql;
  my_bool can;

  myheader("test_wl6587");

  /* initialize the server user */
  rc= mysql_query(mysql,
                  "CREATE USER wl6587_cli@localhost IDENTIFIED BY 'wl6587'");
  myquery(rc);
  rc= mysql_query(mysql, "ALTER USER wl6587_cli@localhost PASSWORD EXPIRE");
  myquery(rc);

  /* prepare the connection */
  l_mysql= mysql_client_init(NULL);
  DIE_UNLESS(l_mysql != NULL);

  /* connect must fail : the flag is off by default */
  l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
                              "wl6587", "test", opt_port,
                              opt_unix_socket, 0);
  DIE_UNLESS(l_mysql == 0);

  l_mysql= mysql_client_init(NULL);
  DIE_UNLESS(l_mysql != NULL);

  /* try the last argument. should work */
  l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
                         "wl6587", "test", opt_port,
                         opt_unix_socket,
                         CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS);
  DIE_UNLESS(l_mysql != 0);

  /* must fail : sandbox mode */
  rc= mysql_query(l_mysql, "SELECT USER()");
  myerror2(l_mysql,NULL);
  DIE_UNLESS(rc != 0);

  mysql_close(l_mysql);

  /* try setting the option */

  l_mysql= mysql_client_init(NULL);
  DIE_UNLESS(l_mysql != NULL);

  can= TRUE;
  rc= mysql_options(l_mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &can);
  DIE_UNLESS(rc == 0);

  l_mysql= mysql_real_connect(l_mysql, opt_host, "wl6587_cli",
                         "wl6587", "test", opt_port,
                         opt_unix_socket, 0);
  DIE_UNLESS(l_mysql != 0);

  /* must fail : sandbox mode */
  rc= mysql_query(l_mysql, "SELECT USER()");
  myerror2(l_mysql,NULL);
  DIE_UNLESS(rc != 0);

  mysql_close(l_mysql);

  /* try change user against an expired account */

  l_mysql= mysql_client_init(NULL);
  DIE_UNLESS(l_mysql != NULL);

  can= FALSE;
  rc= mysql_options(l_mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &can);
  DIE_UNLESS(rc == 0);


  l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
                         opt_password, current_db, opt_port,
                         opt_unix_socket, 0);
  DIE_UNLESS(l_mysql != 0);

  rc= mysql_change_user(l_mysql, "wl6587_cli", "wl6587", "test");
  DIE_UNLESS(rc == TRUE);

  mysql_close(l_mysql);

  /* cleanup */
  rc= mysql_query(mysql, "DROP USER wl6587_cli@localhost");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug6049()
{
  MYSQL_STMT *stmt;
  MYSQL_BIND my_bind[1];
  MYSQL_RES *res;
  MYSQL_ROW row;
  const char *stmt_text;
  char buffer[30];
  ulong length;
  int rc;

  myheader("test_bug6049");

  stmt_text= "SELECT MAKETIME(-25, 12, 12)";

  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);
  res= mysql_store_result(mysql);
  row= mysql_fetch_row(res);

  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_execute(stmt, rc);
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  memset(my_bind, 0, sizeof(my_bind));
  my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
  my_bind[0].buffer         = &buffer;
  my_bind[0].buffer_length  = sizeof(buffer);
  my_bind[0].length         = &length;

  mysql_stmt_bind_result(stmt, my_bind);
  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == 0);

  if (!opt_silent)
  {
    printf("Result from query: %s\n", row[0]);
    printf("Result from prepared statement: %s\n", (char*) buffer);
  }

  DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);

  mysql_free_result(res);
  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug1115()
{
  MYSQL_STMT *stmt;
  int rc;
  MYSQL_BIND my_bind[1];
  ulong length[1];
  char szData[11];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_bug1115");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_select(\
session_id  char(9) NOT NULL, \
    a       int(8) unsigned NOT NULL, \
    b        int(5) NOT NULL, \
    c      int(5) NOT NULL, \
    d  datetime NOT NULL)");
  myquery(rc);
  rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
                         "(\"abc\", 1, 2, 3, 2003-08-30), "
                         "(\"abd\", 1, 2, 3, 2003-08-30), "
                         "(\"abf\", 1, 2, 3, 2003-08-30), "
                         "(\"abg\", 1, 2, 3, 2003-08-30), "
                         "(\"abh\", 1, 2, 3, 2003-08-30), "
                         "(\"abj\", 1, 2, 3, 2003-08-30), "
                         "(\"abk\", 1, 2, 3, 2003-08-30), "
                         "(\"abl\", 1, 2, 3, 2003-08-30), "
                         "(\"abq\", 1, 2, 3, 2003-08-30) ");
  myquery(rc);
  rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
                         "(\"abw\", 1, 2, 3, 2003-08-30), "
                         "(\"abe\", 1, 2, 3, 2003-08-30), "
                         "(\"abr\", 1, 2, 3, 2003-08-30), "
                         "(\"abt\", 1, 2, 3, 2003-08-30), "
                         "(\"aby\", 1, 2, 3, 2003-08-30), "
                         "(\"abu\", 1, 2, 3, 2003-08-30), "
                         "(\"abi\", 1, 2, 3, 2003-08-30), "
                         "(\"abo\", 1, 2, 3, 2003-08-30), "
                         "(\"abp\", 1, 2, 3, 2003-08-30), "
                         "(\"abz\", 1, 2, 3, 2003-08-30), "
                         "(\"abx\", 1, 2, 3, 2003-08-30)");
  myquery(rc);

  strmov(query, "SELECT * FROM test_select WHERE "
                "CONVERT(session_id USING utf8)= ?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 1);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  strmov(szData, (char *)"abc");
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (void *)szData;
  my_bind[0].buffer_length= 10;
  my_bind[0].length= &length[0];
  length[0]= 3;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 1);

  strmov(szData, (char *)"venu");
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (void *)szData;
  my_bind[0].buffer_length= 10;
  my_bind[0].length= &length[0];
  length[0]= 4;
  my_bind[0].is_null= 0;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 0);

  strmov(szData, (char *)"abc");
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (void *)szData;
  my_bind[0].buffer_length= 10;
  my_bind[0].length= &length[0];
  length[0]= 3;
  my_bind[0].is_null= 0;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 1);

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_store_result2()
{
  MYSQL_STMT *stmt;
  int        rc;
  int        nData;
  ulong      length;
  MYSQL_BIND my_bind[1];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_store_result2");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
  myquery(rc);

  rc= mysql_commit(mysql);
  myquery(rc);

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
  my_bind[0].buffer= (void *) &nData;      /* integer data */
  my_bind[0].length= &length;
  my_bind[0].is_null= 0;

  strmov((char *)query , "SELECT col1 FROM test_store_result where col1= ?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_bind_result(stmt, my_bind);
  check_execute(stmt, rc);

  nData= 10; length= 0;
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  nData= 0;
  rc= mysql_stmt_store_result(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n row 1: %d", nData);
  DIE_UNLESS(nData == 10);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  nData= 20;
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  nData= 0;
  rc= mysql_stmt_store_result(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n row 1: %d", nData);
  DIE_UNLESS(nData == 20);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);
  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug3796()
{
  MYSQL_STMT *stmt;
  MYSQL_BIND my_bind[1];
  const char *concat_arg0= "concat_with_";
  enum { OUT_BUFF_SIZE= 30 };
  char out_buff[OUT_BUFF_SIZE];
  char canonical_buff[OUT_BUFF_SIZE];
  ulong out_length;
  const char *stmt_text;
  int rc;

  myheader("test_bug3796");

  /* Create and fill test table */
  stmt_text= "DROP TABLE IF EXISTS t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  /* Create statement handle and prepare it with select */
  stmt= mysql_stmt_init(mysql);
  stmt_text= "SELECT concat(?, b) FROM t1";

  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_execute(stmt, rc);

  /* Bind input buffers */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (void *) concat_arg0;
  my_bind[0].buffer_length= strlen(concat_arg0);

  mysql_stmt_bind_param(stmt, my_bind);

  /* Execute the select statement */
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  my_bind[0].buffer= (void *) out_buff;
  my_bind[0].buffer_length= OUT_BUFF_SIZE;
  my_bind[0].length= &out_length;

  mysql_stmt_bind_result(stmt, my_bind);

  rc= mysql_stmt_fetch(stmt);
  if (!opt_silent)
    printf("Concat result: '%s'\n", out_buff);
  check_execute(stmt, rc);
  strmov(canonical_buff, concat_arg0);
  strcat(canonical_buff, "ONE");
  DIE_UNLESS(strlen(canonical_buff) == out_length &&
         strncmp(out_buff, canonical_buff, out_length) == 0);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);
  strmov(canonical_buff + strlen(concat_arg0), "TWO");
  DIE_UNLESS(strlen(canonical_buff) == out_length &&
         strncmp(out_buff, canonical_buff, out_length) == 0);
  if (!opt_silent)
    printf("Concat result: '%s'\n", out_buff);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  mysql_stmt_close(stmt);

  stmt_text= "DROP TABLE IF EXISTS t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_union_param()
{
  MYSQL_STMT *stmt;
  char *query;
  int rc, i;
  MYSQL_BIND      my_bind[2];
  char            my_val[4];
  ulong           my_length= 3L;
  my_bool         my_null= FALSE;
  myheader("test_union_param");

  strmov(my_val, "abc");

  query= (char*)"select ? as my_col union distinct select ?";
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  /* bind parameters */
  my_bind[0].buffer_type=    MYSQL_TYPE_STRING;
  my_bind[0].buffer=         (char*) &my_val;
  my_bind[0].buffer_length=  4;
  my_bind[0].length=         &my_length;
  my_bind[0].is_null=        (char*)&my_null;
  my_bind[1].buffer_type=    MYSQL_TYPE_STRING;
  my_bind[1].buffer=         (char*) &my_val;
  my_bind[1].buffer_length=  4;
  my_bind[1].length=         &my_length;
  my_bind[1].is_null=        (char*)&my_null;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  for (i= 0; i < 3; i++)
  {
    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);
    rc= my_process_stmt_result(stmt);
    DIE_UNLESS(rc == 1);
  }

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug11656()
{
  MYSQL_STMT *stmt;
  MYSQL_BIND my_bind[2];
  int rc;
  const char *stmt_text;
  char buf[2][20];
  int i= 0;
  ulong type;

  myheader("test_bug11656");

  mysql_query(mysql, "drop table if exists t1");

  rc= mysql_query(mysql, "create table t1 ("
                  "server varchar(40) not null, "
                  "test_kind varchar(1) not null, "
                  "test_id varchar(30) not null , "
                  "primary key (server,test_kind,test_id))");
  myquery(rc);

  stmt_text= "select distinct test_kind, test_id from t1 "
             "where server in (?, ?)";
  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
  check_execute(stmt, rc);
  type= (ulong) CURSOR_TYPE_READ_ONLY;
  mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);

  memset(my_bind, 0, sizeof(my_bind));
  strmov(buf[0], "pcint502_MY2");
  strmov(buf[1], "*");
  for (i=0; i < 2; i++)
  {
    my_bind[i].buffer_type= MYSQL_TYPE_STRING;
    my_bind[i].buffer= (uchar* *)&buf[i];
    my_bind[i].buffer_length= strlen(buf[i]);
  }
  mysql_stmt_bind_param(stmt, my_bind);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  mysql_stmt_close(stmt);
  rc= mysql_query(mysql, "drop table t1");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_long_data()
{
  MYSQL_STMT *stmt;
  int        rc, int_data;
  char       *data= NullS;
  MYSQL_RES  *result;
  MYSQL_BIND my_bind[3];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_long_data");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, "
                         "      col2 long varchar, col3 long varbinary)");
  myquery(rc);

  strmov(query, "INSERT INTO test_long_data(col1, col2) VALUES(?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt_r(stmt);

  strmov(query, "INSERT INTO test_long_data(col1, col2, col3) VALUES(?, ?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 3);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer= (void *)&int_data;
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;

  my_bind[1].buffer_type= MYSQL_TYPE_STRING;

  my_bind[2]= my_bind[1];
  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  int_data= 999;
  data= (char *)"Michael";

  /* supply data in pieces */
  rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
  data= (char *)" 'Monty' Widenius";
  rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
  check_execute(stmt, rc);
  rc= mysql_stmt_send_long_data(stmt, 2, "Venu (venu@mysql.com)", 4);
  check_execute(stmt, rc);

  /* execute */
  rc= mysql_stmt_execute(stmt);
  if (!opt_silent)
    fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
  check_execute(stmt, rc);

  rc= mysql_commit(mysql);
  myquery(rc);

  /* now fetch the results ..*/
  rc= mysql_query(mysql, "SELECT * FROM test_long_data");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 1);
  mysql_free_result(result);

  verify_col_data("test_long_data", "col1", "999");
  verify_col_data("test_long_data", "col2", "Michael 'Monty' Widenius");
  verify_col_data("test_long_data", "col3", "Venu");
  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_update()
{
  MYSQL_STMT *stmt;
  int        rc;
  char       szData[25];
  int        nData= 1;
  MYSQL_RES  *result;
  MYSQL_BIND my_bind[2];
  ulong length[2];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_update");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_update("
                               "col1 int primary key auto_increment, "
                               "col2 varchar(50), col3 int )");
  myquery(rc);

  strmov(query, "INSERT INTO test_update(col2, col3) VALUES(?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  /* string data */
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= szData;
  my_bind[0].buffer_length= sizeof(szData);
  my_bind[0].length= &length[0];
  length[0]= sprintf(szData, "inserted-data");

  my_bind[1].buffer= (void *)&nData;
  my_bind[1].buffer_type= MYSQL_TYPE_LONG;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  nData= 100;
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  verify_affected_rows(1);
  mysql_stmt_close(stmt);

  strmov(query, "UPDATE test_update SET col2= ? WHERE col3= ?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);
  nData= 100;

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= szData;
  my_bind[0].buffer_length= sizeof(szData);
  my_bind[0].length= &length[0];
  length[0]= sprintf(szData, "updated-data");

  my_bind[1].buffer= (void *)&nData;
  my_bind[1].buffer_type= MYSQL_TYPE_LONG;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  verify_affected_rows(1);

  mysql_stmt_close(stmt);

  /* now fetch the results ..*/
  rc= mysql_commit(mysql);
  myquery(rc);

  /* test the results now, only one row should exist */
  rc= mysql_query(mysql, "SELECT * FROM test_update");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 1);
  mysql_free_result(result);
}

Project: mysql-server
File: mysql_client_test.c

static void test_ts()
{
  MYSQL_STMT *stmt;
  MYSQL_BIND my_bind[6];
  MYSQL_TIME ts;
  MYSQL_RES  *prep_res;
  char       strts[30];
  ulong      length;
  int        rc, field_count;
  char       name;
  char query[MAX_TEST_QUERY_LENGTH];
  const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
                            "SELECT a, b, c FROM test_ts WHERE %c=?",
                            "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
  myheader("test_ts");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)");
  myquery(rc);

  stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)");
  check_stmt(stmt);

  ts.year= 2003;
  ts.month= 07;
  ts.day= 12;
  ts.hour= 21;
  ts.minute= 07;
  ts.second= 46;
  ts.second_part= 0;
  length= (long)(strmov(strts, "2003-07-12 21:07:46") - strts);

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
  my_bind[0].buffer= (void *)&ts;
  my_bind[0].buffer_length= sizeof(ts);

  my_bind[2]= my_bind[1]= my_bind[0];

  my_bind[3].buffer_type= MYSQL_TYPE_STRING;
  my_bind[3].buffer= (void *)strts;
  my_bind[3].buffer_length= sizeof(strts);
  my_bind[3].length= &length;

  my_bind[5]= my_bind[4]= my_bind[3];

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);

  verify_col_data("test_ts", "a", "2003-07-12");
  verify_col_data("test_ts", "b", "21:07:46");
  verify_col_data("test_ts", "c", "2003-07-12 21:07:46");

  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts");
  check_stmt(stmt);

  prep_res= mysql_stmt_result_metadata(stmt);
  mytest(prep_res);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 2);
  field_count= mysql_num_fields(prep_res);

  mysql_free_result(prep_res);
  mysql_stmt_close(stmt);

  for (name= 'a'; field_count--; name++)
  {
    int row_count= 0;

    sprintf(query, queries[field_count], name);

    if (!opt_silent)
      fprintf(stdout, "\n  %s", query);
    stmt= mysql_simple_prepare(mysql, query);
    check_stmt(stmt);

    rc= mysql_stmt_bind_param(stmt, my_bind);
    check_execute(stmt, rc);

    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);

    while (mysql_stmt_fetch(stmt) == 0)
      row_count++;

    if (!opt_silent)
      fprintf(stdout, "\n   returned '%d' rows", row_count);
    DIE_UNLESS(row_count == 2);
    mysql_stmt_close(stmt);
  }
}

Project: mysql-server
File: mysql_client_test.c

static void test_mysql_insert_id()
{
  my_ulonglong res;
  int rc;

  myheader("test_mysql_insert_id");

  rc= mysql_query(mysql, "drop table if exists t1");
  myquery(rc);
  /* table without auto_increment column */
  rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t1 values (1,'a')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert into t1 values (null,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert into t1 select 5,'c'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);

  /*
    Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
    sporadically
  */
  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t2 values (null,'b')");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t1 select 5,'c'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "drop table t2");
  myquery(rc);
  
  rc= mysql_query(mysql, "insert into t1 select null,'d'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 300);
  rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    Behaviour change: old code used to return 0; but 400 is consistent
    with INSERT VALUES, and the manual's section of mysql_insert_id() does not
    say INSERT SELECT should be different.
  */
  DIE_UNLESS(res == 400);

  /* table with auto_increment column */
  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t2 values (1,'a')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 1);
  /* this should not influence next INSERT if it doesn't have auto_inc */
  rc= mysql_query(mysql, "insert into t1 values (10,'e')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);

  rc= mysql_query(mysql, "insert into t2 values (null,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 2);
  rc= mysql_query(mysql, "insert into t2 select 5,'c'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    Manual says that for multirow insert this should have been 5, but does not
    say for INSERT SELECT. This is a behaviour change: old code used to return
    0. We try to be consistent with INSERT VALUES.
  */
  DIE_UNLESS(res == 5);
  rc= mysql_query(mysql, "insert into t2 select null,'d'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 6);
  /* with more than one row */
  rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 11);
  rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    Manual says that for multirow insert this should have been 13, but does
    not say for INSERT SELECT. This is a behaviour change: old code used to
    return 0. We try to be consistent with INSERT VALUES.
  */
  DIE_UNLESS(res == 13);
  rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 14);
  rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 16);
  rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
  myquery_r(rc);
  rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
  myquery_r(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  /* mixing autogenerated and explicit values */
  rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
  myquery_r(rc);
  rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
  myquery_r(rc);
  rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    according to the manual, this might be 20 or 300, but it looks like
    auto_increment column takes priority over last_insert_id().
  */
  DIE_UNLESS(res == 20);
  /* If first autogenerated number fails and 2nd works: */
  rc= mysql_query(mysql, "drop table t2");
  myquery(rc);
  rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
                  "auto_increment, f2 varchar(255), unique (f2))");
  myquery(rc);
  rc= mysql_query(mysql, "insert into t2 values (null,'e')");
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 1);
  rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 2);
  /* If autogenerated fails and explicit works: */
  rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    Behaviour change: old code returned 3 (first autogenerated, even if it
    fails); we now return first successful autogenerated.
  */
  DIE_UNLESS(res == 13);
  /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
  rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 372);
  /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
  rc= mysql_query(mysql, "insert into t2 values (null,'g')");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 15);
  rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 0);
  /*
    Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
    mysql_insert_id() returns the id of the row, instead of not being
    affected.
  */
  rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
                  "update f2=concat('we updated ',f2)");
  myquery(rc);
  res= mysql_insert_id(mysql);
  DIE_UNLESS(res == 15);

  rc= mysql_query(mysql, "drop table t1,t2");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_datetime_ranges()
{
  const char *stmt_text;
  int rc, i;
  MYSQL_STMT *stmt;
  MYSQL_BIND my_bind[6];
  MYSQL_TIME tm[6];

  myheader("test_datetime_ranges");

  stmt_text= "drop table if exists t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
                              "hour datetime, min datetime, sec datetime)";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  stmt= mysql_simple_prepare(mysql,
                             "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
  check_stmt(stmt);
  verify_param_count(stmt, 6);

  memset(my_bind, 0, sizeof(my_bind));
  for (i= 0; i < 6; i++)
  {
    my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
    my_bind[i].buffer= &tm[i];
  }
  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
  tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
  tm[0].second_part= 0; tm[0].neg= 0;

  tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
  tm[0].year= 10000;  tm[1].month= 13; tm[2].day= 32;
  tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  my_process_warnings(mysql, 12);

  verify_col_data("t1", "year", "0000-00-00 00:00:00");
  verify_col_data("t1", "month", "0000-00-00 00:00:00");
  verify_col_data("t1", "day", "0000-00-00 00:00:00");
  verify_col_data("t1", "hour", "0000-00-00 00:00:00");
  verify_col_data("t1", "min", "0000-00-00 00:00:00");
  verify_col_data("t1", "sec", "0000-00-00 00:00:00");

  mysql_stmt_close(stmt);

  stmt_text= "delete from t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
                                    "VALUES (?, ?, ?)");
  check_stmt(stmt);
  verify_param_count(stmt, 3);

  /*
    We reuse contents of bind and tm arrays left from previous part of test.
  */
  for (i= 0; i < 3; i++)
    my_bind[i].buffer_type= MYSQL_TYPE_DATE;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  my_process_warnings(mysql, 6);

  verify_col_data("t1", "year", "0000-00-00 00:00:00");
  verify_col_data("t1", "month", "0000-00-00 00:00:00");
  verify_col_data("t1", "day", "0000-00-00 00:00:00");

  mysql_stmt_close(stmt);

  stmt_text= "drop table t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  stmt= mysql_simple_prepare(mysql,
                             "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
  check_stmt(stmt);
  verify_param_count(stmt, 5);

  /*
    Again we reuse what we can from previous part of test.
  */
  for (i= 0; i < 5; i++)
    my_bind[i].buffer_type= MYSQL_TYPE_TIME;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
  tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
  tm[0].second_part= 0; tm[0].neg= 0;

  tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
  tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  my_process_warnings(mysql, 2);

  verify_col_data("t1", "day_ovfl", "838:59:59");
  verify_col_data("t1", "day", "828:30:30");
  verify_col_data("t1", "hour", "270:30:30");
  verify_col_data("t1", "min", "00:00:00");
  verify_col_data("t1", "sec", "00:00:00");

  mysql_stmt_close(stmt);

  stmt_text= "drop table t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_cuted_rows()
{
  int        rc, count;
  MYSQL_RES  *result;

  myheader("test_cuted_rows");

  mysql_query(mysql, "DROP TABLE if exists t1");
  mysql_query(mysql, "DROP TABLE if exists t2");

  rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)");
  myquery(rc);

  count= mysql_warning_count(mysql);
  if (!opt_silent)
    fprintf(stdout, "\n total warnings: %d", count);
  DIE_UNLESS(count == 0);

  rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
  myquery(rc);

  count= mysql_warning_count(mysql);
  if (!opt_silent)
    fprintf(stdout, "\n total warnings: %d", count);
  DIE_UNLESS(count == 2);

  rc= mysql_query(mysql, "SHOW WARNINGS");
  myquery(rc);

  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 2);
  mysql_free_result(result);

  rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)");
  myquery(rc);

  count= mysql_warning_count(mysql);
  if (!opt_silent)
    fprintf(stdout, "\n total warnings: %d", count);
  DIE_UNLESS(count == 2);

  rc= mysql_query(mysql, "SHOW WARNINGS");
  myquery(rc);

  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 2);
  mysql_free_result(result);
}

Project: mysql-server
File: mysql_client_test.c

static void test_prepare_multi_statements()
{
  MYSQL *mysql_local;
  MYSQL_STMT *stmt;
  char query[MAX_TEST_QUERY_LENGTH];
  myheader("test_prepare_multi_statements");

  if (!(mysql_local= mysql_client_init(NULL)))
  {
    fprintf(stderr, "\n mysql_client_init() failed");
    exit(1);
  }

  if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
                           opt_password, current_db, opt_port,
                           opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
  {
    fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
    exit(1);
  }
  mysql_local->reconnect= 1;
  strmov(query, "select 1; select 'another value'");
  stmt= mysql_simple_prepare(mysql_local, query);
  check_stmt_r(stmt);
  mysql_close(mysql_local);
}

Project: mysql-server
File: mysql_client_test.c

static void test_decimal_bug()
{
  MYSQL_STMT *stmt;
  MYSQL_BIND my_bind[1];
  char       data[30];
  int        rc;
  my_bool    is_null;

  myheader("test_decimal_bug");

  mysql_autocommit(mysql, TRUE);

  rc= mysql_query(mysql, "drop table if exists test_decimal_bug");
  myquery(rc);

  rc= mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10, 2))");
  myquery(rc);

  rc= mysql_query(mysql, "insert into test_decimal_bug value(8), (10.22), (5.61)");
  myquery(rc);

  stmt= mysql_simple_prepare(mysql, "select c1 from test_decimal_bug where c1= ?");
  check_stmt(stmt);

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_NEWDECIMAL;
  my_bind[0].buffer= (void *)data;
  my_bind[0].buffer_length= 25;
  my_bind[0].is_null= &is_null;

  is_null= 0;
  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  strmov(data, "8.0");
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  data[0]= 0;
  rc= mysql_stmt_bind_result(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n data: %s", data);
  DIE_UNLESS(strcmp(data, "8.00") == 0);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  strmov(data, "5.61");
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  data[0]= 0;
  rc= mysql_stmt_bind_result(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n data: %s", data);
  DIE_UNLESS(strcmp(data, "5.61") == 0);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  is_null= 1;
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  strmov(data, "10.22"); is_null= 0;
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  data[0]= 0;
  rc= mysql_stmt_bind_result(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n data: %s", data);
  DIE_UNLESS(strcmp(data, "10.22") == 0);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug17309863()
{
  MYSQL *lmysql;
  unsigned long thread_id;
  char query[MAX_TEST_QUERY_LENGTH];
  int rc;

  myheader("test_bug17309863");

  if (!opt_silent)
    fprintf(stdout, "\n Establishing a test connection ...");
  if (!(lmysql= mysql_client_init(NULL)))
  {
    myerror("mysql_client_init() failed");
    exit(1);
  }
  lmysql->reconnect= 1;
  if (!(mysql_real_connect(lmysql, opt_host, opt_user,
                           opt_password, current_db, opt_port,
                           opt_unix_socket, 0)))
  {
    myerror("connection failed");
    exit(1);
  }
  if (!opt_silent)
    fprintf(stdout, "OK");

  thread_id= mysql_thread_id(lmysql);
  sprintf(query, "KILL %lu", thread_id);

  /*
    Running the "KILL <thread_id>" query in a separate connection.
  */
  if (thread_query(query))
    exit(1);

  /*
    The above KILL statement should have closed our connection. But reconnect
    flag allows to detect this before sending query and re-establish it without
    returning an error.
  */
  rc= mysql_query(lmysql, "SELECT 'bug17309863'");
  myquery(rc);

  mysql_close(lmysql);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug1180()
{
  MYSQL_STMT *stmt;
  int rc;
  MYSQL_BIND my_bind[1];
  ulong length[1];
  char szData[11];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_select_bug");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_select(session_id  char(9) NOT NULL)");
  myquery(rc);
  rc= mysql_query(mysql, "INSERT INTO test_select VALUES (\"abc\")");
  myquery(rc);

  strmov(query, "SELECT * FROM test_select WHERE ?= \"1111\" and "
                "session_id= \"abc\"");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 1);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  strmov(szData, (char *)"abc");
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (void *)szData;
  my_bind[0].buffer_length= 10;
  my_bind[0].length= &length[0];
  length[0]= 3;
  my_bind[0].is_null= 0;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 0);

  strmov(szData, (char *)"1111");
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (void *)szData;
  my_bind[0].buffer_length= 10;
  my_bind[0].length= &length[0];
  length[0]= 4;
  my_bind[0].is_null= 0;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 1);

  strmov(szData, (char *)"abc");
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (void *)szData;
  my_bind[0].buffer_length= 10;
  my_bind[0].length= &length[0];
  length[0]= 3;
  my_bind[0].is_null= 0;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 0);

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_mem_overun()
{
  char       buffer[10000], field[10];
  MYSQL_STMT *stmt;
  MYSQL_RES  *field_res;
  int        rc, i, length;

  myheader("test_mem_overun");

  /*
    Test a memory ovverun bug when a table had 1000 fields with
    a row of data
  */
  rc= mysql_query(mysql, "drop table if exists t_mem_overun");
  myquery(rc);

  strxmov(buffer, "create table t_mem_overun(", NullS);
  for (i= 0; i < 1000; i++)
  {
    sprintf(field, "c%d int", i);
    strxmov(buffer, buffer, field, ", ", NullS);
  }
  length= strlen(buffer);
  buffer[length-2]= ')';
  buffer[--length]= '\0';

  rc= mysql_real_query(mysql, buffer, length);
  myquery(rc);

  strxmov(buffer, "insert into t_mem_overun values(", NullS);
  for (i= 0; i < 1000; i++)
  {
    strxmov(buffer, buffer, "1, ", NullS);
  }
  length= strlen(buffer);
  buffer[length-2]= ')';
  buffer[--length]= '\0';

  rc= mysql_real_query(mysql, buffer, length);
  myquery(rc);

  rc= mysql_query(mysql, "select * from t_mem_overun");
  myquery(rc);

  rc= my_process_result(mysql);
  DIE_UNLESS(rc == 1);

  stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun");
  check_stmt(stmt);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  field_res= mysql_stmt_result_metadata(stmt);
  mytest(field_res);

  if (!opt_silent)
    fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
  DIE_UNLESS( 1000 == mysql_num_fields(field_res));

  rc= mysql_stmt_store_result(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  mysql_free_result(field_res);

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_wl4435_2()
{
  MYSQL_STMT *stmt;
  int  i;
  int  rc;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_wl4435_2");
  mct_start_logging("test_wl4435_2");

  /*
    Do a few iterations so that we catch any problem with incorrect
    handling/flushing prepared statement results.
  */

  for (i= 0; i < 10; ++i)
  {
    /*
      Prepare a procedure. That can be moved out of the loop, but it was
      left in the loop for the sake of having as many statements as
      possible.
    */

    rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
    myquery(rc);

    rc= mysql_query(mysql,
      "CREATE PROCEDURE p1()"
      "BEGIN "
      "  SELECT 1; "
      "  SELECT 2, 3 UNION SELECT 4, 5; "
      "  SELECT 6, 7, 8; "
      "END");
    myquery(rc);

    /* Invoke a procedure, that returns several result sets. */

    strmov(query, "CALL p1()");
    stmt= mysql_simple_prepare(mysql, query);
    check_stmt(stmt);

    /* Execute! */

    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);

    /* Flush all the results. */

    mysql_stmt_close(stmt);

    /* Clean up. */
    rc= mysql_commit(mysql);
    myquery(rc);

    rc= mysql_query(mysql, "DROP PROCEDURE p1");
    myquery(rc);
  }
  mct_close_log();
}

Project: mysql-server
File: mysql_client_test.c

static void test_stmt_close()
{
  MYSQL *lmysql;
  MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x;
  MYSQL_BIND  my_bind[1];
  MYSQL_RES   *result;
  unsigned int  count;
  int   rc;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_stmt_close");

  if (!opt_silent)
    fprintf(stdout, "\n Establishing a test connection ...");
  if (!(lmysql= mysql_client_init(NULL)))
  {
    myerror("mysql_client_init() failed");
    exit(1);
  }
  if (!(mysql_real_connect(lmysql, opt_host, opt_user,
                           opt_password, current_db, opt_port,
                           opt_unix_socket, 0)))
  {
    myerror("connection failed");
    exit(1);
  }
  lmysql->reconnect= 1;
  if (!opt_silent)
    fprintf(stdout, "OK");


  /* set AUTOCOMMIT to ON*/
  mysql_autocommit(lmysql, TRUE);

  rc= mysql_query(lmysql, "SET SQL_MODE = ''");
  myquery(rc);

  rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close");
  myquery(rc);

  rc= mysql_query(lmysql, "CREATE TABLE test_stmt_close(id int)");
  myquery(rc);

  strmov(query, "DO \"nothing\"");
  stmt1= mysql_simple_prepare(lmysql, query);
  check_stmt(stmt1);

  verify_param_count(stmt1, 0);

  strmov(query, "INSERT INTO test_stmt_close(id) VALUES(?)");
  stmt_x= mysql_simple_prepare(mysql, query);
  check_stmt(stmt_x);

  verify_param_count(stmt_x, 1);

  strmov(query, "UPDATE test_stmt_close SET id= ? WHERE id= ?");
  stmt3= mysql_simple_prepare(lmysql, query);
  check_stmt(stmt3);

  verify_param_count(stmt3, 2);

  strmov(query, "SELECT * FROM test_stmt_close WHERE id= ?");
  stmt2= mysql_simple_prepare(lmysql, query);
  check_stmt(stmt2);

  verify_param_count(stmt2, 1);

  rc= mysql_stmt_close(stmt1);
  if (!opt_silent)
    fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
  DIE_UNLESS(rc == 0);

  /*
    Originally we were going to close all statements automatically in
    mysql_close(). This proved to not work well - users weren't able to
    close statements by hand once mysql_close() had been called.
    Now mysql_close() doesn't free any statements, so this test doesn't
    serve its original designation any more.
    Here we free stmt2 and stmt3 by hand to avoid memory leaks.
  */
  mysql_stmt_close(stmt2);
  mysql_stmt_close(stmt3);
  mysql_close(lmysql);

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer= (void *)&count;
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
  count= 100;

  rc= mysql_stmt_bind_param(stmt_x, my_bind);
  check_execute(stmt_x, rc);

  rc= mysql_stmt_execute(stmt_x);
  check_execute(stmt_x, rc);

  verify_st_affected_rows(stmt_x, 1);

  rc= mysql_stmt_close(stmt_x);
  if (!opt_silent)
    fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
  DIE_UNLESS( rc == 0);

  rc= mysql_query(mysql, "SELECT id FROM test_stmt_close");
  myquery(rc);

  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 1);
  mysql_free_result(result);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug17512527()
{
  MYSQL *conn1, *conn2;
  MYSQL_STMT *stmt1, *stmt2;
  const char *stmt1_txt= "SELECT NOW();";
  const char *stmt2_txt= "SELECT 1;";
  unsigned long thread_id;
  char query[MAX_TEST_QUERY_LENGTH];
  int rc;

  conn1= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
  conn2= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 0);

  stmt1 = mysql_stmt_init(conn1);
  check_stmt(stmt1);
  rc= mysql_stmt_prepare(stmt1, stmt1_txt, strlen(stmt1_txt));
  check_execute(stmt1, rc);

  thread_id= mysql_thread_id(conn1);
  sprintf(query, "KILL %lu", thread_id);
  if (thread_query(query))
    exit(1);

  /*
    After the connection is killed, the connection is
    re-established due to the reconnect flag.
  */
  stmt2 = mysql_stmt_init(conn1);
  check_stmt(stmt2);

  rc= mysql_stmt_prepare(stmt2, stmt2_txt, strlen(stmt2_txt));
  check_execute(stmt1, rc);

  mysql_stmt_close(stmt2);
  mysql_stmt_close(stmt1);

  mysql_close(conn1);
  mysql_close(conn2);
}

Project: mysql-server
File: mysql_client_test.c

static void test_temporal_param()
{
#define N_PARAMS 3
  MYSQL_STMT   *stmt= 0;
  uint         rc;
  ulong        length[N_PARAMS],  length2[N_PARAMS];
  MYSQL_BIND   my_bind[N_PARAMS], my_bind2[N_PARAMS];
  my_bool      is_null[N_PARAMS], is_null2[N_PARAMS];
  MYSQL_TIME   tm;
  longlong     bigint= 123;
  double       real= 123;
  char         dec[40];

  /* Initialize param/fetch buffers for data, null flags, lengths */
  memset(&my_bind, 0, sizeof(my_bind));
  memset(&my_bind2, 0, sizeof(my_bind2));
  memset(&length, 0, sizeof(length));
  memset(&length2, 0, sizeof(length2));
  memset(&is_null, 0, sizeof(is_null));
  memset(&is_null2, 0, sizeof(is_null2));

  /* Initialize the first input parameter */
  my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
  my_bind[0].buffer= (void *) &tm;
  my_bind[0].is_null= &is_null[0];
  my_bind[0].length= &length[0];
  my_bind[0].buffer_length= sizeof(tm);

  /* Clone the second and the third input parameter */
  my_bind[2]= my_bind[1]= my_bind[0];

  /* Initialize fetch parameters */
  my_bind2[0].buffer_type= MYSQL_TYPE_LONGLONG;
  my_bind2[0].length= &length2[0];
  my_bind2[0].is_null= &is_null2[0];
  my_bind2[0].buffer_length= sizeof(bigint);
  my_bind2[0].buffer= (void *) &bigint;

  my_bind2[1].buffer_type= MYSQL_TYPE_DOUBLE;
  my_bind2[1].length= &length2[1];
  my_bind2[1].is_null= &is_null2[1];
  my_bind2[1].buffer_length= sizeof(real);
  my_bind2[1].buffer= (void *) &real;

  my_bind2[2].buffer_type= MYSQL_TYPE_STRING;
  my_bind2[2].length= &length2[2];
  my_bind2[2].is_null= &is_null2[2];
  my_bind2[2].buffer_length= sizeof(dec);
  my_bind2[2].buffer= (void *) &dec;


  /* Prepare and bind input and output parameters */
  stmt= mysql_simple_prepare(mysql, "SELECT CAST(? AS SIGNED), ?+0e0, ?+0.0");
  check_stmt(stmt);
  verify_param_count(stmt, N_PARAMS);

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_bind_result(stmt, my_bind2);
  check_execute(stmt, rc);

  /* Initialize DATETIME value */
  tm.neg= 0;
  tm.time_type= MYSQL_TIMESTAMP_DATETIME;
  tm.year= 2001;
  tm.month= 10;
  tm.day= 20;
  tm.hour= 10;
  tm.minute= 10;
  tm.second= 59;
  tm.second_part= 500000;

  /* Execute and fetch */
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_store_result(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    printf("\n%lld %f '%s'\n", bigint, real, dec);

  /* Check values.  */
  DIE_UNLESS(bigint ==  20011020101100LL);
  DIE_UNLESS(real == 20011020101059.5);
  DIE_UNLESS(!strcmp(dec, "20011020101059.5"));

  mysql_stmt_close(stmt);

  /* Re-initialize input parameters to TIME data type */
  my_bind[0].buffer_type= my_bind[1].buffer_type=
                          my_bind[2].buffer_type= MYSQL_TYPE_TIME;

  /* Prepare and bind intput and output parameters */
  stmt= mysql_simple_prepare(mysql, "SELECT CAST(? AS SIGNED), ?+0e0, ?+0.0");
  check_stmt(stmt);
  verify_param_count(stmt, N_PARAMS);

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_bind_result(stmt, my_bind2);
  check_execute(stmt, rc);

  /* Initialize TIME value */
  tm.neg= 0;
  tm.time_type= MYSQL_TIMESTAMP_TIME;
  tm.year= tm.month= tm.day= 0;
  tm.hour= 10;
  tm.minute= 10;
  tm.second= 59;
  tm.second_part= 500000;

  /* Execute and fetch */
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_store_result(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    printf("\n%lld %f '%s'\n", bigint, real, dec);

  /* Check returned values */
  DIE_UNLESS(bigint ==  101100);
  DIE_UNLESS(real ==  101059.5);
  DIE_UNLESS(!strcmp(dec, "101059.5"));

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: client.c

MYSQL * STDCALL
mysql_init(MYSQL *mysql)
{
  if (mysql_server_init(0, NULL, NULL))
    return 0;
  if (!mysql)
  {
    if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
    {
      set_mysql_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
      return 0;
    }
    mysql->free_me=1;
  }
  else
    memset(mysql, 0, sizeof(*(mysql)));
  mysql->charset=default_client_charset_info;
  strmov(mysql->net.sqlstate, not_error_sqlstate);

  /*
    Only enable LOAD DATA INFILE by default if configured with
    --enable-local-infile
  */

#if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER)
  mysql->options.client_flag|= CLIENT_LOCAL_FILES;
#endif

#ifdef HAVE_SMEM
  mysql->options.shared_memory_base_name= (char*) def_shared_memory_base_name;
#endif

  mysql->options.methods_to_use= MYSQL_OPT_GUESS_CONNECTION;
  mysql->options.report_data_truncation= TRUE;  /* default */

  /*
    By default we don't reconnect because it could silently corrupt data (after
    reconnection you potentially lose table locks, user variables, session
    variables (transactions but they are specifically dealt with in
    mysql_reconnect()).
    This is a change: < 5.0.3 mysql->reconnect was set to 1 by default.
    How this change impacts existing apps:
    - existing apps which relyed on the default will see a behaviour change;
    they will have to set reconnect=1 after mysql_real_connect().
    - existing apps which explicitely asked for reconnection (the only way they
    could do it was by setting mysql.reconnect to 1 after mysql_real_connect())
    will not see a behaviour change.
    - existing apps which explicitely asked for no reconnection
    (mysql.reconnect=0) will not see a behaviour change.
  */
  mysql->reconnect= 0;
 
  mysql->options.secure_auth= TRUE;

  return mysql;

Project: mysql-server
File: mysql_client_test.c

static void test_prepare_field_result()
{
  MYSQL_STMT *stmt;
  MYSQL_RES  *result;
  int        rc;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_prepare_field_result");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_field_result");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_prepare_field_result(int_c int, "
                         "var_c varchar(50), ts_c timestamp, "
                         "char_c char(4), date_c date, extra tinyint)");
  myquery(rc);

  /* insert */
  strmov(query, "SELECT int_c, var_c, date_c as date, ts_c, char_c FROM "
                " test_prepare_field_result as t1 WHERE int_c=?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 1);

  result= mysql_stmt_result_metadata(stmt);
  mytest(result);

  my_print_result_metadata(result);

  if (!opt_silent)
    fprintf(stdout, "\n\n field attributes:\n");
  verify_prepare_field(result, 0, "int_c", "int_c", MYSQL_TYPE_LONG,
                       "t1", "test_prepare_field_result", current_db, 11, 0);
  verify_prepare_field(result, 1, "var_c", "var_c", MYSQL_TYPE_VAR_STRING,
                       "t1", "test_prepare_field_result", current_db, 50, 0);
  verify_prepare_field(result, 2, "date", "date_c", MYSQL_TYPE_DATE,
                       "t1", "test_prepare_field_result", current_db, 10, 0);
  verify_prepare_field(result, 3, "ts_c", "ts_c", MYSQL_TYPE_TIMESTAMP,
                       "t1", "test_prepare_field_result", current_db, 19, 0);
  verify_prepare_field(result, 4, "char_c", "char_c",
                       (mysql_get_server_version(mysql) <= 50000 ?
                        MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING),
                       "t1", "test_prepare_field_result", current_db, 4, 0);

  verify_field_count(result, 5);
  mysql_free_result(result);
  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_simple_delete()
{
  MYSQL_STMT *stmt;
  int        rc;
  char       szData[30]= {0};
  int        nData= 1;
  MYSQL_RES  *result;
  MYSQL_BIND my_bind[2];
  ulong length[2];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_simple_delete");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_simple_delete");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_simple_delete(col1 int, \
                                col2 varchar(50), col3 int )");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO test_simple_delete VALUES(1, 'MySQL', 100)");
  myquery(rc);

  verify_affected_rows(1);

  rc= mysql_commit(mysql);
  myquery(rc);

  /* insert by prepare */
  strmov(query, "DELETE FROM test_simple_delete WHERE col1= ? AND "
                "CONVERT(col2 USING utf8)= ? AND col3= 100");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  nData= 1;
  strmov(szData, "MySQL");
  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
  my_bind[1].buffer= szData;               /* string data */
  my_bind[1].buffer_length= sizeof(szData);
  my_bind[1].length= &length[1];
  length[1]= 5;

  my_bind[0].buffer= (void *)&nData;
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  verify_affected_rows(1);

  mysql_stmt_close(stmt);

  /* now fetch the results ..*/
  rc= mysql_commit(mysql);
  myquery(rc);

  /* test the results now, only one row should exist */
  rc= mysql_query(mysql, "SELECT * FROM test_simple_delete");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 0);
  mysql_free_result(result);
}

Project: mysql-server
File: mysql_client_test.c

static void test_ps_query_cache()
{
  MYSQL      *lmysql= mysql;
  MYSQL_STMT *stmt;
  int        rc;
  MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */
  int32      p_int_data, r_int_data;
  char       p_str_data[32], r_str_data[32];
  unsigned long p_str_length, r_str_length;
  MYSQL_RES  *r_metadata;
  char       query[MAX_TEST_QUERY_LENGTH];
  uint       hits1, hits2;
  enum enum_test_ps_query_cache
  {
    /*
      We iterate the same prepare/executes block, but have iterations where
      we vary the query cache conditions.
    */
    /* the query cache is enabled for the duration of prep&execs: */
    TEST_QCACHE_ON= 0,
    /*
      same but using a new connection (to see if qcache serves results from
      the previous connection as it should):
    */
    TEST_QCACHE_ON_WITH_OTHER_CONN,
    /*
      First border case: disables the query cache before prepare and
      re-enables it before execution (to test if we have no bug then):
    */
    TEST_QCACHE_OFF_ON,
    /*
      Second border case: enables the query cache before prepare and
      disables it before execution:
    */
    TEST_QCACHE_ON_OFF
  };
  enum enum_test_ps_query_cache iteration;

  myheader("test_ps_query_cache");

  rc= mysql_query(mysql, "SET SQL_MODE=''");
  myquery(rc);

  /* prepare the table */

  rc= mysql_query(mysql, "drop table if exists t1");
  myquery(rc);

  rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
                         "value2 varchar(100), value1 varchar(100))");
  myquery(rc);

  rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
                          "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
  myquery(rc);

  for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++)
  {

    switch (iteration) {
    case TEST_QCACHE_ON:
    case TEST_QCACHE_ON_OFF:
      rc= mysql_query(lmysql, "set global query_cache_size=1000000");
      myquery(rc);
      break;
    case TEST_QCACHE_OFF_ON:
      rc= mysql_query(lmysql, "set global query_cache_size=0");
      myquery(rc);
      break;
    case TEST_QCACHE_ON_WITH_OTHER_CONN:
      if (!opt_silent)
        fprintf(stdout, "\n Establishing a test connection ...");
      if (!(lmysql= mysql_client_init(NULL)))
      {
        printf("mysql_client_init() failed");
        DIE_UNLESS(0);
      }
      if (!(mysql_real_connect(lmysql, opt_host, opt_user,
                               opt_password, current_db, opt_port,
                               opt_unix_socket, 0)))
      {
        printf("connection failed");
        mysql_close(lmysql);
        DIE_UNLESS(0);
      }
      rc= mysql_query(lmysql, "SET SQL_MODE=''");
      myquery(rc);

      if (!opt_silent)
        fprintf(stdout, "OK");
    }

    strmov(query, "select id1, value1 from t1 where id1= ? or "
           "CONVERT(value1 USING utf8)= ?");
    stmt= mysql_simple_prepare(lmysql, query);
    check_stmt(stmt);

    verify_param_count(stmt, 2);

    switch (iteration) {
    case TEST_QCACHE_OFF_ON:
      rc= mysql_query(lmysql, "set global query_cache_size=1000000");
      myquery(rc);
      break;
    case TEST_QCACHE_ON_OFF:
      rc= mysql_query(lmysql, "set global query_cache_size=0");
      myquery(rc);
    default:
      break;
    }

    memset(p_bind, 0, sizeof(p_bind));
    p_bind[0].buffer_type= MYSQL_TYPE_LONG;
    p_bind[0].buffer= (void *)&p_int_data;
    p_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
    p_bind[1].buffer= (void *)p_str_data;
    p_bind[1].buffer_length= array_elements(p_str_data);
    p_bind[1].length= &p_str_length;

    rc= mysql_stmt_bind_param(stmt, p_bind);
    check_execute(stmt, rc);

    p_int_data= 1;
    strmov(p_str_data, "hh");
    p_str_length= strlen(p_str_data);

    memset(r_bind, 0, sizeof(r_bind));
    r_bind[0].buffer_type= MYSQL_TYPE_LONG;
    r_bind[0].buffer= (void *)&r_int_data;
    r_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
    r_bind[1].buffer= (void *)r_str_data;
    r_bind[1].buffer_length= array_elements(r_str_data);
    r_bind[1].length= &r_str_length;

    rc= mysql_stmt_bind_result(stmt, r_bind);
    check_execute(stmt, rc);

    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);

    test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);

    /* now retry with the same parameter values and see qcache hits */
    hits1= query_cache_hits(lmysql);
    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);
    test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
    hits2= query_cache_hits(lmysql);
    switch(iteration) {
    case TEST_QCACHE_ON_WITH_OTHER_CONN:
    case TEST_QCACHE_ON:                 /* should have hit */
      DIE_UNLESS(hits2-hits1 == 1);
      break;
    case TEST_QCACHE_OFF_ON:
    case TEST_QCACHE_ON_OFF:             /* should not have hit */
      DIE_UNLESS(hits2-hits1 == 0);
      break;
    }

    /* now modify parameter values and see qcache hits */
    strmov(p_str_data, "ii");
    p_str_length= strlen(p_str_data);
    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);
    test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
    hits1= query_cache_hits(lmysql);

    switch(iteration) {
    case TEST_QCACHE_ON:
    case TEST_QCACHE_OFF_ON:
    case TEST_QCACHE_ON_OFF:             /* should not have hit */
      DIE_UNLESS(hits2-hits1 == 0);
      break;
    case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
      DIE_UNLESS(hits1-hits2 == 1);
      break;
    }

    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);

    test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
    hits2= query_cache_hits(lmysql);

    mysql_stmt_close(stmt);

    switch(iteration) {
    case TEST_QCACHE_ON:                 /* should have hit */
      DIE_UNLESS(hits2-hits1 == 1);
      break;
    case TEST_QCACHE_OFF_ON:
    case TEST_QCACHE_ON_OFF:             /* should not have hit */
      DIE_UNLESS(hits2-hits1 == 0);
      break;
    case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
      DIE_UNLESS(hits2-hits1 == 1);
      break;
    }

  } /* for(iteration=...) */

  if (lmysql != mysql)
    mysql_close(lmysql);

  rc= mysql_query(mysql, "set global query_cache_size=DEFAULT");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_logs()
{
  MYSQL_STMT *stmt;
  MYSQL_BIND my_bind[2];
  char       data[255];
  ulong      length;
  int        rc;
  short      id;

  myheader("test_logs");


  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))");
  myquery(rc);

  strmov((char *)data, "INSERT INTO test_logs VALUES(?, ?)");
  stmt= mysql_simple_prepare(mysql, data);
  check_stmt(stmt);

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
  my_bind[0].buffer= (void *)&id;

  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
  my_bind[1].buffer= (void *)&data;
  my_bind[1].buffer_length= 255;
  my_bind[1].length= &length;

  id= 9876;
  length= (ulong)(strmov((char *)data, "MySQL - Open Source Database")- data);

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  strmov((char *)data, "'");
  length= 1;

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  strmov((char *)data, "\"");
  length= 1;

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  length= (ulong)(strmov((char *)data, "my\'sql\'")-data);
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  length= (ulong)(strmov((char *)data, "my\"sql\"")-data);
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);

  strmov((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')");
  stmt= mysql_simple_prepare(mysql, data);
  check_stmt(stmt);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);

  strmov((char *)data, "SELECT * FROM test_logs WHERE id=?");
  stmt= mysql_simple_prepare(mysql, data);
  check_stmt(stmt);

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  my_bind[1].buffer_length= 255;
  rc= mysql_stmt_bind_result(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
  {
    fprintf(stdout, "id    : %d\n", id);
    fprintf(stdout, "name  : %s(%ld)\n", data, length);
  }

  DIE_UNLESS(id == 9876);
  DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */
  DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n name  : %s(%ld)", data, length);

  DIE_UNLESS(length == 1);
  DIE_UNLESS(strcmp(data, "'") == 0);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n name  : %s(%ld)", data, length);

  DIE_UNLESS(length == 1);
  DIE_UNLESS(strcmp(data, "\"") == 0);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n name  : %s(%ld)", data, length);

  DIE_UNLESS(length == 7);
  DIE_UNLESS(strcmp(data, "my\'sql\'") == 0);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  if (!opt_silent)
    fprintf(stdout, "\n name  : %s(%ld)", data, length);

  DIE_UNLESS(length == 7);
  /*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  mysql_stmt_close(stmt);

  rc= mysql_query(mysql, "DROP TABLE test_logs");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_long_data_bin()
{
  MYSQL_STMT *stmt;
  int        rc;
  char       data[255];
  long       length;
  MYSQL_RES  *result;
  MYSQL_BIND my_bind[2];
  char query[MAX_TEST_QUERY_LENGTH];


  myheader("test_long_data_bin");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_bin");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_long_data_bin(id int, longbin long varbinary)");
  myquery(rc);

  strmov(query, "INSERT INTO test_long_data_bin VALUES(?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer= (void *)&length;
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
  length= 0;

  my_bind[1].buffer= data;           /* string data */
  my_bind[1].buffer_type= MYSQL_TYPE_LONG_BLOB;
  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  length= 10;
  strmov(data, "MySQL AB");

  /* supply data in pieces */
  {
    int i;
    for (i= 0; i < 100; i++)
    {
      rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 4);
      check_execute(stmt, rc);
    }
  }
  /* execute */
  rc= mysql_stmt_execute(stmt);
  if (!opt_silent)
    fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);

  rc= mysql_commit(mysql);
  myquery(rc);

  /* now fetch the results ..*/
  rc= mysql_query(mysql, "SELECT LENGTH(longbin), longbin FROM test_long_data_bin");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 1);
  mysql_free_result(result);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug1644()
{
  MYSQL_STMT *stmt;
  MYSQL_RES *result;
  MYSQL_ROW row;
  MYSQL_BIND my_bind[4];
  int num;
  my_bool isnull;
  int rc, i;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_bug1644");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS foo_dfr");
  myquery(rc);

  rc= mysql_query(mysql,
           "CREATE TABLE foo_dfr(col1 int, col2 int, col3 int, col4 int);");
  myquery(rc);

  strmov(query, "INSERT INTO foo_dfr VALUES (?, ?, ?, ? )");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 4);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  num= 22;
  isnull= 0;
  for (i= 0 ; i < 4 ; i++)
  {
    my_bind[i].buffer_type= MYSQL_TYPE_LONG;
    my_bind[i].buffer= (void *)&num;
    my_bind[i].is_null= &isnull;
  }

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  isnull= 1;
  for (i= 0 ; i < 4 ; i++)
    my_bind[i].is_null= &isnull;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  isnull= 0;
  num= 88;
  for (i= 0 ; i < 4 ; i++)
    my_bind[i].is_null= &isnull;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);

  rc= mysql_query(mysql, "SELECT * FROM foo_dfr");
  myquery(rc);

  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 3);

  mysql_data_seek(result, 0);

  row= mysql_fetch_row(result);
  mytest(row);
  for (i= 0 ; i < 4 ; i++)
  {
    DIE_UNLESS(strcmp(row[i], "22") == 0);
  }
  row= mysql_fetch_row(result);
  mytest(row);
  for (i= 0 ; i < 4 ; i++)
  {
    DIE_UNLESS(row[i] == 0);
  }
  row= mysql_fetch_row(result);
  mytest(row);
  for (i= 0 ; i < 4 ; i++)
  {
    DIE_UNLESS(strcmp(row[i], "88") == 0);
  }
  row= mysql_fetch_row(result);
  mytest_r(row);

  mysql_free_result(result);
}

Project: mysql-server
File: mysql_client_test.c

static void test_prepare_insert_update()
{
  MYSQL_STMT *stmt;
  int        rc;
  int        i;
  const char *testcase[]= {
    "CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B))",
    "INSERT t1 VALUES (1,2,10), (3,4,20)",
    "INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100",
    "SELECT * FROM t1",
    "INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0",
    "SELECT * FROM t1",
    "INSERT t1 VALUES (2,1,11), (7,4,40) ON DUPLICATE KEY UPDATE c=c+VALUES(a)",
    NULL};
  const char **cur_query;

  myheader("test_prepare_insert_update");
  
  for (cur_query= testcase; *cur_query; cur_query++)
  {
    char query[MAX_TEST_QUERY_LENGTH];
    printf("\nRunning query: %s", *cur_query);
    strmov(query, *cur_query);
    stmt= mysql_simple_prepare(mysql, query);
    check_stmt(stmt);

    verify_param_count(stmt, 0);
    rc= mysql_stmt_execute(stmt);

    check_execute(stmt, rc);
    /* try the last query several times */
    if (!cur_query[1])
    {
      for (i=0; i < 3;i++)
      {
        printf("\nExecuting last statement again");
        rc= mysql_stmt_execute(stmt);
        check_execute(stmt, rc);
        rc= mysql_stmt_execute(stmt);
        check_execute(stmt, rc);
      }
    }
    mysql_stmt_close(stmt);
  }

  rc= mysql_commit(mysql);
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_prepare_syntax()
{
  MYSQL_STMT *stmt;
  int        rc;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_prepare_syntax");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_syntax");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_prepare_syntax("
                         "id int, name varchar(50), extra int)");
  myquery(rc);

  strmov(query, "INSERT INTO test_prepare_syntax VALUES(?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt_r(stmt);

  strmov(query, "SELECT id, name FROM test_prepare_syntax WHERE id=? AND WHERE");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt_r(stmt);

  /* now fetch the results ..*/
  rc= mysql_commit(mysql);
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_date_frac()
{
  int        rc;

  myheader("test_date");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP(6), \
                                                 c2 TIME(6), \
                                                 c3 DATETIME(6), \
                                                 c4 DATE)");

  myquery(rc);

  bind_date_conv(5,TRUE);
}

Project: mysql-server
File: mysql_client_test.c

static void test_wl5924()
{
  int rc;
  MYSQL *l_mysql;
  MYSQL_RES *res;
  MYSQL_ROW row;

  myheader("test_wl5924");
  l_mysql= mysql_client_init(NULL);
  DIE_UNLESS(l_mysql != NULL);

  /* we want a non-default character set */
  rc= mysql_set_character_set(l_mysql, "cp1251");
  DIE_UNLESS(rc == 0);

  /* put in an attr */
  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
                     "key1", "value1");
  DIE_UNLESS(rc == 0);

  /* put a second attr */
  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
                     "key2", "value2");
  DIE_UNLESS(rc == 0);

  /* put the second attr again : should fail */
  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
                     "key2", "value2");
  DIE_UNLESS(rc != 0);

  /* delete the second attr */
  rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_DELETE,
                    "key2");
  DIE_UNLESS(rc == 0);

  /* put the second attr again : should pass */
  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
                     "key2", "value2");
  DIE_UNLESS(rc == 0);

  /* full reset */
  rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_RESET, NULL);
  DIE_UNLESS(rc == 0);

  /* put the second attr again : should pass */
  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
                     "key2", "value2");
  DIE_UNLESS(rc == 0);

  /* full reset */
  rc= mysql_options(l_mysql, MYSQL_OPT_CONNECT_ATTR_RESET, NULL);
  DIE_UNLESS(rc == 0);

  /* add a third attr */
  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
                     "key3", "value3");
  DIE_UNLESS(rc == 0);

  /* add a fourth attr */
  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
                     "key4", "value4");
  DIE_UNLESS(rc == 0);

  /* add a non-ascii attr */
  /* note : this is Георги, Кодинов in windows-1251 */
  rc= mysql_options4(l_mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
                     "\xc3\xe5\xee\xf0\xe3\xe8",
                     "\xca\xee\xe4\xe8\xed\xee\xe2");
  DIE_UNLESS(rc == 0);

  l_mysql= mysql_real_connect(l_mysql, opt_host, opt_user,
                         opt_password, current_db, opt_port,
                         opt_unix_socket, 0);
  DIE_UNLESS(l_mysql != 0);

  rc= mysql_query(l_mysql,
                  "SELECT ATTR_NAME, ATTR_VALUE "
                  " FROM performance_schema.session_account_connect_attrs"
                  " WHERE ATTR_NAME IN ('key1','key2','key3','key4',"
                  "  '\xc3\xe5\xee\xf0\xe3\xe8') AND"
                  "  PROCESSLIST_ID = CONNECTION_ID() ORDER BY ATTR_NAME");
  myquery2(l_mysql,rc);
  res= mysql_use_result(l_mysql);
  DIE_UNLESS(res);

  row= mysql_fetch_row(res);
  DIE_UNLESS(row);
  DIE_UNLESS(0 == strcmp(row[0], "key3"));
  DIE_UNLESS(0 == strcmp(row[1], "value3"));

  row= mysql_fetch_row(res);
  DIE_UNLESS(row);
  DIE_UNLESS(0 == strcmp(row[0], "key4"));
  DIE_UNLESS(0 == strcmp(row[1], "value4"));

  row= mysql_fetch_row(res);
  DIE_UNLESS(row);
  DIE_UNLESS(0 == strcmp(row[0], "\xc3\xe5\xee\xf0\xe3\xe8"));
  DIE_UNLESS(0 == strcmp(row[1], "\xca\xee\xe4\xe8\xed\xee\xe2"));

  mysql_free_result(res);

  l_mysql->reconnect= 1;
  rc= mysql_reconnect(l_mysql);
  myquery2(l_mysql,rc);

  mysql_close(l_mysql);
}

Project: mysql-server
File: client.c

int STDCALL
mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
{
  DBUG_ENTER("mysql_option");
  DBUG_PRINT("enter",("option: %d",(int) option));
  switch (option) {
  case MYSQL_OPT_CONNECT_TIMEOUT:
    mysql->options.connect_timeout= *(uint*) arg;
    break;
  case MYSQL_OPT_READ_TIMEOUT:
    mysql->options.read_timeout= *(uint*) arg;
    break;
  case MYSQL_OPT_WRITE_TIMEOUT:
    mysql->options.write_timeout= *(uint*) arg;
    break;
  case MYSQL_OPT_COMPRESS:
    mysql->options.compress= 1;			/* Remember for connect */
    mysql->options.client_flag|= CLIENT_COMPRESS;
    break;
  case MYSQL_OPT_NAMED_PIPE:			/* This option is depricated */
    mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */
    break;
  case MYSQL_OPT_LOCAL_INFILE:			/* Allow LOAD DATA LOCAL ?*/
    if (!arg || MY_TEST(*(uint*) arg))
      mysql->options.client_flag|= CLIENT_LOCAL_FILES;
    else
      mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
    break;
  case MYSQL_INIT_COMMAND:
    add_init_command(&mysql->options,arg);
    break;
  case MYSQL_READ_DEFAULT_FILE:
    my_free(mysql->options.my_cnf_file);
    mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
    break;
  case MYSQL_READ_DEFAULT_GROUP:
    my_free(mysql->options.my_cnf_group);
    mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
    break;
  case MYSQL_SET_CHARSET_DIR:
    my_free(mysql->options.charset_dir);
    mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME));
    break;
  case MYSQL_SET_CHARSET_NAME:
    my_free(mysql->options.charset_name);
    mysql->options.charset_name=my_strdup(arg,MYF(MY_WME));
    break;
  case MYSQL_OPT_PROTOCOL:
    mysql->options.protocol= *(uint*) arg;
    break;
  case MYSQL_SHARED_MEMORY_BASE_NAME:
#ifdef HAVE_SMEM
    if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
      my_free(mysql->options.shared_memory_base_name);
    mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME));
#endif
    break;
  case MYSQL_OPT_USE_REMOTE_CONNECTION:
  case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
  case MYSQL_OPT_GUESS_CONNECTION:
    mysql->options.methods_to_use= option;
    break;
  case MYSQL_SET_CLIENT_IP:
    my_free(mysql->options.ci.client_ip);
    mysql->options.ci.client_ip= my_strdup(arg, MYF(MY_WME));
    break;
  case MYSQL_SECURE_AUTH:
    mysql->options.secure_auth= *(my_bool *) arg;
    break;
  case MYSQL_REPORT_DATA_TRUNCATION:
    mysql->options.report_data_truncation= MY_TEST(*(my_bool *) arg);
    break;
  case MYSQL_OPT_RECONNECT:
    mysql->reconnect= *(my_bool *) arg;
    break;
  case MYSQL_OPT_BIND:
    my_free(mysql->options.ci.bind_address);
    mysql->options.ci.bind_address= my_strdup(arg, MYF(MY_WME));
    break;
  case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
    if (*(my_bool*) arg)
      mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
    else
      mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
    break;
  case MYSQL_PLUGIN_DIR:
    EXTENSION_SET_STRING(&mysql->options, plugin_dir, arg);
    break;
  case MYSQL_DEFAULT_AUTH:
    EXTENSION_SET_STRING(&mysql->options, default_auth, arg);
    break;
  case MYSQL_OPT_SSL_KEY:      SET_SSL_OPTION(ssl_key, arg);     break;
  case MYSQL_OPT_SSL_CERT:     SET_SSL_OPTION(ssl_cert, arg);    break;
  case MYSQL_OPT_SSL_CA:       SET_SSL_OPTION(ssl_ca, arg);      break;
  case MYSQL_OPT_SSL_CAPATH:   SET_SSL_OPTION(ssl_capath, arg);  break;
  case MYSQL_OPT_SSL_CIPHER:   SET_SSL_OPTION(ssl_cipher, arg);  break;
  case MYSQL_OPT_SSL_CRL:      EXTENSION_SET_SSL_STRING(&mysql->options,
                                                        ssl_crl, arg);
                               break;
  case MYSQL_OPT_SSL_CRLPATH:  EXTENSION_SET_SSL_STRING(&mysql->options,
                                                        ssl_crlpath, arg);
                               break;
  case MYSQL_SERVER_PUBLIC_KEY:
    EXTENSION_SET_STRING(&mysql->options, server_public_key_path, arg);
    break;

  case MYSQL_OPT_CONNECT_ATTR_RESET:
    ENSURE_EXTENSIONS_PRESENT(&mysql->options);
    if (my_hash_inited(&mysql->options.extension->connection_attributes))
    {
      my_hash_free(&mysql->options.extension->connection_attributes);
      mysql->options.extension->connection_attributes_length= 0;
    }
    break;
  case MYSQL_OPT_CONNECT_ATTR_DELETE:
    ENSURE_EXTENSIONS_PRESENT(&mysql->options);
    if (my_hash_inited(&mysql->options.extension->connection_attributes))
    {
      size_t len;
      uchar *elt;

      len= arg ? strlen(arg) : 0;

      if (len)
      {
        elt= my_hash_search(&mysql->options.extension->connection_attributes,
                            arg, len);
        if (elt)
        {
          LEX_STRING *attr= (LEX_STRING *) elt;
          LEX_STRING *key= attr, *value= attr + 1;

          mysql->options.extension->connection_attributes_length-=
            get_length_store_length(key->length) + key->length +
            get_length_store_length(value->length) + value->length;

          my_hash_delete(&mysql->options.extension->connection_attributes,
                         elt);

        }
      }
    }
    break;
  case MYSQL_ENABLE_CLEARTEXT_PLUGIN:
    ENSURE_EXTENSIONS_PRESENT(&mysql->options);
    mysql->options.extension->enable_cleartext_plugin= 
      (*(my_bool*) arg) ? TRUE : FALSE;
    break;
  case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
    if (*(my_bool*) arg)
      mysql->options.client_flag|= CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS;
    else
      mysql->options.client_flag&= ~CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS;
    break;

  default:
    DBUG_RETURN(1);
  }
  DBUG_RETURN(0);

Project: mysql-server
File: client.c


void STDCALL mysql_close(MYSQL *mysql)
{
  DBUG_ENTER("mysql_close");
  if (mysql)					/* Some simple safety */
  {
    /* If connection is still up, send a QUIT message */
    if (mysql->net.vio != 0)
    {
      free_old_query(mysql);
      mysql->status=MYSQL_STATUS_READY; /* Force command */
      mysql->reconnect=0;
      simple_command(mysql,COM_QUIT,(uchar*) 0,0,1);
      end_server(mysql);			/* Sets mysql->net.vio= 0 */
    }
    mysql_close_free_options(mysql);
    mysql_close_free(mysql);
    mysql_detach_stmt_list(&mysql->stmts, "mysql_close");
#ifndef MYSQL_SERVER
    if (mysql->thd)
      (*mysql->methods->free_embedded_thd)(mysql);
#endif
    if (mysql->free_me)
      my_free(mysql);
  }
  DBUG_VOID_RETURN;

Project: mysql-server
File: mysql_client_test.c

static void test_ps_conj_select()
{
  MYSQL_STMT *stmt;
  int        rc;
  MYSQL_BIND my_bind[2];
  int32      int_data;
  char       str_data[32];
  unsigned long str_length;
  char query[MAX_TEST_QUERY_LENGTH];
  myheader("test_ps_conj_select");

  rc= mysql_query(mysql, "drop table if exists t1");
  myquery(rc);

  rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
                         "value2 varchar(100), value1 varchar(100))");
  myquery(rc);

  rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
                          "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
  myquery(rc);

  strmov(query, "select id1, value1 from t1 where id1= ? or "
                "CONVERT(value1 USING utf8)= ?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
  my_bind[0].buffer= (void *)&int_data;

  my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
  my_bind[1].buffer= (void *)str_data;
  my_bind[1].buffer_length= array_elements(str_data);
  my_bind[1].length= &str_length;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  int_data= 1;
  strmov(str_data, "hh");
  str_length= strlen(str_data);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 3);

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_wl4435()
{
  MYSQL_STMT *stmt;
  int        rc;
  char query[MAX_TEST_QUERY_LENGTH];

  char       str_data[20][WL4435_STRING_SIZE];
  double     dbl_data[20];
  char       dec_data[20][WL4435_STRING_SIZE];
  int        int_data[20];
  ulong      str_length= WL4435_STRING_SIZE;
  my_bool    is_null;
  MYSQL_BIND ps_params[WL4435_NUM_PARAMS];

  int exec_counter;

  myheader("test_wl4435");
  mct_start_logging("test_wl4435");

  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
  myquery(rc);

  rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p2");
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE t1(a1 INT, a2 CHAR(32), "
                       "  a3 DOUBLE(4, 2), a4 DECIMAL(3, 1))");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE t2(b0 INT, b1 INT, b2 CHAR(32), "
                       "  b3 DOUBLE(4, 2), b4 DECIMAL(3, 1))");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO t1 VALUES"
    "(1, '11', 12.34, 56.7), "
    "(2, '12', 56.78, 90.1), "
    "(3, '13', 23.45, 67.8)");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO t2 VALUES"
    "(100, 10, '110', 70.70, 10.1), "
    "(200, 20, '120', 80.80, 20.2), "
    "(300, 30, '130', 90.90, 30.3)");
  myquery(rc);

  rc= mysql_query(mysql,
    "CREATE PROCEDURE p1("
    "   IN v0 INT, "
    "   OUT v_str_1 CHAR(32), "
    "   OUT v_dbl_1 DOUBLE(4, 2), "
    "   OUT v_dec_1 DECIMAL(6, 3), "
    "   OUT v_int_1 INT, "
    "   IN v1 INT, "
    "   INOUT v_str_2 CHAR(64), "
    "   INOUT v_dbl_2 DOUBLE(5, 3), "
    "   INOUT v_dec_2 DECIMAL(7, 4), "
    "   INOUT v_int_2 INT)"
    "BEGIN "
    "   SET v0 = -1; "
    "   SET v1 = -1; "
    "   SET v_str_1 = 'test_1'; "
    "   SET v_dbl_1 = 12.34; "
    "   SET v_dec_1 = 567.891; "
    "   SET v_int_1 = 2345; "
    "   SET v_str_2 = 'test_2'; "
    "   SET v_dbl_2 = 67.891; "
    "   SET v_dec_2 = 234.6789; "
    "   SET v_int_2 = 6789; "
    "   SELECT * FROM t1; "
    "   SELECT * FROM t2; "
    "END");
  myquery(rc);

  rc= mysql_query(mysql,
    "CREATE PROCEDURE p2("
    "   IN i1 VARCHAR(255) CHARACTER SET koi8r, "
    "   OUT o1 VARCHAR(255) CHARACTER SET cp1251, "
    "   OUT o2 VARBINARY(255)) "
    "BEGIN "
    "   SET o1 = i1; "
    "   SET o2 = i1; "
    "END");
  myquery(rc);

  strmov(query, "CALL p1(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  /* Init PS-parameters. */

  memset(ps_params, 0, sizeof (ps_params));

  /* - v0 -- INT */

  ps_params[0].buffer_type= MYSQL_TYPE_LONG;
  ps_params[0].buffer= (char *) &int_data[0];
  ps_params[0].length= 0;
  ps_params[0].is_null= 0;

  /* - v_str_1 -- CHAR(32) */

  ps_params[1].buffer_type= MYSQL_TYPE_STRING;
  ps_params[1].buffer= (char *) str_data[0];
  ps_params[1].buffer_length= WL4435_STRING_SIZE;
  ps_params[1].length= &str_length;
  ps_params[1].is_null= 0;

  /* - v_dbl_1 -- DOUBLE */

  ps_params[2].buffer_type= MYSQL_TYPE_DOUBLE;
  ps_params[2].buffer= (char *) &dbl_data[0];
  ps_params[2].length= 0;
  ps_params[2].is_null= 0;

  /* - v_dec_1 -- DECIMAL */

  ps_params[3].buffer_type= MYSQL_TYPE_NEWDECIMAL;
  ps_params[3].buffer= (char *) dec_data[0];
  ps_params[3].buffer_length= WL4435_STRING_SIZE;
  ps_params[3].length= 0;
  ps_params[3].is_null= 0;

  /* - v_int_1 -- INT */

  ps_params[4].buffer_type= MYSQL_TYPE_LONG;
  ps_params[4].buffer= (char *) &int_data[0];
  ps_params[4].length= 0;
  ps_params[4].is_null= 0;

  /* - v1 -- INT */

  ps_params[5].buffer_type= MYSQL_TYPE_LONG;
  ps_params[5].buffer= (char *) &int_data[0];
  ps_params[5].length= 0;
  ps_params[5].is_null= 0;

  /* - v_str_2 -- CHAR(32) */

  ps_params[6].buffer_type= MYSQL_TYPE_STRING;
  ps_params[6].buffer= (char *) str_data[0];
  ps_params[6].buffer_length= WL4435_STRING_SIZE;
  ps_params[6].length= &str_length;
  ps_params[6].is_null= 0;

  /* - v_dbl_2 -- DOUBLE */

  ps_params[7].buffer_type= MYSQL_TYPE_DOUBLE;
  ps_params[7].buffer= (char *) &dbl_data[0];
  ps_params[7].length= 0;
  ps_params[7].is_null= 0;

  /* - v_dec_2 -- DECIMAL */

  ps_params[8].buffer_type= MYSQL_TYPE_DECIMAL;
  ps_params[8].buffer= (char *) dec_data[0];
  ps_params[8].buffer_length= WL4435_STRING_SIZE;
  ps_params[8].length= 0;
  ps_params[8].is_null= 0;

  /* - v_int_2 -- INT */

  ps_params[9].buffer_type= MYSQL_TYPE_LONG;
  ps_params[9].buffer= (char *) &int_data[0];
  ps_params[9].length= 0;
  ps_params[9].is_null= 0;

  /* Bind parameters. */

  rc= mysql_stmt_bind_param(stmt, ps_params);

  /* Execute! */

  for (exec_counter= 0; exec_counter < 3; ++exec_counter)
  {
    int i;
    int num_fields;
    MYSQL_BIND *rs_bind;

    mct_log("\nexec_counter: %d\n", (int) exec_counter);

    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);

    while (1)
    {
      MYSQL_FIELD *fields;

      MYSQL_RES *rs_metadata= mysql_stmt_result_metadata(stmt);

      num_fields= mysql_stmt_field_count(stmt);
      fields= mysql_fetch_fields(rs_metadata);

      rs_bind= (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
      memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);

      mct_log("num_fields: %d\n", (int) num_fields);

      for (i = 0; i < num_fields; ++i)
      {
        mct_log("  - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
                "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
                "type: %d; decimals: %d\n",
                (int) i,
                (const char *) fields[i].name,
                (const char *) fields[i].org_name,
                (const char *) fields[i].table,
                (const char *) fields[i].org_table,
                (const char *) fields[i].db,
                (const char *) fields[i].catalog,
                (int) fields[i].length,
                (int) fields[i].max_length,
                (int) fields[i].type,
                (int) fields[i].decimals);

        rs_bind[i].buffer_type= fields[i].type;
        rs_bind[i].is_null= &is_null;

        switch (fields[i].type)
        {
          case MYSQL_TYPE_LONG:
            rs_bind[i].buffer= (char *) &(int_data[i]);
            rs_bind[i].buffer_length= sizeof (int_data);
            break;

          case MYSQL_TYPE_STRING:
            rs_bind[i].buffer= (char *) str_data[i];
            rs_bind[i].buffer_length= WL4435_STRING_SIZE;
            rs_bind[i].length= &str_length;
            break;

          case MYSQL_TYPE_DOUBLE:
            rs_bind[i].buffer= (char *) &dbl_data[i];
            rs_bind[i].buffer_length= sizeof (dbl_data);
            break;

          case MYSQL_TYPE_NEWDECIMAL:
            rs_bind[i].buffer= (char *) dec_data[i];
            rs_bind[i].buffer_length= WL4435_STRING_SIZE;
            rs_bind[i].length= &str_length;
            break;

          default:
            fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
            exit(1);
        }
      }

      rc= mysql_stmt_bind_result(stmt, rs_bind);
      check_execute(stmt, rc);

      mct_log("Data:\n");

      while (1)
      {
        int rc= mysql_stmt_fetch(stmt);

        if (rc == 1 || rc == MYSQL_NO_DATA)
          break;

        mct_log(" ");

        for (i = 0; i < num_fields; ++i)
        {
          switch (rs_bind[i].buffer_type)
          {
            case MYSQL_TYPE_LONG:
              mct_log(" int: %ld;",
                      (long) *((int *) rs_bind[i].buffer));
              break;

            case MYSQL_TYPE_STRING:
              mct_log(" str: '%s';",
                      (char *) rs_bind[i].buffer);
              break;

            case MYSQL_TYPE_DOUBLE:
              mct_log(" dbl: %lf;",
                      (double) *((double *) rs_bind[i].buffer));
              break;

            case MYSQL_TYPE_NEWDECIMAL:
              mct_log(" dec: '%s';",
                      (char *) rs_bind[i].buffer);
              break;

            default:
              printf("  unexpected type (%d)\n",
                rs_bind[i].buffer_type);
          }
        }
        mct_log("\n");
      }

      mct_log("EOF\n");

      rc= mysql_stmt_next_result(stmt);
      mct_log("mysql_stmt_next_result(): %d; field_count: %d\n",
              (int) rc, (int) mysql->field_count);

      free(rs_bind);
      mysql_free_result(rs_metadata);

      if (rc > 0)
      {
        printf("Error: %s (errno: %d)\n",
               mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
        DIE(rc > 0);
      }

      if (rc)
        break;

      if (!mysql->field_count)
      {
        /* This is the last OK-packet. No more resultsets. */
        break;
      }
    }

  }

  mysql_stmt_close(stmt);

  mct_close_log();

  rc= mysql_commit(mysql);
  myquery(rc);

  /* i18n part of test case. */

  {
    const char *str_koi8r= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
    const char *str_cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
    char o1_buffer[255];
    ulong o1_length;
    char o2_buffer[255];
    ulong o2_length;

    MYSQL_BIND rs_bind[2];

    strmov(query, "CALL p2(?, ?, ?)");
    stmt= mysql_simple_prepare(mysql, query);
    check_stmt(stmt);

    /* Init PS-parameters. */

    memset(ps_params, 0, sizeof (ps_params));

    ps_params[0].buffer_type= MYSQL_TYPE_STRING;
    ps_params[0].buffer= (char *) str_koi8r;
    ps_params[0].buffer_length= strlen(str_koi8r);

    ps_params[1].buffer_type= MYSQL_TYPE_STRING;
    ps_params[1].buffer= o1_buffer;
    ps_params[1].buffer_length= 0;

    ps_params[2].buffer_type= MYSQL_TYPE_STRING;
    ps_params[2].buffer= o2_buffer;
    ps_params[2].buffer_length= 0;

    /* Bind parameters. */

    rc= mysql_stmt_bind_param(stmt, ps_params);
    check_execute(stmt, rc);

    /* Prevent converting to character_set_results. */

    rc= mysql_query(mysql, "SET NAMES binary");
    myquery(rc);

    /* Execute statement. */

    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);

    /* Bind result. */

    memset(rs_bind, 0, sizeof (rs_bind));

    rs_bind[0].buffer_type= MYSQL_TYPE_STRING;
    rs_bind[0].buffer= o1_buffer;
    rs_bind[0].buffer_length= sizeof (o1_buffer);
    rs_bind[0].length= &o1_length;

    rs_bind[1].buffer_type= MYSQL_TYPE_BLOB;
    rs_bind[1].buffer= o2_buffer;
    rs_bind[1].buffer_length= sizeof (o2_buffer);
    rs_bind[1].length= &o2_length;

    rc= mysql_stmt_bind_result(stmt, rs_bind);
    check_execute(stmt, rc);

    /* Fetch result. */

    rc= mysql_stmt_fetch(stmt);
    check_execute(stmt, rc);

    /* Check result. */

    DIE_UNLESS(o1_length == strlen(str_cp1251));
    DIE_UNLESS(o2_length == strlen(str_koi8r));
    DIE_UNLESS(!memcmp(o1_buffer, str_cp1251, o1_length));
    DIE_UNLESS(!memcmp(o2_buffer, str_koi8r, o2_length));

    rc= mysql_stmt_fetch(stmt);
    DIE_UNLESS(rc == MYSQL_NO_DATA);

    rc= mysql_stmt_next_result(stmt);
    DIE_UNLESS(rc == 0 && mysql->field_count == 0);

    mysql_stmt_close(stmt);

    rc= mysql_commit(mysql);
    myquery(rc);
  }
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug56976()
{
  MYSQL_STMT   *stmt;
  MYSQL_BIND    bind[1];
  int           rc;
  const char*   query = "SELECT LENGTH(?)";
  char *long_buffer;
  unsigned long i, packet_len = 256 * 1024L;
  unsigned long dos_len    = 8 * 1024 * 1024L;

  DBUG_ENTER("test_bug56976");
  myheader("test_bug56976");

  stmt= mysql_stmt_init(mysql);
  check_stmt(stmt);

  rc= mysql_stmt_prepare(stmt, query, strlen(query));
  check_execute(stmt, rc);

  memset(bind, 0, sizeof(bind));
  bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;

  rc= mysql_stmt_bind_param(stmt, bind);
  check_execute(stmt, rc);

  long_buffer= (char*) my_malloc(packet_len, MYF(0));
  DIE_UNLESS(long_buffer);

  memset(long_buffer, 'a', packet_len);

  for (i= 0; i < dos_len / packet_len; i++)
  {
    rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len);
    check_execute(stmt, rc);
  }

  my_free(long_buffer);
  rc= mysql_stmt_execute(stmt);

  DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);

  mysql_stmt_close(stmt);

  DBUG_VOID_RETURN;
}

Project: mysql-server
File: client.c

MYSQL * STDCALL 
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
		       const char *passwd, const char *db,
		       uint port, const char *unix_socket,ulong client_flag)
{
  char		buff[NAME_LEN+USERNAME_LENGTH+100];
  int           scramble_data_len, pkt_scramble_len= 0;
  char          *end,*host_info= 0, *server_version_end, *pkt_end;
  char          *scramble_data;
  const char    *scramble_plugin;
  ulong		pkt_length;
  NET		*net= &mysql->net;
#ifdef __WIN__
  HANDLE	hPipe=INVALID_HANDLE_VALUE;
#endif
#ifdef HAVE_SYS_UN_H
  struct	sockaddr_un UNIXaddr;
#endif
  DBUG_ENTER("mysql_real_connect");

  DBUG_PRINT("enter",("host: %s  db: %s  user: %s (client)",
		      host ? host : "(Null)",
		      db ? db : "(Null)",
		      user ? user : "(Null)"));

  /* Test whether we're already connected */
  if (net->vio)
  {
    set_mysql_error(mysql, CR_ALREADY_CONNECTED, unknown_sqlstate);
    DBUG_RETURN(0);
  }

  if (set_connect_attributes(mysql, buff, sizeof(buff)))
    DBUG_RETURN(0);

  mysql->methods= &client_methods;
  net->vio = 0;				/* If something goes wrong */
  mysql->client_flag=0;			/* For handshake */

  /* use default options */
  if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
  {
    mysql_read_default_options(&mysql->options,
			       (mysql->options.my_cnf_file ?
				mysql->options.my_cnf_file : "my"),
			       mysql->options.my_cnf_group);
    my_free(mysql->options.my_cnf_file);
    my_free(mysql->options.my_cnf_group);
    mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
  }

  /* Some empty-string-tests are done because of ODBC */
  if (!host || !host[0])
    host=mysql->options.host;
  if (!user || !user[0])
  {
    user=mysql->options.user;
    if (!user)
      user= "";
  }
  if (!passwd)
  {
    passwd=mysql->options.password;
#if !defined(DONT_USE_MYSQL_PWD) && !defined(MYSQL_SERVER)
    if (!passwd)
      passwd=getenv("MYSQL_PWD");		/* get it from environment */
#endif
    if (!passwd)
      passwd= "";
  }
  if (!db || !db[0])
    db=mysql->options.db;
  if (!port)
    port=mysql->options.port;
  if (!unix_socket)
    unix_socket=mysql->options.unix_socket;

  mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
  DBUG_PRINT("info", ("Connecting"));

  /*
    Part 0: Grab a socket and connect it to the server
  */
#if defined(HAVE_SMEM)
  if ((!mysql->options.protocol ||
       mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) &&
      (!host || !strcmp(host,LOCAL_HOST)))
  {
    HANDLE handle_map;
    DBUG_PRINT("info", ("Using shared memory"));

    handle_map= create_shared_memory(mysql, net,
                                     get_win32_connect_timeout(mysql));

    if (handle_map == INVALID_HANDLE_VALUE)
    {
      DBUG_PRINT("error",
		 ("host: '%s'  socket: '%s'  shared memory: %s  have_tcpip: %d",
		  host ? host : "<null>",
		  unix_socket ? unix_socket : "<null>",
		  (int) mysql->options.shared_memory_base_name,
		  (int) have_tcpip));
      if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
	goto error;

      /*
        Try also with PIPE or TCP/IP. Clear the error from
        create_shared_memory().
      */

      net_clear_error(net);
    }
    else
    {
      mysql->options.protocol=MYSQL_PROTOCOL_MEMORY;
      unix_socket = 0;
      host=mysql->options.shared_memory_base_name;
      my_snprintf(host_info=buff, sizeof(buff)-1,
                  ER(CR_SHARED_MEMORY_CONNECTION), host);
    }
  }
#endif /* HAVE_SMEM */
#if defined(HAVE_SYS_UN_H)
  if (!net->vio &&
      (!mysql->options.protocol ||
       mysql->options.protocol == MYSQL_PROTOCOL_SOCKET) &&
      (unix_socket || mysql_unix_port) &&
      (!host || !strcmp(host,LOCAL_HOST)))
  {
    my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0);
    DBUG_PRINT("info", ("Using socket"));
    if (sock == SOCKET_ERROR)
    {
      set_mysql_extended_error(mysql, CR_SOCKET_CREATE_ERROR,
                               unknown_sqlstate,
                               ER(CR_SOCKET_CREATE_ERROR),
                               socket_errno);
      goto error;
    }

    net->vio= vio_new(sock, VIO_TYPE_SOCKET,
                      VIO_LOCALHOST | VIO_BUFFERED_READ);
    if (!net->vio)
    {
      DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
      set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
      closesocket(sock);
      goto error;
    }

    host= LOCAL_HOST;
    if (!unix_socket)
      unix_socket= mysql_unix_port;
    host_info= (char*) ER(CR_LOCALHOST_CONNECTION);
    DBUG_PRINT("info", ("Using UNIX sock '%s'", unix_socket));

    memset(&UNIXaddr, 0, sizeof(UNIXaddr));
    UNIXaddr.sun_family= AF_UNIX;
    strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1);

    if (vio_socket_connect(net->vio, (struct sockaddr *) &UNIXaddr,
                           sizeof(UNIXaddr), get_vio_connect_timeout(mysql)))
    {
      DBUG_PRINT("error",("Got error %d on connect to local server",
			  socket_errno));
      set_mysql_extended_error(mysql, CR_CONNECTION_ERROR,
                               unknown_sqlstate,
                               ER(CR_CONNECTION_ERROR),
                               unix_socket, socket_errno);
      vio_delete(net->vio);
      net->vio= 0;
      goto error;
    }
    mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
  }
#elif defined(_WIN32)
  if (!net->vio &&
      (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
       (host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
       (! have_tcpip && (unix_socket || !host && is_NT()))))
  {
    hPipe= create_named_pipe(mysql, get_win32_connect_timeout(mysql),
                             &host, &unix_socket);

    if (hPipe == INVALID_HANDLE_VALUE)
    {
      DBUG_PRINT("error",
		 ("host: '%s'  socket: '%s'  have_tcpip: %d",
		  host ? host : "<null>",
		  unix_socket ? unix_socket : "<null>",
		  (int) have_tcpip));
      if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
	  (host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
	  (unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
	goto error;
      /* Try also with TCP/IP */
    }
    else
    {
      net->vio= vio_new_win32pipe(hPipe);
      my_snprintf(host_info=buff, sizeof(buff)-1,
                  ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
    }
  }
#endif
  DBUG_PRINT("info", ("net->vio: %p  protocol: %d",
                      net->vio, mysql->options.protocol));
  if (!net->vio &&
      (!mysql->options.protocol ||
       mysql->options.protocol == MYSQL_PROTOCOL_TCP))
  {
    struct addrinfo *res_lst, *client_bind_ai_lst= NULL, hints, *t_res;
    char port_buf[NI_MAXSERV];
    my_socket sock= SOCKET_ERROR;
    int gai_errno, saved_error= 0, status= -1, bind_result= 0;
    uint flags= VIO_BUFFERED_READ;

    unix_socket=0;				/* This is not used */

    if (!port)
      port= mysql_port;

    if (!host)
      host= LOCAL_HOST;

    my_snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
    DBUG_PRINT("info",("Server name: '%s'.  TCP sock: %d", host, port));

    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype= SOCK_STREAM;
    hints.ai_protocol= IPPROTO_TCP;
    hints.ai_family= AF_UNSPEC;

    DBUG_PRINT("info",("IPV6 getaddrinfo %s", host));
    my_snprintf(port_buf, NI_MAXSERV, "%d", port);
    gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);

    if (gai_errno != 0) 
    { 
      /* 
        For DBUG we are keeping the right message but for client we default to
        historical error message.
      */
      DBUG_PRINT("info",("IPV6 getaddrinfo error %d", gai_errno));
      set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
                               ER(CR_UNKNOWN_HOST), host, errno);

      goto error;
    }

    /* Get address info for client bind name if it is provided */
    if (mysql->options.ci.bind_address)
    {
      int bind_gai_errno= 0;

      DBUG_PRINT("info",("Resolving addresses for client bind: '%s'",
                         mysql->options.ci.bind_address));
      /* Lookup address info for name */
      bind_gai_errno= getaddrinfo(mysql->options.ci.bind_address, 0,
                                  &hints, &client_bind_ai_lst);
      if (bind_gai_errno)
      {
        DBUG_PRINT("info",("client bind getaddrinfo error %d", bind_gai_errno));
        set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
                                 ER(CR_UNKNOWN_HOST),
                                 mysql->options.ci.bind_address,
                                 bind_gai_errno);

        freeaddrinfo(res_lst);
        goto error;
      }
      DBUG_PRINT("info", ("  got address info for client bind name"));
    }

    /*
      A hostname might map to multiple IP addresses (IPv4/IPv6). Go over the
      list of IP addresses until a successful connection can be established.
      For each IP address, attempt to bind the socket to each client address
      for the client-side bind hostname until the bind is successful.
    */
    DBUG_PRINT("info", ("Try connect on all addresses for host."));
    for (t_res= res_lst; t_res; t_res= t_res->ai_next)
    {
      DBUG_PRINT("info", ("Create socket, family: %d  type: %d  proto: %d",
                          t_res->ai_family, t_res->ai_socktype,
                          t_res->ai_protocol));

      sock= socket(t_res->ai_family, t_res->ai_socktype, t_res->ai_protocol);
      if (sock == SOCKET_ERROR)
      {
        DBUG_PRINT("info", ("Socket created was invalid"));
        /* Try next address if there is one */
        saved_error= socket_errno;
        continue;
      }

      if (client_bind_ai_lst)
      {
        struct addrinfo* curr_bind_ai= NULL;
        DBUG_PRINT("info", ("Attempting to bind socket to bind address(es)"));

        /*
           We'll attempt to bind to each of the addresses returned, until
           we find one that works.
           If none works, we'll try the next destination host address
           (if any)
        */
        curr_bind_ai= client_bind_ai_lst;

        while (curr_bind_ai != NULL)
        {
          /* Attempt to bind the socket to the given address */
          bind_result= bind(sock,
                            curr_bind_ai->ai_addr,
                            curr_bind_ai->ai_addrlen);
          if (!bind_result)
            break;   /* Success */

          DBUG_PRINT("info", ("bind failed, attempting another bind address"));
          /* Problem with the bind, move to next address if present */
          curr_bind_ai= curr_bind_ai->ai_next;
        }

        if (bind_result)
        {
          /*
            Could not bind to any client-side address with this destination
             Try the next destination address (if any)
          */
          DBUG_PRINT("info", ("All bind attempts with this address failed"));
          saved_error= socket_errno;
          closesocket(sock);
          continue;
        }
        DBUG_PRINT("info", ("Successfully bound client side of socket"));
      }

      /* Create a new Vio object to abstract the socket. */
      if (!net->vio)
      {
        if (!(net->vio= vio_new(sock, VIO_TYPE_TCPIP, flags)))
        {
          set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
          closesocket(sock);
          freeaddrinfo(res_lst);
          if (client_bind_ai_lst)
            freeaddrinfo(client_bind_ai_lst);
          goto error;
        }
      }
      /* Just reinitialize if one is already allocated. */
      else if (vio_reset(net->vio, VIO_TYPE_TCPIP, sock, NULL, flags))
      {
        set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
        closesocket(sock);
        freeaddrinfo(res_lst);
        if (client_bind_ai_lst)
          freeaddrinfo(client_bind_ai_lst);
        goto error;
      }

      DBUG_PRINT("info", ("Connect socket"));
      status= vio_socket_connect(net->vio, t_res->ai_addr, t_res->ai_addrlen,
                                 get_vio_connect_timeout(mysql));
      /*
        Here we rely on vio_socket_connect() to return success only if
        the connect attempt was really successful. Otherwise we would
        stop trying another address, believing we were successful.
      */
      if (!status)
        break;

      /*
        Save either the socket error status or the error code of
        the failed vio_connection operation. It is necessary to
        avoid having it overwritten by later operations.
      */
      saved_error= socket_errno;

      DBUG_PRINT("info", ("No success, close socket, try next address."));
      closesocket(sock);
    }
    DBUG_PRINT("info",
               ("End of connect attempts, sock: %d  status: %d  error: %d",
                sock, status, saved_error));

    freeaddrinfo(res_lst);
    if (client_bind_ai_lst)
      freeaddrinfo(client_bind_ai_lst);

    if (sock == SOCKET_ERROR)
    {
      set_mysql_extended_error(mysql, CR_IPSOCK_ERROR, unknown_sqlstate,
                                ER(CR_IPSOCK_ERROR), saved_error);
      goto error;
    }

    if (status)
    {
      DBUG_PRINT("error",("Got error %d on connect to '%s'", saved_error, host));
      set_mysql_extended_error(mysql, CR_CONN_HOST_ERROR, unknown_sqlstate,
                                ER(CR_CONN_HOST_ERROR), host, saved_error);
      goto error;
    }
  }

  DBUG_PRINT("info", ("net->vio: %p", net->vio));
  if (!net->vio)
  {
    DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
    set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
    goto error;
  }

  if (my_net_init(net, net->vio))
  {
    vio_delete(net->vio);
    net->vio = 0;
    set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
    goto error;
  }
  vio_keepalive(net->vio,TRUE);

  /* If user set read_timeout, let it override the default */
  if (mysql->options.read_timeout)
    my_net_set_read_timeout(net, mysql->options.read_timeout);

  /* If user set write_timeout, let it override the default */
  if (mysql->options.write_timeout)
    my_net_set_write_timeout(net, mysql->options.write_timeout);

  if (mysql->options.max_allowed_packet)
    net->max_packet_size= mysql->options.max_allowed_packet;

  /* Get version info */
  mysql->protocol_version= PROTOCOL_VERSION;	/* Assume this */
  if (mysql->options.connect_timeout &&
      (vio_io_wait(net->vio, VIO_IO_EVENT_READ,
                   get_vio_connect_timeout(mysql)) < 1))
  {
    set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
                             ER(CR_SERVER_LOST_EXTENDED),
                             "waiting for initial communication packet",
                             socket_errno);
    goto error;
  }

  /*
    Part 1: Connection established, read and parse first packet
  */
  DBUG_PRINT("info", ("Read first packet."));

  if ((pkt_length=cli_safe_read(mysql)) == packet_error)
  {
    if (mysql->net.last_errno == CR_SERVER_LOST)
      set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
                               ER(CR_SERVER_LOST_EXTENDED),
                               "reading initial communication packet",
                               socket_errno);
    goto error;
  }
  pkt_end= (char*)net->read_pos + pkt_length;
  /* Check if version of protocol matches current one */
  mysql->protocol_version= net->read_pos[0];
  DBUG_DUMP("packet",(uchar*) net->read_pos,10);
  DBUG_PRINT("info",("mysql protocol version %d, server=%d",
		     PROTOCOL_VERSION, mysql->protocol_version));
  if (mysql->protocol_version != PROTOCOL_VERSION)
  {
    set_mysql_extended_error(mysql, CR_VERSION_ERROR, unknown_sqlstate,
                             ER(CR_VERSION_ERROR), mysql->protocol_version,
                             PROTOCOL_VERSION);
    goto error;
  }
  server_version_end= end= strend((char*) net->read_pos+1);
  mysql->thread_id=uint4korr(end+1);
  end+=5;
  /* 
    Scramble is split into two parts because old clients do not understand
    long scrambles; here goes the first part.
  */
  scramble_data= end;
  scramble_data_len= SCRAMBLE_LENGTH_323 + 1;
  scramble_plugin= old_password_plugin_name;
  end+= scramble_data_len;

  if (pkt_end >= end + 1)
    mysql->server_capabilities=uint2korr(end);
  if (pkt_end >= end + 18)
  {
    /* New protocol with 16 bytes to describe server characteristics */
    mysql->server_language=end[2];
    mysql->server_status=uint2korr(end+3);
    mysql->server_capabilities|= uint2korr(end+5) << 16;
    pkt_scramble_len= end[7];
    if (pkt_scramble_len < 0)
    {
      set_mysql_error(mysql, CR_MALFORMED_PACKET,
                      unknown_sqlstate);        /* purecov: inspected */
      goto error;
    }
  }
  end+= 18;

  if (mysql->options.secure_auth && passwd[0] &&
      !(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
  {
    set_mysql_error(mysql, CR_SECURE_AUTH, unknown_sqlstate);
    goto error;
  }

  if (mysql_init_character_set(mysql))
    goto error;

  /* Save connection information */
  if (!my_multi_malloc(MYF(0),
		       &mysql->host_info, (uint) strlen(host_info)+1,
		       &mysql->host,      (uint) strlen(host)+1,
		       &mysql->unix_socket,unix_socket ?
		       (uint) strlen(unix_socket)+1 : (uint) 1,
		       &mysql->server_version,
		       (uint) (server_version_end - (char*) net->read_pos + 1),
		       NullS) ||
      !(mysql->user=my_strdup(user,MYF(0))) ||
      !(mysql->passwd=my_strdup(passwd,MYF(0))))
  {
    set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
    goto error;
  }
  strmov(mysql->host_info,host_info);
  strmov(mysql->host,host);
  if (unix_socket)
    strmov(mysql->unix_socket,unix_socket);
  else
    mysql->unix_socket=0;
  strmov(mysql->server_version,(char*) net->read_pos+1);
  mysql->port=port;

  if (pkt_end >= end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1)
  {
    /*
     move the first scramble part - directly in the NET buffer -
     to get a full continuous scramble. We've read all the header,
     and can overwrite it now.
    */
    memmove(end - SCRAMBLE_LENGTH_323, scramble_data,
            SCRAMBLE_LENGTH_323);
    scramble_data= end - SCRAMBLE_LENGTH_323;
    if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
    {
      scramble_data_len= pkt_scramble_len;
      scramble_plugin= scramble_data + scramble_data_len;
      if (scramble_data + scramble_data_len > pkt_end)
        scramble_data_len= pkt_end - scramble_data;
    }
    else
    {
      scramble_data_len= pkt_end - scramble_data;
      scramble_plugin= native_password_plugin_name;
    }
  }
  else
    mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;

  mysql->client_flag= client_flag;

  /*
    Part 2: invoke the plugin to send the authentication data to the server
  */

  if (run_plugin_auth(mysql, scramble_data, scramble_data_len,
                      scramble_plugin, db))
    goto error;

  /*
    Part 3: authenticated, finish the initialization of the connection
  */

  if (mysql->client_flag & CLIENT_COMPRESS)      /* We will use compression */
    net->compress=1;

#ifdef CHECK_LICENSE 
  if (check_license(mysql))
    goto error;
#endif

  if (db && !mysql->db && mysql_select_db(mysql, db))
  {
    if (mysql->net.last_errno == CR_SERVER_LOST)
        set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
                                 ER(CR_SERVER_LOST_EXTENDED),
                                 "Setting intital database",
                                 errno);
    goto error;
  }

  /*
     Using init_commands is not supported when connecting from within the
     server.
  */
#ifndef MYSQL_SERVER
  if (mysql->options.init_commands)
  {
    DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
    char **ptr= (char**)init_commands->buffer;
    char **end_command= ptr + init_commands->elements;

    my_bool reconnect=mysql->reconnect;
    mysql->reconnect=0;

    for (; ptr < end_command; ptr++)
    {
      int status;

      if (mysql_real_query(mysql,*ptr, (ulong) strlen(*ptr)))
	goto error;

      do {
        if (mysql->fields)
        {
          MYSQL_RES *res;
          if (!(res= cli_use_result(mysql)))
            goto error;
          mysql_free_result(res);
        }
        if ((status= mysql_next_result(mysql)) > 0)
          goto error;
      } while (status == 0);
    }
    mysql->reconnect=reconnect;
  }
#endif

  DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql));
  DBUG_RETURN(mysql);

error:
  DBUG_PRINT("error",("message: %u/%s (%s)",
                      net->last_errno,
                      net->sqlstate,
                      net->last_error));
  {
    /* Free alloced memory */
    end_server(mysql);
    mysql_close_free(mysql);
    if (!(client_flag & CLIENT_REMEMBER_OPTIONS))
      mysql_close_free_options(mysql);
  }
  DBUG_RETURN(0);

Project: mysql-server
File: mysql_client_test.c

static void test_manual_sample()
{
  unsigned int param_count;
  MYSQL_STMT   *stmt;
  short        small_data;
  int          int_data;
  int          rc;
  char         str_data[50];
  ulonglong    affected_rows;
  MYSQL_BIND   my_bind[3];
  my_bool      is_null;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_manual_sample");

  /*
    Sample which is incorporated directly in the manual under Prepared
    statements section (Example from mysql_stmt_execute()
  */

  mysql_autocommit(mysql, 1);
  if (mysql_query(mysql, "DROP TABLE IF EXISTS test_table"))
  {
    fprintf(stderr, "\n drop table failed");
    fprintf(stderr, "\n %s", mysql_error(mysql));
    exit(1);
  }
  if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \
                                                 col3 smallint, \
                                                 col4 timestamp)"))
  {
    fprintf(stderr, "\n create table failed");
    fprintf(stderr, "\n %s", mysql_error(mysql));
    exit(1);
  }

  /* Prepare a insert query with 3 parameters */
  strmov(query, "INSERT INTO test_table(col1, col2, col3) values(?, ?, ?)");
  if (!(stmt= mysql_simple_prepare(mysql, query)))
  {
    fprintf(stderr, "\n prepare, insert failed");
    fprintf(stderr, "\n %s", mysql_error(mysql));
    exit(1);
  }
  if (!opt_silent)
    fprintf(stdout, "\n prepare, insert successful");

  /* Get the parameter count from the statement */
  param_count= mysql_stmt_param_count(stmt);

  if (!opt_silent)
    fprintf(stdout, "\n total parameters in insert: %d", param_count);
  if (param_count != 3) /* validate parameter count */
  {
    fprintf(stderr, "\n invalid parameter count returned by MySQL");
    exit(1);
  }

  /* Bind the data for the parameters */

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  /* INTEGER PART */
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
  my_bind[0].buffer= (void *)&int_data;

  /* STRING PART */
  my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
  my_bind[1].buffer= (void *)str_data;
  my_bind[1].buffer_length= sizeof(str_data);

  /* SMALLINT PART */
  my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
  my_bind[2].buffer= (void *)&small_data;
  my_bind[2].is_null= &is_null;
  is_null= 0;

  /* Bind the buffers */
  if (mysql_stmt_bind_param(stmt, my_bind))
  {
    fprintf(stderr, "\n param bind failed");
    fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
    exit(1);
  }

  /* Specify the data */
  int_data= 10;             /* integer */
  strmov(str_data, "MySQL"); /* string  */

  /* INSERT SMALLINT data as NULL */
  is_null= 1;

  /* Execute the insert statement - 1*/
  if (mysql_stmt_execute(stmt))
  {
    fprintf(stderr, "\n execute 1 failed");
    fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
    exit(1);
  }

  /* Get the total rows affected */
  affected_rows= mysql_stmt_affected_rows(stmt);

  if (!opt_silent)
    fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
  if (affected_rows != 1) /* validate affected rows */
  {
    fprintf(stderr, "\n invalid affected rows by MySQL");
    exit(1);
  }

  /* Re-execute the insert, by changing the values */
  int_data= 1000;
  strmov(str_data, "The most popular open source database");
  small_data= 1000;         /* smallint */
  is_null= 0;               /* reset */

  /* Execute the insert statement - 2*/
  if (mysql_stmt_execute(stmt))
  {
    fprintf(stderr, "\n execute 2 failed");
    fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
    exit(1);
  }

  /* Get the total rows affected */
  affected_rows= mysql_stmt_affected_rows(stmt);

  if (!opt_silent)
    fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
  if (affected_rows != 1) /* validate affected rows */
  {
    fprintf(stderr, "\n invalid affected rows by MySQL");
    exit(1);
  }

  /* Close the statement */
  if (mysql_stmt_close(stmt))
  {
    fprintf(stderr, "\n failed while closing the statement");
    fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
    exit(1);
  }
  rc= my_stmt_result("SELECT * FROM test_table");
  DIE_UNLESS(rc == 2);

  /* DROP THE TABLE */
  if (mysql_query(mysql, "DROP TABLE test_table"))
  {
    fprintf(stderr, "\n drop table failed");
    fprintf(stderr, "\n %s", mysql_error(mysql));
    exit(1);
  }
  if (!opt_silent)
    fprintf(stdout, "Success !!!");
}

Project: mysql-server
File: mysql_client_test.c

static void test_fetch_null()
{
  MYSQL_STMT *stmt;
  int        rc;
  int        i, nData;
  MYSQL_BIND my_bind[11];
  ulong      length[11];
  my_bool    is_null[11];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_fetch_null");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_fetch_null("
                         " col1 tinyint, col2 smallint, "
                         " col3 int, col4 bigint, "
                         " col5 float, col6 double, "
                         " col7 date, col8 time, "
                         " col9 varbinary(10), "
                         " col10 varchar(50), "
                         " col11 char(20))");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) "
                         "VALUES (1000), (88), (389789)");
  myquery(rc);

  rc= mysql_commit(mysql);
  myquery(rc);

  /* fetch */
  memset(my_bind, 0, sizeof(my_bind));
  for (i= 0; i < (int) array_elements(my_bind); i++)
  {
    my_bind[i].buffer_type= MYSQL_TYPE_LONG;
    my_bind[i].is_null= &is_null[i];
    my_bind[i].length= &length[i];
  }
  my_bind[i-1].buffer= (void *)&nData;              /* Last column is not null */

  strmov((char *)query , "SELECT * FROM test_fetch_null");

  rc= my_stmt_result(query);
  DIE_UNLESS(rc == 3);

  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  rc= mysql_stmt_bind_result(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= 0;
  while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
  {
    rc++;
    for (i= 0; i < 10; i++)
    {
      if (!opt_silent)
        fprintf(stdout, "\n data[%d] : %s", i,
                is_null[i] ? "NULL" : "NOT NULL");
      DIE_UNLESS(is_null[i]);
    }
    if (!opt_silent)
      fprintf(stdout, "\n data[%d]: %d", i, nData);
    DIE_UNLESS(nData == 1000 || nData == 88 || nData == 389789);
    DIE_UNLESS(is_null[i] == 0);
    DIE_UNLESS(length[i] == 4);
  }
  DIE_UNLESS(rc == 3);
  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_view_insert_fields()
{
  MYSQL_STMT	*stmt;
  char		parm[11][1000];
  ulong         l[11];
  int		rc, i;
  MYSQL_BIND	my_bind[11];
  const char    *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";

  myheader("test_view_insert_fields");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
  myquery(rc);
  rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
  myquery(rc);
  rc= mysql_query(mysql,
                  "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
                  "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
                  "K4N4 varchar(4) NOT NULL default '0000',"
                  "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
                  "F3N5 varchar(5) NOT NULL default '00000',"
                  "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
                  "F6N4 varchar(4) NOT NULL default '0000',"
                  "F7F8 double NOT NULL default '0',"
                  "F8F8 double NOT NULL default '0',"
                  "F9D8 decimal(8,2) NOT NULL default '0.00',"
                  "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
                  "CHARSET=latin1 COLLATE latin1_bin");
  myquery(rc);
  rc= mysql_query(mysql,
                  "CREATE VIEW v1 AS select sql_no_cache "
                  " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
                  " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
                  " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
                  " from t1 T0001");

  memset(my_bind, 0, sizeof(my_bind));
  for (i= 0; i < 11; i++)
  {
    l[i]= 20;
    my_bind[i].buffer_type= MYSQL_TYPE_STRING;
    my_bind[i].is_null= 0;
    my_bind[i].buffer= (char *)&parm[i];

    strmov(parm[i], "1");
    my_bind[i].buffer_length= 2;
    my_bind[i].length= &l[i];
  }
  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, query, strlen(query));
  check_execute(stmt, rc);
  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  mysql_stmt_close(stmt);

  query= "select * from t1";
  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, query, strlen(query));
  check_execute(stmt, rc);
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(1 == rc);

  mysql_stmt_close(stmt);
  rc= mysql_query(mysql, "DROP VIEW v1");
  myquery(rc);
  rc= mysql_query(mysql, "DROP TABLE t1");
  myquery(rc);

}

Project: mysql-server
File: mysql_client_test.c

static void test_select()
{
  MYSQL_STMT *stmt;
  int        rc;
  char       szData[25];
  int        nData= 1;
  MYSQL_BIND my_bind[2];
  ulong length[2];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_select");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
  myquery(rc);

  /* insert a row and commit the transaction */
  rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
  myquery(rc);

  /* now insert the second row, and roll back the transaction */
  rc= mysql_query(mysql, "INSERT INTO test_select VALUES(20, 'mysql')");
  myquery(rc);

  rc= mysql_commit(mysql);
  myquery(rc);

  strmov(query, "SELECT * FROM test_select WHERE id= ? "
                "AND CONVERT(name USING utf8) =?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  /* string data */
  nData= 10;
  strmov(szData, (char *)"venu");
  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
  my_bind[1].buffer= (void *)szData;
  my_bind[1].buffer_length= 4;
  my_bind[1].length= &length[1];
  length[1]= 4;

  my_bind[0].buffer= (void *)&nData;
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 1);

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_ps_null_param()
{
  MYSQL_STMT *stmt;
  int        rc;

  MYSQL_BIND in_bind;
  my_bool    in_is_null;
  long int   in_long;

  MYSQL_BIND out_bind;
  ulong      out_length;
  my_bool    out_is_null;
  char       out_str_data[20];

  const char *queries[]= {"select ?", "select ?+1",
                    "select col1 from test_ps_nulls where col1 <=> ?",
                    NULL
                    };
  const char **cur_query= queries;

  myheader("test_null_ps_param_in_result");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ps_nulls");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_ps_nulls(col1 int)");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO test_ps_nulls values (1), (null)");
  myquery(rc);

  /* Always memset all members of bind parameter */
  memset(&in_bind, 0, sizeof(in_bind));
  memset(&out_bind, 0, sizeof(out_bind));

  in_bind.buffer_type= MYSQL_TYPE_LONG;
  in_bind.is_null= &in_is_null;
  in_bind.length= 0;
  in_bind.buffer= (void *)&in_long;
  in_is_null= 1;
  in_long= 1;

  out_bind.buffer_type= MYSQL_TYPE_STRING;
  out_bind.is_null= &out_is_null;
  out_bind.length= &out_length;
  out_bind.buffer= out_str_data;
  out_bind.buffer_length= array_elements(out_str_data);

  /* Execute several queries, all returning NULL in result. */
  for(cur_query= queries; *cur_query; cur_query++)
  {
    char query[MAX_TEST_QUERY_LENGTH];
    strmov(query, *cur_query);
    stmt= mysql_simple_prepare(mysql, query);
    check_stmt(stmt);
    verify_param_count(stmt, 1);

    rc= mysql_stmt_bind_param(stmt, &in_bind);
    check_execute(stmt, rc);
    rc= mysql_stmt_bind_result(stmt, &out_bind);
    check_execute(stmt, rc);
    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);
    rc= mysql_stmt_fetch(stmt);
    DIE_UNLESS(rc != MYSQL_NO_DATA);
    DIE_UNLESS(out_is_null);
    rc= mysql_stmt_fetch(stmt);
    DIE_UNLESS(rc == MYSQL_NO_DATA);
    mysql_stmt_close(stmt);
  }
}

Project: mysql-server
File: mysql_client_test.c

static void test_prepare_noparam()
{
  MYSQL_STMT *stmt;
  int        rc;
  MYSQL_RES  *result;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_prepare_noparam");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
  myquery(rc);


  rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 int, col2 varchar(50))");
  myquery(rc);

  /* insert by prepare */
  strmov(query, "INSERT INTO my_prepare VALUES(10, 'venu')");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 0);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);

  /* now fetch the results ..*/
  rc= mysql_commit(mysql);
  myquery(rc);

  /* test the results now, only one row should exist */
  rc= mysql_query(mysql, "SELECT * FROM my_prepare");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 1);
  mysql_free_result(result);
}

Project: mysql-server
File: mysql_client_test.c

static void test_bug36004()
{
  int rc, warning_count= 0;
  MYSQL_STMT *stmt;

  DBUG_ENTER("test_bug36004");
  myheader("test_bug36004");

  rc= mysql_query(mysql, "drop table if exists inexistant");
  myquery(rc);

  DIE_UNLESS(mysql_warning_count(mysql) == 1);
  query_int_variable(mysql, "@@warning_count", &warning_count);
  DIE_UNLESS(warning_count);

  stmt= mysql_simple_prepare(mysql, "select 1");
  check_stmt(stmt);

  DIE_UNLESS(mysql_warning_count(mysql) == 0);
  query_int_variable(mysql, "@@warning_count", &warning_count);
  DIE_UNLESS(warning_count);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  DIE_UNLESS(mysql_warning_count(mysql) == 0);
  mysql_stmt_close(stmt);

  query_int_variable(mysql, "@@warning_count", &warning_count);
  DIE_UNLESS(warning_count);

  stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
  check_stmt(stmt);

  query_int_variable(mysql, "@@warning_count", &warning_count);
  DIE_UNLESS(warning_count == 0);
  mysql_stmt_close(stmt);

  DBUG_VOID_RETURN;
}

Project: mysql-server
File: mysql_client_test.c

static void test_prepare_ext()
{
  MYSQL_STMT *stmt;
  int        rc;
  char       *sql;
  int        nData= 1;
  char       tData= 1;
  short      sData= 10;
  longlong   bData= 20;
  MYSQL_BIND my_bind[6];
  char query[MAX_TEST_QUERY_LENGTH];
  myheader("test_prepare_ext");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext");
  myquery(rc);

  sql= (char *)"CREATE TABLE test_prepare_ext"
               "("
               " c1  tinyint,"
               " c2  smallint,"
               " c3  mediumint,"
               " c4  int,"
               " c5  integer,"
               " c6  bigint,"
               " c7  float,"
               " c8  double,"
               " c9  double precision,"
               " c10 real,"
               " c11 decimal(7, 4),"
               " c12 numeric(8, 4),"
               " c13 date,"
               " c14 datetime,"
               " c15 timestamp,"
               " c16 time,"
               " c17 year,"
               " c18 bit,"
               " c19 bool,"
               " c20 char,"
               " c21 char(10),"
               " c22 varchar(30),"
               " c23 tinyblob,"
               " c24 tinytext,"
               " c25 blob,"
               " c26 text,"
               " c27 mediumblob,"
               " c28 mediumtext,"
               " c29 longblob,"
               " c30 longtext,"
               " c31 enum('one', 'two', 'three'),"
               " c32 set('monday', 'tuesday', 'wednesday'))";

  rc= mysql_query(mysql, sql);
  myquery(rc);

  /* insert by prepare - all integers */
  strmov(query, (char *)"INSERT INTO test_prepare_ext(c1, c2, c3, c4, c5, c6) VALUES(?, ?, ?, ?, ?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 6);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  /*tinyint*/
  my_bind[0].buffer_type= MYSQL_TYPE_TINY;
  my_bind[0].buffer= (void *)&tData;

  /*smallint*/
  my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
  my_bind[1].buffer= (void *)&sData;

  /*mediumint*/
  my_bind[2].buffer_type= MYSQL_TYPE_LONG;
  my_bind[2].buffer= (void *)&nData;

  /*int*/
  my_bind[3].buffer_type= MYSQL_TYPE_LONG;
  my_bind[3].buffer= (void *)&nData;

  /*integer*/
  my_bind[4].buffer_type= MYSQL_TYPE_LONG;
  my_bind[4].buffer= (void *)&nData;

  /*bigint*/
  my_bind[5].buffer_type= MYSQL_TYPE_LONGLONG;
  my_bind[5].buffer= (void *)&bData;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  /*
  *  integer to integer
  */
  for (nData= 0; nData<10; nData++, tData++, sData++, bData++)
  {
    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);
  }
  mysql_stmt_close(stmt);

  /* now fetch the results ..*/

  stmt= mysql_simple_prepare(mysql, "SELECT c1, c2, c3, c4, c5, c6 "
                                    "FROM test_prepare_ext");
  check_stmt(stmt);

  /* get the result */
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(nData == rc);

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_view_2where()
{
  MYSQL_STMT *stmt;
  int rc, i;
  MYSQL_BIND      my_bind[8];
  char            parms[8][100];
  ulong           length[8];
  const char *query=
    "select relid, report, handle, log_group, username, variant, type, "
    "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
    "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
    "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";

  myheader("test_view_2where");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
  myquery(rc);
  rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
  myquery(rc);
  rc= mysql_query(mysql,
                  "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
                  " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
                  " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
                  " USERNAME varchar(12) NOT NULL,"
                  " VARIANT varchar(12) NOT NULL,"
                  " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
                  " VERSION varchar(6) NOT NULL default '000000',"
                  " ERFDAT varchar(8) NOT NULL default '00000000',"
                  " ERFTIME varchar(6) NOT NULL default '000000',"
                  " ERFNAME varchar(12) NOT NULL,"
                  " AEDAT varchar(8) NOT NULL default '00000000',"
                  " AETIME varchar(6) NOT NULL default '000000',"
                  " AENAME varchar(12) NOT NULL,"
                  " DEPENDVARS varchar(10) NOT NULL,"
                  " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
                  " CLUSTD blob,"
                  " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
                                "USERNAME, VARIANT, TYPE, SRTF2))"
                 " CHARSET=latin1 COLLATE latin1_bin");
  myquery(rc);
  rc= mysql_query(mysql,
                  "CREATE VIEW V_LTDX AS select T0001.MANDT AS "
                  " MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
                  " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
                  " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
                  " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
                  " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
                  " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
                  " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
                  " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
                  " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
  myquery(rc);
  memset(my_bind, 0, sizeof(my_bind));
  for (i=0; i < 8; i++) {
    strmov(parms[i], "1");
    my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
    my_bind[i].buffer = (char *)&parms[i];
    my_bind[i].buffer_length = 100;
    my_bind[i].is_null = 0;
    my_bind[i].length = &length[i];
    length[i] = 1;
  }
  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, query, strlen(query));
  check_execute(stmt, rc);

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt,rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(0 == rc);

  mysql_stmt_close(stmt);

  rc= mysql_query(mysql, "DROP VIEW V_LTDX");
  myquery(rc);
  rc= mysql_query(mysql, "DROP TABLE LTDX");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_null()
{
  MYSQL_STMT *stmt;
  int        rc;
  uint       nData;
  MYSQL_BIND my_bind[2];
  my_bool    is_null[2];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_null");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_null");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_null(col1 int, col2 varchar(50))");
  myquery(rc);

  /* insert by prepare, wrong column name */
  strmov(query, "INSERT INTO test_null(col3, col2) VALUES(?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt_r(stmt);

  strmov(query, "INSERT INTO test_null(col1, col2) VALUES(?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
  my_bind[0].is_null= &is_null[0];
  is_null[0]= 1;
  my_bind[1]= my_bind[0];

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  /* now, execute the prepared statement to insert 10 records.. */
  for (nData= 0; nData<10; nData++)
  {
    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);
  }

  /* Re-bind with MYSQL_TYPE_NULL */
  my_bind[0].buffer_type= MYSQL_TYPE_NULL;
  is_null[0]= 0; /* reset */
  my_bind[1]= my_bind[0];

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  for (nData= 0; nData<10; nData++)
  {
    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);
  }

  mysql_stmt_close(stmt);

  /* now fetch the results ..*/
  rc= mysql_commit(mysql);
  myquery(rc);

  nData*= 2;
  rc= my_stmt_result("SELECT * FROM test_null");;
  DIE_UNLESS((int) nData == rc);

  /* Fetch results */
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;
  my_bind[0].buffer= (void *)&nData; /* this buffer won't be altered */
  my_bind[0].length= 0;
  my_bind[1]= my_bind[0];
  my_bind[0].is_null= &is_null[0];
  my_bind[1].is_null= &is_null[1];

  stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_null");
  check_stmt(stmt);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_bind_result(stmt, my_bind);
  check_execute(stmt, rc);

  rc= 0;
  is_null[0]= is_null[1]= 0;
  while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
  {
    DIE_UNLESS(is_null[0]);
    DIE_UNLESS(is_null[1]);
    rc++;
    is_null[0]= is_null[1]= 0;
  }
  DIE_UNLESS(rc == (int) nData);
  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_wl5968()
{
  int rc;

  myheader("test_wl5968");

  rc= mysql_query(mysql, "START TRANSACTION");
  myquery(rc);
  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
  rc= mysql_query(mysql, "COMMIT");
  myquery(rc);
  rc= mysql_query(mysql, "START TRANSACTION READ ONLY");
  myquery(rc);
  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY);
  rc= mysql_query(mysql, "COMMIT");
  myquery(rc);
  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
  rc= mysql_query(mysql, "START TRANSACTION");
  myquery(rc);
  DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
  DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS_READONLY));
  rc= mysql_query(mysql, "COMMIT");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_nstmts()
{
  MYSQL_STMT  *stmt;
  char        query[255];
  int         rc;
  static uint i, total_stmts= 2000;
  MYSQL_BIND  my_bind[1];

  myheader("test_nstmts");

  mysql_autocommit(mysql, TRUE);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_nstmts");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_nstmts(id int)");
  myquery(rc);

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer= (void *)&i;
  my_bind[0].buffer_type= MYSQL_TYPE_LONG;

  for (i= 0; i < total_stmts; i++)
  {
    if (!opt_silent)
      fprintf(stdout, "\r stmt: %d", i);

    strmov(query, "insert into test_nstmts values(?)");
    stmt= mysql_simple_prepare(mysql, query);
    check_stmt(stmt);

    rc= mysql_stmt_bind_param(stmt, my_bind);
    check_execute(stmt, rc);

    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);

    mysql_stmt_close(stmt);
  }

  stmt= mysql_simple_prepare(mysql, " select count(*) from test_nstmts");
  check_stmt(stmt);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  i= 0;
  rc= mysql_stmt_bind_result(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);
  if (!opt_silent)
    fprintf(stdout, "\n total rows: %d", i);
  DIE_UNLESS( i == total_stmts);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);

  mysql_stmt_close(stmt);

  rc= mysql_query(mysql, "DROP TABLE test_nstmts");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_view()
{
  MYSQL_STMT *stmt;
  int rc, i;
  MYSQL_BIND      my_bind[1];
  char            str_data[50];
  ulong           length = 0L;
  long            is_null = 0L;
  const char *query=
    "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";

  myheader("test_view");

  rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
  myquery(rc);

  rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
  myquery(rc);
  rc= mysql_query(mysql,"CREATE TABLE t1 ("
                        " SERVERGRP varchar(20) NOT NULL default '', "
                        " DBINSTANCE varchar(20) NOT NULL default '', "
                        " PRIMARY KEY  (SERVERGRP)) "
                        " CHARSET=latin1 collate=latin1_bin");
  myquery(rc);
  rc= mysql_query(mysql,"CREATE TABLE t2 ("
                        " SERVERNAME varchar(20) NOT NULL, "
                        " SERVERGRP varchar(20) NOT NULL, "
                        " PRIMARY KEY (SERVERNAME)) "
                        " CHARSET=latin1 COLLATE latin1_bin");
  myquery(rc);
  rc= mysql_query(mysql,
                  "CREATE TABLE t3 ("
                  " SERVERGRP varchar(20) BINARY NOT NULL, "
                  " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
                  " ACTSTATE char(1) NOT NULL , "
                  " LOCAL_NAME varchar(30) NOT NULL, "
                  " CHG_DATE varchar(8) NOT NULL default '00000000', "
                  " CHG_TIME varchar(6) NOT NULL default '000000', "
                  " MXUSER varchar(12) NOT NULL default '', "
                  " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
                  " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
  myquery(rc);
  rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
                  " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
                  " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
                  " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
                  " ((T0002.SERVERGRP = T0001.SERVERGRP) and"
                  " (T0002.SERVERGRP = T0003.SERVERGRP)"
                  " and (T0003.MAPSTATE = _latin1'A') and"
                  " (T0003.ACTSTATE = _latin1' '))");
  myquery(rc);

  stmt= mysql_stmt_init(mysql);
  rc= mysql_stmt_prepare(stmt, query, strlen(query));
  check_execute(stmt, rc);

  strmov(str_data, "TEST");
  memset(my_bind, 0, sizeof(my_bind));
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (char *)&str_data;
  my_bind[0].buffer_length= 50;
  my_bind[0].length= &length;
  length= 4;
  my_bind[0].is_null= (char*)&is_null;
  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt,rc);

  for (i= 0; i < 3; i++)
  {
    rc= mysql_stmt_execute(stmt);
    check_execute(stmt, rc);
    rc= my_process_stmt_result(stmt);
    DIE_UNLESS(1 == rc);
  }
  mysql_stmt_close(stmt);

  rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
  myquery(rc);
  rc= mysql_query(mysql, "DROP VIEW v1");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_sqlmode()
{
  MYSQL_STMT *stmt;
  MYSQL_BIND my_bind[2];
  char       c1[5], c2[5];
  int        rc;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_sqlmode");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))");
  myquery(rc);

  /* PIPES_AS_CONCAT */
  strmov(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
  if (!opt_silent)
    fprintf(stdout, "\n With %s", query);
  rc= mysql_query(mysql, query);
  myquery(rc);

  strmov(query, "INSERT INTO test_piping VALUES(?||?)");
  if (!opt_silent)
    fprintf(stdout, "\n  query: %s", query);
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  if (!opt_silent)
    fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));

  /*
    We need to memset bind structure because mysql_stmt_bind_param checks all
    its members.
  */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= (void *)c1;
  my_bind[0].buffer_length= 2;

  my_bind[1].buffer_type= MYSQL_TYPE_STRING;
  my_bind[1].buffer= (void *)c2;
  my_bind[1].buffer_length= 3;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  strmov(c1, "My"); strmov(c2, "SQL");
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  mysql_stmt_close(stmt);

  verify_col_data("test_piping", "name", "MySQL");

  rc= mysql_query(mysql, "DELETE FROM test_piping");
  myquery(rc);

  strmov(query, "SELECT connection_id    ()");
  if (!opt_silent)
    fprintf(stdout, "\n  query: %s", query);
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);
  mysql_stmt_close(stmt);

  /* ANSI */
  strmov(query, "SET SQL_MODE= \"ANSI\"");
  if (!opt_silent)
    fprintf(stdout, "\n With %s", query);
  rc= mysql_query(mysql, query);
  myquery(rc);

  strmov(query, "INSERT INTO test_piping VALUES(?||?)");
  if (!opt_silent)
    fprintf(stdout, "\n  query: %s", query);
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);
  if (!opt_silent)
    fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  strmov(c1, "My"); strmov(c2, "SQL");
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);
  verify_col_data("test_piping", "name", "MySQL");

  /* ANSI mode spaces ... */
  strmov(query, "SELECT connection_id    ()");
  if (!opt_silent)
    fprintf(stdout, "\n  query: %s", query);
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);
  if (!opt_silent)
    fprintf(stdout, "\n  returned 1 row\n");

  mysql_stmt_close(stmt);

  /* IGNORE SPACE MODE */
  strmov(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
  if (!opt_silent)
    fprintf(stdout, "\n With %s", query);
  rc= mysql_query(mysql, query);
  myquery(rc);

  strmov(query, "SELECT connection_id    ()");
  if (!opt_silent)
    fprintf(stdout, "\n  query: %s", query);
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_NO_DATA);
  if (!opt_silent)
    fprintf(stdout, "\n  returned 1 row");

  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_explain_bug()
{
  MYSQL_STMT *stmt;
  MYSQL_RES  *result;
  int        rc;

  myheader("test_explain_bug");

  mysql_autocommit(mysql, TRUE);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_explain");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))");
  myquery(rc);

  stmt= mysql_simple_prepare(mysql, "explain test_explain");
  check_stmt(stmt);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 2);

  result= mysql_stmt_result_metadata(stmt);
  mytest(result);

  if (!opt_silent)
    fprintf(stdout, "\n total fields in the result: %d",
            mysql_num_fields(result));
  DIE_UNLESS(6 == mysql_num_fields(result));

  verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
                       mysql_get_server_version(mysql) <= 50000 ?
                       MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
                       0, 0, "information_schema", 64, 0);

  verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
                       0, 0, "information_schema", 0, 0);

  verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
                       mysql_get_server_version(mysql) <= 50000 ?
                       MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
                       0, 0, "information_schema", 3, 0);

  verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
                       mysql_get_server_version(mysql) <= 50000 ?
                       MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
                       0, 0, "information_schema", 3, 0);

  if ( mysql_get_server_version(mysql) >= 50027 )
  {
    /*  The patch for bug#23037 changes column type of DEAULT to blob */
    verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
                         MYSQL_TYPE_BLOB, 0, 0, "information_schema", 0, 0);
  }
  else
  {
    verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
                         mysql_get_server_version(mysql) >= 50027 ?
                         MYSQL_TYPE_BLOB :
                         mysql_get_server_version(mysql) <= 50000 ?
                         MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
                         0, 0, "information_schema",
                         mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
  }

  verify_prepare_field(result, 5, "Extra", "EXTRA",
                       mysql_get_server_version(mysql) <= 50000 ?
                       MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
                       0, 0, "information_schema",
                       mysql_get_server_version(mysql) <= 50602 ? 27 : 30,
                       0);

  mysql_free_result(result);
  mysql_stmt_close(stmt);

  stmt= mysql_simple_prepare(mysql, "explain select id, name FROM test_explain");
  check_stmt(stmt);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= my_process_stmt_result(stmt);
  DIE_UNLESS(rc == 1);

  result= mysql_stmt_result_metadata(stmt);
  mytest(result);

  if (!opt_silent)
    fprintf(stdout, "\n total fields in the result: %d",
            mysql_num_fields(result));
  DIE_UNLESS(10 == mysql_num_fields(result));

  verify_prepare_field(result, 0, "id", "", MYSQL_TYPE_LONGLONG,
                       "", "", "", 3, 0);

  verify_prepare_field(result, 1, "select_type", "", MYSQL_TYPE_VAR_STRING,
                       "", "", "", 19, 0);

  verify_prepare_field(result, 2, "table", "", MYSQL_TYPE_VAR_STRING,
                       "", "", "", NAME_CHAR_LEN, 0);

  verify_prepare_field(result, 3, "type", "", MYSQL_TYPE_VAR_STRING,
                       "", "", "", 10, 0);

  verify_prepare_field(result, 4, "possible_keys", "", MYSQL_TYPE_VAR_STRING,
                       "", "", "", NAME_CHAR_LEN*MAX_KEY, 0);

  verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
                       "", "", "", NAME_CHAR_LEN, 0);

  if (mysql_get_server_version(mysql) <= 50000)
  {
    verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG, "",
                         "", "", 3, 0);
  }
  else
  {
    verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_VAR_STRING, "", 
                         "", "", NAME_CHAR_LEN*MAX_KEY, 0);
  }

  verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
                       "", "", "", NAME_CHAR_LEN*16, 0);

  verify_prepare_field(result, 8, "rows", "", MYSQL_TYPE_LONGLONG,
                       "", "", "", 10, 0);

  verify_prepare_field(result, 9, "Extra", "", MYSQL_TYPE_VAR_STRING,
                       "", "", "", 255, 0);

  mysql_free_result(result);
  mysql_stmt_close(stmt);
}

Project: mysql-server
File: mysql_client_test.c

static void test_prepare_simple()
{
  MYSQL_STMT *stmt;
  int        rc;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_prepare_simple");

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_simple");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_prepare_simple("
                         "id int, name varchar(50))");
  myquery(rc);

  /* insert */
  strmov(query, "INSERT INTO test_prepare_simple VALUES(?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);
  mysql_stmt_close(stmt);

  /* update */
  strmov(query, "UPDATE test_prepare_simple SET id=? "
                "WHERE id=? AND CONVERT(name USING utf8)= ?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 3);
  mysql_stmt_close(stmt);

  /* delete */
  strmov(query, "DELETE FROM test_prepare_simple WHERE id=10");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 0);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  mysql_stmt_close(stmt);

  /* delete */
  strmov(query, "DELETE FROM test_prepare_simple WHERE id=?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 1);

  mysql_stmt_close(stmt);

  /* select */
  strmov(query, "SELECT * FROM test_prepare_simple WHERE id=? "
                "AND CONVERT(name USING utf8)= ?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  mysql_stmt_close(stmt);

  /* now fetch the results ..*/
  rc= mysql_commit(mysql);
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_long_data_str1()
{
  MYSQL_STMT *stmt;
  int        rc, i;
  char       data[255];
  long       length;
  ulong      max_blob_length, blob_length, length1;
  my_bool    true_value;
  MYSQL_RES  *result;
  MYSQL_BIND my_bind[2];
  MYSQL_FIELD *field;
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_long_data_str1");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(longstr long varchar, blb long varbinary)");
  myquery(rc);

  strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  my_bind[0].buffer= data;            /* string data */
  my_bind[0].buffer_length= sizeof(data);
  my_bind[0].length= &length1;
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  length1= 0;

  my_bind[1]= my_bind[0];
  my_bind[1].buffer_type= MYSQL_TYPE_BLOB;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);
  length= sprintf(data, "MySQL AB");

  /* supply data in pieces */
  for (i= 0; i < 3; i++)
  {
    rc= mysql_stmt_send_long_data(stmt, 0, data, length);
    check_execute(stmt, rc);

    rc= mysql_stmt_send_long_data(stmt, 1, data, 2);
    check_execute(stmt, rc);
  }

  /* execute */
  rc= mysql_stmt_execute(stmt);
  if (!opt_silent)
    fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
  check_execute(stmt, rc);

  mysql_stmt_close(stmt);

  rc= mysql_commit(mysql);
  myquery(rc);

  /* now fetch the results ..*/
  rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr, LENGTH(blb), blb FROM test_long_data_str");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);

  mysql_field_seek(result, 1);
  field= mysql_fetch_field(result);
  max_blob_length= field->max_length;

  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 1);
  mysql_free_result(result);

  sprintf(data, "%ld", (long)i*length);
  verify_col_data("test_long_data_str", "length(longstr)", data);

  sprintf(data, "%d", i*2);
  verify_col_data("test_long_data_str", "length(blb)", data);

  /* Test length of field->max_length */
  stmt= mysql_simple_prepare(mysql, "SELECT * from test_long_data_str");
  check_stmt(stmt);
  verify_param_count(stmt, 0);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_store_result(stmt);
  check_execute(stmt, rc);

  result= mysql_stmt_result_metadata(stmt);
  field= mysql_fetch_fields(result);

  /* First test what happens if STMT_ATTR_UPDATE_MAX_LENGTH is not used */
  DIE_UNLESS(field->max_length == 0);
  mysql_free_result(result);

  /* Enable updating of field->max_length */
  true_value= 1;
  mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &true_value);
  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);

  rc= mysql_stmt_store_result(stmt);
  check_execute(stmt, rc);

  result= mysql_stmt_result_metadata(stmt);
  field= mysql_fetch_fields(result);

  DIE_UNLESS(field->max_length == max_blob_length);

  /* Fetch results into a data buffer that is smaller than data */
  memset(my_bind, 0, sizeof(*my_bind));
  my_bind[0].buffer_type= MYSQL_TYPE_BLOB;
  my_bind[0].buffer= (void *) &data; /* this buffer won't be altered */
  my_bind[0].buffer_length= 16;
  my_bind[0].length= &blob_length;
  my_bind[0].error= &my_bind[0].error_value;
  rc= mysql_stmt_bind_result(stmt, my_bind);
  data[16]= 0;

  rc= mysql_stmt_fetch(stmt);
  DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
  DIE_UNLESS(my_bind[0].error_value);
  DIE_UNLESS(strlen(data) == 16);
  DIE_UNLESS(blob_length == max_blob_length);

  /* Fetch all data */
  memset((my_bind+1), 0, sizeof(*my_bind));
  my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
  my_bind[1].buffer= (void *) &data; /* this buffer won't be altered */
  my_bind[1].buffer_length= sizeof(data);
  my_bind[1].length= &blob_length;
  memset(data, 0, sizeof(data));
  mysql_stmt_fetch_column(stmt, my_bind+1, 0, 0);
  DIE_UNLESS(strlen(data) == max_blob_length);

  mysql_free_result(result);
  mysql_stmt_close(stmt);

  /* Drop created table */
  rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
  myquery(rc);
}

Project: mysql-server
File: mysql_client_test.c

static void test_simple_update()
{
  MYSQL_STMT *stmt;
  int        rc;
  char       szData[25];
  int        nData= 1;
  MYSQL_RES  *result;
  MYSQL_BIND my_bind[2];
  ulong      length[2];
  char query[MAX_TEST_QUERY_LENGTH];

  myheader("test_simple_update");

  rc= mysql_autocommit(mysql, TRUE);
  myquery(rc);

  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
  myquery(rc);

  rc= mysql_query(mysql, "CREATE TABLE test_update(col1 int, "
                         " col2 varchar(50), col3 int )");
  myquery(rc);

  rc= mysql_query(mysql, "INSERT INTO test_update VALUES(1, 'MySQL', 100)");
  myquery(rc);

  verify_affected_rows(1);

  rc= mysql_commit(mysql);
  myquery(rc);

  /* insert by prepare */
  strmov(query, "UPDATE test_update SET col2= ? WHERE col1= ?");
  stmt= mysql_simple_prepare(mysql, query);
  check_stmt(stmt);

  verify_param_count(stmt, 2);

  /* Always memset all members of bind parameter */
  memset(my_bind, 0, sizeof(my_bind));

  nData= 1;
  my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  my_bind[0].buffer= szData;                /* string data */
  my_bind[0].buffer_length= sizeof(szData);
  my_bind[0].length= &length[0];
  length[0]= sprintf(szData, "updated-data");

  my_bind[1].buffer= (void *) &nData;
  my_bind[1].buffer_type= MYSQL_TYPE_LONG;

  rc= mysql_stmt_bind_param(stmt, my_bind);
  check_execute(stmt, rc);

  rc= mysql_stmt_execute(stmt);
  check_execute(stmt, rc);
  verify_affected_rows(1);

  mysql_stmt_close(stmt);

  /* now fetch the results ..*/
  rc= mysql_commit(mysql);
  myquery(rc);

  /* test the results now, only one row should exist */
  rc= mysql_query(mysql, "SELECT * FROM test_update");
  myquery(rc);

  /* get the result */
  result= mysql_store_result(mysql);
  mytest(result);

  rc= my_process_result_set(result);
  DIE_UNLESS(rc == 1);
  mysql_free_result(result);
}