From b3ff97aa610d853025e83f75991fffbd37458ff3 Mon Sep 17 00:00:00 2001 From: Neil Dong Date: Fri, 20 May 2016 20:27:40 +0800 Subject: [PATCH 1/3] //Fix for bug #80631 Any ResultSet.getString return garbled result with json type data // Fix chinese(or other non-ascii encoding) garbled in [mysql 5.7 JSON type] // Use UTF-8 encoding , because mysql use utf8mb4 for JSON type store ; --- src/com/mysql/jdbc/Field.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/com/mysql/jdbc/Field.java b/src/com/mysql/jdbc/Field.java index 6d34ac0..076c3eb 100644 --- a/src/com/mysql/jdbc/Field.java +++ b/src/com/mysql/jdbc/Field.java @@ -190,6 +190,12 @@ this.encoding = "UTF-16"; } + // Fix chinese(or other non-ascii encoding) garbled in [mysql 5.7 JSON type] + // Use UTF-8 encoding , because mysql use utf8mb4 for JSON type store ; + if (this.mysqlType == MysqlDefs.FIELD_TYPE_JSON) { + this.encoding = "UTF-8"; + } + // Handle VARBINARY/BINARY (server doesn't have a different type for this boolean isBinary = isBinary(); @@ -330,8 +336,8 @@ private void setupForUtf8StringInBlob() { /** * Constructor used when communicating with pre 4.1 servers */ - Field(MySQLConnection conn, byte[] buffer, int nameStart, int nameLength, int tableNameStart, int tableNameLength, int length, int mysqlType, short colFlag, - int colDecimals) throws SQLException { + Field(MySQLConnection conn, byte[] buffer, int nameStart, int nameLength, int tableNameStart, int tableNameLength, int length, int mysqlType, + short colFlag, int colDecimals) throws SQLException { this(conn, buffer, -1, -1, tableNameStart, tableNameLength, -1, -1, nameStart, nameLength, -1, -1, length, mysqlType, colFlag, colDecimals, -1, -1, NO_CHARSET_INFO); } @@ -781,8 +787,8 @@ private boolean isNativeNumericType() { } private boolean isNativeDateTimeType() { - return (this.mysqlType == MysqlDefs.FIELD_TYPE_DATE || this.mysqlType == MysqlDefs.FIELD_TYPE_NEWDATE || this.mysqlType == MysqlDefs.FIELD_TYPE_DATETIME - || this.mysqlType == MysqlDefs.FIELD_TYPE_TIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIMESTAMP); + return (this.mysqlType == MysqlDefs.FIELD_TYPE_DATE || this.mysqlType == MysqlDefs.FIELD_TYPE_NEWDATE + || this.mysqlType == MysqlDefs.FIELD_TYPE_DATETIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIMESTAMP); } public void setConnection(MySQLConnection conn) { From 5513fef14a3cc1389c3aa92316caca6a853b84a5 Mon Sep 17 00:00:00 2001 From: Neil Dong Date: Sat, 18 Jun 2016 14:12:36 +0800 Subject: [PATCH 2/3] //Fix for bug #80631 Any ResultSet.getString return garbled result with json type data // Fix chinese(or other non-ascii encoding) garbled in [mysql 5.7 JSON type] // Use UTF-8 encoding , because mysql use utf8mb4 for JSON type store ; (reverted from commit b3ff97aa610d853025e83f75991fffbd37458ff3) --- src/com/mysql/jdbc/Field.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/com/mysql/jdbc/Field.java b/src/com/mysql/jdbc/Field.java index 076c3eb..6d34ac0 100644 --- a/src/com/mysql/jdbc/Field.java +++ b/src/com/mysql/jdbc/Field.java @@ -190,12 +190,6 @@ this.encoding = "UTF-16"; } - // Fix chinese(or other non-ascii encoding) garbled in [mysql 5.7 JSON type] - // Use UTF-8 encoding , because mysql use utf8mb4 for JSON type store ; - if (this.mysqlType == MysqlDefs.FIELD_TYPE_JSON) { - this.encoding = "UTF-8"; - } - // Handle VARBINARY/BINARY (server doesn't have a different type for this boolean isBinary = isBinary(); @@ -336,8 +330,8 @@ private void setupForUtf8StringInBlob() { /** * Constructor used when communicating with pre 4.1 servers */ - Field(MySQLConnection conn, byte[] buffer, int nameStart, int nameLength, int tableNameStart, int tableNameLength, int length, int mysqlType, - short colFlag, int colDecimals) throws SQLException { + Field(MySQLConnection conn, byte[] buffer, int nameStart, int nameLength, int tableNameStart, int tableNameLength, int length, int mysqlType, short colFlag, + int colDecimals) throws SQLException { this(conn, buffer, -1, -1, tableNameStart, tableNameLength, -1, -1, nameStart, nameLength, -1, -1, length, mysqlType, colFlag, colDecimals, -1, -1, NO_CHARSET_INFO); } @@ -787,8 +781,8 @@ private boolean isNativeNumericType() { } private boolean isNativeDateTimeType() { - return (this.mysqlType == MysqlDefs.FIELD_TYPE_DATE || this.mysqlType == MysqlDefs.FIELD_TYPE_NEWDATE - || this.mysqlType == MysqlDefs.FIELD_TYPE_DATETIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIMESTAMP); + return (this.mysqlType == MysqlDefs.FIELD_TYPE_DATE || this.mysqlType == MysqlDefs.FIELD_TYPE_NEWDATE || this.mysqlType == MysqlDefs.FIELD_TYPE_DATETIME + || this.mysqlType == MysqlDefs.FIELD_TYPE_TIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIMESTAMP); } public void setConnection(MySQLConnection conn) { From fbe81715699621509a26a8fc8f965d2fdacae302 Mon Sep 17 00:00:00 2001 From: Neil Dong Date: Sat, 18 Jun 2016 14:13:42 +0800 Subject: [PATCH 3/3] //Fix for bug #80631 Any ResultSet.getString return garbled result with json type data // Fix chinese(or other non-ascii encoding) garbled in [mysql 5.7 JSON type] // Use UTF-8 encoding , because mysql use utf8mb4 for JSON type store ; --- src/com/mysql/jdbc/Field.java | 7 +++++ .../regression/ResultSetRegressionTest.java | 30 +++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/com/mysql/jdbc/Field.java b/src/com/mysql/jdbc/Field.java index 6d34ac0..efa473c 100644 --- a/src/com/mysql/jdbc/Field.java +++ b/src/com/mysql/jdbc/Field.java @@ -190,6 +190,13 @@ this.encoding = "UTF-16"; } + + // Fix chinese(or other non-ascii encoding) garbled in [mysql 5.7 JSON type] + // Use UTF-8 encoding , because mysql use utf8mb4 for storing JSON type ; + if (this.mysqlType == MysqlDefs.FIELD_TYPE_JSON) { + this.encoding = "UTF-8"; + } + // Handle VARBINARY/BINARY (server doesn't have a different type for this boolean isBinary = isBinary(); diff --git a/src/testsuite/regression/ResultSetRegressionTest.java b/src/testsuite/regression/ResultSetRegressionTest.java index a4b087a..2575807 100644 --- a/src/testsuite/regression/ResultSetRegressionTest.java +++ b/src/testsuite/regression/ResultSetRegressionTest.java @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 @@ -4971,4 +4971,32 @@ public void testBug56479() throws Exception { assertEquals(ts2, this.rs.getTimestamp(3)); assertFalse(this.rs.next()); } + + + /** + * Tests fix for Bug#80631 - ResultSet.getString return garbled result with json type data + */ + public void testBug80631() throws Exception { + //MySQL 5.7.9 (2015-10-21, General Availability) + if (!versionMeetsMinimum(5, 7, 9)) { + return; + } + + createTable("testBug80631", "(row_id int, json_field json)"); + String chinese = "{\"chinese\": \"\u4e2d\u6587\"}"; + String japanese = "{\"japanese\": \"\u685c\"}"; + String emoji = "{\"emoji\": \"\ue415\"}"; + + System.out.println("INSERT INTO testBug80631 VALUES (1, '" + chinese + "'), (2, '" + japanese + "'), (3, '" + emoji + "')"); + this.stmt.executeUpdate("INSERT INTO testBug80631 VALUES (1, '" + chinese + "'), (2, '" + japanese + "'), (3, '" + emoji + "')"); + + this.rs = this.stmt.executeQuery("SELECT json_field FROM testBug80631 ORDER BY row_id ASC"); + + assertTrue(this.rs.next()); + assertEquals(chinese, this.rs.getString(1)); + assertTrue(this.rs.next()); + assertEquals(japanese, this.rs.getString(1)); + assertTrue(this.rs.next()); + assertEquals(emoji, this.rs.getString(1)); + } }