@@ -104,7 +104,7 @@ module Database.PostgreSQL.Simple.FromField
105#include "MachDeps.h"
105#include "MachDeps.h"
107−import Control.Applicative ( (<|>), (<$>), pure )
107+import Control.Applicative ( (<|>), (<$>), pure, (*>) )
108import Control.Concurrent.MVar (MVar, newMVar)
108import Control.Concurrent.MVar (MVar, newMVar)
109import Control.Exception (Exception)
109import Control.Exception (Exception)
110import qualified Data.Aeson as JSON
110import qualified Data.Aeson as JSON
@@ -138,6 +138,7 @@ import qualified Data.Text.Lazy as LT
138import Data.UUID (UUID)
138import Data.UUID (UUID)
139import qualified Data.UUID as UUID
139import qualified Data.UUID as UUID
140import Data.Scientific (Scientific)
140import Data.Scientific (Scientific)
141+import GHC.Real (infinity, notANumber)
142-- | Exception thrown if conversion from a SQL value to a Haskell
143-- | Exception thrown if conversion from a SQL value to a Haskell
143-- value fails.
144-- value fails.
@@ -314,18 +315,18 @@ instance FromField Integer where
314-- | int2, float4 (Uses attoparsec's 'double' routine, for
315-- | int2, float4 (Uses attoparsec's 'double' routine, for
315-- better accuracy convert to 'Scientific' or 'Rational' first)
316-- better accuracy convert to 'Scientific' or 'Rational' first)
316instance FromField Float where
317instance FromField Float where
317− fromField = atto ok (realToFrac <$> double)
318+ fromField = atto ok (realToFrac <$> pg_double)
318 where ok = $(mkCompats [TI.float4,TI.int2])
319 where ok = $(mkCompats [TI.float4,TI.int2])
320-- | int2, int4, float4, float8 (Uses attoparsec's 'double' routine, for
321-- | int2, int4, float4, float8 (Uses attoparsec's 'double' routine, for
321-- better accuracy convert to 'Scientific' or 'Rational' first)
322-- better accuracy convert to 'Scientific' or 'Rational' first)
322instance FromField Double where
323instance FromField Double where
323− fromField = atto ok double
324+ fromField = atto ok pg_double
324 where ok = $(mkCompats [TI.float4,TI.float8,TI.int2,TI.int4])
325 where ok = $(mkCompats [TI.float4,TI.float8,TI.int2,TI.int4])
326-- | int2, int4, float4, float8, numeric
327-- | int2, int4, float4, float8, numeric
327instance FromField (Ratio Integer) where
328instance FromField (Ratio Integer) where
328− fromField = atto ok rational
329+ fromField = atto ok pg_rational
329 where ok = $(mkCompats [TI.float4,TI.float8,TI.int2,TI.int4,TI.numeric])
330 where ok = $(mkCompats [TI.float4,TI.float8,TI.int2,TI.int4,TI.numeric])
331-- | int2, int4, float4, float8, numeric
332-- | int2, int4, float4, float8, numeric
@@ -336,6 +337,20 @@ instance FromField Scientific where
336unBinary :: Binary t -> t
337unBinary :: Binary t -> t
337unBinary (Binary x) = x
338unBinary (Binary x) = x
340+pg_double :: Parser Double
342+ = (string "NaN" *> pure ( 0 / 0))
343+ <|> (string "Infinity" *> pure ( 1 / 0))
344+ <|> (string "-Infinity" *> pure (-1 / 0))
347+pg_rational :: Parser Rational
349+ = (string "NaN" *> pure notANumber )
350+ <|> (string "Infinity" *> pure infinity )
351+ <|> (string "-Infinity" *> pure (-infinity))
339-- | bytea, name, text, \"char\", bpchar, varchar, unknown
354-- | bytea, name, text, \"char\", bpchar, varchar, unknown
340instance FromField SB.ByteString where
355instance FromField SB.ByteString where
341 fromField f dat = if typeOid f == $(inlineTypoid TI.bytea)
356 fromField f dat = if typeOid f == $(inlineTypoid TI.bytea)