Bug #64205 Connected through Connector/J 5.1 to MySQL 5.5, the error message is garbled.
Submitted: 2 Feb 2012 5:21 Modified: 25 May 2012 20:43
Reporter: Nozomu Wakamatsu Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:5.1.18 OS:Any
Assigned to: Alexander Soklakov CPU Architecture:Any
Tags: language, lc_messages_dir, utf8

[2 Feb 2012 5:21] Nozomu Wakamatsu
Description:
I am using the MySQL 5.5.20 and Connector/J 5.1.18.
MySQL Server is Solaris11, Connecter/J is JDK 1.7.0_02-b13 64bit on Windows7 64bit.

Issue a query from Connector/J to MySQL.
If the query fails, an error message is garbled.

Connecter/J are get the character code of the error message from "SHOW VARIABLES LIKE 'language'".
But, "language" is replaced by the "lc_messages_dir" from MySQL 5.5.
Therefore, the error message unable to get the character code, use by default character code CP1252.

How to repeat:
Cause a garbled query.
SELECT * FROM `test`.`ほげほげ`;

Result.
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Table 'test.??≫??’??≫??’' doesn't exist
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1049)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)
	at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2293)
	at jp.co.afy_systems.framework.database.wrapper.PreparedStatementWrapper.executeQuery(PreparedStatementWrapper.java:46)
	at jp.co.afy_systems.framework.database.dao.AbstractDao.executeQuery(AbstractDao.java:167)
	... 4 more

Suggested fix:
com.mysql.jdbc.CharsetMapping
1122: String errorMessageFile = conn.getServerVariable("language");
1123+ if (errorMessageFile == null) {
1124+     errorMessageFile = conn.getServerVariable("lc_messages_dir");
1125+ }

com.mysql.jdbc.ConnectionImpl
3843: query = versionComment + "SHOW VARIABLES WHERE Variable_name ='language'"
3844+         + " OR Variable_name = 'lc_messages_dir'"
3845:         + " OR Variable_name = 'net_write_timeout'"
[2 Feb 2012 13:15] Valeriy Kravchuk
Thank you for the bug report. Verified by code review. lc_messages_dir is not referenced anywhere in the code, so it just can not work correctly with MySQL server 5.5.
[3 Feb 2012 5:38] Nozomu Wakamatsu
Thank you for response.

Suggested fix is an interim measure of "lc_messages_dir".
To resolve the garbled, would need to be modified further.

For example,if "errorMessageEncodingMysql" is null, return to "character_set_results".
If feasible, Should be encoded to each of column name and the error message.

When will it be fixed?
[14 May 2012 9:32] Alexander Soklakov
patch for cJ 5.1.20

Attachment: bug64205.diff (text/x-patch), 1.83 KiB.

[14 May 2012 9:35] Alexander Soklakov
Thank you for the important bug report.

I see no need to analyze "lc_messages_dir". As described in http://dev.mysql.com/doc/refman/5.5/en/charset-errors.html as of MySQL 5.5, the server constructs error messages using UTF-8 and returns them to clients in the character set specified by the character_set_results system variable. So the only need is to avoid old-style mapping (language->charset) and correctly analyze character_set_results.

Look at attached patch, please.
[15 May 2012 6:33] Nozomu Wakamatsu
Thank you for the patch.

Attached a patch to Connector/J 5.1.20.
I was confirmed that the problem has been resolved.
[25 May 2012 20:43] John Russell
Added to changelog for 5.1.21: 

When Connector/J was connected to a MySQL 5.5 server, the error
message for an invalid query could be returned in the wrong character
set and appear garbled.