on db148ff help sign in
rel8/src/Rel8/Expr/Ord.hs
138 lines 4.4 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, nullable, unsafeLiftOpNull )
26import Rel8.Expr.Opaleye ( toPrimExpr, zipPrimExprsWith )
27import Rel8.Schema.Null ( Nullity( Null, NotNull ), Sql )
28import qualified Rel8.Schema.Null as Schema ( nullable )
29import Rel8.Type.Ord ( DBOrd )
32lt :: DBOrd a => Expr a -> Expr a -> Expr Bool
33lt = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:<))
36le :: DBOrd a => Expr a -> Expr a -> Expr Bool
37le = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:<=))
40gt :: DBOrd a => Expr a -> Expr a -> Expr Bool
41gt = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:>))
44ge :: DBOrd a => Expr a -> Expr a -> Expr Bool
45ge = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:>=))
48-- | Corresponds to the SQL @<@ operator. Note that this differs from SQL @<@
49-- as @null@ will sort below any other value. For a version of @<@ that exactly
50-- matches SQL, see '(<?)'.
51(<.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
52(<.) = case Schema.nullable @a of
53 Null -> \ma mb -> isNull ma &&. isNonNull mb ||. ma <? mb
54 NotNull -> lt
55infix 4 <.
58-- | Corresponds to the SQL @<=@ operator. Note that this differs from SQL @<=@
59-- as @null@ will sort below any other value. For a version of @<=@ that exactly
60-- matches SQL, see '(<=?)'.
61(<=.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
62(<=.) = case Schema.nullable @a of
63 Null -> \ma mb -> isNull ma ||. ma <=? mb
64 NotNull -> le
65infix 4 <=.
68-- | Corresponds to the SQL @>@ operator. Note that this differs from SQL @>@
69-- as @null@ will sort below any other value. For a version of @>@ that exactly
70-- matches SQL, see '(>?)'.
71(>.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
72(>.) = case Schema.nullable @a of
73 Null -> \ma mb -> isNonNull ma &&. isNull mb ||. ma >? mb
74 NotNull -> gt
75infix 4 >.
78-- | Corresponds to the SQL @>=@ operator. Note that this differs from SQL @>@
79-- as @null@ will sort below any other value. For a version of @>=@ that
80-- exactly matches SQL, see '(>=?)'.
81(>=.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
82(>=.) = case Schema.nullable @a of
83 Null -> \ma mb -> isNull mb ||. ma >=? mb
84 NotNull -> ge
85infix 4 >=.
88-- | Corresponds to the SQL @<@ operator. Returns @null@ if either arguments
89-- are @null@.
90(<?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
91a <? b = coalesce $ unsafeLiftOpNull lt a b
92infix 4 <?
95-- | Corresponds to the SQL @<=@ operator. Returns @null@ if either arguments
96-- are @null@.
97(<=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
98a <=? b = coalesce $ unsafeLiftOpNull le a b
99infix 4 <=?
102-- | Corresponds to the SQL @>@ operator. Returns @null@ if either arguments
103-- are @null@.
104(>?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
105a >? b = coalesce $ unsafeLiftOpNull gt a b
106infix 4 >?
109-- | Corresponds to the SQL @>=@ operator. Returns @null@ if either arguments
110-- are @null@.
111(>=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
112a >=? b = coalesce $ unsafeLiftOpNull ge a b
113infix 4 >=?
116-- | Given two expressions, return the expression that sorts less than the
117-- other.
118--
119-- Corresponds to the SQL @least()@ function.
120leastExpr :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr a
121leastExpr ma mb = case Schema.nullable @a of
122 Null -> nullable ma (\a -> nullable mb (least_ a) mb) ma
123 NotNull -> least_ ma mb
124 where
125 least_ a b = Expr (Opaleye.FunExpr "LEAST" [toPrimExpr a, toPrimExpr b])
128-- | Given two expressions, return the expression that sorts greater than the
129-- other.
130--
131-- Corresponds to the SQL @greatest()@ function.
132greatestExpr :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr a
133greatestExpr ma mb = case Schema.nullable @a of
134 Null -> nullable mb (\a -> nullable ma (greatest_ a) mb) ma
135 NotNull -> greatest_ ma mb
136 where
137 greatest_ a b =
138 Expr (Opaleye.FunExpr "GREATEST" [toPrimExpr a, toPrimExpr b])