on 2ba99ea help sign in
rel8/src/Rel8/Expr/Ord.hs
137 lines 4.3 kB history raw
1{-# language DataKinds #-}
2{-# language FlexibleContexts #-}
3{-# language GADTs #-}
4{-# language ScopedTypeVariables #-}
5{-# language TypeApplications #-}
7{-# options_ghc -fno-warn-redundant-constraints #-}
9module Rel8.Expr.Ord
10 ( (<.), (<=.), (>.), (>=.)
11 , (<?), (<=?), (>?), (>=?)
12 , leastExpr, greatestExpr
13 )
14where
16-- base
17import Prelude
19-- opaleye
20import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
22-- rel8
23import Rel8.Expr ( Expr( Expr ) )
24import Rel8.Expr.Bool ( (&&.), (||.), coalesce )
25import Rel8.Expr.Null ( isNull, isNonNull, nullableExpr, unsafeLiftOpNull )
26import Rel8.Expr.Opaleye ( toPrimExpr, zipPrimExprsWith )
27import Rel8.Schema.Null ( Nullity( Null, NotNull ), Sql, nullable )
28import Rel8.Type.Ord ( DBOrd )
31lt :: DBOrd a => Expr a -> Expr a -> Expr Bool
32lt = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:<))
35le :: DBOrd a => Expr a -> Expr a -> Expr Bool
36le = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:<=))
39gt :: DBOrd a => Expr a -> Expr a -> Expr Bool
40gt = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:>))
43ge :: DBOrd a => Expr a -> Expr a -> Expr Bool
44ge = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:>=))
47-- | Corresponds to the SQL @<@ operator. Note that this differs from SQL @<@
48-- as @null@ will sort below any other value. For a version of @<@ that exactly
49-- matches SQL, see '(<?)'.
50(<.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
51(<.) = case nullable @a of
52 Null -> \ma mb -> isNull ma &&. isNonNull mb ||. ma <? mb
53 NotNull -> lt
54infix 4 <.
57-- | Corresponds to the SQL @<=@ operator. Note that this differs from SQL @<=@
58-- as @null@ will sort below any other value. For a version of @<=@ that exactly
59-- matches SQL, see '(<=?)'.
60(<=.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
61(<=.) = case nullable @a of
62 Null -> \ma mb -> isNull ma ||. ma <=? mb
63 NotNull -> le
64infix 4 <=.
67-- | Corresponds to the SQL @>@ operator. Note that this differs from SQL @>@
68-- as @null@ will sort below any other value. For a version of @>@ that exactly
69-- matches SQL, see '(>?)'.
70(>.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
71(>.) = case nullable @a of
72 Null -> \ma mb -> isNonNull ma &&. isNull mb ||. ma >? mb
73 NotNull -> gt
74infix 4 >.
77-- | Corresponds to the SQL @>=@ operator. Note that this differs from SQL @>@
78-- as @null@ will sort below any other value. For a version of @>=@ that
79-- exactly matches SQL, see '(>=?)'.
80(>=.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
81(>=.) = case nullable @a of
82 Null -> \ma mb -> isNull mb ||. ma >=? mb
83 NotNull -> ge
84infix 4 >=.
87-- | Corresponds to the SQL @<@ operator. Returns @null@ if either arguments
88-- are @null@.
89(<?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
90a <? b = coalesce $ unsafeLiftOpNull lt a b
91infix 4 <?
94-- | Corresponds to the SQL @<=@ operator. Returns @null@ if either arguments
95-- are @null@.
96(<=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
97a <=? b = coalesce $ unsafeLiftOpNull le a b
98infix 4 <=?
101-- | Corresponds to the SQL @>@ operator. Returns @null@ if either arguments
102-- are @null@.
103(>?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
104a >? b = coalesce $ unsafeLiftOpNull gt a b
105infix 4 >?
108-- | Corresponds to the SQL @>=@ operator. Returns @null@ if either arguments
109-- are @null@.
110(>=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
111a >=? b = coalesce $ unsafeLiftOpNull ge a b
112infix 4 >=?
115-- | Given two expressions, return the expression that sorts less than the
116-- other.
117--
118-- Corresponds to the SQL @least()@ function.
119leastExpr :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr a
120leastExpr ma mb = case nullable @a of
121 Null -> nullableExpr ma (\a -> nullableExpr mb (least_ a) mb) ma
122 NotNull -> least_ ma mb
123 where
124 least_ a b = Expr (Opaleye.FunExpr "LEAST" [toPrimExpr a, toPrimExpr b])
127-- | Given two expressions, return the expression that sorts greater than the
128-- other.
129--
130-- Corresponds to the SQL @greatest()@ function.
131greatestExpr :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr a
132greatestExpr ma mb = case nullable @a of
133 Null -> nullableExpr mb (\a -> nullableExpr ma (greatest_ a) mb) ma
134 NotNull -> greatest_ ma mb
135 where
136 greatest_ a b =
137 Expr (Opaleye.FunExpr "GREATEST" [toPrimExpr a, toPrimExpr b])