From f123992fc7b698bd472060dbdc0b13ecf27bf665 Mon Sep 17 00:00:00 2001 From: Fumiaki Kinoshita Date: Mon, 27 Nov 2023 18:43:13 +0900 Subject: [PATCH] persistent-mysql: treat tinyint as SqlOther "tinyint", not SqlBool --- persistent-mysql/ChangeLog.md | 5 +++++ persistent-mysql/Database/Persist/MySQL.hs | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/persistent-mysql/ChangeLog.md b/persistent-mysql/ChangeLog.md index 1a8cfae56..45e7e6d20 100644 --- a/persistent-mysql/ChangeLog.md +++ b/persistent-mysql/ChangeLog.md @@ -1,5 +1,10 @@ # Changelog for persistent-mysql +## 2.13.1.5 + +* [#1526](https://github.com/yesodweb/persistent/pull/1526) + * Parse `tinyint` column as `SqlOther "tinyint"` rather than `SqlBool`, fixing breakage in legitimate non-Boolean uses of `tinyint` on MySQL 8.0 + ## 2.13.1.4 * [#1459](https://github.com/yesodweb/persistent/pull/1459) diff --git a/persistent-mysql/Database/Persist/MySQL.hs b/persistent-mysql/Database/Persist/MySQL.hs index 76e01a81a..73f0a1ded 100644 --- a/persistent-mysql/Database/Persist/MySQL.hs +++ b/persistent-mysql/Database/Persist/MySQL.hs @@ -827,14 +827,16 @@ data ColumnInfo = ColumnInfo -- @INFORMATION_SCHEMA@ tables. parseColumnType :: Text -> ColumnInfo -> ExceptT String IO (SqlType, Maybe Integer) -- Ints --- The display width is deprecated and being removed in MySQL 8.X. To be --- consistent with earlier versions, which do report it, accept either +-- The display width is deprecated and being removed in MySQL 8.X +-- with [an exception of tinyint(1) which is used for boolean values](https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html#mysqld-8-0-19-deprecation-removal). +-- To be consistent with earlier versions, which do report it, accept either -- the bare type in `ciColumnType ci`, or the type adorned with the expected -- value for the display width (ie the defaults for int and bigint, or the -- value explicitly set in `showSqlType` for SqlBool). -- parseColumnType "tinyint" ci - | ciColumnType ci == "tinyint" || ciColumnType ci == "tinyint(1)" = return (SqlBool, Nothing) + | ciColumnType ci == "tinyint(1)" = return (SqlBool, Nothing) + | otherwise = return (SqlOther "tinyint", Nothing) parseColumnType "int" ci | ciColumnType ci == "int" || ciColumnType ci == "int(11)" = return (SqlInt32, Nothing) parseColumnType "bigint" ci @@ -1023,10 +1025,8 @@ showSqlType :: SqlType -> String showSqlType SqlBlob Nothing _ = "BLOB" showSqlType SqlBlob (Just i) _ = "VARBINARY(" ++ show i ++ ")" --- "tinyint(1)" has been used historically here. In MySQL 8, the display width --- is deprecated, and in the future it may need to be removed here. However, --- "(1)" is not the default in older MySQL versions, so for them omitting it --- would alter the exact form of the column type in the information_schema. +-- While integer widths are deprecated in MySQL 8.0, "tinyint(1)" remains as an exception. +-- cf. https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html#mysqld-8-0-19-deprecation-removal showSqlType SqlBool _ _ = "TINYINT(1)" showSqlType SqlDay _ _ = "DATE" showSqlType SqlDayTime _ _ = "DATETIME"