@@ -1,14 +1,13 @@
11{-|
22Module: Squeal.PostgreSQL.Expression
33Description: Squeal expressions
4−Copyright: (c) Eitan Chatav, 2017
4+Copyright: (c) Eitan Chatav, 2019
55Maintainer: eitan@morphism.tech
66Stability: experimental
77
88Squeal expressions are the atoms used to build statements.
99-}
1010
11−{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
1211{-# LANGUAGE
1312 AllowAmbiguousTypes
1413 , ConstraintKinds
@@ -34,339 +33,214 @@ Squeal expressions are the atoms used to build statements.
3433module Squeal.PostgreSQL.Expression
3534 ( -- * Expression
3635 Expression (..)
36+ , Expr
37+ , type (-->)
38+ , FunctionDB
39+ , unsafeFunction
40+ , function
41+ , unsafeLeftOp
42+ , leftOp
43+ , unsafeRightOp
44+ , rightOp
3745 , Operator
38− , HasParameter (parameter)
39− , param
40− -- ** Null
41− , null_
42− , notNull
43− , coalesce
44− , fromNull
45− , isNull
46− , isNotNull
47− , matchNull
48− , nullIf
49− -- ** Collections
50− , array
51− , cardinality
52− , index
53− , row
54− , field
55− -- ** Functions
46+ , OperatorDB
5647 , unsafeBinaryOp
57− , unsafeUnaryOp
58− , unsafeFunction
59− , unsafeFunction2
60− , unsafeVariadicFunction
61− , atan2_
62− , cast
63− , quot_
64− , rem_
65− , trunc
66− , round_
67− , ceiling_
68− , greatest
69− , least
70− -- ** Conditions
71− , true
72− , false
73− , not_
74− , (.&&)
75− , (.||)
76− , Condition
77− , caseWhenThenElse
78− , ifThenElse
79− , (.==)
80− , (./=)
81− , (.>=)
82− , (.<)
83− , (.<=)
84− , (.>)
85− , between
86− , notBetween
87− , betweenSymmetric
88− , notBetweenSymmetric
89− , isDistinctFrom
90− , isNotDistinctFrom
91− , isTrue
92− , isNotTrue
93− , isFalse
94− , isNotFalse
95− , isUnknown
96− , isNotUnknown
97− -- ** Time
98− , currentDate
99− , currentTime
100− , currentTimestamp
101− , localTime
102− , localTimestamp
103− , TimeOp (..)
104− , makeDate
105− , makeTime
106− , makeTimestamp
107− , makeTimestamptz
108− -- ** Text
109− , lower
110− , upper
111− , charLength
112− , like
113− , ilike
114− -- ** Json
115− -- *** Json and Jsonb operators
116− , (.->)
117− , (.->>)
118− , (.#>)
119− , (.#>>)
120− -- *** Jsonb operators
121− , (.@>)
122− , (.<@)
123− , (.?)
124− , (.?|)
125− , (.?&)
126− , (.-.)
127− , (#-.)
128− -- *** Functions
129− , jsonLit
130− , jsonbLit
131− , toJson
132− , toJsonb
133− , arrayToJson
134− , rowToJson
135− , jsonBuildArray
136− , jsonbBuildArray
137− , jsonBuildObject
138− , jsonbBuildObject
139− , jsonObject
140− , jsonbObject
141− , jsonZipObject
142− , jsonbZipObject
143− , jsonArrayLength
144− , jsonbArrayLength
145− , jsonExtractPath
146− , jsonbExtractPath
147− , jsonExtractPathAsText
148− , jsonbExtractPathAsText
149− , jsonTypeof
150− , jsonbTypeof
151− , jsonStripNulls
152− , jsonbStripNulls
153− , jsonbSet
154− , jsonbInsert
155− , jsonbPretty
156− -- ** Text Search
157− , (@@)
158− , (.&)
159− , (.|)
160− , (.!)
161− , (<->)
162− -- ** Aggregation
163− , Aggregate (..)
164− , Distinction (..)
165− , PGAvg
166− -- * Window Functions
167− , WindowDefinition (..)
168− , partitionBy
169− , WindowFunction (..)
170− , rank
171− , rowNumber
172− , denseRank
173− , percentRank
174− , cumeDist
175− , ntile
176− , lag
177− , lead
178− , firstValue
179− , lastValue
180− , nthValue
181− -- * Sorting
182− , SortExpression (..)
183− , OrderBy (..)
184− -- * Types
185− , TypeExpression (..)
186− , PGTyped (..)
187− , typedef
188− , typetable
189− , typeview
190− , bool
191− , int2
192− , smallint
193− , int4
194− , int
195− , integer
196− , int8
197− , bigint
198− , numeric
199− , float4
200− , real
201− , float8
202− , doublePrecision
203− , money
204− , text
205− , char
206− , character
207− , varchar
208− , characterVarying
209− , bytea
210− , timestamp
211− , timestampWithTimeZone
212− , date
213− , time
214− , timeWithTimeZone
215− , interval
216− , uuid
217− , inet
218− , json
219− , jsonb
220− , vararray
221− , fixarray
222− , tsvector
223− , tsquery
224− , arrayToTSvector
225− , tsvectorLength
226− , numnode
227− , plainToTSquery
228− , phraseToTSquery
229− , websearchToTSquery
230− , queryTree
231− , toTSquery
232− , toTSvector
48+ , binaryOp
49+ , FunctionVar
50+ , unsafeFunctionVar
51+ , type (--->)
52+ , FunctionNDB
53+ , unsafeFunctionN
54+ , functionN
55+ , PGSubset (..)
56+ , PGIntersect (..)
23357 -- * Re-export
23458 , (&)
235− , NP (..)
236− , (:*:) (..)
23759 , K (..)
60+ , unK
23861 ) where
23962
24063import Control.Category
24164import Control.DeepSeq
24265import Data.ByteString (ByteString)
243−import Data.ByteString.Lazy (toStrict)
24466import Data.Function ((&))
24567import Data.Semigroup hiding (All)
246−import qualified Data.Aeson as JSON
24768import Data.String
248−import Data.Word
24969import Generics.SOP hiding (All, from)
250−import GHC.Generics ((:*:) (..))
25170import GHC.OverloadedLabels
25271import GHC.TypeLits
25372import Numeric
25473import Prelude hiding (id, (.))
25574
256−import qualified Data.ByteString as ByteString
25775import qualified GHC.Generics as GHC
258−import qualified Generics.SOP as SOP
25976
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
26079import Squeal.PostgreSQL.Render
26180import Squeal.PostgreSQL.Schema
26281
82+-- $setup
83+-- >>> import Squeal.PostgreSQL
84+
26385{-----------------------------------------
26486column expressions
26587-----------------------------------------}
26688
26789{- | `Expression`s are used in a variety of contexts,
268−such as in the target list of the `Squeal.PostgreSQL.Query.select` command,
90+such as in the target `Squeal.PostgreSQL.Query.List` of the
91+`Squeal.PostgreSQL.Query.select` command,
26992as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
27093`Squeal.PostgreSQL.Manipulation.update`,
271−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
27295
27396The expression syntax allows the calculation of
27497values from primitive expression using arithmetic, logical,
27598and other operations.
99+
100+The type parameters of `Expression` are
101+
102+* @outer :: @ `FromType`, the @from@ clauses of any outer queries in which
103+ the `Expression` is a correlated subquery expression;
104+* @commons :: @ `FromType`, the `Squeal.PostgreSQL.Query.CommonTableExpression`s
105+ that are in scope for the `Expression`;
106+* @grp :: @ `Grouping`, the `Grouping` of the @from@ clause which may limit
107+ which columns may be referenced by alias;
108+* @schemas :: @ `SchemasType`, the schemas of your database that are in
109+ scope for the `Expression`;
110+* @from :: @ `FromType`, the @from@ clause which the `Expression` may use
111+ to reference columns by alias;
112+* @ty :: @ `NullityType`, the type of the `Expression`.
276113-}
277114newtype Expression
278115 (outer :: FromType)
279− (grp :: Grouping)
280116 (commons :: FromType)
117+ (grp :: Grouping)
281118 (schemas :: SchemasType)
282119 (params :: [NullityType])
283120 (from :: FromType)
284121 (ty :: NullityType)
285122 = UnsafeExpression { renderExpression :: ByteString }
286123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
287−instance RenderSQL (Expression outer grp commons schemas params from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
288125 renderSQL = renderExpression
289126
127+-- | An `Expr` is a closed `Expression`.
128+-- It is a F@RankNType@ but don't be scared.
129+-- Think of it as an expression which sees no
130+-- namespaces, so you can't use parameters
131+-- or alias references. It can be used as
132+-- a simple piece of more complex `Expression`s.
133+type Expr x
134+ = forall outer commons grp schemas params from
135+ . Expression outer commons grp schemas params from x
136+ -- ^ cannot reference aliases
137+
138+-- | A @RankNType@ for binary operators.
290139type Operator x1 x2 y
291− = forall outer grp commons schemas params from
292− . Expression outer grp commons schemas params from x1
293− -> Expression outer grp commons schemas params from x2
294− -> Expression outer grp commons schemas params from y
295−
296−type (:-->) x y
297− = forall outer grp commons schemas params from
298− . Expression outer grp commons schemas params from x
299− -> Expression outer grp commons schemas params from y
300−
301−{- | A `HasParameter` constraint is used to indicate a value that is
302−supplied externally to a SQL statement.
303−`Squeal.PostgreSQL.PQ.manipulateParams`,
304−`Squeal.PostgreSQL.PQ.queryParams` and
305−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
306−separately from the SQL command string, in which case `param`s are used to
307−refer to the out-of-line data values.
308−-}
309−class KnownNat n => HasParameter
310− (n :: Nat)
311− (params :: [NullityType])
312− (ty :: NullityType)
313− | n params -> ty where
314− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
315− --
316− -- >>> let expr = parameter @1 int4 :: Expression outer grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
317− -- >>> printSQL expr
318− -- ($1 :: int4)
319− parameter
320− :: TypeExpression schemas ty
321− -> Expression outer grp commons schemas params from ty
322− parameter ty = UnsafeExpression $ parenthesized $
323− "$" <> renderNat @n <+> "::"
324− <+> renderSQL ty
325−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
326−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
327− => HasParameter n (ty' : params) ty
328−
329−-- | `param` takes a `Nat` using type application and for basic types,
330−-- infers a `TypeExpression`.
331−--
332−-- >>> let expr = param @1 :: Expression outer grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
333−-- >>> printSQL expr
334−-- ($1 :: int4)
335−param
336− :: forall n outer commons schemas params from grp ty
337− . (PGTyped schemas ty, HasParameter n params ty)
338− => Expression outer grp commons schemas params from ty -- ^ param
339−param = parameter @n (pgtype @schemas)
140+ = forall outer commons grp schemas params from
141+ . Expression outer commons grp schemas params from x1
142+ -- ^ left input
143+ -> Expression outer commons grp schemas params from x2
144+ -- ^ right input
145+ -> Expression outer commons grp schemas params from y
146+ -- ^ output
147+
148+type OperatorDB schemas x1 x2 y
149+ = forall outer commons grp params from
150+ . Expression outer commons grp schemas params from x1
151+ -- ^ left input
152+ -> Expression outer commons grp schemas params from x2
153+ -- ^ right input
154+ -> Expression outer commons grp schemas params from y
155+ -- ^ output
156+
157+-- | A @RankNType@ for functions with a single argument.
158+-- These could be either function calls or unary operators.
159+-- This is a subtype of the usual Haskell function type `Prelude.->`,
160+-- indeed a subcategory as it is closed under the usual
161+-- `Prelude..` and `Prelude.id`.
162+type (-->) x y
163+ = forall outer commons grp schemas params from
164+ . Expression outer commons grp schemas params from x
165+ -- ^ input
166+ -> Expression outer commons grp schemas params from y
167+ -- ^ output
168+
169+type FunctionDB schemas x y
170+ = forall outer commons grp params from
171+ . Expression outer commons grp schemas params from x
172+ -- ^ input
173+ -> Expression outer commons grp schemas params from y
174+ -- ^ output
175+
176+{- | A @RankNType@ for functions with a fixed-length list of heterogeneous arguments.
177+Use the `*:` operator to end your argument lists, like so.
178+
179+>>> printSQL (unsafeFunctionN "fun" (true :* false :* localTime *: true))
180+fun(TRUE, FALSE, LOCALTIME, TRUE)
181+-}
182+type (--->) xs y
183+ = forall outer commons grp schemas params from
184+ . NP (Expression outer commons grp schemas params from) xs
185+ -- ^ inputs
186+ -> Expression outer commons grp schemas params from y
187+ -- ^ output
188+
189+type FunctionNDB schemas xs y
190+ = forall outer commons grp params from
191+ . NP (Expression outer commons grp schemas params from) xs
192+ -- ^ inputs
193+ -> Expression outer commons grp schemas params from y
194+ -- ^ output
195+
196+{- | A @RankNType@ for functions with a variable-length list of
197+homogeneous arguments and at least 1 more argument.
198+-}
199+type FunctionVar x0 x1 y
200+ = forall outer commons grp schemas params from
201+ . [Expression outer commons grp schemas params from x0]
202+ -- ^ inputs
203+ -> Expression outer commons grp schemas params from x1
204+ -- ^ must have at least 1 input
205+ -> Expression outer commons grp schemas params from y
206+ -- ^ output
207+
208+{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
209+greatest(TRUE, NULL, FALSE)
210+-}
211+unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
212+unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
213+ (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
340214
341215instance (HasUnique tab (Join outer from) row, Has col row ty)
342− => IsLabel col (Expression outer 'Ungrouped commons schemas params from ty) where
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
343217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
344218instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
345− => IsLabel col (NP (Expression outer 'Ungrouped commons schemas params from) tys) where
219+ => IsLabel col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
346220 fromLabel = fromLabel @col :* Nil
347221instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
348222 => IsLabel col
349− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
350224 fromLabel = fromLabel @col `As` Alias
351225instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
352226 => IsLabel col
353− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
354228 fromLabel = fromLabel @col :* Nil
355229
356230instance (Has tab (Join outer from) row, Has col row ty)
357− => IsQualified tab col (Expression outer 'Ungrouped commons schemas params from ty) where
231+ => IsQualified tab col (Expression outer commons 'Ungrouped schemas params from ty) where
358232 tab ! col = UnsafeExpression $
359233 renderSQL tab <> "." <> renderSQL col
360234instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
361− => IsQualified tab col (NP (Expression outer 'Ungrouped commons schemas params from) tys) where
235+ => IsQualified tab col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
362236 tab ! col = tab ! col :* Nil
363237instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
364238 => IsQualified tab col
365− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
366240 tab ! col = tab ! col `As` col
367241instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
368242 => IsQualified tab col
369− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
370244 tab ! col = tab ! col :* Nil
371245
372246instance
@@ -374,7 +248,7 @@ instance
374248 , Has col row ty
375249 , GroupedBy tab col bys
376250 ) => IsLabel col
377− (Expression outer ('Grouped bys) commons schemas params from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
378252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
379253instance
380254 ( HasUnique tab (Join outer from) row
@@ -382,7 +256,7 @@ instance
382256 , GroupedBy tab col bys
383257 , tys ~ '[ty]
384258 ) => IsLabel col
385− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
386260 fromLabel = fromLabel @col :* Nil
387261instance
388262 ( HasUnique tab (Join outer from) row
@@ -390,7 +264,7 @@ instance
390264 , GroupedBy tab col bys
391265 , column ~ (col ::: ty)
392266 ) => IsLabel col
393− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
394268 fromLabel = fromLabel @col `As` Alias
395269instance
396270 ( HasUnique tab (Join outer from) row
@@ -398,7 +272,7 @@ instance
398272 , GroupedBy tab col bys
399273 , columns ~ '[col ::: ty]
400274 ) => IsLabel col
401− (NP (Aliased (Expression outer ('Grouped bys) commons schemas params from)) columns) where
275+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
402276 fromLabel = fromLabel @col :* Nil
403277
404278instance
@@ -406,7 +280,7 @@ instance
406280 , Has col row ty
407281 , GroupedBy tab col bys
408282 ) => IsQualified tab col
409− (Expression outer ('Grouped bys) commons schemas params from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
410284 tab ! col = UnsafeExpression $
411285 renderSQL tab <> "." <> renderSQL col
412286instance
@@ -415,7 +289,7 @@ instance
415289 , GroupedBy tab col bys
416290 , tys ~ '[ty]
417291 ) => IsQualified tab col
418− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
419293 tab ! col = tab ! col :* Nil
420294instance
421295 ( Has tab (Join outer from) row
@@ -423,7 +297,7 @@ instance
423297 , GroupedBy tab col bys
424298 , column ~ (col ::: ty)
425299 ) => IsQualified tab col
426− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
427301 tab ! col = tab ! col `As` col
428302instance
429303 ( Has tab (Join outer from) row
@@ -431,241 +305,78 @@ instance
431305 , GroupedBy tab col bys
432306 , columns ~ '[col ::: ty]
433307 ) => IsQualified tab col
434− (NP (Aliased (Expression outer ('Grouped bys) commons schemas params from)) columns) where
308+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
435309 tab ! col = tab ! col :* Nil
436310
437−-- | analagous to `Nothing`
438−--
439−-- >>> printSQL null_
440−-- NULL
441−null_ :: Expression outer grp commons schemas params from ('Null ty)
442−null_ = UnsafeExpression "NULL"
443−
444−-- | analagous to `Just`
445−--
446−-- >>> printSQL $ notNull true
447−-- TRUE
448−notNull
449− :: Expression outer grp commons schemas params from ('NotNull ty)
450− -> Expression outer grp commons schemas params from ('Null ty)
451−notNull = UnsafeExpression . renderSQL
452−
453−-- | return the leftmost value which is not NULL
454−--
455−-- >>> printSQL $ coalesce [null_, true] false
456−-- COALESCE(NULL, TRUE, FALSE)
457−coalesce
458− :: [Expression outer grp commons schemas params from ('Null ty)]
459− -- ^ @NULL@s may be present
460− -> Expression outer grp commons schemas params from ('NotNull ty)
461− -- ^ @NULL@ is absent
462− -> Expression outer grp commons schemas params from ('NotNull ty)
463−coalesce nullxs notNullx = UnsafeExpression $
464− "COALESCE" <> parenthesized (commaSeparated
465− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
466−
467−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
468−--
469−-- >>> printSQL $ fromNull true null_
470−-- COALESCE(NULL, TRUE)
471−fromNull
472− :: Expression outer grp commons schemas params from ('NotNull ty)
473− -- ^ what to convert @NULL@ to
474− -> Expression outer grp commons schemas params from ('Null ty)
475− -> Expression outer grp commons schemas params from ('NotNull ty)
476−fromNull notNullx nullx = coalesce [nullx] notNullx
477−
478−-- | >>> printSQL $ null_ & isNull
479−-- NULL IS NULL
480−isNull
481− :: Expression outer grp commons schemas params from ('Null ty)
482− -- ^ possibly @NULL@
483− -> Condition outer grp commons schemas params from
484−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
485−
486−-- | >>> printSQL $ null_ & isNotNull
487−-- NULL IS NOT NULL
488−isNotNull
489− :: Expression outer grp commons schemas params from ('Null ty)
490− -- ^ possibly @NULL@
491− -> Condition outer grp commons schemas params from
492−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
493−
494−-- | analagous to `maybe` using @IS NULL@
495−--
496−-- >>> printSQL $ matchNull true not_ null_
497−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
498−matchNull
499− :: Expression outer grp commons schemas params from (nullty)
500− -- ^ what to convert @NULL@ to
501− -> ( Expression outer grp commons schemas params from ('NotNull ty)
502− -> Expression outer grp commons schemas params from (nullty) )
503− -- ^ function to perform when @NULL@ is absent
504− -> Expression outer grp commons schemas params from ('Null ty)
505− -> Expression outer grp commons schemas params from (nullty)
506−matchNull y f x = ifThenElse (isNull x) y
507− (f (UnsafeExpression (renderSQL x)))
508−
509−{-| right inverse to `fromNull`, if its arguments are equal then
510−`nullIf` gives @NULL@.
511−
512−>>> :set -XTypeApplications -XDataKinds
513−>>> let expr = nullIf false (param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
514−>>> printSQL expr
515−NULL IF (FALSE, ($1 :: bool))
516−-}
517−nullIf
518− :: Expression outer grp commons schemas params from ('NotNull ty)
519− -- ^ @NULL@ is absent
520− -> Expression outer grp commons schemas params from ('NotNull ty)
521− -- ^ @NULL@ is absent
522− -> Expression outer grp commons schemas params from ('Null ty)
523−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
524− (renderSQL x <> ", " <> renderSQL y)
525−
526−-- | >>> printSQL $ array [null_, false, true]
527−-- ARRAY[NULL, FALSE, TRUE]
528−array
529− :: [Expression outer grp commons schemas params from ty]
530− -- ^ array elements
531− -> Expression outer grp commons schemas params from (nullity ('PGvararray ty))
532−array xs = UnsafeExpression $
533− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
534−
535−-- | >>> printSQL $ cardinality (array [null_, false, true])
536−-- cardinality(ARRAY[NULL, FALSE, TRUE])
537−cardinality :: nullity ('PGvararray ty) :--> nullity 'PGint8
538−cardinality = unsafeFunction "cardinality"
539−
540−-- | >>> printSQL $ array [null_, false, true] & index 2
541−-- (ARRAY[NULL, FALSE, TRUE])[2]
542−index
543− :: Word64 -- ^ index
544− -> nullity ('PGvararray ty) -- ^ array
545− :--> NullifyType ty
546−index n expr = UnsafeExpression $
547− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
548−
549311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
550− (Expression outer grp commons schemas params from (nullity ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
551313 label = UnsafeExpression $ renderSQL (PGlabel @label)
552314
553−-- | A row constructor is an expression that builds a row value
554−-- (also called a composite value) using values for its member fields.
555−--
556−-- >>> :{
557−-- type Complex = 'PGcomposite
558−-- '[ "real" ::: 'NotNull 'PGfloat8
559−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
560−-- :}
561−--
562−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
563−-- >>> printSQL i
564−-- ROW(0, 1)
565−row
566− :: SListI row
567− => NP (Aliased (Expression outer grp commons schemas params from)) row
568− -- ^ zero or more expressions for the row field values
569− -> Expression outer grp commons schemas params from (nullity ('PGcomposite row))
570−row exprs = UnsafeExpression $ "ROW" <> parenthesized
571− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
572−
573−-- | >>> :{
574−-- type Complex = 'PGcomposite
575−-- '[ "real" ::: 'NotNull 'PGfloat8
576−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
577−-- type Schema = '["complex" ::: 'Typedef Complex]
578−-- :}
579−--
580−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
581−-- >>> printSQL $ i & field #complex #imaginary
582−-- (ROW(0, 1)::"complex")."imaginary"
583−field
584− :: ( Has sch schemas schema
585− , Has tydef schema ('Typedef ('PGcomposite row))
586− , Has field row ty)
587− => QualifiedAlias sch tydef -- ^ row type
588− -> Alias field -- ^ field name
589− -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
590− -> Expression outer grp commons schemas params from ty
591−field td fld expr = UnsafeExpression $
592− parenthesized (renderSQL expr <> "::" <> renderSQL td)
593− <> "." <> renderSQL fld
594−
595−instance Semigroup
596− (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
597− (<>) = unsafeBinaryOp "||"
598−
599−instance Monoid
600− (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
601− mempty = array []
602− mappend = (<>)
603−
604−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
605−-- >>> printSQL expr
606−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
607−greatest
608− :: Expression outer grp commons schemas params from (nullty)
609− -- ^ needs at least 1 argument
610− -> [Expression outer grp commons schemas params from (nullty)]
611− -- ^ or more
612− -> Expression outer grp commons schemas params from (nullty)
613−greatest x xs = UnsafeExpression $ "GREATEST("
614− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
615−
616−-- | >>> printSQL $ least currentTimestamp [null_]
617−-- LEAST(CURRENT_TIMESTAMP, NULL)
618−least
619− :: Expression outer grp commons schemas params from (nullty)
620− -- ^ needs at least 1 argument
621− -> [Expression outer grp commons schemas params from (nullty)]
622− -- ^ or more
623− -> Expression outer grp commons schemas params from (nullty)
624−least x xs = UnsafeExpression $ "LEAST("
625− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
626−
627315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
628316-- (TRUE OR FALSE)
629−unsafeBinaryOp
630− :: ByteString
631− -- ^ operator
632− -> Operator ty0 ty1 ty2
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
633318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
634319 renderSQL x <+> op <+> renderSQL y
635320
636−-- | >>> printSQL $ unsafeUnaryOp "NOT" true
321+binaryOp
322+ :: forall op sch schemas schema x y z.
323+ ( Has sch schemas schema
324+ , Has op schema ('Operator ('BinaryOp x y z)) )
325+ => OperatorDB schemas x y z
326+binaryOp = unsafeBinaryOp $ renderSymbol @op
327+
328+-- | >>> printSQL $ unsafeLeftOp "NOT" true
637329-- (NOT TRUE)
638−unsafeUnaryOp :: ByteString {- ^ operator -} -> x :--> y
639−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
640− op <+> renderSQL x
330+unsafeLeftOp :: ByteString -> x --> y
331+unsafeLeftOp op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
332+
333+leftOp
334+ :: forall op sch schemas schema x y.
335+ ( Has sch schemas schema
336+ , Has op schema ('Operator ('LeftOp x y)) )
337+ => FunctionDB schemas x y
338+leftOp = unsafeLeftOp $ renderSymbol @op
339+
340+-- | >>> printSQL $ true & unsafeRightOp "IS NOT TRUE"
341+-- (TRUE IS NOT TRUE)
342+unsafeRightOp :: ByteString -> x --> y
343+unsafeRightOp op x = UnsafeExpression $ parenthesized $ renderSQL x <+> op
344+
345+rightOp
346+ :: forall op sch schemas schema x y.
347+ ( Has sch schemas schema
348+ , Has op schema ('Operator ('RightOp x y)) )
349+ => FunctionDB schemas x y
350+rightOp = unsafeRightOp $ renderSymbol @op
641351
642352-- | >>> printSQL $ unsafeFunction "f" true
643353-- f(TRUE)
644−unsafeFunction :: ByteString {- ^ function -} -> x :--> y
354+unsafeFunction :: ByteString -> x --> y
645355unsafeFunction fun x = UnsafeExpression $
646356 fun <> parenthesized (renderSQL x)
647357
648−unsafeFunction2
649− :: ByteString
650− -- ^ function
651− -> Expression outer grp commons schemas params from ty1
652− -> Expression outer grp commons schemas params from ty2
653− -> Expression outer grp commons schemas params from ty
654−unsafeFunction2 fun x1 x2 = UnsafeExpression $
655− fun <> parenthesized (commaSeparated [renderSQL x1, renderSQL x2])
358+function
359+ :: (Has sch schemas schema, Has fun schema ('Function ('[x] :=> 'Returns y)))
360+ => QualifiedAlias sch fun
361+ -> FunctionDB schemas x y
362+function = unsafeFunction . renderSQL
363+
364+-- | >>> printSQL $ unsafeFunctionN "f" (currentTime :* localTimestamp :* false *: literal 'a')
365+-- f(CURRENT_TIME, LOCALTIMESTAMP, FALSE, E'a')
366+unsafeFunctionN :: SListI xs => ByteString -> xs ---> y
367+unsafeFunctionN fun xs = UnsafeExpression $
368+ fun <> parenthesized (renderCommaSeparated renderSQL xs)
656369
657−-- | Helper for defining variadic functions.
658−unsafeVariadicFunction
659− :: SListI elems
660− => ByteString
661− -- ^ function
662− -> NP (Expression outer grp commons schemas params from) elems
663− -> Expression outer grp commons schemas params from ret
664−unsafeVariadicFunction fun x = UnsafeExpression $
665− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderSQL) x)))
370+functionN
371+ :: ( Has sch schemas schema
372+ , Has fun schema ('Function (xs :=> 'Returns y))
373+ , SListI xs )
374+ => QualifiedAlias sch fun
375+ -> FunctionNDB schemas xs y
376+functionN = unsafeFunctionN . renderSQL
666377
667378instance ty `In` PGNum
668− => Num (Expression outer grp commons schemas params from (nullity ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
669380 (+) = unsafeBinaryOp "+"
670381 (-) = unsafeBinaryOp "-"
671382 (*) = unsafeBinaryOp "*"
@@ -677,7 +388,7 @@ instance ty `In` PGNum
677388 . show
678389
679390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
680− (Expression outer grp commons schemas params from (nullity ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
681392 (/) = unsafeBinaryOp "/"
682393 fromRational
683394 = UnsafeExpression
@@ -687,7 +398,7 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
687398 . fromRat @Double
688399
689400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
690− (Expression outer grp commons schemas params from (nullity ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
691402 pi = UnsafeExpression "pi()"
692403 exp = unsafeFunction "exp"
693404 log = unsafeFunction "ln"
@@ -708,1849 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
708419 acosh x = log (x + sqrt (x*x - 1))
709420 atanh x = log ((1 + x) / (1 - x)) / 2
710421
711−-- | >>> :{
712−-- let
713−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
714−-- expression = atan2_ pi 2
715−-- in printSQL expression
716−-- :}
717−-- atan2(pi(), 2)
718−atan2_
719− :: float `In` PGFloating
720− => Expression outer grp commons schemas params from (nullity float)
721− -- ^ numerator
722− -> Expression outer grp commons schemas params from (nullity float)
723− -- ^ denominator
724− -> Expression outer grp commons schemas params from (nullity float)
725−atan2_ y x = UnsafeExpression $
726− "atan2(" <> renderSQL y <> ", " <> renderSQL x <> ")"
727−
728−-- When a `cast` is applied to an `Expression` of a known type, it
729−-- represents a run-time type conversion. The cast will succeed only if a
730−-- suitable type conversion operation has been defined.
731−--
732−-- | >>> printSQL $ true & cast int4
733−-- (TRUE :: int4)
734−cast
735− :: TypeExpression schemas ty1
736− -- ^ type to cast as
737− -> Expression outer grp commons schemas params from ty0
738− -- ^ value to convert
739− -> Expression outer grp commons schemas params from ty1
740−cast ty x = UnsafeExpression $ parenthesized $
741− renderSQL x <+> "::" <+> renderSQL ty
742−
743−-- | integer division, truncates the result
744−--
745−-- >>> :{
746−-- let
747−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
748−-- expression = 5 `quot_` 2
749−-- in printSQL expression
750−-- :}
751−-- (5 / 2)
752−quot_
753− :: int `In` PGIntegral
754− => Operator (nullity int) (nullity int) (nullity int)
755−quot_ = unsafeBinaryOp "/"
756−
757−-- | remainder upon integer division
758−--
759−-- >>> :{
760−-- let
761−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
762−-- expression = 5 `rem_` 2
763−-- in printSQL expression
764−-- :}
765−-- (5 % 2)
766−rem_
767− :: int `In` PGIntegral
768− => Operator (nullity int) (nullity int) (nullity int)
769−rem_ = unsafeBinaryOp "%"
770−
771−-- | >>> :{
772−-- let
773−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
774−-- expression = trunc pi
775−-- in printSQL expression
776−-- :}
777−-- trunc(pi())
778−trunc :: frac `In` PGFloating => nullity frac :--> nullity frac
779−trunc = unsafeFunction "trunc"
780−
781−-- | >>> :{
782−-- let
783−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
784−-- expression = round_ pi
785−-- in printSQL expression
786−-- :}
787−-- round(pi())
788−round_ :: frac `In` PGFloating => nullity frac :--> nullity frac
789−round_ = unsafeFunction "round"
790−
791−-- | >>> :{
792−-- let
793−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
794−-- expression = ceiling_ pi
795−-- in printSQL expression
796−-- :}
797−-- ceiling(pi())
798−ceiling_ :: frac `In` PGFloating => nullity frac :--> nullity frac
799−ceiling_ = unsafeFunction "ceiling"
800−
801−-- | A `Condition` is an `Expression`, which can evaluate
802−-- to `true`, `false` or `null_`. This is because SQL uses
803−-- a three valued logic.
804−type Condition outer grp commons schemas params from =
805− Expression outer grp commons schemas params from ('Null 'PGbool)
806−
807−-- | >>> printSQL true
808−-- TRUE
809−true :: Expression outer grp commons schemas params from (nullity 'PGbool)
810−true = UnsafeExpression "TRUE"
811−
812−-- | >>> printSQL false
813−-- FALSE
814−false :: Expression outer grp commons schemas params from (nullity 'PGbool)
815−false = UnsafeExpression "FALSE"
816−
817−-- | >>> printSQL $ not_ true
818−-- (NOT TRUE)
819−not_ :: nullity 'PGbool :--> nullity 'PGbool
820−not_ = unsafeUnaryOp "NOT"
821−
822−-- | >>> printSQL $ true .&& false
823−-- (TRUE AND FALSE)
824−(.&&) :: Operator (nullity 'PGbool) (nullity 'PGbool) (nullity 'PGbool)
825−infixr 3 .&&
826−(.&&) = unsafeBinaryOp "AND"
827−
828−-- | >>> printSQL $ true .|| false
829−-- (TRUE OR FALSE)
830−(.||) :: Operator (nullity 'PGbool) (nullity 'PGbool) (nullity 'PGbool)
831−infixr 2 .||
832−(.||) = unsafeBinaryOp "OR"
833−
834−-- | >>> :{
835−-- let
836−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
837−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
838−-- in printSQL expression
839−-- :}
840−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
841−caseWhenThenElse
842− :: [ ( Condition outer grp commons schemas params from
843− , Expression outer grp commons schemas params from ty
844− ) ]
845− -- ^ whens and thens
846− -> Expression outer grp commons schemas params from ty
847− -- ^ else
848− -> Expression outer grp commons schemas params from ty
849−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
850− [ "CASE"
851− , mconcat
852− [ mconcat
853− [ " WHEN ", renderSQL when_
854− , " THEN ", renderSQL then_
855− ]
856− | (when_,then_) <- whenThens
857− ]
858− , " ELSE ", renderSQL else_
859− , " END"
860− ]
861−
862−-- | >>> :{
863−-- let
864−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
865−-- expression = ifThenElse true 1 0
866−-- in printSQL expression
867−-- :}
868−-- CASE WHEN TRUE THEN 1 ELSE 0 END
869−ifThenElse
870− :: Condition outer grp commons schemas params from
871− -> Expression outer grp commons schemas params from ty -- ^ then
872− -> Expression outer grp commons schemas params from ty -- ^ else
873− -> Expression outer grp commons schemas params from ty
874−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
875−
876−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
877−-- will produce @NULL@s if one of their arguments is @NULL@.
878−--
879−-- >>> printSQL $ true .== null_
880−-- (TRUE = NULL)
881−(.==) :: Operator (nullity0 ty) (nullity1 ty) ('Null 'PGbool)
882−(.==) = unsafeBinaryOp "="
883−infix 4 .==
884−
885−-- | >>> printSQL $ true ./= null_
886−-- (TRUE <> NULL)
887−(./=) :: Operator (nullity0 ty) (nullity1 ty) ('Null 'PGbool)
888−(./=) = unsafeBinaryOp "<>"
889−infix 4 ./=
890−
891−-- | >>> printSQL $ true .>= null_
892−-- (TRUE >= NULL)
893−(.>=) :: Operator (nullity0 ty) (nullity1 ty) ('Null 'PGbool)
894−(.>=) = unsafeBinaryOp ">="
895−infix 4 .>=
896−
897−-- | >>> printSQL $ true .< null_
898−-- (TRUE < NULL)
899−(.<) :: Operator (nullity0 ty) (nullity1 ty) ('Null 'PGbool)
900−(.<) = unsafeBinaryOp "<"
901−infix 4 .<
902−
903−-- | >>> printSQL $ true .<= null_
904−-- (TRUE <= NULL)
905−(.<=) :: Operator (nullity0 ty) (nullity1 ty) ('Null 'PGbool)
906−(.<=) = unsafeBinaryOp "<="
907−infix 4 .<=
908−
909−-- | >>> printSQL $ true .> null_
910−-- (TRUE > NULL)
911−(.>) :: Operator (nullity0 ty) (nullity1 ty) ('Null 'PGbool)
912−(.>) = unsafeBinaryOp ">"
913−infix 4 .>
914−
915−{- | between
916−>>> printSQL $ true `between` (null_, false)
917−TRUE BETWEEN NULL AND FALSE
918−-}
919−between
920− :: Expression outer grp commons schemas params from (nullity ty)
921− -> ( Expression outer grp commons schemas params from (nullity ty)
922− , Expression outer grp commons schemas params from (nullity ty) ) -- ^ bounds
923− -> Condition outer grp commons schemas params from
924−between a (x,y) = UnsafeExpression $ renderSQL a <+> "BETWEEN"
925− <+> renderSQL x <+> "AND" <+> renderSQL y
926−
927−{- | not between
928−>>> printSQL $ true `notBetween` (null_, false)
929−TRUE NOT BETWEEN NULL AND FALSE
930−-}
931−notBetween
932− :: Expression outer grp commons schemas params from (nullity ty)
933− -> ( Expression outer grp commons schemas params from (nullity ty)
934− , Expression outer grp commons schemas params from (nullity ty) ) -- ^ bounds
935− -> Condition outer grp commons schemas params from
936−notBetween a (x,y) = UnsafeExpression $ renderSQL a <+> "NOT BETWEEN"
937− <+> renderSQL x <+> "AND" <+> renderSQL y
938−
939−{- | between, after sorting the comparison values
940−>>> printSQL $ true `betweenSymmetric` (null_, false)
941−TRUE BETWEEN SYMMETRIC NULL AND FALSE
942−-}
943−betweenSymmetric
944− :: Expression outer grp commons schemas params from (nullity ty)
945− -> ( Expression outer grp commons schemas params from (nullity ty)
946− , Expression outer grp commons schemas params from (nullity ty) ) -- ^ bounds
947− -> Condition outer grp commons schemas params from
948−betweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
949− <+> "BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
950−
951−{- | not between, after sorting the comparison values
952−>>> printSQL $ true `notBetweenSymmetric` (null_, false)
953−TRUE NOT BETWEEN SYMMETRIC NULL AND FALSE
954−-}
955−notBetweenSymmetric
956− :: Expression outer grp commons schemas params from (nullity ty)
957− -> ( Expression outer grp commons schemas params from (nullity ty)
958− , Expression outer grp commons schemas params from (nullity ty) ) -- ^ bounds
959− -> Condition outer grp commons schemas params from
960−notBetweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
961− <+> "NOT BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
962−
963−{- | not equal, treating null like an ordinary value
964−>>> printSQL $ true `isDistinctFrom` null_
965−(TRUE IS DISTINCT FROM NULL)
966−-}
967−isDistinctFrom :: Operator (nullity0 ty) (nullity1 ty) ('Null 'PGbool)
968−isDistinctFrom = unsafeBinaryOp "IS DISTINCT FROM"
969−
970−{- | equal, treating null like an ordinary value
971−>>> printSQL $ true `isNotDistinctFrom` null_
972−(TRUE IS NOT DISTINCT FROM NULL)
973−-}
974−isNotDistinctFrom :: Operator (nullity0 ty) (nullity1 ty) ('Null 'PGbool)
975−isNotDistinctFrom = unsafeBinaryOp "IS NOT DISTINCT FROM"
976−
977−{- | is true
978−>>> printSQL $ true & isTrue
979−TRUE IS TRUE
980−-}
981−isTrue
982− :: Expression outer grp commons schemas params from (nullity 'PGbool)
983− -> Condition outer grp commons schemas params from
984−isTrue b = UnsafeExpression $ renderSQL b <+> "IS TRUE"
985−
986−{- | is false or unknown
987−>>> printSQL $ true & isNotTrue
988−TRUE IS NOT TRUE
989−-}
990−isNotTrue
991− :: Expression outer grp commons schemas params from (nullity 'PGbool)
992− -> Condition outer grp commons schemas params from
993−isNotTrue b = UnsafeExpression $ renderSQL b <+> "IS NOT TRUE"
994−
995−{- | is false
996−>>> printSQL $ true & isFalse
997−TRUE IS FALSE
998−-}
999−isFalse
1000− :: Expression outer grp commons schemas params from (nullity 'PGbool)
1001− -> Condition outer grp commons schemas params from
1002−isFalse b = UnsafeExpression $ renderSQL b <+> "IS FALSE"
1003−
1004−{- | is true or unknown
1005−>>> printSQL $ true & isNotFalse
1006−TRUE IS NOT FALSE
1007−-}
1008−isNotFalse
1009− :: Expression outer grp commons schemas params from (nullity 'PGbool)
1010− -> Condition outer grp commons schemas params from
1011−isNotFalse b = UnsafeExpression $ renderSQL b <+> "IS NOT FALSE"
1012−
1013−{- | is unknown
1014−>>> printSQL $ true & isUnknown
1015−TRUE IS UNKNOWN
1016−-}
1017−isUnknown
1018− :: Expression outer grp commons schemas params from (nullity 'PGbool)
1019− -> Condition outer grp commons schemas params from
1020−isUnknown b = UnsafeExpression $ renderSQL b <+> "IS UNKNOWN"
1021−
1022−{- | is true or false
1023−>>> printSQL $ true & isNotUnknown
1024−TRUE IS NOT UNKNOWN
1025−-}
1026−isNotUnknown
1027− :: Expression outer grp commons schemas params from (nullity 'PGbool)
1028− -> Condition outer grp commons schemas params from
1029−isNotUnknown b = UnsafeExpression $ renderSQL b <+> "IS NOT UNKNOWN"
1030−
1031−-- | >>> printSQL currentDate
1032−-- CURRENT_DATE
1033−currentDate
1034− :: Expression outer grp commons schemas params from (nullity 'PGdate)
1035−currentDate = UnsafeExpression "CURRENT_DATE"
1036−
1037−-- | >>> printSQL currentTime
1038−-- CURRENT_TIME
1039−currentTime
1040− :: Expression outer grp commons schemas params from (nullity 'PGtimetz)
1041−currentTime = UnsafeExpression "CURRENT_TIME"
1042−
1043−-- | >>> printSQL currentTimestamp
1044−-- CURRENT_TIMESTAMP
1045−currentTimestamp
1046− :: Expression outer grp commons schemas params from (nullity 'PGtimestamptz)
1047−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
1048−
1049−-- | >>> printSQL localTime
1050−-- LOCALTIME
1051−localTime
1052− :: Expression outer grp commons schemas params from (nullity 'PGtime)
1053−localTime = UnsafeExpression "LOCALTIME"
1054−
1055−-- | >>> printSQL localTimestamp
1056−-- LOCALTIMESTAMP
1057−localTimestamp
1058− :: Expression outer grp commons schemas params from (nullity 'PGtimestamp)
1059−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
1060−
1061−{-----------------------------------------
1062−text
1063−-----------------------------------------}
1064−
1065−escape :: Char -> String
1066−escape = \case
1067− '\NUL' -> "\\0"
1068− '\'' -> "''"
1069− '"' -> "\\\""
1070− '\b' -> "\\b"
1071− '\n' -> "\\n"
1072− '\r' -> "\\r"
1073− '\t' -> "\\t"
1074− '\\' -> "\\\\"
1075− c -> [c]
422+-- | Contained by operators
423+class PGSubset ty where
424+ (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
425+ (@>) = unsafeBinaryOp "@>"
426+ (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
427+ (<@) = unsafeBinaryOp "<@"
428+instance PGSubset 'PGjsonb
429+instance PGSubset 'PGtsquery
430+instance PGSubset ('PGvararray ty)
431+instance PGSubset ('PGrange ty)
432+
433+class PGIntersect ty where
434+ (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
435+ (@&&) = unsafeBinaryOp "&&"
436+instance PGIntersect ('PGvararray ty)
437+instance PGIntersect ('PGrange ty)
1076438
1077439instance IsString
1078− (Expression outer grp commons schemas params from (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1079441 fromString str = UnsafeExpression $
1080442 "E\'" <> fromString (escape =<< str) <> "\'"
1081443instance IsString
1082− (Expression outer grp commons schemas params from (nullity 'PGtsvector)) where
1083− fromString str = cast tsvector . UnsafeExpression $
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
1084446 "E\'" <> fromString (escape =<< str) <> "\'"
1085447instance IsString
1086− (Expression outer grp commons schemas params from (nullity 'PGtsquery)) where
1087− fromString str = cast tsquery . UnsafeExpression $
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
1088450 "E\'" <> fromString (escape =<< str) <> "\'"
1089451
1090452instance Semigroup
1091− (Expression outer grp commons schemas params from (nullity 'PGtext)) where
453+ (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
1092454 (<>) = unsafeBinaryOp "||"
1093455instance Semigroup
1094− (Expression outer grp commons schemas params from (nullity 'PGtsvector)) where
456+ (Expression outer commons grp schemas params from (null 'PGjsonb)) where
457+ (<>) = unsafeBinaryOp "||"
458+instance Semigroup
459+ (Expression outer commons grp schemas params from (null 'PGtext)) where
460+ (<>) = unsafeBinaryOp "||"
461+instance Semigroup
462+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1095463 (<>) = unsafeBinaryOp "||"
1096464
1097465instance Monoid
1098− (Expression outer grp commons schemas params from (nullity 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1099467 mempty = fromString ""
1100468 mappend = (<>)
1101469instance Monoid
1102− (Expression outer grp commons schemas params from (nullity 'PGtsvector)) where
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1103471 mempty = fromString ""
1104472 mappend = (<>)
1105−
1106−-- | >>> printSQL $ lower "ARRRGGG"
1107−-- lower(E'ARRRGGG')
1108−lower
1109− :: nullity 'PGtext
1110− -- ^ string to lower case
1111− :--> nullity 'PGtext
1112−lower = unsafeFunction "lower"
1113−
1114−-- | >>> printSQL $ upper "eeee"
1115−-- upper(E'eeee')
1116−upper
1117− :: nullity 'PGtext
1118− -- ^ string to upper case
1119− :--> nullity 'PGtext
1120−upper = unsafeFunction "upper"
1121−
1122−-- | >>> printSQL $ charLength "four"
1123−-- char_length(E'four')
1124−charLength
1125− :: nullity 'PGtext
1126− -- ^ string to measure
1127− :--> nullity 'PGint4
1128−charLength = unsafeFunction "char_length"
1129−
1130−-- | The `like` expression returns true if the @string@ matches
1131−-- the supplied @pattern@. If @pattern@ does not contain percent signs
1132−-- or underscores, then the pattern only represents the string itself;
1133−-- in that case `like` acts like the equals operator. An underscore (_)
1134−-- in pattern stands for (matches) any single character; a percent sign (%)
1135−-- matches any sequence of zero or more characters.
1136−--
1137−-- >>> printSQL $ "abc" `like` "a%"
1138−-- (E'abc' LIKE E'a%')
1139−like :: Operator (nullity 'PGtext) (nullity 'PGtext) ('Null 'PGbool)
1140−like = unsafeBinaryOp "LIKE"
1141−
1142−-- | The key word ILIKE can be used instead of LIKE to make the
1143−-- match case-insensitive according to the active locale.
1144−--
1145−-- >>> printSQL $ "abc" `ilike` "a%"
1146−-- (E'abc' ILIKE E'a%')
1147−ilike :: Operator (nullity 'PGtext) (nullity 'PGtext) ('Null 'PGbool)
1148−ilike = unsafeBinaryOp "ILIKE"
1149−
1150−{-----------------------------------------
1151− -- json and jsonb support
1152−
1153−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1154−comments lifted directly from this page.
1155−
1156−Table 9.44: json and jsonb operators
1157−-----------------------------------------}
1158−
1159−-- | Get JSON value (object field or array element) at a key.
1160−(.->)
1161− :: (json `In` PGJsonType, key `In` PGJsonKey)
1162− => Operator (nullity json) (nullity key) ('Null json)
1163−infixl 8 .->
1164−(.->) = unsafeBinaryOp "->"
1165−
1166−-- | Get JSON value (object field or array element) at a key, as text.
1167−(.->>)
1168− :: (json `In` PGJsonType, key `In` PGJsonKey)
1169− => Operator (nullity json) (nullity key) ('Null 'PGtext)
1170−infixl 8 .->>
1171−(.->>) = unsafeBinaryOp "->>"
1172−
1173−-- | Get JSON value at a specified path.
1174−(.#>)
1175− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1176− => Operator (nullity json) (nullity path) ('Null json)
1177−infixl 8 .#>
1178−(.#>) = unsafeBinaryOp "#>"
1179−
1180−-- | Get JSON value at a specified path as text.
1181−(.#>>)
1182− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1183− => Operator (nullity json) (nullity path) ('Null 'PGtext)
1184−infixl 8 .#>>
1185−(.#>>) = unsafeBinaryOp "#>>"
1186−
1187−-- Additional jsonb operators
1188−
1189−-- | Does the left JSON value contain the right JSON path/value entries at the
1190−-- top level?
1191−(.@>)
1192− :: Operator (nullity 'PGjsonb) (nullity 'PGjsonb) ('Null 'PGbool)
1193−infixl 9 .@>
1194−(.@>) = unsafeBinaryOp "@>"
1195−
1196−-- | Are the left JSON path/value entries contained at the top level within the
1197−-- right JSON value?
1198−(.<@) :: Operator (nullity 'PGjsonb) (nullity 'PGjsonb) ('Null 'PGbool)
1199−infixl 9 .<@
1200−(.<@) = unsafeBinaryOp "<@"
1201−
1202−-- | Does the string exist as a top-level key within the JSON value?
1203−(.?) :: Operator (nullity 'PGjsonb) (nullity 'PGtext) ('Null 'PGbool)
1204−infixl 9 .?
1205−(.?) = unsafeBinaryOp "?"
1206−
1207−-- | Do any of these array strings exist as top-level keys?
1208−(.?|) :: Operator
1209− (nullity 'PGjsonb)
1210− (nullity ('PGvararray ('NotNull 'PGtext)))
1211− ('Null 'PGbool)
1212−infixl 9 .?|
1213−(.?|) = unsafeBinaryOp "?|"
1214−
1215−-- | Do all of these array strings exist as top-level keys?
1216−(.?&) :: Operator
1217− (nullity 'PGjsonb)
1218− (nullity ('PGvararray ('NotNull 'PGtext)))
1219− ('Null 'PGbool)
1220−infixl 9 .?&
1221−(.?&) = unsafeBinaryOp "?&"
1222−
1223−-- | Concatenate two jsonb values into a new jsonb value.
1224−instance Semigroup
1225− (Expression outer grp commons schemas params from (nullity 'PGjsonb)) where
1226− (<>) = unsafeBinaryOp "||"
1227−
1228−-- | Delete a key or keys from a JSON object, or remove an array element.
1229−--
1230−-- If the right operand is..
1231−--
1232−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1233−-- are matched based on their key value.
1234−--
1235−-- @ text[] @: Delete multiple key/value pairs or string elements
1236−-- from left operand. Key/value pairs are matched based on their key value.
1237−--
1238−-- @ integer @: Delete the array element with specified index (Negative integers
1239−-- count from the end). Throws an error if top level container is not an array.
1240−(.-.)
1241− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1242− => Operator (nullity 'PGjsonb) (nullity key) (nullity 'PGjsonb)
1243−infixl 6 .-.
1244−(.-.) = unsafeBinaryOp "-"
1245−
1246−-- | Delete the field or element with specified path (for JSON arrays, negative
1247−-- integers count from the end)
1248−(#-.)
1249− :: PGTextArray "(#-.)" arrayty
1250− => Operator (nullity 'PGjsonb) (nullity arrayty)(nullity 'PGjsonb)
1251−infixl 6 #-.
1252−(#-.) = unsafeBinaryOp "#-"
1253−
1254−{-----------------------------------------
1255−Table 9.45: JSON creation functions
1256−-----------------------------------------}
1257−
1258−-- | Literal binary JSON
1259−jsonbLit
1260− :: JSON.ToJSON x
1261− => x -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1262−jsonbLit = cast jsonb . UnsafeExpression
1263− . singleQuotedUtf8 . toStrict . JSON.encode
1264−
1265−-- | Literal JSON
1266−jsonLit
1267− :: JSON.ToJSON x
1268− => x -> Expression outer grp commons schemas params from (nullity 'PGjson)
1269−jsonLit = cast json . UnsafeExpression
1270− . singleQuotedUtf8 . toStrict . JSON.encode
1271−
1272−-- | Returns the value as json. Arrays and composites are converted
1273−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1274−-- type to json, the cast function will be used to perform the conversion;
1275−-- otherwise, a scalar value is produced. For any scalar type other than a
1276−-- number, a Boolean, or a null value, the text representation will be used, in
1277−-- such a fashion that it is a valid json value.
1278−toJson :: nullity ty :--> nullity 'PGjson
1279−toJson = unsafeFunction "to_json"
1280−
1281−-- | Returns the value as jsonb. Arrays and composites are converted
1282−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1283−-- type to json, the cast function will be used to perform the conversion;
1284−-- otherwise, a scalar value is produced. For any scalar type other than a
1285−-- number, a Boolean, or a null value, the text representation will be used, in
1286−-- such a fashion that it is a valid jsonb value.
1287−toJsonb :: nullity ty :--> nullity 'PGjsonb
1288−toJsonb = unsafeFunction "to_jsonb"
1289−
1290−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1291−-- becomes a JSON array of arrays.
1292−arrayToJson
1293− :: PGArray "arrayToJson" arr
1294− => nullity arr :--> nullity 'PGjson
1295−arrayToJson = unsafeFunction "array_to_json"
1296−
1297−-- | Returns the row as a JSON object.
1298−rowToJson :: nullity ('PGcomposite ty) :--> nullity 'PGjson
1299−rowToJson = unsafeFunction "row_to_json"
1300−
1301−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1302−-- argument list.
1303−jsonBuildArray
1304− :: SListI elems
1305− => NP (Expression outer grp commons schemas params from) elems
1306− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1307−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1308−
1309−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1310−-- variadic argument list.
1311−jsonbBuildArray
1312− :: SListI elems
1313− => NP (Expression outer grp commons schemas params from) elems
1314− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1315−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1316−
1317−unsafeRowFunction
1318− :: SOP.SListI elems
1319− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1320− -> [ByteString]
1321−unsafeRowFunction =
1322− (`appEndo` []) . hcfoldMap (Proxy :: SOP.Proxy SOP.Top)
1323− (\(col `As` name) -> Endo $ \xs ->
1324− renderAliasString name : renderSQL col : xs)
1325− where
1326− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1327− renderAliasString = singleQuotedText . fromString . symbolVal
1328−
1329−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1330−-- argument list. The elements of the argument list must alternate between text
1331−-- and values.
1332−jsonBuildObject
1333− :: SOP.SListI elems
1334− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1335− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1336−jsonBuildObject
1337− = unsafeFunction "json_build_object"
1338− . UnsafeExpression
1339− . commaSeparated
1340− . unsafeRowFunction
1341−
1342−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1343−-- variadic argument list. The elements of the argument list must alternate
1344−-- between text and values.
1345−jsonbBuildObject
1346− :: SOP.SListI elems
1347− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1348− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1349−jsonbBuildObject
1350− = unsafeFunction "jsonb_build_object"
1351− . UnsafeExpression
1352− . commaSeparated
1353− . unsafeRowFunction
1354−
1355−-- | Builds a JSON object out of a text array. The array must have either
1356−-- exactly one dimension with an even number of members, in which case they are
1357−-- taken as alternating key/value pairs, or two dimensions such that each inner
1358−-- array has exactly two elements, which are taken as a key/value pair.
1359−jsonObject
1360− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1361− => nullity arr :--> nullity 'PGjson
1362−jsonObject = unsafeFunction "json_object"
1363−
1364−-- | Builds a binary JSON object out of a text array. The array must have either
1365−-- exactly one dimension with an even number of members, in which case they are
1366−-- taken as alternating key/value pairs, or two dimensions such that each inner
1367−-- array has exactly two elements, which are taken as a key/value pair.
1368−jsonbObject
1369− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1370− => nullity arr :--> nullity 'PGjsonb
1371−jsonbObject = unsafeFunction "jsonb_object"
1372−
1373−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1374−-- keys and one for values, that are zipped pairwise to create a JSON object.
1375−jsonZipObject
1376− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1377− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1378− => Expression outer grp commons schemas params from (nullity keysArray)
1379− -> Expression outer grp commons schemas params from (nullity valuesArray)
1380− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1381−jsonZipObject ks vs =
1382− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1383−
1384−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1385−-- keys and one for values, that are zipped pairwise to create a binary JSON
1386−-- object.
1387−jsonbZipObject
1388− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1389− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1390− => Expression outer grp commons schemas params from (nullity keysArray)
1391− -> Expression outer grp commons schemas params from (nullity valuesArray)
1392− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1393−jsonbZipObject ks vs =
1394− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1395−
1396−{-----------------------------------------
1397−Table 9.46: JSON processing functions
1398−-----------------------------------------}
1399−
1400−-- | Returns the number of elements in the outermost JSON array.
1401−jsonArrayLength :: nullity 'PGjson :--> nullity 'PGint4
1402−jsonArrayLength = unsafeFunction "json_array_length"
1403−
1404−-- | Returns the number of elements in the outermost binary JSON array.
1405−jsonbArrayLength :: nullity 'PGjsonb :--> nullity 'PGint4
1406−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1407−
1408−-- | Returns JSON value pointed to by the given path (equivalent to #>
1409−-- operator).
1410−jsonExtractPath
1411− :: SListI elems
1412− => Expression outer grp commons schemas params from (nullity 'PGjson)
1413− -> NP (Expression outer grp commons schemas params from) elems
1414− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1415−jsonExtractPath x xs =
1416− unsafeVariadicFunction "json_extract_path" (x :* xs)
1417−
1418−-- | Returns JSON value pointed to by the given path (equivalent to #>
1419−-- operator).
1420−jsonbExtractPath
1421− :: SListI elems
1422− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1423− -> NP (Expression outer grp commons schemas params from) elems
1424− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1425−jsonbExtractPath x xs =
1426− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1427−
1428−-- | Returns JSON value pointed to by the given path (equivalent to #>
1429−-- operator), as text.
1430−jsonExtractPathAsText
1431− :: SListI elems
1432− => Expression outer grp commons schemas params from (nullity 'PGjson)
1433− -> NP (Expression outer grp commons schemas params from) elems
1434− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1435−jsonExtractPathAsText x xs =
1436− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1437−
1438−-- | Returns JSON value pointed to by the given path (equivalent to #>
1439−-- operator), as text.
1440−jsonbExtractPathAsText
1441− :: SListI elems
1442− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1443− -> NP (Expression outer grp commons schemas params from) elems
1444− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1445−jsonbExtractPathAsText x xs =
1446− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1447−
1448−-- | Returns the type of the outermost JSON value as a text string. Possible
1449−-- types are object, array, string, number, boolean, and null.
1450−jsonTypeof :: nullity 'PGjson :--> nullity 'PGtext
1451−jsonTypeof = unsafeFunction "json_typeof"
1452−
1453−-- | Returns the type of the outermost binary JSON value as a text string.
1454−-- Possible types are object, array, string, number, boolean, and null.
1455−jsonbTypeof :: nullity 'PGjsonb :--> nullity 'PGtext
1456−jsonbTypeof = unsafeFunction "jsonb_typeof"
1457−
1458−-- | Returns its argument with all object fields that have null values omitted.
1459−-- Other null values are untouched.
1460−jsonStripNulls :: nullity 'PGjson :--> nullity 'PGjson
1461−jsonStripNulls = unsafeFunction "json_strip_nulls"
1462−
1463−-- | Returns its argument with all object fields that have null values omitted.
1464−-- Other null values are untouched.
1465−jsonbStripNulls :: nullity 'PGjsonb :--> nullity 'PGjsonb
1466−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1467−
1468−-- | @ jsonbSet target path new_value create_missing @
1469−--
1470−-- Returns target with the section designated by path replaced by new_value,
1471−-- or with new_value added if create_missing is true ( default is true) and the
1472−-- item designated by path does not exist. As with the path orientated
1473−-- operators, negative integers that appear in path count from the end of JSON
1474−-- arrays.
1475−jsonbSet
1476− :: PGTextArray "jsonbSet" arr
1477− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1478− -> Expression outer grp commons schemas params from (nullity arr)
1479− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1480− -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1481− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1482−jsonbSet tgt path val createMissing = case createMissing of
1483− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1484− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1485−
1486−-- | @ jsonbInsert target path new_value insert_after @
1487−--
1488−-- Returns target with new_value inserted. If target section designated by
1489−-- path is in a JSONB array, new_value will be inserted before target or after
1490−-- if insert_after is true (default is false). If target section designated by
1491−-- path is in JSONB object, new_value will be inserted only if target does not
1492−-- exist. As with the path orientated operators, negative integers that appear
1493−-- in path count from the end of JSON arrays.
1494−jsonbInsert
1495− :: PGTextArray "jsonbInsert" arr
1496− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1497− -> Expression outer grp commons schemas params from (nullity arr)
1498− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1499− -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1500− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1501−jsonbInsert tgt path val insertAfter = case insertAfter of
1502− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1503− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1504−
1505−-- | Returns its argument as indented JSON text.
1506−jsonbPretty :: nullity 'PGjsonb :--> nullity 'PGtext
1507−jsonbPretty = unsafeFunction "jsonb_pretty"
1508−
1509−(@@) :: Operator (nullity 'PGtsvector) (nullity 'PGtsquery) ('Null 'PGbool)
1510−(@@) = unsafeBinaryOp "@@"
1511−
1512−(.&) :: Operator (nullity 'PGtsquery) (nullity 'PGtsquery) (nullity 'PGtsquery)
1513−(.&) = unsafeBinaryOp "&&"
1514−
1515−(.|) :: Operator (nullity 'PGtsquery) (nullity 'PGtsquery) (nullity 'PGtsquery)
1516−(.|) = unsafeBinaryOp "||"
1517−
1518−(.!) :: nullity 'PGtsquery :--> nullity 'PGtsquery
1519−(.!) = unsafeUnaryOp "!!"
1520−
1521−(<->) :: Operator (nullity 'PGtsquery) (nullity 'PGtsquery) (nullity 'PGtsquery)
1522−(<->) = unsafeBinaryOp "<->"
1523−
1524−arrayToTSvector
1525− :: nullity ('PGvararray ('NotNull 'PGtext))
1526− :--> nullity 'PGtsvector
1527−arrayToTSvector = unsafeFunction "array_to_tsvector"
1528−
1529−tsvectorLength :: nullity 'PGtsvector :--> nullity 'PGint4
1530−tsvectorLength = unsafeFunction "length"
1531−
1532−numnode :: nullity 'PGtsquery :--> nullity 'PGint4
1533−numnode = unsafeFunction "numnode"
1534−
1535−plainToTSquery
1536− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1537− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1538− -> Expression outer grp commons schemas params from (nullity 'PGtsquery)
1539−plainToTSquery = unsafeFunction2 "plainto_tsquery"
1540−
1541−phraseToTSquery
1542− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1543− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1544− -> Expression outer grp commons schemas params from (nullity 'PGtsquery)
1545−phraseToTSquery = unsafeFunction2 "phraseto_tsquery"
1546−
1547−websearchToTSquery
1548− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1549− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1550− -> Expression outer grp commons schemas params from (nullity 'PGtsquery)
1551−websearchToTSquery = unsafeFunction2 "websearch_to_tsquery"
1552−
1553−queryTree :: nullity 'PGtsquery :--> nullity 'PGtext
1554−queryTree = unsafeFunction "query_tree"
1555−
1556−toTSquery
1557− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1558− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1559− -> Expression outer grp commons schemas params from (nullity 'PGtsquery)
1560−toTSquery = unsafeFunction2 "to_tsquery"
1561−
1562−toTSvector
1563− :: ty `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1564− => Expression outer grp commons schemas params from (nullity 'PGtext)
1565− -> Expression outer grp commons schemas params from (nullity ty)
1566− -> Expression outer grp commons schemas params from (nullity 'PGtsquery)
1567−toTSvector = unsafeFunction2 "to_tsvector"
1568−
1569−{-----------------------------------------
1570−aggregation
1571−-----------------------------------------}
1572−
1573−{- |
1574−`Aggregate` functions compute a single result from a set of input values.
1575−`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1576−as `WindowFunction`s.
1577−-}
1578−class Aggregate expr1 expr2 aggr
1579− | aggr -> expr1, aggr -> expr2 where
1580−
1581− -- | A special aggregation that does not require an input
1582− --
1583− -- >>> :{
1584− -- let
1585− -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1586− -- expression = countStar
1587− -- in printSQL expression
1588− -- :}
1589− -- count(*)
1590− countStar :: aggr ('NotNull 'PGint8)
1591−
1592− -- | >>> :{
1593− -- let
1594− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1595− -- expression = count (All #col)
1596− -- in printSQL expression
1597− -- :}
1598− -- count(ALL "col")
1599− count
1600− :: expr1 ty
1601− -- ^ what to count
1602− -> aggr ('NotNull 'PGint8)
1603−
1604− -- | >>> :{
1605− -- let
1606− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('NotNull 'PGnumeric)
1607− -- expression = sum_ (Distinct #col)
1608− -- in printSQL expression
1609− -- :}
1610− -- sum(DISTINCT "col")
1611− sum_
1612− :: ty `In` PGNum
1613− => expr1 (nullity ty)
1614− -> aggr ('NotNull ty)
1615−
1616− -- | input values, including nulls, concatenated into an array
1617− arrayAgg
1618− :: expr1 ty
1619− -> aggr ('Null ('PGvararray ty))
1620−
1621− -- | aggregates values as a JSON array
1622− jsonAgg
1623− :: expr1 ty
1624− -> aggr ('Null 'PGjson)
1625−
1626− -- | aggregates values as a JSON array
1627− jsonbAgg
1628− :: expr1 ty
1629− -> aggr ('Null 'PGjsonb)
1630−
1631− {- |
1632− the bitwise AND of all non-null input values, or null if none
1633− >>> :{
1634− let
1635− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] ('Null 'PGint4)
1636− expression = bitAnd (Distinct #col)
1637− in printSQL expression
1638− :}
1639− bit_and(DISTINCT "col")
1640− -}
1641− bitAnd
1642− :: int `In` PGIntegral
1643− => expr1 (nullity int)
1644− -- ^ what to aggregate
1645− -> aggr ('Null int)
1646−
1647− {- |
1648− the bitwise OR of all non-null input values, or null if none
1649−
1650− >>> :{
1651− let
1652− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] ('Null 'PGint4)
1653− expression = bitOr (All #col)
1654− in printSQL expression
1655− :}
1656− bit_or(ALL "col")
1657− -}
1658− bitOr
1659− :: int `In` PGIntegral
1660− => expr1 (nullity int)
1661− -- ^ what to aggregate
1662− -> aggr ('Null int)
1663−
1664− {- |
1665− true if all input values are true, otherwise false
1666−
1667− >>> :{
1668− let
1669− winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] ('Null 'PGbool)
1670− winFun = boolAnd #col
1671− in printSQL winFun
1672− :}
1673− bool_and("col")
1674− -}
1675− boolAnd
1676− :: expr1 (nullity 'PGbool)
1677− -- ^ what to aggregate
1678− -> aggr ('Null 'PGbool)
1679−
1680− {- |
1681− true if at least one input value is true, otherwise false
1682−
1683− >>> :{
1684− let
1685− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] ('Null 'PGbool)
1686− expression = boolOr (All #col)
1687− in printSQL expression
1688− :}
1689− bool_or(ALL "col")
1690− -}
1691− boolOr
1692− :: expr1(nullity 'PGbool)
1693− -- ^ what to aggregate
1694− -> aggr ('Null 'PGbool)
1695−
1696− {- |
1697− equivalent to `boolAnd`
1698−
1699− >>> :{
1700− let
1701− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] ('Null 'PGbool)
1702− expression = every (Distinct #col)
1703− in printSQL expression
1704− :}
1705− every(DISTINCT "col")
1706− -}
1707− every
1708− :: expr1 (nullity 'PGbool)
1709− -- ^ what to aggregate
1710− -> aggr ('Null 'PGbool)
1711−
1712− {- |maximum value of expression across all input values-}
1713− max_
1714− :: expr1 (nullity ty)
1715− -- ^ what to maximize
1716− -> aggr ('Null ty)
1717−
1718− -- | minimum value of expression across all input values
1719− min_
1720− :: expr1 (nullity ty)
1721− -- ^ what to minimize
1722− -> aggr ('Null ty)
1723−
1724− -- | the average (arithmetic mean) of all input values
1725− avg
1726− :: expr1 (nullity ty)
1727− -- ^ what to average
1728− -> aggr ('Null (PGAvg ty))
1729−
1730− {- | correlation coefficient
1731− >>> :{
1732− let
1733− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1734− expression = corr (All (#y :*: #x))
1735− in printSQL expression
1736− :}
1737− corr(ALL "y", "x")
1738− -}
1739− corr
1740− :: expr2 (nullity 'PGfloat8)
1741− -> aggr ('Null 'PGfloat8)
1742−
1743− {- | population covariance
1744− >>> :{
1745− let
1746− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1747− expression = covarPop (All (#y :*: #x))
1748− in printSQL expression
1749− :}
1750− covar_pop(ALL "y", "x")
1751− -}
1752− covarPop
1753− :: expr2 (nullity 'PGfloat8)
1754− -> aggr ('Null 'PGfloat8)
1755−
1756− {- | sample covariance
1757− >>> :{
1758− let
1759− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1760− winFun = covarSamp (#y :*: #x)
1761− in printSQL winFun
1762− :}
1763− covar_samp("y", "x")
1764− -}
1765− covarSamp
1766− :: expr2 (nullity 'PGfloat8)
1767− -> aggr ('Null 'PGfloat8)
1768−
1769− {- | average of the independent variable (sum(X)/N)
1770− >>> :{
1771− let
1772− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1773− expression = regrAvgX (All (#y :*: #x))
1774− in printSQL expression
1775− :}
1776− regr_avgx(ALL "y", "x")
1777− -}
1778− regrAvgX
1779− :: expr2 (nullity 'PGfloat8)
1780− -> aggr ('Null 'PGfloat8)
1781−
1782− {- | average of the dependent variable (sum(Y)/N)
1783− >>> :{
1784− let
1785− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1786− winFun = regrAvgY (#y :*: #x)
1787− in printSQL winFun
1788− :}
1789− regr_avgy("y", "x")
1790− -}
1791− regrAvgY
1792− :: expr2 (nullity 'PGfloat8)
1793− -> aggr ('Null 'PGfloat8)
1794−
1795− {- | number of input rows in which both expressions are nonnull
1796− >>> :{
1797− let
1798− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGint8)
1799− winFun = regrCount (#y :*: #x)
1800− in printSQL winFun
1801− :}
1802− regr_count("y", "x")
1803− -}
1804− regrCount
1805− :: expr2 (nullity 'PGfloat8)
1806− -> aggr ('Null 'PGint8)
1807−
1808− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1809− >>> :{
1810− let
1811− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1812− expression = regrIntercept (All (#y :*: #x))
1813− in printSQL expression
1814− :}
1815− regr_intercept(ALL "y", "x")
1816− -}
1817− regrIntercept
1818− :: expr2 (nullity 'PGfloat8)
1819− -> aggr ('Null 'PGfloat8)
1820−
1821− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1822− regrR2
1823− :: expr2 (nullity 'PGfloat8)
1824− -> aggr ('Null 'PGfloat8)
1825−
1826− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1827− -- determined by the (X, Y) pairs
1828− regrSlope
1829− :: expr2 (nullity 'PGfloat8)
1830− -> aggr ('Null 'PGfloat8)
1831−
1832− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1833− -- (“sum of squares” of the independent variable)
1834− regrSxx
1835− :: expr2 (nullity 'PGfloat8)
1836− -> aggr ('Null 'PGfloat8)
1837−
1838− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1839− -- (“sum of products” of independent times dependent variable)
1840− regrSxy
1841− :: expr2 (nullity 'PGfloat8)
1842− -> aggr ('Null 'PGfloat8)
1843−
1844− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1845− -- (“sum of squares” of the dependent variable)
1846− regrSyy
1847− :: expr2 (nullity 'PGfloat8)
1848− -> aggr ('Null 'PGfloat8)
1849−
1850− -- | historical alias for `stddevSamp`
1851− stddev
1852− :: expr1 (nullity ty)
1853− -> aggr ('Null (PGAvg ty))
1854−
1855− -- | population standard deviation of the input values
1856− stddevPop
1857− :: expr1 (nullity ty)
1858− -> aggr ('Null (PGAvg ty))
1859−
1860− -- | sample standard deviation of the input values
1861− stddevSamp
1862− :: expr1 (nullity ty)
1863− -> aggr ('Null (PGAvg ty))
1864−
1865− -- | historical alias for `varSamp`
1866− variance
1867− :: expr1 (nullity ty)
1868− -> aggr ('Null (PGAvg ty))
1869−
1870− -- | population variance of the input values
1871− -- (square of the population standard deviation)
1872− varPop
1873− :: expr1 (nullity ty)
1874− -> aggr ('Null (PGAvg ty))
1875−
1876− -- | sample variance of the input values
1877− -- (square of the sample standard deviation)
1878− varSamp
1879− :: expr1 (nullity ty)
1880− -> aggr ('Null (PGAvg ty))
1881−
1882−{- |
1883−`Distinction`s are used for the input of `Aggregate` `Expression`s.
1884−`All` invokes the aggregate once for each input row.
1885−`Distinct` invokes the aggregate once for each distinct value of the expression
1886−(or distinct set of values, for multiple expressions) found in the input
1887−-}
1888−data Distinction expr ty
1889− = All (expr ty)
1890− | Distinct (expr ty)
1891− deriving (GHC.Generic,Show,Eq,Ord)
1892−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1893−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1894− renderSQL = \case
1895− All x -> "ALL" <+> renderSQL x
1896− Distinct x -> "DISTINCT" <+> renderSQL x
1897−instance RenderSQL
1898− (Distinction
1899− ( Expression outer grp commons schemas params from
1900− :*:
1901− Expression outer grp commons schemas params from) xty ) where
1902− renderSQL = \case
1903− All (x :*: x') ->
1904− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1905− Distinct (x :*: x') ->
1906− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1907−
1908−instance Aggregate
1909− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1910− (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1911− (Expression outer ('Grouped bys) commons schemas params from) where
1912− countStar = UnsafeExpression "count(*)"
1913− count = unsafeAggregate1 "count"
1914− sum_ = unsafeAggregate1 "sum"
1915− arrayAgg = unsafeAggregate1 "array_agg"
1916− jsonAgg = unsafeAggregate1 "json_agg"
1917− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1918− bitAnd = unsafeAggregate1 "bit_and"
1919− bitOr = unsafeAggregate1 "bit_or"
1920− boolAnd = unsafeAggregate1 "bool_and"
1921− boolOr = unsafeAggregate1 "bool_or"
1922− every = unsafeAggregate1 "every"
1923− max_ = unsafeAggregate1 "max"
1924− min_ = unsafeAggregate1 "min"
1925− avg = unsafeAggregate1 "avg"
1926− corr = unsafeAggregate2 "corr"
1927− covarPop = unsafeAggregate2 "covar_pop"
1928− covarSamp = unsafeAggregate2 "covar_samp"
1929− regrAvgX = unsafeAggregate2 "regr_avgx"
1930− regrAvgY = unsafeAggregate2 "regr_avgy"
1931− regrCount = unsafeAggregate2 "regr_count"
1932− regrIntercept = unsafeAggregate2 "regr_intercept"
1933− regrR2 = unsafeAggregate2 "regr_r2"
1934− regrSlope = unsafeAggregate2 "regr_slope"
1935− regrSxx = unsafeAggregate2 "regr_sxx"
1936− regrSxy = unsafeAggregate2 "regr_sxy"
1937− regrSyy = unsafeAggregate2 "regr_syy"
1938− stddev = unsafeAggregate1 "stddev"
1939− stddevPop = unsafeAggregate1 "stddev_pop"
1940− stddevSamp = unsafeAggregate1 "stddev_samp"
1941− variance = unsafeAggregate1 "variance"
1942− varPop = unsafeAggregate1 "var_pop"
1943− varSamp = unsafeAggregate1 "var_samp"
1944−instance Aggregate
1945− (Expression outer grp commons schemas params from)
1946− (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1947− (WindowFunction outer grp commons schemas params from) where
1948− countStar = UnsafeWindowFunction "count(*)"
1949− count = unsafeWindowFunction1 "count"
1950− sum_ = unsafeWindowFunction1 "sum"
1951− arrayAgg = unsafeWindowFunction1 "array_agg"
1952− jsonAgg = unsafeWindowFunction1 "json_agg"
1953− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1954− bitAnd = unsafeWindowFunction1 "bit_and"
1955− bitOr = unsafeWindowFunction1 "bit_or"
1956− boolAnd = unsafeWindowFunction1 "bool_and"
1957− boolOr = unsafeWindowFunction1 "bool_or"
1958− every = unsafeWindowFunction1 "every"
1959− max_ = unsafeWindowFunction1 "max"
1960− min_ = unsafeWindowFunction1 "min"
1961− avg = unsafeWindowFunction1 "avg"
1962− corr = unsafeWindowFunction2 "corr"
1963− covarPop = unsafeWindowFunction2 "covar_pop"
1964− covarSamp = unsafeWindowFunction2 "covar_samp"
1965− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1966− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1967− regrCount = unsafeWindowFunction2 "regr_count"
1968− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1969− regrR2 = unsafeWindowFunction2 "regr_r2"
1970− regrSlope = unsafeWindowFunction2 "regr_slope"
1971− regrSxx = unsafeWindowFunction2 "regr_sxx"
1972− regrSxy = unsafeWindowFunction2 "regr_sxy"
1973− regrSyy = unsafeWindowFunction2 "regr_syy"
1974− stddev = unsafeWindowFunction1 "stddev"
1975− stddevPop = unsafeWindowFunction1 "stddev_pop"
1976− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1977− variance = unsafeWindowFunction1 "variance"
1978− varPop = unsafeWindowFunction1 "var_pop"
1979− varSamp = unsafeWindowFunction1 "var_samp"
1980−
1981−-- | escape hatch to define aggregate functions
1982−unsafeAggregate1
1983− :: ByteString -- ^ aggregate function
1984− -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1985− -> Expression outer ('Grouped bys) commons schemas params from yty
1986−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1987− [fun, "(", renderSQL x, ")"]
1988−
1989−-- | escape hatch to define aggregate binary functions
1990−unsafeAggregate2
1991− :: ByteString -- ^ aggregate function
1992− -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1993− -> Expression outer ('Grouped bys) commons schemas params from yty
1994−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1995− [fun, "(", renderSQL xx, ")"]
1996−
1997−-- | A type family that calculates `PGAvg` type of a `PGType`.
1998−type family PGAvg ty where
1999− PGAvg 'PGint2 = 'PGnumeric
2000− PGAvg 'PGint4 = 'PGnumeric
2001− PGAvg 'PGint8 = 'PGnumeric
2002− PGAvg 'PGnumeric = 'PGnumeric
2003− PGAvg 'PGfloat4 = 'PGfloat8
2004− PGAvg 'PGfloat8 = 'PGfloat8
2005− PGAvg 'PGinterval = 'PGinterval
2006− PGAvg pg = TypeError
2007− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
2008−
2009−{-----------------------------------------
2010−type expressions
2011−-----------------------------------------}
2012−
2013−-- | `TypeExpression`s are used in `cast`s and
2014−-- `Squeal.PostgreSQL.Definition.createTable` commands.
2015−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
2016− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
2017− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2018−instance RenderSQL (TypeExpression schemas ty) where
2019− renderSQL = renderTypeExpression
2020−
2021−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
2022−typedef
2023− :: (Has sch schemas schema, Has td schema ('Typedef ty))
2024− => QualifiedAlias sch td
2025− -> TypeExpression schemas (nullity ty)
2026−typedef = UnsafeTypeExpression . renderSQL
2027−
2028−-- | The composite type corresponding to a `Table` definition can be expressed
2029−-- by its alias.
2030−typetable
2031− :: (Has sch schemas schema, Has tab schema ('Table table))
2032− => QualifiedAlias sch tab
2033− -> TypeExpression schemas (nullity ('PGcomposite (TableToRow table)))
2034−typetable = UnsafeTypeExpression . renderSQL
2035−
2036−-- | The composite type corresponding to a `View` definition can be expressed
2037−-- by its alias.
2038−typeview
2039− :: (Has sch schemas schema, Has vw schema ('View view))
2040− => QualifiedAlias sch vw
2041− -> TypeExpression schemas (nullity ('PGcomposite view))
2042−typeview = UnsafeTypeExpression . renderSQL
2043−
2044−-- | logical Boolean (true/false)
2045−bool :: TypeExpression schemas (nullity 'PGbool)
2046−bool = UnsafeTypeExpression "bool"
2047−-- | signed two-byte integer
2048−int2, smallint :: TypeExpression schemas (nullity 'PGint2)
2049−int2 = UnsafeTypeExpression "int2"
2050−smallint = UnsafeTypeExpression "smallint"
2051−-- | signed four-byte integer
2052−int4, int, integer :: TypeExpression schemas (nullity 'PGint4)
2053−int4 = UnsafeTypeExpression "int4"
2054−int = UnsafeTypeExpression "int"
2055−integer = UnsafeTypeExpression "integer"
2056−-- | signed eight-byte integer
2057−int8, bigint :: TypeExpression schemas (nullity 'PGint8)
2058−int8 = UnsafeTypeExpression "int8"
2059−bigint = UnsafeTypeExpression "bigint"
2060−-- | arbitrary precision numeric type
2061−numeric :: TypeExpression schemas (nullity 'PGnumeric)
2062−numeric = UnsafeTypeExpression "numeric"
2063−-- | single precision floating-point number (4 bytes)
2064−float4, real :: TypeExpression schemas (nullity 'PGfloat4)
2065−float4 = UnsafeTypeExpression "float4"
2066−real = UnsafeTypeExpression "real"
2067−-- | double precision floating-point number (8 bytes)
2068−float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
2069−float8 = UnsafeTypeExpression "float8"
2070−doublePrecision = UnsafeTypeExpression "double precision"
2071−-- | currency amount
2072−money :: TypeExpression schema (nullity 'PGmoney)
2073−money = UnsafeTypeExpression "money"
2074−-- | variable-length character string
2075−text :: TypeExpression schemas (nullity 'PGtext)
2076−text = UnsafeTypeExpression "text"
2077−-- | fixed-length character string
2078−char, character
2079− :: forall n schemas nullity. (KnownNat n, 1 <= n)
2080− => TypeExpression schemas (nullity ('PGchar n))
2081−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
2082−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
2083−-- | variable-length character string
2084−varchar, characterVarying
2085− :: forall n schemas nullity. (KnownNat n, 1 <= n)
2086− => TypeExpression schemas (nullity ('PGvarchar n))
2087−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
2088−characterVarying = UnsafeTypeExpression $
2089− "character varying(" <> renderNat @n <> ")"
2090−-- | binary data ("byte array")
2091−bytea :: TypeExpression schemas (nullity 'PGbytea)
2092−bytea = UnsafeTypeExpression "bytea"
2093−-- | date and time (no time zone)
2094−timestamp :: TypeExpression schemas (nullity 'PGtimestamp)
2095−timestamp = UnsafeTypeExpression "timestamp"
2096−-- | date and time, including time zone
2097−timestampWithTimeZone :: TypeExpression schemas (nullity 'PGtimestamptz)
2098−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
2099−-- | calendar date (year, month, day)
2100−date :: TypeExpression schemas (nullity 'PGdate)
2101−date = UnsafeTypeExpression "date"
2102−-- | time of day (no time zone)
2103−time :: TypeExpression schemas (nullity 'PGtime)
2104−time = UnsafeTypeExpression "time"
2105−-- | time of day, including time zone
2106−timeWithTimeZone :: TypeExpression schemas (nullity 'PGtimetz)
2107−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
2108−-- | time span
2109−interval :: TypeExpression schemas (nullity 'PGinterval)
2110−interval = UnsafeTypeExpression "interval"
2111−-- | universally unique identifier
2112−uuid :: TypeExpression schemas (nullity 'PGuuid)
2113−uuid = UnsafeTypeExpression "uuid"
2114−-- | IPv4 or IPv6 host address
2115−inet :: TypeExpression schemas (nullity 'PGinet)
2116−inet = UnsafeTypeExpression "inet"
2117−-- | textual JSON data
2118−json :: TypeExpression schemas (nullity 'PGjson)
2119−json = UnsafeTypeExpression "json"
2120−-- | binary JSON data, decomposed
2121−jsonb :: TypeExpression schemas (nullity 'PGjsonb)
2122−jsonb = UnsafeTypeExpression "jsonb"
2123−-- | variable length array
2124−vararray
2125− :: TypeExpression schemas pg
2126− -> TypeExpression schemas (nullity ('PGvararray pg))
2127−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
2128−-- | fixed length array
2129−--
2130−-- >>> renderSQL (fixarray @'[2] json)
2131−-- "json[2]"
2132−fixarray
2133− :: forall dims schemas nullity pg. SOP.All KnownNat dims
2134− => TypeExpression schemas pg
2135− -> TypeExpression schemas (nullity ('PGfixarray dims pg))
2136−fixarray ty = UnsafeTypeExpression $
2137− renderSQL ty <> renderDims @dims
2138− where
2139− renderDims :: forall ns. SOP.All KnownNat ns => ByteString
2140− renderDims =
2141− ("[" <>)
2142− . (<> "]")
2143− . ByteString.intercalate "]["
2144− . hcollapse
2145− $ hcmap (SOP.Proxy @KnownNat)
2146− (K . fromString . show . natVal)
2147− (hpure SOP.Proxy :: NP SOP.Proxy ns)
2148−tsvector :: TypeExpression schemas (nullity 'PGtsvector)
2149−tsvector = UnsafeTypeExpression "tsvector"
2150−tsquery :: TypeExpression schemas (nullity 'PGtsquery)
2151−tsquery = UnsafeTypeExpression "tsquery"
2152−
2153−-- | `pgtype` is a demoted version of a `PGType`
2154−class PGTyped schemas (ty :: NullityType) where
2155− pgtype :: TypeExpression schemas ty
2156−instance PGTyped schemas (nullity 'PGbool) where pgtype = bool
2157−instance PGTyped schemas (nullity 'PGint2) where pgtype = int2
2158−instance PGTyped schemas (nullity 'PGint4) where pgtype = int4
2159−instance PGTyped schemas (nullity 'PGint8) where pgtype = int8
2160−instance PGTyped schemas (nullity 'PGnumeric) where pgtype = numeric
2161−instance PGTyped schemas (nullity 'PGfloat4) where pgtype = float4
2162−instance PGTyped schemas (nullity 'PGfloat8) where pgtype = float8
2163−instance PGTyped schemas (nullity 'PGmoney) where pgtype = money
2164−instance PGTyped schemas (nullity 'PGtext) where pgtype = text
2165−instance (KnownNat n, 1 <= n)
2166− => PGTyped schemas (nullity ('PGchar n)) where pgtype = char @n
2167−instance (KnownNat n, 1 <= n)
2168− => PGTyped schemas (nullity ('PGvarchar n)) where pgtype = varchar @n
2169−instance PGTyped schemas (nullity 'PGbytea) where pgtype = bytea
2170−instance PGTyped schemas (nullity 'PGtimestamp) where pgtype = timestamp
2171−instance PGTyped schemas (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
2172−instance PGTyped schemas (nullity 'PGdate) where pgtype = date
2173−instance PGTyped schemas (nullity 'PGtime) where pgtype = time
2174−instance PGTyped schemas (nullity 'PGtimetz) where pgtype = timeWithTimeZone
2175−instance PGTyped schemas (nullity 'PGinterval) where pgtype = interval
2176−instance PGTyped schemas (nullity 'PGuuid) where pgtype = uuid
2177−instance PGTyped schemas (nullity 'PGjson) where pgtype = json
2178−instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
2179−instance PGTyped schemas ty
2180− => PGTyped schemas (nullity ('PGvararray ty)) where
2181− pgtype = vararray (pgtype @schemas @ty)
2182−instance (SOP.All KnownNat dims, PGTyped schemas ty)
2183− => PGTyped schemas (nullity ('PGfixarray dims ty)) where
2184− pgtype = fixarray @dims (pgtype @schemas @ty)
2185−instance PGTyped schemas (nullity 'PGtsvector) where pgtype = tsvector
2186−instance PGTyped schemas (nullity 'PGtsquery) where pgtype = tsquery
2187−
2188−{-----------------------------------------
2189−Sorting
2190−-----------------------------------------}
2191−
2192−-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2193−-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2194−-- set the sort direction of a `NotNull` result
2195−-- column to ascending or descending. Ascending order puts smaller values
2196−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2197−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2198−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2199−-- determine whether nulls appear before or after non-null values in the sort
2200−-- ordering of a `Null` result column.
2201−data SortExpression outer grp commons schemas params from where
2202− Asc
2203− :: Expression outer grp commons schemas params from ('NotNull ty)
2204− -> SortExpression outer grp commons schemas params from
2205− Desc
2206− :: Expression outer grp commons schemas params from ('NotNull ty)
2207− -> SortExpression outer grp commons schemas params from
2208− AscNullsFirst
2209− :: Expression outer grp commons schemas params from ('Null ty)
2210− -> SortExpression outer grp commons schemas params from
2211− AscNullsLast
2212− :: Expression outer grp commons schemas params from ('Null ty)
2213− -> SortExpression outer grp commons schemas params from
2214− DescNullsFirst
2215− :: Expression outer grp commons schemas params from ('Null ty)
2216− -> SortExpression outer grp commons schemas params from
2217− DescNullsLast
2218− :: Expression outer grp commons schemas params from ('Null ty)
2219− -> SortExpression outer grp commons schemas params from
2220−deriving instance Show (SortExpression outer grp commons schemas params from)
2221−
2222−{- |
2223−The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2224−to be sorted according to the specified `SortExpression`(s).
2225−If two rows are equal according to the leftmost expression,
2226−they are compared according to the next expression and so on.
2227−If they are equal according to all specified expressions,
2228−they are returned in an implementation-dependent order.
2229−
2230−You can also control the order in which rows are processed by window functions
2231−using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2232−-}
2233−class OrderBy expr where
2234− orderBy
2235− :: [SortExpression outer grp commons schemas params from]
2236− -> expr outer grp commons schemas params from
2237− -> expr outer grp commons schemas params from
2238−
2239−-- | Render a `SortExpression`.
2240−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2241− renderSQL = \case
2242− Asc expression -> renderSQL expression <+> "ASC"
2243− Desc expression -> renderSQL expression <+> "DESC"
2244− AscNullsFirst expression -> renderSQL expression
2245− <+> "ASC NULLS FIRST"
2246− DescNullsFirst expression -> renderSQL expression
2247− <+> "DESC NULLS FIRST"
2248− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2249− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2250−
2251−-- | A `WindowDefinition` is a set of table rows that are somehow related
2252−-- to the current row
2253−data WindowDefinition outer grp commons schemas params from where
2254− WindowDefinition
2255− :: SListI bys
2256− => NP (Expression outer grp commons schemas params from) bys
2257− -> [SortExpression outer grp commons schemas params from]
2258− -> WindowDefinition outer grp commons schemas params from
2259−
2260−instance OrderBy WindowDefinition where
2261− orderBy sortsR (WindowDefinition parts sortsL)
2262− = WindowDefinition parts (sortsL ++ sortsR)
2263−
2264−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2265− renderSQL (WindowDefinition part ord) =
2266− renderPartitionByClause part <> renderOrderByClause ord
2267− where
2268− renderPartitionByClause = \case
2269− Nil -> ""
2270− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2271− renderOrderByClause = \case
2272− [] -> ""
2273− srts -> " ORDER" <+> "BY"
2274− <+> commaSeparated (renderSQL <$> srts)
2275−
2276−{- |
2277−The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2278−or partitions, that share the same values of the `partitionBy` `Expression`(s).
2279−For each row, the window function is computed across the rows that fall into
2280−the same partition as the current row.
2281−-}
2282−partitionBy
2283− :: SListI bys
2284− => NP (Expression outer grp commons schemas params from) bys
2285− -> WindowDefinition outer grp commons schemas params from
2286−partitionBy bys = WindowDefinition bys []
2287−
2288−{- |
2289−A window function performs a calculation across a set of table rows
2290−that are somehow related to the current row. This is comparable to the type
2291−of calculation that can be done with an aggregate function.
2292−However, window functions do not cause rows to become grouped into a single
2293−output row like non-window aggregate calls would.
2294−Instead, the rows retain their separate identities.
2295−Behind the scenes, the window function is able to access more than
2296−just the current row of the query result.
2297−-}
2298−newtype WindowFunction
2299− (outer :: FromType)
2300− (grp :: Grouping)
2301− (commons :: FromType)
2302− (schemas :: SchemasType)
2303− (params :: [NullityType])
2304− (from :: FromType)
2305− (ty :: NullityType)
2306− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2307− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2308−
2309−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2310− renderSQL = renderWindowFunction
2311−
2312−unsafeWindowFunction1
2313− :: ByteString
2314− -> Expression outer grp commons schemas params from ty0
2315− -> WindowFunction outer grp commons schemas params from ty1
2316−unsafeWindowFunction1 fun x
2317− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2318−
2319−unsafeWindowFunction2
2320− :: ByteString
2321− -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2322− -> WindowFunction outer grp commons schemas params from ty1
2323−unsafeWindowFunction2 fun (x :*: x')
2324− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2325−
2326−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2327−>>> printSQL rank
2328−rank()
2329−-}
2330−rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2331−rank = UnsafeWindowFunction "rank()"
2332−
2333−{- | number of the current row within its partition, counting from 1
2334−>>> printSQL rowNumber
2335−row_number()
2336−-}
2337−rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2338−rowNumber = UnsafeWindowFunction "row_number()"
2339−
2340−{- | rank of the current row without gaps; this function counts peer groups
2341−>>> printSQL denseRank
2342−dense_rank()
2343−-}
2344−denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2345−denseRank = UnsafeWindowFunction "dense_rank()"
2346−
2347−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2348−>>> printSQL percentRank
2349−percent_rank()
2350−-}
2351−percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2352−percentRank = UnsafeWindowFunction "percent_rank()"
2353−
2354−{- | cumulative distribution: (number of partition rows
2355−preceding or peer with current row) / total partition rows
2356−>>> printSQL cumeDist
2357−cume_dist()
2358−-}
2359−cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2360−cumeDist = UnsafeWindowFunction "cume_dist()"
2361−
2362−{- | integer ranging from 1 to the argument value,
2363−dividing the partition as equally as possible
2364−-}
2365−ntile
2366− :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2367− -- ^ num buckets
2368− -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2369−ntile = unsafeWindowFunction1 "ntile"
2370−
2371−{- | returns value evaluated at the row that is offset rows before the current
2372−row within the partition; if there is no such row, instead return default
2373−(which must be of the same type as value). Both offset and default are
2374−evaluated with respect to the current row.
2375−-}
2376−lag
2377− :: Expression outer grp commons schemas params from ty
2378− -- ^ value
2379− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2380− -- ^ offset
2381− -> Expression outer grp commons schemas params from ty
2382− -- ^ default
2383− -> WindowFunction outer grp commons schemas params from ty
2384−lag value offset def = UnsafeWindowFunction $ "lag"
2385− <> parenthesized
2386− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2387−
2388−{- | returns value evaluated at the row that is offset rows after the current
2389−row within the partition; if there is no such row, instead return default
2390−(which must be of the same type as value). Both offset and default are
2391−evaluated with respect to the current row.
2392−-}
2393−lead
2394− :: Expression outer grp commons schemas params from ty
2395− -- ^ value
2396− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2397− -- ^ offset
2398− -> Expression outer grp commons schemas params from ty
2399− -- ^ default
2400− -> WindowFunction outer grp commons schemas params from ty
2401−lead value offset def = UnsafeWindowFunction $ "lag"
2402− <> parenthesized
2403− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2404−
2405−{- | returns value evaluated at the row that is the
2406−first row of the window frame
2407−-}
2408−firstValue
2409− :: Expression outer grp commons schemas params from ty
2410− -- ^ value
2411− -> WindowFunction outer grp commons schemas params from ty
2412−firstValue = unsafeWindowFunction1 "first_value"
2413−
2414−{- | returns value evaluated at the row that is the
2415−last row of the window frame
2416−-}
2417−lastValue
2418− :: Expression outer grp commons schemas params from ty
2419− -- ^ value
2420− -> WindowFunction outer grp commons schemas params from ty
2421−lastValue = unsafeWindowFunction1 "last_value"
2422−
2423−{- | returns value evaluated at the row that is the nth
2424−row of the window frame (counting from 1); null if no such row
2425−-}
2426−nthValue
2427− :: Expression outer grp commons schemas params from (nullity ty)
2428− -- ^ value
2429− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2430− -- ^ nth
2431− -> WindowFunction outer grp commons schemas params from ('Null ty)
2432−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2433− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])
2434−
2435−{-|
2436−Create date from year, month and day fields
2437−
2438−>>> printSQL (makeDate 1984 7 3)
2439−make_date(1984, 7, 3)
2440−-}
2441−makeDate
2442− :: Expression outer grp commons schemas params from (nullity 'PGint4)
2443− -- ^ year
2444− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2445− -- ^ month
2446− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2447− -- ^ day
2448− -> Expression outer grp commons schemas params from (nullity 'PGdate)
2449−makeDate y m d = UnsafeExpression $ "make_date" <>
2450− parenthesized (renderCommaSeparated renderSQL (y :* m :* d :* Nil))
2451−
2452−{-|
2453−Create time from hour, minute and seconds fields
2454−
2455−>>> printSQL (makeTime 8 15 23.5)
2456−make_time(8, 15, 23.5)
2457−-}
2458−makeTime
2459− :: Expression outer grp commons schemas params from (nullity 'PGint4)
2460− -- ^ hour
2461− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2462− -- ^ min
2463− -> Expression outer grp commons schemas params from (nullity 'PGfloat8)
2464− -- ^ sec
2465− -> Expression outer grp commons schemas params from (nullity 'PGtime)
2466−makeTime h m s = UnsafeExpression $ "make_time" <>
2467− parenthesized (renderCommaSeparated renderSQL (h :* m :* s :* Nil))
2468−
2469−{-|
2470−Create timestamp from year, month, day, hour, minute and seconds fields
2471−
2472−>>> printSQL (makeTimestamp 2013 7 15 8 15 23.5)
2473−make_timestamp(2013, 7, 15, 8, 15, 23.5)
2474−-}
2475−makeTimestamp
2476− :: Expression outer grp commons schemas params from (nullity 'PGint4)
2477− -- ^ year
2478− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2479− -- ^ month
2480− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2481− -- ^ day
2482− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2483− -- ^ hour
2484− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2485− -- ^ min
2486− -> Expression outer grp commons schemas params from (nullity 'PGfloat8)
2487− -- ^ sec
2488− -> Expression outer grp commons schemas params from (nullity 'PGtimestamp)
2489−makeTimestamp y mon d h m s =
2490− UnsafeExpression $ "make_timestamp" <> parenthesized
2491− (renderCommaSeparated renderSQL (y :* mon :* d :* h :* m :* s :* Nil))
2492−
2493−{-|
2494−Create timestamp with time zone from
2495−year, month, day, hour, minute and seconds fields;
2496−the current time zone is used
2497−
2498−>>> printSQL (makeTimestamptz 2013 7 15 8 15 23.5)
2499−make_timestamptz(2013, 7, 15, 8, 15, 23.5)
2500−-}
2501−makeTimestamptz
2502− :: Expression outer grp commons schemas params from (nullity 'PGint4)
2503− -- ^ year
2504− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2505− -- ^ month
2506− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2507− -- ^ day
2508− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2509− -- ^ hour
2510− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2511− -- ^ min
2512− -> Expression outer grp commons schemas params from (nullity 'PGfloat8)
2513− -- ^ sec
2514− -> Expression outer grp commons schemas params from (nullity 'PGtimestamptz)
2515−makeTimestamptz y mon d h m s =
2516− UnsafeExpression $ "make_timestamptz" <> parenthesized
2517− (renderCommaSeparated renderSQL (y :* mon :* d :* h :* m :* s :* Nil))
2518−
2519−{-|
2520−Affine space operations on time types.
2521−-}
2522−class TimeOp time diff | time -> diff where
2523− {-|
2524− >>> printSQL (makeDate 1984 7 3 !+ 365)
2525− (make_date(1984, 7, 3) + 365)
2526− -}
2527− (!+) :: Operator (nullity time) (nullity diff) (nullity time)
2528− (!+) = unsafeBinaryOp "+"
2529− {-|
2530− >>> printSQL (365 +! makeDate 1984 7 3)
2531− (365 + make_date(1984, 7, 3))
2532− -}
2533− (+!) :: Operator (nullity diff) (nullity time) (nullity time)
2534− (+!) = unsafeBinaryOp "+"
2535− {-|
2536− >>> printSQL (makeDate 1984 7 3 !- 365)
2537− (make_date(1984, 7, 3) - 365)
2538− -}
2539− (!-) :: Operator (nullity time) (nullity diff) (nullity time)
2540− (!-) = unsafeBinaryOp "-"
2541− {-|
2542− >>> printSQL (makeDate 1984 7 3 !-! currentDate)
2543− (make_date(1984, 7, 3) - CURRENT_DATE)
2544− -}
2545− (!-!) :: Operator (nullity time) (nullity time) (nullity diff)
2546− (!-!) = unsafeBinaryOp "-"
2547−instance TimeOp 'PGtimestamp 'PGinterval
2548−instance TimeOp 'PGtimestamptz 'PGinterval
2549−instance TimeOp 'PGtime 'PGinterval
2550−instance TimeOp 'PGtimetz 'PGinterval
2551−instance TimeOp 'PGinterval 'PGinterval
2552−instance TimeOp 'PGdate 'PGint4
2553−infixl 6 !+
2554−infixl 6 +!
2555−infixl 6 !-
2556−infixl 6 !-!