sum_'s type is (PersistField a, PersistField b) => expr (Value a) -> expr (Value (Maybe b)). But sum of course cannot return any type. In Postgres, it returns numeric for bigints, which is represented as PersistRational. Details here. Example:
module Main where
import Control.Monad.IO.Class
import Control.Monad.Logger
import Database.Esqueleto
import Database.Persist
import Database.Persist.Postgresql
import Database.Persist.TH
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Number
value Int
|]
connStr = "host=localhost dbname=test user=test password=test port=5432"
main :: IO ()
main = runStderrLoggingT $ withPostgresqlPool connStr 10 $ \pool -> liftIO $ do
flip runSqlPersistMPool pool $ do
runMigration migrateAll
johnId <- insert $ Number 5
janeId <- insert $ Number 22
return ()
_ :: [Value (Maybe Int)] <- select $
from $ \number -> do
return $ sum_ $ number ^. NumberValue
return ()
enolan at behemoth in ~/junk/esqueleto-bug
$ stack exec esqueleto-bug
[Debug#SQL] INSERT INTO "number"("value") VALUES(?) RETURNING "id"; [PersistInt64 5]
[Debug#SQL] INSERT INTO "number"("value") VALUES(?) RETURNING "id"; [PersistInt64 22]
[Debug#SQL] SELECT SUM("number"."value")
FROM "number"
; []
esqueleto-bug: PersistMarshalError "int Expected Integer, received: PersistRational (27 % 1)"
I suppose it needs a type family/fundep. Test case repo here.
sum_
's type is(PersistField a, PersistField b) => expr (Value a) -> expr (Value (Maybe b))
. But sum of course cannot return any type. In Postgres, it returnsnumeric
forbigint
s, which is represented asPersistRational
. Details here. Example:I suppose it needs a type family/fundep. Test case repo here.