Below is the list of changes that have just been committed into a local
5.1 repository of alik. When alik does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-08-27 15:35:41+04:00, anozdrin@ibm. +2 -0
Fix for Bug#30472: libmysql doesn't reset charset, insert_id after
succ. mysql_change_user() call.
The fix is to update mysql->charset attribute after successful user
change in mysql_change_user(). mysql->charset is set to the value
of @@character_set_client variable.
If the value of @@character_set_client variable can not be retrieved
or is invalid, mysql_change_user() will return error status
(TRUE) and do not touch mysql->charset.
libmysql/libmysql.c@stripped, 2007-08-27 15:35:37+04:00, anozdrin@ibm. +35 -1
Update cached character set information.
tests/mysql_client_test.c@stripped, 2007-08-27 15:35:38+04:00, anozdrin@ibm. +177 -2
Provide test case for BUG#30472.
diff -Nrup a/libmysql/libmysql.c b/libmysql/libmysql.c
--- a/libmysql/libmysql.c 2007-07-21 14:36:28 +04:00
+++ b/libmysql/libmysql.c 2007-08-27 15:35:37 +04:00
@@ -689,6 +689,11 @@ my_bool STDCALL mysql_change_user(MYSQL
{
char buff[512],*end=buff;
int rc;
+
+ MYSQL_RES *rs;
+ MYSQL_ROW row;
+ CHARSET_INFO *cs;
+
DBUG_ENTER("mysql_change_user");
if (!user)
@@ -741,7 +746,36 @@ my_bool STDCALL mysql_change_user(MYSQL
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
}
- DBUG_RETURN(rc);
+
+ /* Update cached character set information. */
+
+ if (rc)
+ DBUG_RETURN(TRUE);
+
+ if (mysql_query(mysql, "SHOW VARIABLES LIKE 'character_set_client'"))
+ DBUG_RETURN(TRUE);
+
+ if (!(rs= mysql_store_result(mysql)))
+ {
+ mysql_free_result(rs);
+ DBUG_RETURN(TRUE);
+ }
+
+ if (!(row= mysql_fetch_row(rs)))
+ {
+ mysql_free_result(rs);
+ DBUG_RETURN(TRUE);
+ }
+
+ cs= get_charset_by_csname(row[1], MY_CS_PRIMARY, MYF(MY_WME));
+
+ mysql_free_result(rs);
+
+ if (!cs)
+ DBUG_RETURN(TRUE);
+
+ mysql->charset= cs;
+ DBUG_RETURN(FALSE);
}
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
diff -Nrup a/tests/mysql_client_test.c b/tests/mysql_client_test.c
--- a/tests/mysql_client_test.c 2007-07-20 03:21:43 +04:00
+++ b/tests/mysql_client_test.c 2007-08-27 15:35:38 +04:00
@@ -119,6 +119,8 @@ static void client_disconnect(void);
#define DIE_UNLESS(expr) \
((void) ((expr) ? 0 : (die(__FILE__, __LINE__, #expr), 0)))
+#define DIE_IF(expr) \
+ ((void) ((expr) ? (die(__FILE__, __LINE__, #expr), 0) : 0))
#define DIE(expr) \
die(__FILE__, __LINE__, #expr)
@@ -177,8 +179,8 @@ if (stmt == 0) \
DIE_UNLESS(stmt == 0);\
}
-#define mytest(x) if (!x) {myerror(NULL);DIE_UNLESS(FALSE);}
-#define mytest_r(x) if (x) {myerror(NULL);DIE_UNLESS(FALSE);}
+#define mytest(x) if (!(x)) {myerror(NULL);DIE_UNLESS(FALSE);}
+#define mytest_r(x) if ((x)) {myerror(NULL);DIE_UNLESS(FALSE);}
/* A workaround for Sun Forte 5.6 on Solaris x86 */
@@ -16336,6 +16338,178 @@ static void test_bug29692()
/*
+ Bug#30472: libmysql doesn't reset charset, insert_id after succ.
+ mysql_change_user() call row insertions.
+*/
+
+static void bug30472_retrieve_charset_info(MYSQL *con,
+ char **character_set_name,
+ char **character_set_client,
+ char **character_set_results,
+ char **collation_connection)
+{
+ MYSQL_RES *rs;
+ MYSQL_ROW row;
+
+ /* Get the cached client character set name. */
+
+ DIE_UNLESS(*character_set_name= strdup(mysql_character_set_name(con)));
+
+ /* Retrieve server character set information. */
+
+ DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
+ DIE_UNLESS(rs= mysql_store_result(con));
+ DIE_UNLESS(row= mysql_fetch_row(rs));
+ DIE_UNLESS(*character_set_client= strdup(row[1]));
+ mysql_free_result(rs);
+
+ DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
+ DIE_UNLESS(rs= mysql_store_result(con));
+ DIE_UNLESS(row= mysql_fetch_row(rs));
+ DIE_UNLESS(*character_set_results= strdup(row[1]));
+ mysql_free_result(rs);
+
+ DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
+ DIE_UNLESS(rs= mysql_store_result(con));
+ DIE_UNLESS(row= mysql_fetch_row(rs));
+ DIE_UNLESS(*collation_connection= strdup(row[1]));
+ mysql_free_result(rs);
+}
+
+static void test_bug30472()
+{
+ MYSQL con;
+
+ char *character_set_name_1;
+ char *character_set_client_1;
+ char *character_set_results_1;
+ char *collation_connnection_1;
+
+ char *character_set_name_2;
+ char *character_set_client_2;
+ char *character_set_results_2;
+ char *collation_connnection_2;
+
+ char *character_set_name_3;
+ char *character_set_client_3;
+ char *character_set_results_3;
+ char *collation_connnection_3;
+
+ /* 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));
+
+ /* Create a new table. */
+
+ DIE_IF(mysql_query(&con, "DROP TABLE IF EXISTS t1"));
+ DIE_IF(mysql_query(&con, "CREATE TABLE t1("
+ "c1 INT AUTO_INCREMENT, "
+ "c2 CHAR(1), "
+ "PRIMARY KEY(c1))"));
+
+ /* Retrieve character set information. */
+
+ bug30472_retrieve_charset_info(&con,
+ &character_set_name_1,
+ &character_set_client_1,
+ &character_set_results_1,
+ &collation_connnection_1);
+
+ /* Insert a few records into the table. */
+
+ DIE_IF(mysql_query(&con, "INSERT INTO t1(c2) VALUES ('a')"));
+ DIE_IF(mysql_query(&con, "INSERT INTO t1(c2) VALUES ('b')"));
+ DIE_IF(mysql_query(&con, "INSERT INTO t1(c2) VALUES ('c')"));
+
+ /* Check that mysql_insert_id() == 3. */
+
+ DIE_UNLESS(mysql_insert_id(&con) == 3);
+
+ /* Switch client character set. */
+
+ DIE_IF(mysql_set_character_set(&con, "utf8"));
+
+ /* Retrieve character set information. */
+
+ bug30472_retrieve_charset_info(&con,
+ &character_set_name_2,
+ &character_set_client_2,
+ &character_set_results_2,
+ &collation_connnection_2);
+
+ /*
+ Check that
+ 1) character set has been switched and
+ 2) new character set is different from the original one.
+ */
+
+ DIE_UNLESS(strcmp(character_set_name_2, "utf8") == 0);
+ DIE_UNLESS(strcmp(character_set_client_2, "utf8") == 0);
+ DIE_UNLESS(strcmp(character_set_results_2, "utf8") == 0);
+ DIE_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0);
+
+ DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
+ DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
+ DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
+ DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
+
+ /* Call mysql_change_user() with the same username, password, database. */
+
+ DIE_IF(mysql_change_user(&con,
+ opt_user,
+ opt_password,
+ opt_db ? opt_db : "test"));
+
+ /* Retrieve character set information. */
+
+ bug30472_retrieve_charset_info(&con,
+ &character_set_name_3,
+ &character_set_client_3,
+ &character_set_results_3,
+ &collation_connnection_3);
+
+ /* Check that character set information has been reset. */
+
+ DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
+ DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
+ DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
+ DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
+
+ /* Check that mysql_insert_id() == 0 (the last insert id has been reset). */
+
+ DIE_UNLESS(mysql_insert_id(&con) == 0);
+
+ /* That's it. Cleanup. */
+
+ free(character_set_name_1);
+ free(character_set_client_1);
+ free(character_set_results_1);
+ free(collation_connnection_1);
+
+ free(character_set_name_2);
+ free(character_set_client_2);
+ free(character_set_results_2);
+ free(collation_connnection_2);
+
+ free(character_set_name_3);
+ free(character_set_client_3);
+ free(character_set_results_3);
+ free(collation_connnection_3);
+
+ mysql_close(&con);
+}
+
+
+/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -16626,6 +16800,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug27592", test_bug27592 },
{ "test_bug29687", test_bug29687 },
{ "test_bug29692", test_bug29692 },
+ { "test_bug30472", test_bug30472 },
{ 0, 0 }
};
| Thread |
|---|
| • bk commit into 5.1 tree (anozdrin:1.2574) BUG#30472 | Alexander Nozdrin | 27 Aug |