Hi Dmitry,
On 7/29/10 7:59 AM, Dmitry Shulga wrote:
> #At file:///Users/shulga/projects/mysql/5.1-bugteam-bug47485/ based on
> revid:dmitry.shulga@stripped
>
> 3456 Dmitry Shulga 2010-07-29
> Fixed bug #47485 - mysql_store_result returns a not NULL result set for a
> prepared statement.
> @ include/mysql.h
> enumerator MYSQL_STATUS_STATEMENT_GET_RESULT was added into mysql_status
> enum.
> @ include/mysql.h.pp
> enumerator MYSQL_STATUS_STATEMENT_GET_RESULT was added into mysql_status
> enum.
> @ libmysql/libmysql.c
> Introduce a separate mysql state to distinguish the situation
> when we have a binary result set pending on the server from the
> situation when the result set is in text protocol.
> execute() modified: if mysql->status == MYSQL_STATUS_GET_RESULT
> before return then set it to value MYSQL_STATUS_STATEMENT_GET_RESULT.
> stmt_read_row_unbuffered() and mysql_stmt_store_result()
> were modified: added checking for mysql->status against
> MYSQL_STATUS_STATEMENT_GET_RESULT value instead of MYSQL_STATUS_GET_RESULT.
> @ tests/mysql_client_test.c
> added test_bug47485()
OK to push. Some comments below.
> modified:
> include/mysql.h
> include/mysql.h.pp
> libmysql/libmysql.c
> tests/mysql_client_test.c
> === modified file 'include/mysql.h'
> --- a/include/mysql.h 2010-07-20 17:44:29 +0000
> +++ b/include/mysql.h 2010-07-29 10:59:33 +0000
> @@ -224,7 +224,8 @@ struct st_mysql_options {
>
> enum mysql_status
> {
> - MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
> + MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT,
> + MYSQL_STATUS_STATEMENT_GET_RESULT
> };
>
> enum mysql_protocol_type
>
> === modified file 'include/mysql.h.pp'
> --- a/include/mysql.h.pp 2010-07-20 17:44:29 +0000
> +++ b/include/mysql.h.pp 2010-07-29 10:59:33 +0000
> @@ -293,7 +293,8 @@ struct st_mysql_options {
> };
> enum mysql_status
> {
> - MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
> + MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT,
> + MYSQL_STATUS_STATEMENT_GET_RESULT
> };
> enum mysql_protocol_type
> {
>
> === modified file 'libmysql/libmysql.c'
> --- a/libmysql/libmysql.c 2010-07-06 22:31:54 +0000
> +++ b/libmysql/libmysql.c 2010-07-29 10:59:33 +0000
> @@ -2502,7 +2502,8 @@ static my_bool execute(MYSQL_STMT *stmt,
> if (stmt->mysql)
> set_stmt_errmsg(stmt, net);
> DBUG_RETURN(1);
> - }
> + } else if (mysql->status == MYSQL_STATUS_GET_RESULT)
Coding style, "else" should be on a new line.
> + stmt->mysql->status= MYSQL_STATUS_STATEMENT_GET_RESULT;
> DBUG_RETURN(0);
> }
>
> @@ -2641,7 +2642,7 @@ static int stmt_read_row_unbuffered(MYSQ
> set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
> return 1;
> }
> - if (mysql->status != MYSQL_STATUS_GET_RESULT)
> + if (mysql->status != MYSQL_STATUS_STATEMENT_GET_RESULT)
> {
> set_stmt_error(stmt, stmt->unbuffered_fetch_cancelled ?
> CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
> @@ -4847,7 +4848,7 @@ int STDCALL mysql_stmt_store_result(MYSQ
> DBUG_RETURN(1);
> }
> }
> - else if (mysql->status != MYSQL_STATUS_GET_RESULT)
> + else if (mysql->status != MYSQL_STATUS_STATEMENT_GET_RESULT)
> {
> set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
> DBUG_RETURN(1);
>
> === modified file 'tests/mysql_client_test.c'
> --- a/tests/mysql_client_test.c 2010-07-19 18:34:28 +0000
> +++ b/tests/mysql_client_test.c 2010-07-29 10:59:33 +0000
> @@ -18268,6 +18268,106 @@ static void test_bug54041()
> }
>
>
> +/**
> + Bug#47485: mysql_store_result returns a result set for a prepared statement
> +*/
> +static void test_bug47485()
> +{
> +
> + MYSQL_STMT *stmt_1;
Simply stmt? there is no _2.
> + MYSQL_RES *res;
> + MYSQL_BIND bind[2];
> + int rc;
> + const char* sql_select = "SELECT 1, 'a'";
const char sql_select[]= "SELECT 1, 'a'";
> + int int_data;
> + char str_data[16];
> + my_bool is_null[2];
> + my_bool error[2];
> + unsigned long length[2];
> +
> + DBUG_ENTER("test_bug47485");
> + myheader("test_bug47485");
> +
> + stmt_1= mysql_stmt_init(mysql);
> + check_stmt(stmt_1);
> + rc= mysql_stmt_prepare(stmt_1, sql_select, strlen(sql_select));
> + check_execute(stmt_1, rc);
> +
> + rc= mysql_stmt_execute(stmt_1);
> + check_execute(stmt_1, rc);
> +
> + res = mysql_store_result(mysql);
> + DIE_UNLESS(res == NULL);
> +
> + mysql_stmt_reset(stmt_1);
> +
> + rc= mysql_stmt_execute(stmt_1);
> + check_execute(stmt_1, rc);
> +
> + res = mysql_use_result(mysql);
> + DIE_UNLESS(res == NULL);
> +
> + mysql_stmt_reset(stmt_1);
> +
> + memset(bind, 0, sizeof(bind));
> + bind[0].buffer_type= MYSQL_TYPE_LONG;
> + bind[0].buffer= (char *)&int_data;
> + bind[0].is_null=&is_null[0];
> + bind[0].length=&length[0];
> + bind[0].error=&error[0];
> +
> + bind[1].buffer_type= MYSQL_TYPE_STRING;
> + bind[1].buffer= (char *)str_data;
> + bind[1].buffer_length= sizeof(str_data);
> + bind[1].is_null=&is_null[1];
> + bind[1].length=&length[1];
> + bind[1].error=&error[1];
> +
> + rc= mysql_stmt_bind_result(stmt_1, bind);
> + check_execute(stmt_1, rc);
> +
> + rc= mysql_stmt_execute(stmt_1);
> + check_execute(stmt_1, rc);
> +
> + rc= mysql_stmt_store_result(stmt_1);
> + check_execute(stmt_1, rc);
> +
> + while (!(rc= mysql_stmt_fetch(stmt_1)));
Put the semicolon on a new line.
Regards,
Davi