Skip to content

Commit 0fab8f8

Browse files
author
Rick Owens
committed
Format SqlRational as a decimal ...
... in order to avoid this error when trying to insert a rational value into the database: SqlError {seState = "22P02", seNativeError = 7, seErrorMsg = "execute: PGRES_FATAL_ERROR: ERROR: invalid input syntax for type numeric: \"603 % 10\"\n"} Apparently, the `Show` instance isn't good enough. This implementation technically losses some precision in some cases, but then Haskell's `Rational` is larger than PostgreSQL's `numeric`, so that is fundamentally unavoidable.
1 parent f3923c3 commit 0fab8f8

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

Database/HDBC/PostgreSQL/Utils.hsc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Foreign.Storable
1515
import Foreign.Marshal.Array
1616
import Foreign.Marshal.Alloc
1717
import Foreign.Marshal.Utils
18+
import Data.Fixed (Pico, showFixed)
1819
import Data.Word
1920
import qualified Data.ByteString.UTF8 as BUTF8
2021
import qualified Data.ByteString as B
@@ -76,12 +77,19 @@ withCStringArr0 inp action = withAnyArr0 convfunc freefunc inp action
7677
convfunc y@(SqlUTCTime _) = convfunc (SqlZonedTime (fromSql y))
7778
convfunc y@(SqlEpochTime _) = convfunc (SqlZonedTime (fromSql y))
7879
convfunc (SqlByteString x) = cstrUtf8BString (cleanUpBSNulls x)
80+
convfunc (SqlRational rat) = cstrUtf8BString (showRational rat)
7981
convfunc x = cstrUtf8BString (fromSql x)
8082
freefunc x =
8183
if x == nullPtr
8284
then return ()
8385
else free x
8486

87+
88+
{- | Helper that formats a 'Rational' using decimal. -}
89+
showRational :: Rational -> B.ByteString
90+
showRational rat = BCHAR8.pack $ showFixed True (fromRational rat :: Pico)
91+
92+
8593
cleanUpBSNulls :: B.ByteString -> B.ByteString
8694
cleanUpBSNulls bs | 0 `B.notElem` bs = bs
8795
| otherwise = B.concatMap convfunc bs

0 commit comments

Comments
 (0)