diff options
-rw-r--r-- | sql/sql_class.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 12 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 3 | ||||
-rw-r--r-- | 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 07510c1fbb0..007bf7988dc 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -985,6 +985,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); @@ -1656,6 +1663,13 @@ int select_dumpvar::prepare(List<Item> &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 218c56959a3..92d714c2f66 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1703,7 +1703,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 @@ -1741,7 +1748,7 @@ public: bool send_fields(List<Item> &list, uint flags); bool send_data(List<Item> &items); bool send_eof(); - bool simple_select() { return 1; } + virtual bool check_simple_select() const { return FALSE; } void abort(); }; @@ -2188,6 +2195,7 @@ public: int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &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 0c6a5fe5846..79fad7237a6 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2947,10 +2947,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 d67ecb4c5e0..735b678c09a 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15684,6 +15684,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 @@ -15966,6 +15993,7 @@ static struct my_tests_st my_tests[]= { { "test_bug23383", test_bug23383 }, { "test_bug21635", test_bug21635 }, { "test_status", test_status}, + { "test_bug24179", test_bug24179 }, { 0, 0 } }; |