diff options
-rw-r--r-- | libmysql/libmysql.c | 5 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 43 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.h | 2 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 23 |
5 files changed, 34 insertions, 45 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 2074abd0f85..a896460beeb 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4907,13 +4907,12 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags) { MYSQL *mysql= stmt->mysql; MYSQL_DATA *result= &stmt->result; - my_bool has_cursor= stmt->read_row_func == stmt_read_row_from_cursor; /* Reset stored result set if so was requested or it's a part of cursor fetch. */ - if (result->data && (has_cursor || (flags & RESET_STORE_RESULT))) + if (result->data && (flags & RESET_STORE_RESULT)) { /* Result buffered */ free_root(&result->alloc, MYF(MY_KEEP_PREALLOC)); @@ -4944,7 +4943,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags) mysql->status= MYSQL_STATUS_READY; } } - if (has_cursor || (flags & RESET_SERVER_SIDE)) + if (flags & RESET_SERVER_SIDE) { /* Reset the server side statement and close the server side diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 6d11518198c..e163e71e416 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -106,6 +106,7 @@ public: virtual ~Prepared_statement(); void setup_set_params(); virtual Query_arena::Type type() const; + virtual void close_cursor(); }; static void execute_stmt(THD *thd, Prepared_statement *stmt, @@ -1986,10 +1987,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) cursor= stmt->cursor; if (cursor && cursor->is_open()) - { - my_error(ER_EXEC_STMT_WITH_OPEN_CURSOR, MYF(0)); - DBUG_VOID_RETURN; - } + stmt->close_cursor(); DBUG_ASSERT(thd->free_list == NULL); mysql_reset_thd_for_next_command(thd); @@ -2284,6 +2282,7 @@ void mysql_stmt_reset(THD *thd, char *packet) if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset"))) DBUG_VOID_RETURN; + stmt->close_cursor(); /* will reset statement params */ cursor= stmt->cursor; if (cursor && cursor->is_open()) { @@ -2295,12 +2294,6 @@ void mysql_stmt_reset(THD *thd, char *packet) stmt->state= Query_arena::PREPARED; - /* - Clear parameters from data which could be set by - mysql_stmt_send_long_data() call. - */ - reset_stmt_params(stmt); - mysql_reset_thd_for_next_command(thd); send_ok(thd); @@ -2448,10 +2441,17 @@ void Prepared_statement::setup_set_params() Prepared_statement::~Prepared_statement() { if (cursor) + { + if (cursor->is_open()) + { + cursor->close(FALSE); + free_items(); + free_root(cursor->mem_root, MYF(0)); + } cursor->Cursor::~Cursor(); - free_items(); - if (cursor) - free_root(cursor->mem_root, MYF(0)); + } + else + free_items(); delete lex->result; } @@ -2460,3 +2460,20 @@ Query_arena::Type Prepared_statement::type() const { return PREPARED_STATEMENT; } + + +void Prepared_statement::close_cursor() +{ + if (cursor && cursor->is_open()) + { + thd->change_list= cursor->change_list; + cursor->close(FALSE); + cleanup_stmt_and_thd_after_use(this, thd); + free_root(cursor->mem_root, MYF(0)); + } + /* + Clear parameters from data which could be set by + mysql_stmt_send_long_data() call. + */ + reset_stmt_params(this); +} diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 66e783a2103..524fc784422 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1915,12 +1915,6 @@ Cursor::close(bool is_active) } -Cursor::~Cursor() -{ - if (is_open()) - close(FALSE); -} - /*********************************************************************/ /* diff --git a/sql/sql_select.h b/sql/sql_select.h index ac3e8898cc6..9285e33be33 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -408,7 +408,7 @@ public: void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; } Cursor(THD *thd); - ~Cursor(); + ~Cursor() {} }; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index bc30bf5f186..0b88fa1b273 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13050,27 +13050,6 @@ static void test_bug9478() check_execute(stmt, rc); if (!opt_silent && i == 0) printf("Fetched row: %s\n", a); - /* - Although protocol-wise an attempt to execute a statement which - already has an open cursor associated with it will yield an error, - the client library behavior tested here is consistent with - the non-cursor execution scenario: mysql_stmt_execute will - silently close the cursor if necessary. - */ - { - char buff[9]; - /* Fill in the execute packet */ - int4store(buff, stmt->stmt_id); - buff[4]= 0; /* Flag */ - int4store(buff+5, 1); /* Reserved for array bind */ - rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_EXECUTE, buff, - sizeof(buff), 0,0,1) || - (*mysql->methods->read_query_result)(mysql)); - DIE_UNLESS(rc); - if (!opt_silent && i == 0) - printf("Got error (as expected): %s\n", mysql_error(mysql)); - } - rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); @@ -13429,7 +13408,7 @@ static void test_bug10794() bind[1].length= &a_len; rc= mysql_stmt_bind_param(stmt, bind); check_execute(stmt, rc); - for (i= 0; i < 34; i++) + for (i= 0; i < 42; i++) { id_val= (i+1)*10; sprintf(a, "a%d", i); |