@@ -35,7 +35,7 @@ module Squeal.PostgreSQL.Expression.Range
36 , Range (..)
36 , Range (..)
37 , (<=..<=), (<..<), (<=..<), (<..<=)
37 , (<=..<=), (<..<), (<=..<), (<..<=)
38− , halfGT, halfGTE, halfLT, halfLTE
38+ , greaterThan, atLeast, lessThan, atMost
39 , singleton, whole
39 , singleton, whole
40 , Bound (..)
40 , Bound (..)
41 , closed, open
41 , closed, open
@@ -47,6 +47,7 @@ import qualified GHC.Generics as GHC
47import qualified Generics.SOP as SOP
47import qualified Generics.SOP as SOP
49import Squeal.PostgreSQL.Expression
49import Squeal.PostgreSQL.Expression
50+import Squeal.PostgreSQL.Expression.Type hiding (bool)
50import Squeal.PostgreSQL.PG
51import Squeal.PostgreSQL.PG
51import Squeal.PostgreSQL.Render
52import Squeal.PostgreSQL.Render
52import Squeal.PostgreSQL.Schema
53import Squeal.PostgreSQL.Schema
@@ -54,14 +55,26 @@ import Squeal.PostgreSQL.Schema
55-- >>> import Squeal.PostgreSQL
56-- >>> import Squeal.PostgreSQL
58+-- | Construct a `range`
57−-- | >>> printSQL $ range (halfGTE now)
60+-- >>> printSQL $ range tstzrange (atLeast now)
58−-- [now(), )
61+-- tstzrange(now(), NULL, '[)')
59−-- >>> printSQL $ range (0 <..<= (pi & astype numeric))
62+-- >>> printSQL $ range numrange (0 <=..<= 2*pi)
60−-- (0, (pi() :: numeric)]
63+-- numrange(0, (2 * pi()), '(]')
65+ :: TypeExpression schemas (null ('PGrange ty))
62− :: Range (Expression outer commons grp schemas params from ('NotNull ty))
66+ -> Range (Expression outer commons grp schemas params from ('NotNull ty))
63 -> Expression outer commons grp schemas params from (null ('PGrange ty))
67 -> Expression outer commons grp schemas params from (null ('PGrange ty))
64−range = UnsafeExpression . renderSQL
69+ Empty -> UnsafeExpression "empty"
70+ NonEmpty l u -> UnsafeExpression $ renderSQL ty <> parenthesized
71+ (commaSeparated [renderArg l, renderArg u, renderClopen l u])
73+ renderArg (Bound _ x) = maybe "NULL" renderSQL x
74+ clopenLeft = bool "(" "["
75+ clopenRight = bool ")" "]"
76+ renderClopen (Bound l' _) (Bound u' _) =
77+ "\'" <> clopenLeft l' <> clopenRight u' <> "\'"
66data Bound x = Bound
79data Bound x = Bound
67 { closedBound :: Bool
80 { closedBound :: Bool
@@ -83,27 +96,18 @@ data Range x
83 deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
96 deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
84type instance PG (Range x) = 'PGrange (PG x)
97type instance PG (Range x) = 'PGrange (PG x)
86−instance RenderSQL x => RenderSQL (Range x) where
89− NonEmpty l u -> commaSeparated [renderLower l, renderUpper u]
91− renderLower (Bound isclosed x) =
92− bool "(" "[" isclosed <> maybe "" renderSQL x
93− renderUpper (Bound isclosed x) =
94− maybe "" renderSQL x <> bool ")" "]" isclosed
96(<=..<=), (<..<), (<=..<), (<..<=) :: x -> x -> Range x
99(<=..<=), (<..<), (<=..<), (<..<=) :: x -> x -> Range x
100+infix 4 <=..<=, <..<, <=..<, <..<=
97x <=..<= y = NonEmpty (closed (Just x)) (closed (Just y))
101x <=..<= y = NonEmpty (closed (Just x)) (closed (Just y))
98x <..< y = NonEmpty (open (Just x)) (open (Just y))
102x <..< y = NonEmpty (open (Just x)) (open (Just y))
99x <=..< y = NonEmpty (closed (Just x)) (open (Just y))
103x <=..< y = NonEmpty (closed (Just x)) (open (Just y))
100x <..<= y = NonEmpty (open (Just x)) (closed (Just y))
104x <..<= y = NonEmpty (open (Just x)) (closed (Just y))
102−halfGT, halfGTE, halfLT, halfLTE :: x -> Range x
106+greaterThan, atLeast, lessThan, atMost :: x -> Range x
103−halfGT x = NonEmpty (open (Just x)) (open Nothing)
107+greaterThan x = NonEmpty (open (Just x)) (open Nothing)
104−halfGTE x = NonEmpty (closed (Just x)) (open Nothing)
108+atLeast x = NonEmpty (closed (Just x)) (open Nothing)
105−halfLT x = NonEmpty (open Nothing) (open (Just x))
109+lessThan x = NonEmpty (open Nothing) (open (Just x))
106−halfLTE x = NonEmpty (open Nothing) (closed (Just x))
110+atMost x = NonEmpty (open Nothing) (closed (Just x))
108singleton :: x -> Range x
112singleton :: x -> Range x
109singleton x = x <=..<= x
113singleton x = x <=..<= x