Skip to content

Commit

Permalink
finagle-mysql: Update client charsets to be compatible with MySQL 8
Browse files Browse the repository at this point in the history
**Problem**

Our MySQL client is incompatible with MySQL 8. This change is to support the key
incompatibility of:

  - **Character Sets:**
     MySQL 8.0 improved support for UTF8 character sets and changed the default
     from utf8mb3 to utf8mb4. With MySQL’s improved support, finagle-mysql has
     to expand the supported character sets.

**Solution/Result**

These changes make it so that all of the finagle-mysql tests pass with a locally
running MySQL 8 server.

Differential Revision: https://phabricator.twitter.biz/D590996
  • Loading branch information
dotordogh authored and jenkins committed Jan 12, 2021
1 parent d7da1ad commit 25e581b
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 8 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Bug Fixes

* finagle-core: Fix wraparound bug in `Ring.weight`, as reported by @nvartolomei ``PHAB_ID=D575958``

* finagle-mysql: Update the UTF8 character set to cover those added in MySQL 8.
``PHAB_ID=D590996``

* finagle-thriftmux: Fixed a bug where connections were not established eagerly in ThriftMux
MethodBuilder even when eager connections was enabled. ``PHAB_ID=D589592``

Expand Down Expand Up @@ -97,7 +100,6 @@ Bug Fixes
`java.lang.UnsupportedOperationException: tail of empty stream` when a `c.t.f.s.RetryPolicy`
is converted to a String for showing. ``PHAB_ID=D582199``


20.10.0
-------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,20 @@ object MysqlCharset {
private[this] val Latin1Set = Set(5, 8, 15, 31, 47, 48, 49, 94)

/**
* With MySQL 5.7:
* "SELECT id,collation_name FROM information_schema.collations
* WHERE collation_name LIKE '%utf8' ORDER BY id"
* WHERE collation_name LIKE 'utf8%' ORDER BY id;"
*/
private[this] val Utf8Set = Set(192 to 254: _*) + 33 + 45 + 46 + 83
private[this] val Utf8MySql57Set = Set(192 to 254: _*) + 33 + 45 + 46 + 83

/**
* With MySQL 8.0:
* "SELECT id,collation_name FROM information_schema.collations
* WHERE collation_name LIKE 'utf8%' ORDER BY id;"
*/
private[this] val Utf8MySql8OnlySet = Set(255 to 315: _*) + 76

private[this] val Utf8MySql8Set = Utf8MySql57Set ++ Utf8MySql8OnlySet

/**
* @see https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-sets.html
Expand All @@ -50,9 +60,9 @@ object MysqlCharset {
*/
val Binary: Short = 63.toShort

private[this] val CompatibleSet = Latin1Set ++ Utf8Set + Binary
private[this] val CompatibleSet = Latin1Set ++ Utf8MySql8Set + Binary
def isCompatible(code: Short): Boolean = CompatibleSet(code)
def isUtf8(code: Short): Boolean = Utf8Set(code)
def isUtf8(code: Short): Boolean = Utf8MySql8Set(code)
def isLatin1(code: Short): Boolean = Latin1Set(code)
def isBinary(code: Short): Boolean = code == Binary
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ object Command {
val COM_INIT_DB: Byte = 0x02.toByte // mysql_select_db
val COM_QUERY: Byte = 0x03.toByte // mysql_real_query
val COM_FIELD_LIST: Byte = 0x04.toByte // mysql_list_fields
val COM_CREATE_DB: Byte = 0x05.toByte // mysql_create_db (deperacted)
val COM_CREATE_DB: Byte = 0x05.toByte // mysql_create_db (deprecated)
val COM_DROP_DB: Byte = 0x06.toByte // mysql_drop_db (deprecated)
val COM_REFRESH: Byte = 0x07.toByte // mysql_refresh
val COM_SHUTDOWN: Byte = 0x08.toByte // mysql_shutdown
val COM_SHUTDOWN: Byte =
0x08.toByte // mysql_shutdown (deprecated as of 5.7, removal planned for 8 at some point; use SHUTDOWN in com_query instead).
val COM_STATISTICS: Byte = 0x09.toByte // mysql_stat
val COM_PROCESS_INFO: Byte = 0x0a.toByte // mysql_list_processes
val COM_CONNECT: Byte = 0x0b.toByte // internal thread state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AbortedClientTest extends FunSuite with IntegrationClient {

for (c <- client) {
test("MySql connections are closed cleanly, so MySql doesn't count them as aborted.") {
val abortedClientQuery = "SHOW GLOBAL STATUS LIKE '%Aborted_clients%'"
val abortedClientQuery = "SHOW GLOBAL STATUS LIKE 'Aborted_clients'"
val initialAbortedValue: String =
await(c.select(abortedClientQuery)(row => row.stringOrNull("Value"))).head

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ class PreparedStatementTest extends FunSuite with IntegrationClient with BeforeA
}

test("insert BigDecimal with too much precision") {
// Depending on how the server is configured, this test may fail.
// With the following configurations (which happen to be MySQL's defaults) this test will pass:
// +-----------------------------------------------------------------------------------------------------------------------+
// | @@sql_mode |
// +-----------------------------------------------------------------------------------------------------------------------+
// | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
// +-----------------------------------------------------------------------------------------------------------------------+
intercept[ServerError] {
// this number has more total digits than allowed, 5
insertBigDecimal(Some(BigDecimal("100000")))
Expand Down

0 comments on commit 25e581b

Please sign in to comment.