diff options
author | unknown <anozdrin/alik@station.> | 2007-10-11 17:11:12 +0400 |
---|---|---|
committer | unknown <anozdrin/alik@station.> | 2007-10-11 17:11:12 +0400 |
commit | 3ca34c102a363d41ce7ee7de2a15de288654e967 (patch) | |
tree | 0fe0c93ca75967b614fb1aaa1b624feb63405102 | |
parent | 27e2f30e05e89a4926f5b03661168d572e7153da (diff) | |
download | mariadb-git-3ca34c102a363d41ce7ee7de2a15de288654e967.tar.gz |
A patch for BUG#31418: User locks misfunctioning after
mysql_change_user().
The problem was that THD::ull was not reset in THD::cleanup().
The fix is to reset it.
sql/sql_class.cc:
Reset THD::ull after cleanup to prevent memory corruption.
tests/mysql_client_test.c:
Add test case for BUG#31418.
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 164 |
2 files changed, 134 insertions, 31 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 490aedad0ef..09c8a79c15e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -698,6 +698,7 @@ void THD::cleanup(void) pthread_mutex_lock(&LOCK_user_locks); item_user_lock_release(ull); pthread_mutex_unlock(&LOCK_user_locks); + ull= NULL; } cleanup_done=1; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 9505340c24f..801f2896107 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16827,25 +16827,34 @@ static void bug20023_change_user(MYSQL *con) opt_db ? opt_db : "test")); } -static void bug20023_query_int_variable(MYSQL *con, - const char *var_name, - int *var_value) +static bool query_int_variable(MYSQL *con, + const char *var_name, + int *var_value) { MYSQL_RES *rs; MYSQL_ROW row; char query_buffer[MAX_TEST_QUERY_LENGTH]; + bool is_null; + my_snprintf(query_buffer, sizeof (query_buffer), - "SELECT @@%s", + "SELECT %s", (const char *) var_name); DIE_IF(mysql_query(con, query_buffer)); DIE_UNLESS(rs= mysql_store_result(con)); DIE_UNLESS(row= mysql_fetch_row(rs)); - *var_value= atoi(row[0]); + + is_null= row[0] == NULL; + + if (!is_null) + *var_value= atoi(row[0]); + mysql_free_result(rs); + + return is_null; } static void test_bug20023() @@ -16876,19 +16885,19 @@ static void test_bug20023() CLIENT_FOUND_ROWS)); /*********************************************************************** - Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values. + Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values. ***********************************************************************/ - bug20023_query_int_variable(&con, - "session.sql_big_selects", - &sql_big_selects_orig); + query_int_variable(&con, + "@@session.sql_big_selects", + &sql_big_selects_orig); - bug20023_query_int_variable(&con, - "global.max_join_size", - &max_join_size_orig); + query_int_variable(&con, + "@@global.max_join_size", + &max_join_size_orig); /*********************************************************************** - Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value. + Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value. ***********************************************************************/ /* Issue COM_CHANGE_USER. */ @@ -16897,17 +16906,17 @@ static void test_bug20023() /* Query SQL_BIG_SELECTS. */ - bug20023_query_int_variable(&con, - "session.sql_big_selects", - &sql_big_selects_2); + query_int_variable(&con, + "@@session.sql_big_selects", + &sql_big_selects_2); /* Check that SQL_BIG_SELECTS is reset properly. */ DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2); /*********************************************************************** - Test that if MAX_JOIN_SIZE set to non-default value, - SQL_BIG_SELECTS will be 0. + Test that if MAX_JOIN_SIZE set to non-default value, + SQL_BIG_SELECTS will be 0. ***********************************************************************/ /* Set MAX_JOIN_SIZE to some non-default value. */ @@ -16921,17 +16930,17 @@ static void test_bug20023() /* Query SQL_BIG_SELECTS. */ - bug20023_query_int_variable(&con, - "session.sql_big_selects", - &sql_big_selects_3); + query_int_variable(&con, + "@@session.sql_big_selects", + &sql_big_selects_3); /* Check that SQL_BIG_SELECTS is 0. */ DIE_UNLESS(sql_big_selects_3 == 0); /*********************************************************************** - Test that if MAX_JOIN_SIZE set to default value, - SQL_BIG_SELECTS will be 1. + Test that if MAX_JOIN_SIZE set to default value, + SQL_BIG_SELECTS will be 1. ***********************************************************************/ /* Set MAX_JOIN_SIZE to the default value (-1). */ @@ -16945,17 +16954,17 @@ static void test_bug20023() /* Query SQL_BIG_SELECTS. */ - bug20023_query_int_variable(&con, - "session.sql_big_selects", - &sql_big_selects_4); + query_int_variable(&con, + "@@session.sql_big_selects", + &sql_big_selects_4); /* Check that SQL_BIG_SELECTS is 1. */ DIE_UNLESS(sql_big_selects_4 == 1); /*********************************************************************** - Restore MAX_JOIN_SIZE. - Check that SQL_BIG_SELECTS will be the original one. + Restore MAX_JOIN_SIZE. + Check that SQL_BIG_SELECTS will be the original one. ***********************************************************************/ /* Restore MAX_JOIN_SIZE. */ @@ -16974,21 +16983,113 @@ static void test_bug20023() /* Query SQL_BIG_SELECTS. */ - bug20023_query_int_variable(&con, - "session.sql_big_selects", - &sql_big_selects_5); + query_int_variable(&con, + "@@session.sql_big_selects", + &sql_big_selects_5); /* Check that SQL_BIG_SELECTS is 1. */ DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig); /*********************************************************************** + That's it. Cleanup. + ***********************************************************************/ + + mysql_close(&con); +} + +static void bug31418_impl() +{ + MYSQL con; + + bool is_null; + int rc; + + /* Create a new connection. */ + + DIE_UNLESS(mysql_init(&con)); + + DIE_UNLESS(mysql_real_connect(&con, + opt_host, + opt_user, + opt_password, + opt_db ? opt_db : "test", + opt_port, + opt_unix_socket, + CLIENT_FOUND_ROWS)); + + /*********************************************************************** + Check that lock is free: + - IS_FREE_LOCK() should return 1; + - IS_USED_LOCK() should return NULL; + ***********************************************************************/ + + is_null= query_int_variable(&con, + "IS_FREE_LOCK('bug31418')", + &rc); + DIE_UNLESS(!is_null && rc); + + is_null= query_int_variable(&con, + "IS_USED_LOCK('bug31418')", + &rc); + DIE_UNLESS(is_null); + + /*********************************************************************** + Acquire lock and check the lock status (the lock must be in use): + - IS_FREE_LOCK() should return 0; + - IS_USED_LOCK() should return non-zero thread id; + ***********************************************************************/ + + query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc); + DIE_UNLESS(rc); + + is_null= query_int_variable(&con, + "IS_FREE_LOCK('bug31418')", + &rc); + DIE_UNLESS(!is_null && !rc); + + is_null= query_int_variable(&con, + "IS_USED_LOCK('bug31418')", + &rc); + DIE_UNLESS(!is_null && rc); + + /*********************************************************************** + Issue COM_CHANGE_USER command and check the lock status + (the lock must be free): + - IS_FREE_LOCK() should return 1; + - IS_USED_LOCK() should return NULL; + **********************************************************************/ + + bug20023_change_user(&con); + + is_null= query_int_variable(&con, + "IS_FREE_LOCK('bug31418')", + &rc); + DIE_UNLESS(!is_null && rc); + + is_null= query_int_variable(&con, + "IS_USED_LOCK('bug31418')", + &rc); + DIE_UNLESS(is_null); + + /*********************************************************************** That's it. Cleanup. ***********************************************************************/ mysql_close(&con); } +static void test_bug31418() +{ + /* Run test case for BUG#31418 for three different connections. */ + + bug31418_impl(); + + bug31418_impl(); + + bug31418_impl(); +} + /* Read and parse arguments and MySQL options from my.cnf @@ -17286,6 +17387,7 @@ static struct my_tests_st my_tests[]= { { "test_change_user", test_change_user }, { "test_bug30472", test_bug30472 }, { "test_bug20023", test_bug20023 }, + { "test_bug31418", test_bug31418 }, { 0, 0 } }; |