on 11bcbbb help sign in
rel8/src/Rel8/Expr/Ord.hs
140 lines 4.5 kB history raw
1{-# language DataKinds #-}
2{-# language FlexibleContexts #-}
3{-# language LambdaCase #-}
4{-# language GADTs #-}
5{-# language ScopedTypeVariables #-}
6{-# language TypeApplications #-}
8{-# options_ghc -fno-warn-redundant-constraints #-}
10module Rel8.Expr.Ord
11 ( (<.), (<=.), (>.), (>=.)
12 , (<?), (<=?), (>?), (>=?)
13 , leastExpr, greatestExpr
14 )
15where
17-- base
18import Prelude
20-- opaleye
21import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
23-- rel8
24import Rel8.Expr ( Expr( Expr ) )
25import Rel8.Expr.Bool ( (&&.), (||.), coalesce )
26import Rel8.Expr.Null ( isNull, isNonNull, nullable, unsafeLiftOpNullable )
27import Rel8.Expr.Opaleye ( zipPrimExprsWith )
28import Rel8.Schema.Nullability
29 ( Nullability( NonNullable, Nullable )
30 , Sql, nullabilization
31 )
32import Rel8.Type.Ord ( DBOrd )
35lt :: DBOrd a => Expr a -> Expr a -> Expr Bool
36lt = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:<))
39le :: DBOrd a => Expr a -> Expr a -> Expr Bool
40le = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:<=))
43gt :: DBOrd a => Expr a -> Expr a -> Expr Bool
44gt = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:>))
47ge :: DBOrd a => Expr a -> Expr a -> Expr Bool
48ge = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:>=))
51-- | Corresponds to the SQL @<@ operator. Note that this differs from SQL @<@
52-- as @null@ will sort below any other value. For a version of @<@ that exactly
53-- matches SQL, see '(<?)'.
54(<.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
55(<.) = case nullabilization @a of
56 Nullable -> \ma mb -> isNull ma &&. isNonNull mb ||. ma <? mb
57 NonNullable -> lt
58infix 4 <.
61-- | Corresponds to the SQL @<=@ operator. Note that this differs from SQL @<=@
62-- as @null@ will sort below any other value. For a version of @<=@ that exactly
63-- matches SQL, see '(<=?)'.
64(<=.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
65(<=.) = case nullabilization @a of
66 Nullable -> \ma mb -> isNull ma ||. ma <=? mb
67 NonNullable -> le
68infix 4 <=.
71-- | Corresponds to the SQL @>@ operator. Note that this differs from SQL @>@
72-- as @null@ will sort below any other value. For a version of @>@ that exactly
73-- matches SQL, see '(>?)'.
74(>.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
75(>.) = case nullabilization @a of
76 Nullable -> \ma mb -> isNonNull ma &&. isNull mb ||. ma >? mb
77 NonNullable -> gt
78infix 4 >.
81-- | Corresponds to the SQL @>=@ operator. Note that this differs from SQL @>@
82-- as @null@ will sort below any other value. For a version of @>=@ that
83-- exactly matches SQL, see '(>=?)'.
84(>=.) :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr Bool
85(>=.) = case nullabilization @a of
86 Nullable -> \ma mb -> isNull mb ||. ma >=? mb
87 NonNullable -> ge
88infix 4 >=.
91-- | Corresponds to the SQL @<@ operator. Returns @null@ if either arguments
92-- are @null@.
93(<?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
94a <? b = coalesce $ unsafeLiftOpNullable lt a b
95infix 4 <?
98-- | Corresponds to the SQL @<=@ operator. Returns @null@ if either arguments
99-- are @null@.
100(<=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
101a <=? b = coalesce $ unsafeLiftOpNullable le a b
102infix 4 <=?
105-- | Corresponds to the SQL @>@ operator. Returns @null@ if either arguments
106-- are @null@.
107(>?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
108a >? b = coalesce $ unsafeLiftOpNullable gt a b
109infix 4 >?
112-- | Corresponds to the SQL @>=@ operator. Returns @null@ if either arguments
113-- are @null@.
114(>=?) :: DBOrd a => Expr (Maybe a) -> Expr (Maybe a) -> Expr Bool
115a >=? b = coalesce $ unsafeLiftOpNullable ge a b
116infix 4 >=?
119-- | Given two expressions, return the expression that sorts less than the
120-- other.
121--
122-- Corresponds to the SQL @least()@ function.
123leastExpr :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr a
124leastExpr ma mb = case nullabilization @a of
125 Nullable -> nullable ma (\a -> nullable mb (least_ a) mb) ma
126 NonNullable -> least_ ma mb
127 where
128 least_ (Expr a) (Expr b) = Expr (Opaleye.FunExpr "LEAST" [a, b])
131-- | Given two expressions, return the expression that sorts greater than the
132-- other.
133--
134-- Corresponds to the SQL @greatest()@ function.
135greatestExpr :: forall a. Sql DBOrd a => Expr a -> Expr a -> Expr a
136greatestExpr ma mb = case nullabilization @a of
137 Nullable -> nullable mb (\a -> nullable ma (greatest_ a) mb) ma
138 NonNullable -> greatest_ ma mb
139 where
140 greatest_ (Expr a) (Expr b) = Expr (Opaleye.FunExpr "GREATEST" [a, b])