on master help sign in
Generalize nullable to work on `Table`s
commit8cb6d488075a6e42ba8091c434c8f2c5dd16d266 authorShane O'Brien <shane.obrien@circuithub.com> dateThu 6 May 2021, 18:26 (6 years ago) parentd028b37
3 files changed+20−14
src/Rel8/Expr/Null.hs+3−3 src/Rel8/Expr/Ord.hs+10−11 src/Rel8/Table/Bool.hs+7
src/Rel8/Expr/Null.hs+3−3
@@ -5,7 +5,7 @@
55{-# options -fno-warn-redundant-constraints #-}
66
77module Rel8.Expr.Null
8− ( null, snull, nullable, nullableOf
8+ ( null, snull, nullableExpr, nullableOf
99 , isNull, isNonNull
1010 , nullify, unsafeUnnullify
1111 , mapNull, liftOpNull
@@ -40,8 +40,8 @@ unsafeUnnullify (Expr a) = Expr a
4040
4141
4242-- | Like 'maybe', but to eliminate @null@.
43−nullable :: Expr b -> (Expr a -> Expr b) -> Expr (Maybe a) -> Expr b
44−nullable b f ma = boolExpr (f (unsafeUnnullify ma)) b (isNull ma)
43+nullableExpr :: Expr b -> (Expr a -> Expr b) -> Expr (Maybe a) -> Expr b
44+nullableExpr b f ma = boolExpr (f (unsafeUnnullify ma)) b (isNull ma)
4545
4646
4747nullableOf :: DBType a => Maybe (Expr a) -> Expr (Maybe a)
src/Rel8/Expr/Ord.hs+10−11
@@ -22,10 +22,9 @@ import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
2222-- rel8
2323import Rel8.Expr ( Expr( Expr ) )
2424import Rel8.Expr.Bool ( (&&.), (||.), coalesce )
25−import Rel8.Expr.Null ( isNull, isNonNull, nullable, unsafeLiftOpNull )
25+import Rel8.Expr.Null ( isNull, isNonNull, nullableExpr, unsafeLiftOpNull )
2626import Rel8.Expr.Opaleye ( toPrimExpr, zipPrimExprsWith )
27−import Rel8.Schema.Null ( Nullity( Null, NotNull ), Sql )
28−import qualified Rel8.Schema.Null as Schema ( nullable )
27+import Rel8.Schema.Null ( Nullity( Null, NotNull ), Sql, nullable )
2928import Rel8.Type.Ord ( DBOrd )
3029
3130
@@ -49,7 +48,7 @@ ge = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:>=))
4948-- as @null@ will sort below any other value. For a version of @<@ that exactly
5049-- matches SQL, see '(<?)'.
5150(<.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
52−(<.) = case Schema.nullable @a of
51+(<.) = case nullable @a of
5352 Null -> \ma mb -> isNull ma &&. isNonNull mb ||. ma <? mb
5453 NotNull -> lt
5554infix 4 <.
@@ -59,7 +58,7 @@ infix 4 <.
5958-- as @null@ will sort below any other value. For a version of @<=@ that exactly
6059-- matches SQL, see '(<=?)'.
6160(<=.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
62−(<=.) = case Schema.nullable @a of
61+(<=.) = case nullable @a of
6362 Null -> \ma mb -> isNull ma ||. ma <=? mb
6463 NotNull -> le
6564infix 4 <=.
@@ -69,7 +68,7 @@ infix 4 <=.
6968-- as @null@ will sort below any other value. For a version of @>@ that exactly
7069-- matches SQL, see '(>?)'.
7170(>.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
72−(>.) = case Schema.nullable @a of
71+(>.) = case nullable @a of
7372 Null -> \ma mb -> isNonNull ma &&. isNull mb ||. ma >? mb
7473 NotNull -> gt
7574infix 4 >.
@@ -79,7 +78,7 @@ infix 4 >.
7978-- as @null@ will sort below any other value. For a version of @>=@ that
8079-- exactly matches SQL, see '(>=?)'.
8180(>=.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
82−(>=.) = case Schema.nullable @a of
81+(>=.) = case nullable @a of
8382 Null -> \ma mb -> isNull mb ||. ma >=? mb
8483 NotNull -> ge
8584infix 4 >=.
@@ -118,8 +117,8 @@ infix 4 >=?
118117--
119118-- Corresponds to the SQL @least()@ function.
120119leastExpr :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr a
121−leastExpr ma mb = case Schema.nullable @a of
122− Null -> nullable ma (\a -> nullable mb (least_ a) mb) ma
120+leastExpr ma mb = case nullable @a of
121+ Null -> nullableExpr ma (\a -> nullableExpr mb (least_ a) mb) ma
123122 NotNull -> least_ ma mb
124123 where
125124 least_ a b = Expr (Opaleye.FunExpr "LEAST" [toPrimExpr a, toPrimExpr b])
@@ -130,8 +129,8 @@ leastExpr ma mb = case Schema.nullable @a of
130129--
131130-- Corresponds to the SQL @greatest()@ function.
132131greatestExpr :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr a
133−greatestExpr ma mb = case Schema.nullable @a of
134− Null -> nullable mb (\a -> nullable ma (greatest_ a) mb) ma
132+greatestExpr ma mb = case nullable @a of
133+ Null -> nullableExpr mb (\a -> nullableExpr ma (greatest_ a) mb) ma
135134 NotNull -> greatest_ ma mb
136135 where
137136 greatest_ a b =
src/Rel8/Table/Bool.hs+7
@@ -5,6 +5,7 @@
55module Rel8.Table.Bool
66 ( bool
77 , case_
8+ , nullable
89 )
910where
1011
@@ -14,6 +15,7 @@ import Prelude
1415-- rel8
1516import Rel8.Expr ( Expr, Col(..) )
1617import Rel8.Expr.Bool ( boolExpr, caseExpr )
18+import Rel8.Expr.Null ( isNull, unsafeUnnullify )
1719import Rel8.Schema.HTable ( htabulate, hfield )
1820import Rel8.Table ( Table, fromColumns, toColumns )
1921
@@ -40,3 +42,8 @@ case_ (map (fmap toColumns) -> branches) (toColumns -> fallback) =
4042 DB fallbackExpr ->
4143 case map (fmap (unDB . (`hfield` field))) branches of
4244 branchExprs -> DB (caseExpr branchExprs fallbackExpr)
45+
46+
47+-- | Like 'maybe', but to eliminate @null@.
48+nullable :: Table Expr b => b -> (Expr a -> b) -> Expr (Maybe a) -> b
49+nullable b f ma = bool (f (unsafeUnnullify ma)) b (isNull ma)