Open
Description
See the code at the bottom. It uses coerce
to change the result of lead1_
to be nullable.
Uncommenting the line
fmap fixType <$>
Makes the code fail with
BeamRowReadError {brreColumn = Just 1, brreError = ColumnErrorInternal "Column parse failed with unknown exception"}
Code:
#!/usr/bin/env stack
{- stack script
--snapshot lts-23.0
--system-ghc
--package beam-core
--package beam-postgres
--package postgresql-simple
--package text
s-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
import Data.Coerce (coerce)
import Data.Text (Text)
import Database.Beam
import Database.Beam.Postgres
import Database.PostgreSQL.Simple (Query, execute_)
data PersonT f = Person
{ name :: C f Text
}
deriving (Generic)
type Person = PersonT Identity
type PersonExpr s = PersonT (QExpr Postgres s)
deriving instance Show Person
deriving instance Eq Person
instance Beamable PersonT
instance Table PersonT where
data PrimaryKey PersonT f = PersonKey (C f Text)
deriving stock (Generic)
deriving anyclass (Beamable)
primaryKey Person{name} = PersonKey name
data Db f = Db
{ persons :: f (TableEntity PersonT)
}
deriving (Generic)
instance Database Postgres Db
db :: DatabaseSettings Postgres Db
db = defaultDbSettings
-- The type of `lead1_` is incorrect
fixType :: QExpr Postgres s a -> QExpr Postgres s (Maybe a)
fixType = coerce
query =
fmap fixType <$>
withWindow_
( \Person{name} ->
frame_
noPartition_
(orderPartitionBy_ (asc_ name))
noBounds_
)
( \Person{name} w ->
(name, lead1_ name `over_` w)
)
(all_ $ persons db)
main = do
conn <- connect defaultConnectInfo {connectDatabase = "test"}
execute_ conn "create table if not exists persons (name varchar)"
execute_ conn "delete from persons"
execute_ conn "insert into persons (name) values ('Janne'), ('Jenny')"
results <- runBeamPostgres conn $
runSelectReturningList $ select query
mapM_ print results