@@ -104,7 +104,7 @@ module Database.PostgreSQL.Simple.FromField
104104
105105#include "MachDeps.h"
106106
107−import Control.Applicative ( (<|>), (<$>), pure )
107+import Control.Applicative ( (<|>), (<$>), pure, (*>) )
108108import Control.Concurrent.MVar (MVar, newMVar)
109109import Control.Exception (Exception)
110110import qualified Data.Aeson as JSON
@@ -138,6 +138,7 @@ import qualified Data.Text.Lazy as LT
138138import Data.UUID (UUID)
139139import qualified Data.UUID as UUID
140140import Data.Scientific (Scientific)
141+import GHC.Real (infinity, notANumber)
141142
142143-- | Exception thrown if conversion from a SQL value to a Haskell
143144-- value fails.
@@ -314,18 +315,18 @@ instance FromField Integer where
314315-- | int2, float4 (Uses attoparsec's 'double' routine, for
315316-- better accuracy convert to 'Scientific' or 'Rational' first)
316317instance FromField Float where
317− fromField = atto ok (realToFrac <$> double)
318+ fromField = atto ok (realToFrac <$> pg_double)
318319 where ok = $(mkCompats [TI.float4,TI.int2])
319320
320321-- | int2, int4, float4, float8 (Uses attoparsec's 'double' routine, for
321322-- better accuracy convert to 'Scientific' or 'Rational' first)
322323instance FromField Double where
323− fromField = atto ok double
324+ fromField = atto ok pg_double
324325 where ok = $(mkCompats [TI.float4,TI.float8,TI.int2,TI.int4])
325326
326327-- | int2, int4, float4, float8, numeric
327328instance FromField (Ratio Integer) where
328− fromField = atto ok rational
329+ fromField = atto ok pg_rational
329330 where ok = $(mkCompats [TI.float4,TI.float8,TI.int2,TI.int4,TI.numeric])
330331
331332-- | int2, int4, float4, float8, numeric
@@ -336,6 +337,20 @@ instance FromField Scientific where
336337unBinary :: Binary t -> t
337338unBinary (Binary x) = x
338339
340+pg_double :: Parser Double
341+pg_double
342+ = (string "NaN" *> pure ( 0 / 0))
343+ <|> (string "Infinity" *> pure ( 1 / 0))
344+ <|> (string "-Infinity" *> pure (-1 / 0))
345+ <|> double
346+
347+pg_rational :: Parser Rational
348+pg_rational
349+ = (string "NaN" *> pure notANumber )
350+ <|> (string "Infinity" *> pure infinity )
351+ <|> (string "-Infinity" *> pure (-infinity))
352+ <|> rational
353+
339354-- | bytea, name, text, \"char\", bpchar, varchar, unknown
340355instance FromField SB.ByteString where
341356 fromField f dat = if typeOid f == $(inlineTypoid TI.bytea)