From a0affe1bb74f7f6034a50ac18d70e4e23284c3b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 24 Jan 2020 10:51:15 +0200 Subject: [PATCH] MXS-2784: Use SQL to fetch default character set The Connector-C was changed to always return only the client's charset, not the actual charset that the connection ends up using. To cope with this, the code has to use SQL to join the default character set name to the default collation for it which can be used to extract the numeric ID of the charset. --- include/maxscale/mysql_utils.h | 7 ++++ server/core/mysql_utils.cc | 32 +++++++++++++++++-- .../authenticator/MySQLAuth/dbusers.cc | 4 +-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/include/maxscale/mysql_utils.h b/include/maxscale/mysql_utils.h index 49ac78edd..c945a13fd 100644 --- a/include/maxscale/mysql_utils.h +++ b/include/maxscale/mysql_utils.h @@ -157,4 +157,11 @@ void mxs_mysql_set_log_statements(bool enable); */ bool mxs_mysql_get_log_statements(); +/** + * Get default server character set + * + * @return The numeric identifier of `@@global.character_set_server` + */ +uint8_t mxs_mysql_get_character_set(MYSQL* mysql); + MXS_END_DECLS diff --git a/server/core/mysql_utils.cc b/server/core/mysql_utils.cc index c30fa0ce7..34d3afe6b 100644 --- a/server/core/mysql_utils.cc +++ b/server/core/mysql_utils.cc @@ -205,9 +205,7 @@ MYSQL* mxs_mysql_real_connect(MYSQL* con, SERVER* server, const char* user, cons if (mysql) { /** Copy the server charset */ - MY_CHARSET_INFO cs_info; - mysql_get_character_set_info(mysql, &cs_info); - server->charset = cs_info.number; + server->charset = mxs_mysql_get_character_set(mysql); if (listener && mysql_get_ssl_cipher(con) == NULL) { @@ -435,3 +433,31 @@ bool mxs_mysql_get_log_statements() { return this_unit.log_statements; } + +uint8_t mxs_mysql_get_character_set(MYSQL* mysql) +{ + uint8_t charset = 8; // Default is latin1 with the ID 8 + const char* CHARSET_QUERY = + "SELECT co.id FROM information_schema.collations AS co " + "JOIN information_schema.character_sets AS cs " + "ON (co.collation_name = cs.default_collate_name) " + "WHERE cs.character_set_name=@@global.character_set_server;"; + + if (mysql_query(mysql, CHARSET_QUERY) == 0) + { + if (auto res = mysql_use_result(mysql)) + { + if (auto row = mysql_fetch_row(res)) + { + if (row[0]) + { + charset = atoi(row[0]); + } + } + + mysql_free_result(res); + } + } + + return charset; +} diff --git a/server/modules/authenticator/MySQLAuth/dbusers.cc b/server/modules/authenticator/MySQLAuth/dbusers.cc index 5a5a439b6..cd88952cf 100644 --- a/server/modules/authenticator/MySQLAuth/dbusers.cc +++ b/server/modules/authenticator/MySQLAuth/dbusers.cc @@ -701,9 +701,7 @@ static bool check_server_permissions(SERVICE* service, } /** Copy the server charset */ - MY_CHARSET_INFO cs_info; - mysql_get_character_set_info(mysql, &cs_info); - server->charset = cs_info.number; + server->charset = mxs_mysql_get_character_set(mysql); if (server->version_string[0] == 0) {