diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 835d8bf038f..bb742198381 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -539,7 +539,7 @@ sp_head::init_strings(THD *thd, LEX *lex) Trim "garbage" at the end. This is sometimes needed with the "/ * ! VERSION... * /" wrapper in dump files. */ - endp= skip_rear_comments((char*) m_body_begin, (char*) endp); + endp= skip_rear_comments(thd->charset(), (char*) m_body_begin, (char*) endp); m_body.length= endp - m_body_begin; m_body.str= strmake_root(root, m_body_begin, m_body.length); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7bcdc499011..2428b2e2330 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1098,6 +1098,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) SYNOPSIS skip_rear_comments() + cs character set begin pointer to the beginning of statement end pointer to the end of statement @@ -1108,10 +1109,11 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) Pointer to the last non-comment symbol of the statement. */ -char *skip_rear_comments(char *begin, char *end) +char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end) { - while (begin < end && (end[-1] <= ' ' || end[-1] == '*' || - end[-1] == '/' || end[-1] == ';')) + while (begin < end && (end[-1] == '*' || + end[-1] == '/' || end[-1] == ';') || + my_isspace(cs, end[-1])) end-= 1; return end; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6c9283126c4..f8405ef14ca 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1271,4 +1271,4 @@ extern void lex_free(void); extern void lex_start(THD *thd); extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); -extern char *skip_rear_comments(char *begin, char *end); +extern char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index ba367040b36..bfa799ff289 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -772,7 +772,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->query.str= (char*)str.ptr(); view->query.length= str.length()-1; // we do not need last \0 view->source.str= thd->query + thd->lex->create_view_select_start; - view->source.length= (char *)skip_rear_comments((char *)view->source.str, + view->source.length= (char *)skip_rear_comments(thd->charset(), + (char *)view->source.str, (char *)thd->query + thd->query_length) - view->source.str; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 38346ad0dbc..e56dd693287 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15560,6 +15560,69 @@ static void test_bug24179() } +/* + Bug#27876 (SF with cyrillic variable name fails during execution (regression)) +*/ +static void test_bug27876() +{ + int rc; + MYSQL_RES *result; + + char utf8_func[] = + { + 0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba, + 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba, + 0xd0, 0xb0, + 0x00 + }; + + char utf8_param[] = + { + 0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a, + 0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, + 0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f, + 0x00 + }; + + char query[500]; + + DBUG_ENTER("test_bug27876"); + myheader("test_bug27876"); + + rc= mysql_query(mysql, "set names utf8"); + myquery(rc); + + rc= mysql_query(mysql, "select version()"); + myquery(rc); + result= mysql_store_result(mysql); + mytest(result); + + sprintf(query, "DROP FUNCTION IF EXISTS %s", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + + sprintf(query, + "CREATE FUNCTION %s( %s VARCHAR(25))" + " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s", + utf8_func, utf8_param, utf8_param); + rc= mysql_query(mysql, query); + myquery(rc); + sprintf(query, "SELECT %s(VERSION())", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + result= mysql_store_result(mysql); + mytest(result); + + sprintf(query, "DROP FUNCTION %s", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + + rc= mysql_query(mysql, "set names default"); + myquery(rc); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -15840,6 +15903,7 @@ static struct my_tests_st my_tests[]= { { "test_bug23383", test_bug23383 }, { "test_bug21635", test_bug21635 }, { "test_bug24179", test_bug24179 }, + { "test_bug27876", test_bug27876 }, { 0, 0 } };