From fe84b016e1fd62d92c9f13a1e21784ea8cb200cd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Dec 2006 13:25:06 +0300 Subject: [PATCH 1/3] A fix and a test case for Bug#24179 "select b into $var" fails with --cursor_protocol": fix a misleading error message in case of SELECT .. INTO. sql/sql_class.cc: Implement select_result::check_simple_select hierarchy to support correct error messages in case of SELECT .. INTO and C API cursors. sql/sql_class.h: Set the error message inside the function that checks for the error condition (simple_select, renamed to check_simple_select). sql/sql_prepare.cc: Use a new method that now sets the error. tests/mysql_client_test.c: Add a test case for Bug#24179 "select b into $var" fails with --cursor_protocol" (check for the right error message and error code). --- sql/sql_class.cc | 14 ++++++++++++++ sql/sql_class.h | 12 ++++++++++-- sql/sql_prepare.cc | 3 +-- tests/mysql_client_test.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d2f1e9ed0d9..f46cd2353eb 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -885,6 +885,13 @@ void select_result::cleanup() /* do nothing */ } +bool select_result::check_simple_select() const +{ + my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0)); + return TRUE; +} + + static String default_line_term("\n",default_charset_info); static String default_escaped("\\",default_charset_info); static String default_field_term("\t",default_charset_info); @@ -1553,6 +1560,13 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) } +bool select_dumpvar::check_simple_select() const +{ + my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0)); + return TRUE; +} + + void select_dumpvar::cleanup() { vars.empty(); diff --git a/sql/sql_class.h b/sql/sql_class.h index 41845dc5c76..ec03b9cb4a6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1724,7 +1724,14 @@ public: virtual bool initialize_tables (JOIN *join=0) { return 0; } virtual void send_error(uint errcode,const char *err); virtual bool send_eof()=0; - virtual bool simple_select() { return 0; } + /** + Check if this query returns a result set and therefore is allowed in + cursors and set an error message if it is not the case. + + @retval FALSE success + @retval TRUE error, an error message is set + */ + virtual bool check_simple_select() const; virtual void abort() {} /* Cleanup instance of this class for next execution of a prepared @@ -1762,7 +1769,7 @@ public: bool send_fields(List &list, uint flags); bool send_data(List &items); bool send_eof(); - bool simple_select() { return 1; } + virtual bool check_simple_select() const { return FALSE; } void abort(); }; @@ -2202,6 +2209,7 @@ public: int prepare(List &list, SELECT_LEX_UNIT *u); bool send_data(List &items); bool send_eof(); + virtual bool check_simple_select() const; void cleanup(); }; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1e7601c0951..8b2c2cd3674 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2906,10 +2906,9 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) in INSERT ... SELECT and similar commands. */ - if (open_cursor && lex->result && !lex->result->simple_select()) + if (open_cursor && lex->result && lex->result->check_simple_select()) { DBUG_PRINT("info",("Cursor asked for not SELECT stmt")); - my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0)); return TRUE; } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index c596a589d55..0b8d4d81558 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15456,6 +15456,33 @@ static void test_bug21635() DBUG_VOID_RETURN; } +/* + Bug#24179 "select b into $var" fails with --cursor_protocol" + The failure is correct, check that the returned message is meaningful. +*/ + +static void test_bug24179() +{ + int rc; + MYSQL_STMT *stmt; + + DBUG_ENTER("test_bug24179"); + myheader("test_bug24179"); + + stmt= open_cursor("select 1 into @a"); + rc= mysql_stmt_execute(stmt); + DIE_UNLESS(rc); + if (!opt_silent) + { + printf("Got error (as expected): %d %s\n", + mysql_stmt_errno(stmt), + mysql_stmt_error(stmt)); + } + DIE_UNLESS(mysql_stmt_errno(stmt) == 1323); + + DBUG_VOID_RETURN; +} + /* Read and parse arguments and MySQL options from my.cnf @@ -15735,6 +15762,7 @@ static struct my_tests_st my_tests[]= { { "test_bug21726", test_bug21726 }, { "test_bug23383", test_bug23383 }, { "test_bug21635", test_bug21635 }, + { "test_bug24179", test_bug24179 }, { 0, 0 } }; From 85e15fb3e7dda4a7bfb42767b55a1266b5d69982 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Dec 2006 14:05:27 +0300 Subject: [PATCH 2/3] Use standard shell instead of BASH. --- mysql-test/t/log.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/log.sh b/mysql-test/t/log.sh index 20b265087cc..29cf8d3e1a3 100755 --- a/mysql-test/t/log.sh +++ b/mysql-test/t/log.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh ########################################################################### From 1adc13681283fe637ece524c9b1a4311700cfbd7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Dec 2006 19:48:49 +0300 Subject: [PATCH 3/3] Fix Bug #19044 IM aborts on exit On windows IM aborted on assert once one stoppped it. The reason is that we didn't close the sockets on windows and therefore, the listener thread wasn't able to finish. This happened because we used close() call for it. While on windows one should use closesocket(). On other platfroms we have appropriate defines for closesocket(), so this is the function which should be used. server-tools/instance-manager/listener.cc: close -> closesocket --- server-tools/instance-manager/listener.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc index 3f60c2cc74a..70cd7360f0d 100644 --- a/server-tools/instance-manager/listener.cc +++ b/server-tools/instance-manager/listener.cc @@ -188,7 +188,7 @@ void Listener_thread::run() else { shutdown(client_fd, SHUT_RDWR); - close(client_fd); + closesocket(client_fd); } } } @@ -200,7 +200,7 @@ void Listener_thread::run() log_info("Listener_thread::run(): shutdown requested, exiting..."); for (i= 0; i < num_sockets; i++) - close(sockets[i]); + closesocket(sockets[i]); #ifndef __WIN__ unlink(unix_socket_address.sun_path); @@ -213,7 +213,7 @@ void Listener_thread::run() err: // we have to close the ip sockets in case of error for (i= 0; i < num_sockets; i++) - close(sockets[i]); + closesocket(sockets[i]); thread_registry.unregister_thread(&thread_info); thread_registry.request_shutdown(); @@ -260,7 +260,7 @@ int Listener_thread::create_tcp_socket() { log_error("Listener_thread::run(): bind(ip socket) failed, '%s'", strerror(errno)); - close(ip_socket); + closesocket(ip_socket); return -1; } @@ -268,7 +268,7 @@ int Listener_thread::create_tcp_socket() { log_error("Listener_thread::run(): listen(ip socket) failed, %s", strerror(errno)); - close(ip_socket); + closesocket(ip_socket); return -1; }