@@ -1,14 +1,13 @@
11{-|
2−Module: Squeal.PostgreSQL.Query
2+Module: 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,290 +33,214 @@ Squeal expressions are the atoms used to build statements.
3433module Squeal.PostgreSQL.Expression
3534 ( -- * Expression
3635 Expression (..)
37− , HasParameter (parameter)
38− , param
39− -- ** Null
40− , null_
41− , notNull
42− , coalesce
43− , fromNull
44− , isNull
45− , isNotNull
46− , matchNull
47− , nullIf
48− -- ** Collections
49− , array
50− , index
51− , row
52− , field
53− -- ** Functions
54− , unsafeBinaryOp
55− , unsafeUnaryOp
36+ , Expr
37+ , type (-->)
38+ , FunctionDB
5639 , unsafeFunction
57− , unsafeVariadicFunction
58− , atan2_
59− , cast
60− , quot_
61− , rem_
62− , trunc
63− , round_
64− , ceiling_
65− , greatest
66− , least
67− -- ** Conditions
68− , true
69− , false
70− , not_
71− , (.&&)
72− , (.||)
73− , Condition
74− , caseWhenThenElse
75− , ifThenElse
76− , (.==)
77− , (./=)
78− , (.>=)
79− , (.<)
80− , (.<=)
81− , (.>)
82− -- ** Time
83− , currentDate
84− , currentTime
85− , currentTimestamp
86− , localTime
87− , localTimestamp
88− -- ** Text
89− , lower
90− , upper
91− , charLength
92− , like
93− , ilike
94− -- ** Json
95− -- *** Json and Jsonb operators
96− , (.->)
97− , (.->>)
98− , (.#>)
99− , (.#>>)
100− -- *** Jsonb operators
101− , (.@>)
102− , (.<@)
103− , (.?)
104− , (.?|)
105− , (.?&)
106− , (.-.)
107− , (#-.)
108− -- *** Functions
109− , jsonLit
110− , jsonbLit
111− , toJson
112− , toJsonb
113− , arrayToJson
114− , rowToJson
115− , jsonBuildArray
116− , jsonbBuildArray
117− , jsonBuildObject
118− , jsonbBuildObject
119− , jsonObject
120− , jsonbObject
121− , jsonZipObject
122− , jsonbZipObject
123− , jsonArrayLength
124− , jsonbArrayLength
125− , jsonExtractPath
126− , jsonbExtractPath
127− , jsonExtractPathAsText
128− , jsonbExtractPathAsText
129− , jsonTypeof
130− , jsonbTypeof
131− , jsonStripNulls
132− , jsonbStripNulls
133− , jsonbSet
134− , jsonbInsert
135− , jsonbPretty
136− -- ** Aggregation
137− , Aggregate (..)
138− , Distinction (..)
139− , PGAvg
140− -- * Window Functions
141− , WindowDefinition (..)
142− , partitionBy
143− , WindowFunction (..)
144− , rank
145− , rowNumber
146− , denseRank
147− , percentRank
148− , cumeDist
149− , ntile
150− , lag
151− , lead
152− , firstValue
153− , lastValue
154− , nthValue
155− -- * Sorting
156− , SortExpression (..)
157− , OrderBy (..)
158− -- * Types
159− , TypeExpression (..)
160− , PGTyped (..)
161− , typedef
162− , typetable
163− , typeview
164− , bool
165− , int2
166− , smallint
167− , int4
168− , int
169− , integer
170− , int8
171− , bigint
172− , numeric
173− , float4
174− , real
175− , float8
176− , doublePrecision
177− , text
178− , char
179− , character
180− , varchar
181− , characterVarying
182− , bytea
183− , timestamp
184− , timestampWithTimeZone
185− , date
186− , time
187− , timeWithTimeZone
188− , interval
189− , uuid
190− , inet
191− , json
192− , jsonb
193− , vararray
194− , fixarray
40+ , function
41+ , unsafeLeftOp
42+ , leftOp
43+ , unsafeRightOp
44+ , rightOp
45+ , Operator
46+ , OperatorDB
47+ , unsafeBinaryOp
48+ , binaryOp
49+ , FunctionVar
50+ , unsafeFunctionVar
51+ , type (--->)
52+ , FunctionNDB
53+ , unsafeFunctionN
54+ , functionN
55+ , PGSubset (..)
56+ , PGIntersect (..)
19557 -- * Re-export
19658 , (&)
197− , NP (..)
198− , (:*:) (..)
19959 , K (..)
60+ , unK
20061 ) where
20162
20263import Control.Category
20364import Control.DeepSeq
20465import Data.ByteString (ByteString)
205−import Data.ByteString.Lazy (toStrict)
20666import Data.Function ((&))
20767import Data.Semigroup hiding (All)
208−import qualified Data.Aeson as JSON
209−import Data.Ratio
21068import Data.String
211−import Data.Word
212−import Generics.SOP hiding (from)
213−import GHC.Generics ((:*:) (..))
69+import Generics.SOP hiding (All, from)
21470import GHC.OverloadedLabels
21571import GHC.TypeLits
72+import Numeric
21673import Prelude hiding (id, (.))
21774
218−import qualified Data.ByteString as ByteString
21975import qualified GHC.Generics as GHC
22076
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
22179import Squeal.PostgreSQL.Render
22280import Squeal.PostgreSQL.Schema
22381
82+-- $setup
83+-- >>> import Squeal.PostgreSQL
84+
22485{-----------------------------------------
22586column expressions
22687-----------------------------------------}
22788
22889{- | `Expression`s are used in a variety of contexts,
229−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,
23092as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
23193`Squeal.PostgreSQL.Manipulation.update`,
232−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
23395
23496The expression syntax allows the calculation of
23597values from primitive expression using arithmetic, logical,
23698and 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`.
237113-}
238114newtype Expression
239115 (outer :: FromType)
240− (grp :: Grouping)
241116 (commons :: FromType)
117+ (grp :: Grouping)
242118 (schemas :: SchemasType)
243119 (params :: [NullityType])
244120 (from :: FromType)
245121 (ty :: NullityType)
246122 = UnsafeExpression { renderExpression :: ByteString }
247123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
248−
249−instance RenderSQL (Expression outer grp commons schemas params from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
250125 renderSQL = renderExpression
251126
252−{- | A `HasParameter` constraint is used to indicate a value that is
253−supplied externally to a SQL statement.
254−`Squeal.PostgreSQL.PQ.manipulateParams`,
255−`Squeal.PostgreSQL.PQ.queryParams` and
256−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
257−separately from the SQL command string, in which case `param`s are used to
258−refer to the out-of-line data values.
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.
139+type Operator x1 x2 y
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)
259181-}
260−class KnownNat n => HasParameter
261− (n :: Nat)
262− (params :: [NullityType])
263− (ty :: NullityType)
264− | n params -> ty where
265− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
266− --
267− -- >>> let expr = parameter @1 int4 :: Expression outer grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
268− -- >>> printSQL expr
269− -- ($1 :: int4)
270− parameter
271− :: TypeExpression schemas ty
272− -> Expression outer grp commons schemas params from ty
273− parameter ty = UnsafeExpression $ parenthesized $
274− "$" <> renderNat @n <+> "::"
275− <+> renderSQL ty
276−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
277−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
278− => HasParameter n (ty' : params) ty
279−
280−-- | `param` takes a `Nat` using type application and for basic types,
281−-- infers a `TypeExpression`.
282−--
283−-- >>> let expr = param @1 :: Expression outer grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
284−-- >>> printSQL expr
285−-- ($1 :: int4)
286−param
287− :: forall n outer commons schemas params from grp ty
288− . (PGTyped schemas ty, HasParameter n params ty)
289− => Expression outer grp commons schemas params from ty -- ^ param
290−param = parameter @n (pgtype @schemas)
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)
291214
292215instance (HasUnique tab (Join outer from) row, Has col row ty)
293− => IsLabel col (Expression outer 'Ungrouped commons schemas params from ty) where
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
294217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
295218instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
296− => 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
297220 fromLabel = fromLabel @col :* Nil
298221instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
299222 => IsLabel col
300− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
301224 fromLabel = fromLabel @col `As` Alias
302225instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
303226 => IsLabel col
304− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
305228 fromLabel = fromLabel @col :* Nil
306229
307230instance (Has tab (Join outer from) row, Has col row ty)
308− => 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
309232 tab ! col = UnsafeExpression $
310233 renderSQL tab <> "." <> renderSQL col
311234instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
312− => 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
313236 tab ! col = tab ! col :* Nil
314237instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
315238 => IsQualified tab col
316− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
317240 tab ! col = tab ! col `As` col
318241instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
319242 => IsQualified tab col
320− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
321244 tab ! col = tab ! col :* Nil
322245
323246instance
@@ -325,7 +248,7 @@ instance
325248 , Has col row ty
326249 , GroupedBy tab col bys
327250 ) => IsLabel col
328− (Expression outer ('Grouped bys) commons schemas params from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
329252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
330253instance
331254 ( HasUnique tab (Join outer from) row
@@ -333,7 +256,7 @@ instance
333256 , GroupedBy tab col bys
334257 , tys ~ '[ty]
335258 ) => IsLabel col
336− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
337260 fromLabel = fromLabel @col :* Nil
338261instance
339262 ( HasUnique tab (Join outer from) row
@@ -341,7 +264,7 @@ instance
341264 , GroupedBy tab col bys
342265 , column ~ (col ::: ty)
343266 ) => IsLabel col
344− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
345268 fromLabel = fromLabel @col `As` Alias
346269instance
347270 ( HasUnique tab (Join outer from) row
@@ -349,7 +272,7 @@ instance
349272 , GroupedBy tab col bys
350273 , columns ~ '[col ::: ty]
351274 ) => IsLabel col
352− (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
353276 fromLabel = fromLabel @col :* Nil
354277
355278instance
@@ -357,7 +280,7 @@ instance
357280 , Has col row ty
358281 , GroupedBy tab col bys
359282 ) => IsQualified tab col
360− (Expression outer ('Grouped bys) commons schemas params from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
361284 tab ! col = UnsafeExpression $
362285 renderSQL tab <> "." <> renderSQL col
363286instance
@@ -366,7 +289,7 @@ instance
366289 , GroupedBy tab col bys
367290 , tys ~ '[ty]
368291 ) => IsQualified tab col
369− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
370293 tab ! col = tab ! col :* Nil
371294instance
372295 ( Has tab (Join outer from) row
@@ -374,7 +297,7 @@ instance
374297 , GroupedBy tab col bys
375298 , column ~ (col ::: ty)
376299 ) => IsQualified tab col
377− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
378301 tab ! col = tab ! col `As` col
379302instance
380303 ( Has tab (Join outer from) row
@@ -382,237 +305,78 @@ instance
382305 , GroupedBy tab col bys
383306 , columns ~ '[col ::: ty]
384307 ) => IsQualified tab col
385− (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
386309 tab ! col = tab ! col :* Nil
387310
388−-- | analagous to `Nothing`
389−--
390−-- >>> printSQL null_
391−-- NULL
392−null_ :: Expression outer grp commons schemas params from ('Null ty)
393−null_ = UnsafeExpression "NULL"
394−
395−-- | analagous to `Just`
396−--
397−-- >>> printSQL $ notNull true
398−-- TRUE
399−notNull
400− :: Expression outer grp commons schemas params from ('NotNull ty)
401− -> Expression outer grp commons schemas params from ('Null ty)
402−notNull = UnsafeExpression . renderSQL
403−
404−-- | return the leftmost value which is not NULL
405−--
406−-- >>> printSQL $ coalesce [null_, true] false
407−-- COALESCE(NULL, TRUE, FALSE)
408−coalesce
409− :: [Expression outer grp commons schemas params from ('Null ty)]
410− -- ^ @NULL@s may be present
411− -> Expression outer grp commons schemas params from ('NotNull ty)
412− -- ^ @NULL@ is absent
413− -> Expression outer grp commons schemas params from ('NotNull ty)
414−coalesce nullxs notNullx = UnsafeExpression $
415− "COALESCE" <> parenthesized (commaSeparated
416− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
417−
418−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
419−--
420−-- >>> printSQL $ fromNull true null_
421−-- COALESCE(NULL, TRUE)
422−fromNull
423− :: Expression outer grp commons schemas params from ('NotNull ty)
424− -- ^ what to convert @NULL@ to
425− -> Expression outer grp commons schemas params from ('Null ty)
426− -> Expression outer grp commons schemas params from ('NotNull ty)
427−fromNull notNullx nullx = coalesce [nullx] notNullx
428−
429−-- | >>> printSQL $ null_ & isNull
430−-- NULL IS NULL
431−isNull
432− :: Expression outer grp commons schemas params from ('Null ty)
433− -- ^ possibly @NULL@
434− -> Condition outer grp commons schemas params from
435−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
436−
437−-- | >>> printSQL $ null_ & isNotNull
438−-- NULL IS NOT NULL
439−isNotNull
440− :: Expression outer grp commons schemas params from ('Null ty)
441− -- ^ possibly @NULL@
442− -> Condition outer grp commons schemas params from
443−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
444−
445−-- | analagous to `maybe` using @IS NULL@
446−--
447−-- >>> printSQL $ matchNull true not_ null_
448−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
449−matchNull
450− :: Expression outer grp commons schemas params from (nullty)
451− -- ^ what to convert @NULL@ to
452− -> ( Expression outer grp commons schemas params from ('NotNull ty)
453− -> Expression outer grp commons schemas params from (nullty) )
454− -- ^ function to perform when @NULL@ is absent
455− -> Expression outer grp commons schemas params from ('Null ty)
456− -> Expression outer grp commons schemas params from (nullty)
457−matchNull y f x = ifThenElse (isNull x) y
458− (f (UnsafeExpression (renderSQL x)))
459−
460−{-| right inverse to `fromNull`, if its arguments are equal then
461−`nullIf` gives @NULL@.
462−
463−>>> :set -XTypeApplications -XDataKinds
464−>>> let expr = nullIf false (param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
465−>>> printSQL expr
466−NULL IF (FALSE, ($1 :: bool))
467−-}
468−nullIf
469− :: Expression outer grp commons schemas params from ('NotNull ty)
470− -- ^ @NULL@ is absent
471− -> Expression outer grp commons schemas params from ('NotNull ty)
472− -- ^ @NULL@ is absent
473− -> Expression outer grp commons schemas params from ('Null ty)
474−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
475− (renderSQL x <> ", " <> renderSQL y)
476−
477−-- | >>> printSQL $ array [null_, false, true]
478−-- ARRAY[NULL, FALSE, TRUE]
479−array
480− :: [Expression outer grp commons schemas params from ty]
481− -- ^ array elements
482− -> Expression outer grp commons schemas params from (nullity ('PGvararray ty))
483−array xs = UnsafeExpression $
484− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
485−
486−-- | >>> printSQL $ array [null_, false, true] & index 2
487−-- (ARRAY[NULL, FALSE, TRUE])[2]
488−index
489− :: Word64 -- ^ index
490− -> Expression outer grp commons schemas params from (nullity ('PGvararray ty)) -- ^ array
491− -> Expression outer grp commons schemas params from (NullifyType ty)
492−index n expr = UnsafeExpression $
493− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
494−
495311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
496− (Expression outer grp commons schemas params from (nullity ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
497313 label = UnsafeExpression $ renderSQL (PGlabel @label)
498314
499−-- | A row constructor is an expression that builds a row value
500−-- (also called a composite value) using values for its member fields.
501−--
502−-- >>> :{
503−-- type Complex = 'PGcomposite
504−-- '[ "real" ::: 'NotNull 'PGfloat8
505−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
506−-- :}
507−--
508−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
509−-- >>> printSQL i
510−-- ROW(0, 1)
511−row
512− :: SListI row
513− => NP (Aliased (Expression outer grp commons schemas params from)) row
514− -- ^ zero or more expressions for the row field values
515− -> Expression outer grp commons schemas params from (nullity ('PGcomposite row))
516−row exprs = UnsafeExpression $ "ROW" <> parenthesized
517− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
518−
519−-- | >>> :{
520−-- type Complex = 'PGcomposite
521−-- '[ "real" ::: 'NotNull 'PGfloat8
522−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
523−-- type Schema = '["complex" ::: 'Typedef Complex]
524−-- :}
525−--
526−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
527−-- >>> printSQL $ i & field #complex #imaginary
528−-- (ROW(0, 1)::"complex")."imaginary"
529−field
530− :: ( Has sch schemas schema
531− , Has tydef schema ('Typedef ('PGcomposite row))
532− , Has field row ty)
533− => QualifiedAlias sch tydef -- ^ row type
534− -> Alias field -- ^ field name
535− -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
536− -> Expression outer grp commons schemas params from ty
537−field td fld expr = UnsafeExpression $
538− parenthesized (renderSQL expr <> "::" <> renderSQL td)
539− <> "." <> renderSQL fld
540−
541−instance Semigroup
542− (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
543− (<>) = unsafeBinaryOp "||"
544−
545−instance Monoid
546− (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
547− mempty = array []
548− mappend = (<>)
549−
550−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
551−-- >>> printSQL expr
552−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
553−greatest
554− :: Expression outer grp commons schemas params from (nullty)
555− -- ^ needs at least 1 argument
556− -> [Expression outer grp commons schemas params from (nullty)]
557− -- ^ or more
558− -> Expression outer grp commons schemas params from (nullty)
559−greatest x xs = UnsafeExpression $ "GREATEST("
560− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
561−
562−-- | >>> printSQL $ least currentTimestamp [null_]
563−-- LEAST(CURRENT_TIMESTAMP, NULL)
564−least
565− :: Expression outer grp commons schemas params from (nullty)
566− -- ^ needs at least 1 argument
567− -> [Expression outer grp commons schemas params from (nullty)]
568− -- ^ or more
569− -> Expression outer grp commons schemas params from (nullty)
570−least x xs = UnsafeExpression $ "LEAST("
571− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
572−
573315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
574316-- (TRUE OR FALSE)
575−unsafeBinaryOp
576− :: ByteString
577− -- ^ operator
578− -> Expression outer grp commons schemas params from (ty0)
579− -> Expression outer grp commons schemas params from (ty1)
580− -> Expression outer grp commons schemas params from (ty2)
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
581318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
582319 renderSQL x <+> op <+> renderSQL y
583320
584−-- | >>> 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
585329-- (NOT TRUE)
586−unsafeUnaryOp
587− :: ByteString
588− -- ^ operator
589− -> Expression outer grp commons schemas params from (ty0)
590− -> Expression outer grp commons schemas params from (ty1)
591−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
592− 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
593351
594352-- | >>> printSQL $ unsafeFunction "f" true
595353-- f(TRUE)
596−unsafeFunction
597− :: ByteString
598− -- ^ function
599− -> Expression outer grp commons schemas params from (xty)
600− -> Expression outer grp commons schemas params from (yty)
354+unsafeFunction :: ByteString -> x --> y
601355unsafeFunction fun x = UnsafeExpression $
602356 fun <> parenthesized (renderSQL x)
603357
604−-- | Helper for defining variadic functions.
605−unsafeVariadicFunction
606− :: SListI elems
607− => ByteString
608− -- ^ function
609− -> NP (Expression outer grp commons schemas params from) elems
610− -> Expression outer grp commons schemas params from ret
611−unsafeVariadicFunction fun x = UnsafeExpression $
612− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderSQL) x)))
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)
369+
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
613377
614378instance ty `In` PGNum
615− => Num (Expression outer grp commons schemas params from (nullity ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
616380 (+) = unsafeBinaryOp "+"
617381 (-) = unsafeBinaryOp "-"
618382 (*) = unsafeBinaryOp "*"
@@ -624,12 +388,17 @@ instance ty `In` PGNum
624388 . show
625389
626390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
627− (Expression outer grp commons schemas params from (nullity ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
628392 (/) = unsafeBinaryOp "/"
629− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
393+ fromRational
394+ = UnsafeExpression
395+ . fromString
396+ . ($ "")
397+ . showFFloat Nothing
398+ . fromRat @Double
630399
631400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
632− (Expression outer grp commons schemas params from (nullity ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
633402 pi = UnsafeExpression "pi()"
634403 exp = unsafeFunction "exp"
635404 log = unsafeFunction "ln"
@@ -650,1564 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
650419 acosh x = log (x + sqrt (x*x - 1))
651420 atanh x = log ((1 + x) / (1 - x)) / 2
652421
653−-- | >>> :{
654−-- let
655−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
656−-- expression = atan2_ pi 2
657−-- in printSQL expression
658−-- :}
659−-- atan2(pi(), 2)
660−atan2_
661− :: float `In` PGFloating
662− => Expression outer grp commons schemas params from (nullity float)
663− -- ^ numerator
664− -> Expression outer grp commons schemas params from (nullity float)
665− -- ^ denominator
666− -> Expression outer grp commons schemas params from (nullity float)
667−atan2_ y x = UnsafeExpression $
668− "atan2(" <> renderSQL y <> ", " <> renderSQL x <> ")"
669−
670−-- When a `cast` is applied to an `Expression` of a known type, it
671−-- represents a run-time type conversion. The cast will succeed only if a
672−-- suitable type conversion operation has been defined.
673−--
674−-- | >>> printSQL $ true & cast int4
675−-- (TRUE :: int4)
676−cast
677− :: TypeExpression schemas ty1
678− -- ^ type to cast as
679− -> Expression outer grp commons schemas params from ty0
680− -- ^ value to convert
681− -> Expression outer grp commons schemas params from ty1
682−cast ty x = UnsafeExpression $ parenthesized $
683− renderSQL x <+> "::" <+> renderSQL ty
684−
685−-- | integer division, truncates the result
686−--
687−-- >>> :{
688−-- let
689−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
690−-- expression = 5 `quot_` 2
691−-- in printSQL expression
692−-- :}
693−-- (5 / 2)
694−quot_
695− :: int `In` PGIntegral
696− => Expression outer grp commons schemas params from (nullity int)
697− -- ^ numerator
698− -> Expression outer grp commons schemas params from (nullity int)
699− -- ^ denominator
700− -> Expression outer grp commons schemas params from (nullity int)
701−quot_ = unsafeBinaryOp "/"
702−
703−-- | remainder upon integer division
704−--
705−-- >>> :{
706−-- let
707−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
708−-- expression = 5 `rem_` 2
709−-- in printSQL expression
710−-- :}
711−-- (5 % 2)
712−rem_
713− :: int `In` PGIntegral
714− => Expression outer grp commons schemas params from (nullity int)
715− -- ^ numerator
716− -> Expression outer grp commons schemas params from (nullity int)
717− -- ^ denominator
718− -> Expression outer grp commons schemas params from (nullity int)
719−rem_ = unsafeBinaryOp "%"
720−
721−-- | >>> :{
722−-- let
723−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
724−-- expression = trunc pi
725−-- in printSQL expression
726−-- :}
727−-- trunc(pi())
728−trunc
729− :: frac `In` PGFloating
730− => Expression outer grp commons schemas params from (nullity frac)
731− -- ^ fractional number
732− -> Expression outer grp commons schemas params from (nullity frac)
733−trunc = unsafeFunction "trunc"
734−
735−-- | >>> :{
736−-- let
737−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
738−-- expression = round_ pi
739−-- in printSQL expression
740−-- :}
741−-- round(pi())
742−round_
743− :: frac `In` PGFloating
744− => Expression outer grp commons schemas params from (nullity frac)
745− -- ^ fractional number
746− -> Expression outer grp commons schemas params from (nullity frac)
747−round_ = unsafeFunction "round"
748−
749−-- | >>> :{
750−-- let
751−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
752−-- expression = ceiling_ pi
753−-- in printSQL expression
754−-- :}
755−-- ceiling(pi())
756−ceiling_
757− :: frac `In` PGFloating
758− => Expression outer grp commons schemas params from (nullity frac)
759− -- ^ fractional number
760− -> Expression outer grp commons schemas params from (nullity frac)
761−ceiling_ = unsafeFunction "ceiling"
762−
763−-- | A `Condition` is an `Expression`, which can evaluate
764−-- to `true`, `false` or `null_`. This is because SQL uses
765−-- a three valued logic.
766−type Condition outer grp commons schemas params from =
767− Expression outer grp commons schemas params from ('Null 'PGbool)
768−
769−-- | >>> printSQL true
770−-- TRUE
771−true :: Expression outer grp commons schemas params from (nullity 'PGbool)
772−true = UnsafeExpression "TRUE"
773−
774−-- | >>> printSQL false
775−-- FALSE
776−false :: Expression outer grp commons schemas params from (nullity 'PGbool)
777−false = UnsafeExpression "FALSE"
778−
779−-- | >>> printSQL $ not_ true
780−-- (NOT TRUE)
781−not_
782− :: Expression outer grp commons schemas params from (nullity 'PGbool)
783− -> Expression outer grp commons schemas params from (nullity 'PGbool)
784−not_ = unsafeUnaryOp "NOT"
785−
786−-- | >>> printSQL $ true .&& false
787−-- (TRUE AND FALSE)
788−(.&&)
789− :: Expression outer grp commons schemas params from (nullity 'PGbool)
790− -> Expression outer grp commons schemas params from (nullity 'PGbool)
791− -> Expression outer grp commons schemas params from (nullity 'PGbool)
792−infixr 3 .&&
793−(.&&) = unsafeBinaryOp "AND"
794−
795−-- | >>> printSQL $ true .|| false
796−-- (TRUE OR FALSE)
797−(.||)
798− :: Expression outer grp commons schemas params from (nullity 'PGbool)
799− -> Expression outer grp commons schemas params from (nullity 'PGbool)
800− -> Expression outer grp commons schemas params from (nullity 'PGbool)
801−infixr 2 .||
802−(.||) = unsafeBinaryOp "OR"
803−
804−-- | >>> :{
805−-- let
806−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
807−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
808−-- in printSQL expression
809−-- :}
810−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
811−caseWhenThenElse
812− :: [ ( Condition outer grp commons schemas params from
813− , Expression outer grp commons schemas params from ty
814− ) ]
815− -- ^ whens and thens
816− -> Expression outer grp commons schemas params from ty
817− -- ^ else
818− -> Expression outer grp commons schemas params from ty
819−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
820− [ "CASE"
821− , mconcat
822− [ mconcat
823− [ " WHEN ", renderSQL when_
824− , " THEN ", renderSQL then_
825− ]
826− | (when_,then_) <- whenThens
827− ]
828− , " ELSE ", renderSQL else_
829− , " END"
830− ]
831−
832−-- | >>> :{
833−-- let
834−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
835−-- expression = ifThenElse true 1 0
836−-- in printSQL expression
837−-- :}
838−-- CASE WHEN TRUE THEN 1 ELSE 0 END
839−ifThenElse
840− :: Condition outer grp commons schemas params from
841− -> Expression outer grp commons schemas params from ty -- ^ then
842− -> Expression outer grp commons schemas params from ty -- ^ else
843− -> Expression outer grp commons schemas params from ty
844−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
845−
846−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
847−-- will produce @NULL@s if one of their arguments is @NULL@.
848−--
849−-- >>> printSQL $ true .== null_
850−-- (TRUE = NULL)
851−(.==)
852− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
853− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
854− -> Condition outer grp commons schemas params from
855−(.==) = unsafeBinaryOp "="
856−infix 4 .==
857−
858−-- | >>> printSQL $ true ./= null_
859−-- (TRUE <> NULL)
860−(./=)
861− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
862− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
863− -> Condition outer grp commons schemas params from
864−(./=) = unsafeBinaryOp "<>"
865−infix 4 ./=
866−
867−-- | >>> printSQL $ true .>= null_
868−-- (TRUE >= NULL)
869−(.>=)
870− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
871− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
872− -> Condition outer grp commons schemas params from
873−(.>=) = unsafeBinaryOp ">="
874−infix 4 .>=
875−
876−-- | >>> printSQL $ true .< null_
877−-- (TRUE < NULL)
878−(.<)
879− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
880− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
881− -> Condition outer grp commons schemas params from
882−(.<) = unsafeBinaryOp "<"
883−infix 4 .<
884−
885−-- | >>> printSQL $ true .<= null_
886−-- (TRUE <= NULL)
887−(.<=)
888− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
889− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
890− -> Condition outer grp commons schemas params from
891−(.<=) = unsafeBinaryOp "<="
892−infix 4 .<=
893−
894−-- | >>> printSQL $ true .> null_
895−-- (TRUE > NULL)
896−(.>)
897− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
898− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
899− -> Condition outer grp commons schemas params from
900−(.>) = unsafeBinaryOp ">"
901−infix 4 .>
902−
903−-- | >>> printSQL currentDate
904−-- CURRENT_DATE
905−currentDate
906− :: Expression outer grp commons schemas params from (nullity 'PGdate)
907−currentDate = UnsafeExpression "CURRENT_DATE"
908−
909−-- | >>> printSQL currentTime
910−-- CURRENT_TIME
911−currentTime
912− :: Expression outer grp commons schemas params from (nullity 'PGtimetz)
913−currentTime = UnsafeExpression "CURRENT_TIME"
914−
915−-- | >>> printSQL currentTimestamp
916−-- CURRENT_TIMESTAMP
917−currentTimestamp
918− :: Expression outer grp commons schemas params from (nullity 'PGtimestamptz)
919−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
920−
921−-- | >>> printSQL localTime
922−-- LOCALTIME
923−localTime
924− :: Expression outer grp commons schemas params from (nullity 'PGtime)
925−localTime = UnsafeExpression "LOCALTIME"
926−
927−-- | >>> printSQL localTimestamp
928−-- LOCALTIMESTAMP
929−localTimestamp
930− :: Expression outer grp commons schemas params from (nullity 'PGtimestamp)
931−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
932−
933−{-----------------------------------------
934−text
935−-----------------------------------------}
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)
936438
937439instance IsString
938− (Expression outer grp commons schemas params from (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
939441 fromString str = UnsafeExpression $
940442 "E\'" <> fromString (escape =<< str) <> "\'"
941− where
942− escape = \case
943− '\NUL' -> "\\0"
944− '\'' -> "''"
945− '"' -> "\\\""
946− '\b' -> "\\b"
947− '\n' -> "\\n"
948− '\r' -> "\\r"
949− '\t' -> "\\t"
950− '\\' -> "\\\\"
951− c -> [c]
443+instance IsString
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
446+ "E\'" <> fromString (escape =<< str) <> "\'"
447+instance IsString
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
450+ "E\'" <> fromString (escape =<< str) <> "\'"
952451
953452instance Semigroup
954− (Expression outer grp commons schemas params from (nullity 'PGtext)) where
453+ (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
454+ (<>) = unsafeBinaryOp "||"
455+instance Semigroup
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
955463 (<>) = unsafeBinaryOp "||"
956464
957465instance Monoid
958− (Expression outer grp commons schemas params from (nullity 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
467+ mempty = fromString ""
468+ mappend = (<>)
469+instance Monoid
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
959471 mempty = fromString ""
960472 mappend = (<>)
961−
962−-- | >>> printSQL $ lower "ARRRGGG"
963−-- lower(E'ARRRGGG')
964−lower
965− :: Expression outer grp commons schemas params from (nullity 'PGtext)
966− -- ^ string to lower case
967− -> Expression outer grp commons schemas params from (nullity 'PGtext)
968−lower = unsafeFunction "lower"
969−
970−-- | >>> printSQL $ upper "eeee"
971−-- upper(E'eeee')
972−upper
973− :: Expression outer grp commons schemas params from (nullity 'PGtext)
974− -- ^ string to upper case
975− -> Expression outer grp commons schemas params from (nullity 'PGtext)
976−upper = unsafeFunction "upper"
977−
978−-- | >>> printSQL $ charLength "four"
979−-- char_length(E'four')
980−charLength
981− :: Expression outer grp commons schemas params from (nullity 'PGtext)
982− -- ^ string to measure
983− -> Expression outer grp commons schemas params from (nullity 'PGint4)
984−charLength = unsafeFunction "char_length"
985−
986−-- | The `like` expression returns true if the @string@ matches
987−-- the supplied @pattern@. If @pattern@ does not contain percent signs
988−-- or underscores, then the pattern only represents the string itself;
989−-- in that case `like` acts like the equals operator. An underscore (_)
990−-- in pattern stands for (matches) any single character; a percent sign (%)
991−-- matches any sequence of zero or more characters.
992−--
993−-- >>> printSQL $ "abc" `like` "a%"
994−-- (E'abc' LIKE E'a%')
995−like
996− :: Expression outer grp commons schemas params from (nullity 'PGtext)
997− -- ^ string
998− -> Expression outer grp commons schemas params from (nullity 'PGtext)
999− -- ^ pattern
1000− -> Expression outer grp commons schemas params from (nullity 'PGbool)
1001−like = unsafeBinaryOp "LIKE"
1002−
1003−-- | The key word ILIKE can be used instead of LIKE to make the
1004−-- match case-insensitive according to the active locale.
1005−--
1006−-- >>> printSQL $ "abc" `ilike` "a%"
1007−-- (E'abc' ILIKE E'a%')
1008−ilike
1009− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1010− -- ^ string
1011− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1012− -- ^ pattern
1013− -> Expression outer grp commons schemas params from (nullity 'PGbool)
1014−ilike = unsafeBinaryOp "ILIKE"
1015−
1016−{-----------------------------------------
1017− -- json and jsonb support
1018−
1019−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1020−comments lifted directly from this page.
1021−
1022−Table 9.44: json and jsonb operators
1023−-----------------------------------------}
1024−
1025−-- | Get JSON value (object field or array element) at a key.
1026−(.->)
1027− :: (json `In` PGJsonType, key `In` PGJsonKey)
1028− => Expression outer grp commons schemas params from (nullity json)
1029− -> Expression outer grp commons schemas params from (nullity key)
1030− -> Expression outer grp commons schemas params from ('Null json)
1031−infixl 8 .->
1032−(.->) = unsafeBinaryOp "->"
1033−
1034−-- | Get JSON value (object field or array element) at a key, as text.
1035−(.->>)
1036− :: (json `In` PGJsonType, key `In` PGJsonKey)
1037− => Expression outer grp commons schemas params from (nullity json)
1038− -> Expression outer grp commons schemas params from (nullity key)
1039− -> Expression outer grp commons schemas params from ('Null 'PGtext)
1040−infixl 8 .->>
1041−(.->>) = unsafeBinaryOp "->>"
1042−
1043−-- | Get JSON value at a specified path.
1044−(.#>)
1045− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1046− => Expression outer grp commons schemas params from (nullity json)
1047− -> Expression outer grp commons schemas params from (nullity path)
1048− -> Expression outer grp commons schemas params from ('Null json)
1049−infixl 8 .#>
1050−(.#>) = unsafeBinaryOp "#>"
1051−
1052−-- | Get JSON value at a specified path as text.
1053−(.#>>)
1054− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1055− => Expression outer grp commons schemas params from (nullity json)
1056− -> Expression outer grp commons schemas params from (nullity path)
1057− -> Expression outer grp commons schemas params from ('Null 'PGtext)
1058−infixl 8 .#>>
1059−(.#>>) = unsafeBinaryOp "#>>"
1060−
1061−-- Additional jsonb operators
1062−
1063−-- | Does the left JSON value contain the right JSON path/value entries at the
1064−-- top level?
1065−(.@>)
1066− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1067− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1068− -> Condition outer grp commons schemas params from
1069−infixl 9 .@>
1070−(.@>) = unsafeBinaryOp "@>"
1071−
1072−-- | Are the left JSON path/value entries contained at the top level within the
1073−-- right JSON value?
1074−(.<@)
1075− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1076− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1077− -> Condition outer grp commons schemas params from
1078−infixl 9 .<@
1079−(.<@) = unsafeBinaryOp "<@"
1080−
1081−-- | Does the string exist as a top-level key within the JSON value?
1082−(.?)
1083− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1084− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1085− -> Condition outer grp commons schemas params from
1086−infixl 9 .?
1087−(.?) = unsafeBinaryOp "?"
1088−
1089−-- | Do any of these array strings exist as top-level keys?
1090−(.?|)
1091− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1092− -> Expression outer grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1093− -> Condition outer grp commons schemas params from
1094−infixl 9 .?|
1095−(.?|) = unsafeBinaryOp "?|"
1096−
1097−-- | Do all of these array strings exist as top-level keys?
1098−(.?&)
1099− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1100− -> Expression outer grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1101− -> Condition outer grp commons schemas params from
1102−infixl 9 .?&
1103−(.?&) = unsafeBinaryOp "?&"
1104−
1105−-- | Concatenate two jsonb values into a new jsonb value.
1106−instance Semigroup
1107− (Expression outer grp commons schemas params from (nullity 'PGjsonb)) where
1108− (<>) = unsafeBinaryOp "||"
1109−
1110−-- | Delete a key or keys from a JSON object, or remove an array element.
1111−--
1112−-- If the right operand is..
1113−--
1114−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1115−-- are matched based on their key value.
1116−--
1117−-- @ text[] @: Delete multiple key/value pairs or string elements
1118−-- from left operand. Key/value pairs are matched based on their key value.
1119−--
1120−-- @ integer @: Delete the array element with specified index (Negative integers
1121−-- count from the end). Throws an error if top level container is not an array.
1122−(.-.)
1123− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1124− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1125− -> Expression outer grp commons schemas params from (nullity key)
1126− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1127−infixl 6 .-.
1128−(.-.) = unsafeBinaryOp "-"
1129−
1130−-- | Delete the field or element with specified path (for JSON arrays, negative
1131−-- integers count from the end)
1132−(#-.)
1133− :: PGTextArray "(#-.)" arrayty
1134− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1135− -> Expression outer grp commons schemas params from (nullity arrayty)
1136− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1137−infixl 6 #-.
1138−(#-.) = unsafeBinaryOp "#-"
1139−
1140−{-----------------------------------------
1141−Table 9.45: JSON creation functions
1142−-----------------------------------------}
1143−
1144−-- | Literal binary JSON
1145−jsonbLit
1146− :: JSON.ToJSON x
1147− => x -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1148−jsonbLit = cast jsonb . UnsafeExpression
1149− . singleQuotedUtf8 . toStrict . JSON.encode
1150−
1151−-- | Literal JSON
1152−jsonLit
1153− :: JSON.ToJSON x
1154− => x -> Expression outer grp commons schemas params from (nullity 'PGjson)
1155−jsonLit = cast json . UnsafeExpression
1156− . singleQuotedUtf8 . toStrict . JSON.encode
1157−
1158−-- | Returns the value as json. Arrays and composites are converted
1159−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1160−-- type to json, the cast function will be used to perform the conversion;
1161−-- otherwise, a scalar value is produced. For any scalar type other than a
1162−-- number, a Boolean, or a null value, the text representation will be used, in
1163−-- such a fashion that it is a valid json value.
1164−toJson
1165− :: Expression outer grp commons schemas params from (nullity ty)
1166− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1167−toJson = unsafeFunction "to_json"
1168−
1169−-- | Returns the value as jsonb. Arrays and composites are converted
1170−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1171−-- type to json, the cast function will be used to perform the conversion;
1172−-- otherwise, a scalar value is produced. For any scalar type other than a
1173−-- number, a Boolean, or a null value, the text representation will be used, in
1174−-- such a fashion that it is a valid jsonb value.
1175−toJsonb
1176− :: Expression outer grp commons schemas params from (nullity ty)
1177− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1178−toJsonb = unsafeFunction "to_jsonb"
1179−
1180−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1181−-- becomes a JSON array of arrays.
1182−arrayToJson
1183− :: PGArray "arrayToJson" arr
1184− => Expression outer grp commons schemas params from (nullity arr)
1185− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1186−arrayToJson = unsafeFunction "array_to_json"
1187−
1188−-- | Returns the row as a JSON object.
1189−rowToJson
1190− :: Expression outer grp commons schemas params from (nullity ('PGcomposite ty))
1191− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1192−rowToJson = unsafeFunction "row_to_json"
1193−
1194−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1195−-- argument list.
1196−jsonBuildArray
1197− :: SListI elems
1198− => NP (Expression outer grp commons schemas params from) elems
1199− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1200−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1201−
1202−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1203−-- variadic argument list.
1204−jsonbBuildArray
1205− :: SListI elems
1206− => NP (Expression outer grp commons schemas params from) elems
1207− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1208−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1209−
1210−unsafeRowFunction
1211− :: All Top elems
1212− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1213− -> [ByteString]
1214−unsafeRowFunction =
1215− (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1216− (\(col `As` name) -> Endo $ \xs ->
1217− renderAliasString name : renderSQL col : xs)
1218− where
1219− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1220− renderAliasString = singleQuotedText . fromString . symbolVal
1221−
1222−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1223−-- argument list. The elements of the argument list must alternate between text
1224−-- and values.
1225−jsonBuildObject
1226− :: All Top elems
1227− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1228− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1229−jsonBuildObject
1230− = unsafeFunction "json_build_object"
1231− . UnsafeExpression
1232− . commaSeparated
1233− . unsafeRowFunction
1234−
1235−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1236−-- variadic argument list. The elements of the argument list must alternate
1237−-- between text and values.
1238−jsonbBuildObject
1239− :: All Top elems
1240− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1241− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1242−jsonbBuildObject
1243− = unsafeFunction "jsonb_build_object"
1244− . UnsafeExpression
1245− . commaSeparated
1246− . unsafeRowFunction
1247−
1248−-- | Builds a JSON object out of a text array. The array must have either
1249−-- exactly one dimension with an even number of members, in which case they are
1250−-- taken as alternating key/value pairs, or two dimensions such that each inner
1251−-- array has exactly two elements, which are taken as a key/value pair.
1252−jsonObject
1253− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1254− => Expression outer grp commons schemas params from (nullity arr)
1255− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1256−jsonObject = unsafeFunction "json_object"
1257−
1258−-- | Builds a binary JSON object out of a text array. The array must have either
1259−-- exactly one dimension with an even number of members, in which case they are
1260−-- taken as alternating key/value pairs, or two dimensions such that each inner
1261−-- array has exactly two elements, which are taken as a key/value pair.
1262−jsonbObject
1263− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1264− => Expression outer grp commons schemas params from (nullity arr)
1265− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1266−jsonbObject = unsafeFunction "jsonb_object"
1267−
1268−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1269−-- keys and one for values, that are zipped pairwise to create a JSON object.
1270−jsonZipObject
1271− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1272− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1273− => Expression outer grp commons schemas params from (nullity keysArray)
1274− -> Expression outer grp commons schemas params from (nullity valuesArray)
1275− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1276−jsonZipObject ks vs =
1277− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1278−
1279−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1280−-- keys and one for values, that are zipped pairwise to create a binary JSON
1281−-- object.
1282−jsonbZipObject
1283− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1284− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1285− => Expression outer grp commons schemas params from (nullity keysArray)
1286− -> Expression outer grp commons schemas params from (nullity valuesArray)
1287− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1288−jsonbZipObject ks vs =
1289− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1290−
1291−{-----------------------------------------
1292−Table 9.46: JSON processing functions
1293−-----------------------------------------}
1294−
1295−-- | Returns the number of elements in the outermost JSON array.
1296−jsonArrayLength
1297− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1298− -> Expression outer grp commons schemas params from (nullity 'PGint4)
1299−jsonArrayLength = unsafeFunction "json_array_length"
1300−
1301−-- | Returns the number of elements in the outermost binary JSON array.
1302−jsonbArrayLength
1303− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1304− -> Expression outer grp commons schemas params from (nullity 'PGint4)
1305−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1306−
1307−-- | Returns JSON value pointed to by the given path (equivalent to #>
1308−-- operator).
1309−jsonExtractPath
1310− :: SListI elems
1311− => Expression outer grp commons schemas params from (nullity 'PGjson)
1312− -> NP (Expression outer grp commons schemas params from) elems
1313− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1314−jsonExtractPath x xs =
1315− unsafeVariadicFunction "json_extract_path" (x :* xs)
1316−
1317−-- | Returns JSON value pointed to by the given path (equivalent to #>
1318−-- operator).
1319−jsonbExtractPath
1320− :: SListI elems
1321− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1322− -> NP (Expression outer grp commons schemas params from) elems
1323− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1324−jsonbExtractPath x xs =
1325− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1326−
1327−-- | Returns JSON value pointed to by the given path (equivalent to #>
1328−-- operator), as text.
1329−jsonExtractPathAsText
1330− :: SListI elems
1331− => Expression outer grp commons schemas params from (nullity 'PGjson)
1332− -> NP (Expression outer grp commons schemas params from) elems
1333− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1334−jsonExtractPathAsText x xs =
1335− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1336−
1337−-- | Returns JSON value pointed to by the given path (equivalent to #>
1338−-- operator), as text.
1339−jsonbExtractPathAsText
1340− :: SListI elems
1341− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1342− -> NP (Expression outer grp commons schemas params from) elems
1343− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1344−jsonbExtractPathAsText x xs =
1345− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1346−
1347−-- | Returns the type of the outermost JSON value as a text string. Possible
1348−-- types are object, array, string, number, boolean, and null.
1349−jsonTypeof
1350− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1351− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1352−jsonTypeof = unsafeFunction "json_typeof"
1353−
1354−-- | Returns the type of the outermost binary JSON value as a text string.
1355−-- Possible types are object, array, string, number, boolean, and null.
1356−jsonbTypeof
1357− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1358− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1359−jsonbTypeof = unsafeFunction "jsonb_typeof"
1360−
1361−-- | Returns its argument with all object fields that have null values omitted.
1362−-- Other null values are untouched.
1363−jsonStripNulls
1364− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1365− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1366−jsonStripNulls = unsafeFunction "json_strip_nulls"
1367−
1368−-- | Returns its argument with all object fields that have null values omitted.
1369−-- Other null values are untouched.
1370−jsonbStripNulls
1371− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1372− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1373−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1374−
1375−-- | @ jsonbSet target path new_value create_missing @
1376−--
1377−-- Returns target with the section designated by path replaced by new_value,
1378−-- or with new_value added if create_missing is true ( default is true) and the
1379−-- item designated by path does not exist. As with the path orientated
1380−-- operators, negative integers that appear in path count from the end of JSON
1381−-- arrays.
1382−jsonbSet
1383− :: PGTextArray "jsonbSet" arr
1384− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1385− -> Expression outer grp commons schemas params from (nullity arr)
1386− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1387− -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1388− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1389−jsonbSet tgt path val createMissing = case createMissing of
1390− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1391− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1392−
1393−-- | @ jsonbInsert target path new_value insert_after @
1394−--
1395−-- Returns target with new_value inserted. If target section designated by
1396−-- path is in a JSONB array, new_value will be inserted before target or after
1397−-- if insert_after is true (default is false). If target section designated by
1398−-- path is in JSONB object, new_value will be inserted only if target does not
1399−-- exist. As with the path orientated operators, negative integers that appear
1400−-- in path count from the end of JSON arrays.
1401−jsonbInsert
1402− :: PGTextArray "jsonbInsert" arr
1403− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1404− -> Expression outer grp commons schemas params from (nullity arr)
1405− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1406− -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1407− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1408−jsonbInsert tgt path val insertAfter = case insertAfter of
1409− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1410− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1411−
1412−-- | Returns its argument as indented JSON text.
1413−jsonbPretty
1414− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1415− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1416−jsonbPretty = unsafeFunction "jsonb_pretty"
1417−
1418−{-----------------------------------------
1419−aggregation
1420−-----------------------------------------}
1421−
1422−class Aggregate expr1 expr2 aggr
1423− | aggr -> expr1, aggr -> expr2 where
1424−
1425− -- | A special aggregation that does not require an input
1426− --
1427− -- >>> :{
1428− -- let
1429− -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1430− -- expression = countStar
1431− -- in printSQL expression
1432− -- :}
1433− -- count(*)
1434− countStar :: aggr ('NotNull 'PGint8)
1435−
1436− -- | >>> :{
1437− -- let
1438− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1439− -- expression = count (All #col)
1440− -- in printSQL expression
1441− -- :}
1442− -- count(ALL "col")
1443− count
1444− :: expr1 ty
1445− -- ^ what to count
1446− -> aggr ('NotNull 'PGint8)
1447−
1448− -- | >>> :{
1449− -- let
1450− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Null 'PGnumeric)
1451− -- expression = sum_ (Distinct #col)
1452− -- in printSQL expression
1453− -- :}
1454− -- sum(DISTINCT "col")
1455− sum_
1456− :: ty `In` PGNum
1457− => expr1 (nullity ty)
1458− -> aggr (nullity ty)
1459−
1460− -- | input values, including nulls, concatenated into an array
1461− arrayAgg
1462− :: expr1 ty
1463− -> aggr ('NotNull ('PGvararray ty))
1464−
1465− -- | aggregates values as a JSON array
1466− jsonAgg
1467− :: expr1 ty
1468− -> aggr ('NotNull 'PGjson)
1469−
1470− -- | aggregates values as a JSON array
1471− jsonbAgg
1472− :: expr1 ty
1473− -> aggr ('NotNull 'PGjsonb)
1474−
1475− -- | >>> :{
1476− -- let
1477− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1478− -- expression = bitAnd (Distinct #col)
1479− -- in printSQL expression
1480− -- :}
1481− -- bit_and(DISTINCT "col")
1482− bitAnd
1483− :: int `In` PGIntegral
1484− => expr1 (nullity int)
1485− -- ^ what to aggregate
1486− -> aggr (nullity int)
1487−
1488− -- | >>> :{
1489− -- let
1490− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1491− -- expression = bitOr (All #col)
1492− -- in printSQL expression
1493− -- :}
1494− -- bit_or(ALL "col")
1495− bitOr
1496− :: int `In` PGIntegral
1497− => expr1 (nullity int)
1498− -- ^ what to aggregate
1499− -> aggr (nullity int)
1500−
1501− -- | >>> :{
1502− -- let
1503− -- winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1504− -- winFun = boolAnd #col
1505− -- in printSQL winFun
1506− -- :}
1507− -- bool_and("col")
1508− boolAnd
1509− :: expr1 (nullity 'PGbool)
1510− -- ^ what to aggregate
1511− -> aggr (nullity 'PGbool)
1512−
1513− -- | >>> :{
1514− -- let
1515− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1516− -- expression = boolOr (All #col)
1517− -- in printSQL expression
1518− -- :}
1519− -- bool_or(ALL "col")
1520− boolOr
1521− :: expr1(nullity 'PGbool)
1522− -- ^ what to aggregate
1523− -> aggr (nullity 'PGbool)
1524−
1525− -- | synonym for `boolAnd`
1526− --
1527− -- >>> :{
1528− -- let
1529− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1530− -- expression = every (Distinct #col)
1531− -- in printSQL expression
1532− -- :}
1533− -- every(DISTINCT "col")
1534− every
1535− :: expr1 (nullity 'PGbool)
1536− -- ^ what to aggregate
1537− -> aggr (nullity 'PGbool)
1538−
1539− -- | maximum value of expression across all input values
1540− max_
1541− :: expr1 (nullity ty)
1542− -- ^ what to maximize
1543− -> aggr (nullity ty)
1544−
1545− -- | minimum value of expression across all input values
1546− min_
1547− :: expr1 (nullity ty)
1548− -- ^ what to minimize
1549− -> aggr (nullity ty)
1550−
1551− -- | average aggregation
1552− avg
1553− :: expr1 (nullity ty)
1554− -- ^ what to average
1555− -> aggr (nullity (PGAvg ty))
1556−
1557− {- | correlation coefficient
1558− >>> :{
1559− let
1560− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1561− expression = corr (All (#y :*: #x))
1562− in printSQL expression
1563− :}
1564− corr(ALL "y", "x")
1565− -}
1566− corr
1567− :: expr2 (nullity 'PGfloat8)
1568− -> aggr (nullity 'PGfloat8)
1569−
1570− {- | population covariance
1571− >>> :{
1572− let
1573− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1574− expression = covarPop (All (#y :*: #x))
1575− in printSQL expression
1576− :}
1577− covar_pop(ALL "y", "x")
1578− -}
1579− covarPop
1580− :: expr2 (nullity 'PGfloat8)
1581− -> aggr (nullity 'PGfloat8)
1582−
1583− {- | sample covariance
1584− >>> :{
1585− let
1586− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1587− winFun = covarSamp (#y :*: #x)
1588− in printSQL winFun
1589− :}
1590− covar_samp("y", "x")
1591− -}
1592− covarSamp
1593− :: expr2 (nullity 'PGfloat8)
1594− -> aggr (nullity 'PGfloat8)
1595−
1596− {- | average of the independent variable (sum(X)/N)
1597− >>> :{
1598− let
1599− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1600− expression = regrAvgX (All (#y :*: #x))
1601− in printSQL expression
1602− :}
1603− regr_avgx(ALL "y", "x")
1604− -}
1605− regrAvgX
1606− :: expr2 (nullity 'PGfloat8)
1607− -> aggr (nullity 'PGfloat8)
1608−
1609− {- | average of the dependent variable (sum(Y)/N)
1610− >>> :{
1611− let
1612− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1613− winFun = regrAvgY (#y :*: #x)
1614− in printSQL winFun
1615− :}
1616− regr_avgy("y", "x")
1617− -}
1618− regrAvgY
1619− :: expr2 (nullity 'PGfloat8)
1620− -> aggr (nullity 'PGfloat8)
1621−
1622− {- | number of input rows in which both expressions are nonnull
1623− >>> :{
1624− let
1625− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGint8)
1626− winFun = regrCount (#y :*: #x)
1627− in printSQL winFun
1628− :}
1629− regr_count("y", "x")
1630− -}
1631− regrCount
1632− :: expr2 (nullity 'PGfloat8)
1633− -> aggr (nullity 'PGint8)
1634−
1635− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1636− >>> :{
1637− let
1638− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1639− expression = regrIntercept (All (#y :*: #x))
1640− in printSQL expression
1641− :}
1642− regr_intercept(ALL "y", "x")
1643− -}
1644− regrIntercept
1645− :: expr2 (nullity 'PGfloat8)
1646− -> aggr (nullity 'PGfloat8)
1647−
1648− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1649− regrR2
1650− :: expr2 (nullity 'PGfloat8)
1651− -> aggr (nullity 'PGfloat8)
1652−
1653− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1654− -- determined by the (X, Y) pairs
1655− regrSlope
1656− :: expr2 (nullity 'PGfloat8)
1657− -> aggr (nullity 'PGfloat8)
1658−
1659− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1660− -- (“sum of squares” of the independent variable)
1661− regrSxx
1662− :: expr2 (nullity 'PGfloat8)
1663− -> aggr (nullity 'PGfloat8)
1664−
1665− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1666− -- (“sum of products” of independent times dependent variable)
1667− regrSxy
1668− :: expr2 (nullity 'PGfloat8)
1669− -> aggr (nullity 'PGfloat8)
1670−
1671− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1672− -- (“sum of squares” of the dependent variable)
1673− regrSyy
1674− :: expr2 (nullity 'PGfloat8)
1675− -> aggr (nullity 'PGfloat8)
1676−
1677− -- | historical alias for `stddevSamp`
1678− stddev
1679− :: expr1 (nullity ty)
1680− -> aggr (nullity (PGAvg ty))
1681−
1682− -- | population standard deviation of the input values
1683− stddevPop
1684− :: expr1 (nullity ty)
1685− -> aggr (nullity (PGAvg ty))
1686−
1687− -- | sample standard deviation of the input values
1688− stddevSamp
1689− :: expr1 (nullity ty)
1690− -> aggr (nullity (PGAvg ty))
1691−
1692− -- | historical alias for `varSamp`
1693− variance
1694− :: expr1 (nullity ty)
1695− -> aggr (nullity (PGAvg ty))
1696−
1697− -- | population variance of the input values
1698− -- (square of the population standard deviation)
1699− varPop
1700− :: expr1 (nullity ty)
1701− -> aggr (nullity (PGAvg ty))
1702−
1703− -- | sample variance of the input values
1704− -- (square of the sample standard deviation)
1705− varSamp
1706− :: expr1 (nullity ty)
1707− -> aggr (nullity (PGAvg ty))
1708−
1709−data Distinction expr ty
1710− = All (expr ty)
1711− | Distinct (expr ty)
1712− deriving (GHC.Generic,Show,Eq,Ord)
1713−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1714−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1715− renderSQL = \case
1716− All x -> "ALL" <+> renderSQL x
1717− Distinct x -> "DISTINCT" <+> renderSQL x
1718−instance RenderSQL
1719− (Distinction
1720− ( Expression outer grp commons schemas params from
1721− :*:
1722− Expression outer grp commons schemas params from) xty ) where
1723− renderSQL = \case
1724− All (x :*: x') ->
1725− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1726− Distinct (x :*: x') ->
1727− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1728−
1729−instance Aggregate
1730− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1731− (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1732− (Expression outer ('Grouped bys) commons schemas params from) where
1733− countStar = UnsafeExpression "count(*)"
1734− count = unsafeAggregate1 "count"
1735− sum_ = unsafeAggregate1 "sum"
1736− arrayAgg = unsafeAggregate1 "array_agg"
1737− jsonAgg = unsafeAggregate1 "json_agg"
1738− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1739− bitAnd = unsafeAggregate1 "bit_and"
1740− bitOr = unsafeAggregate1 "bit_or"
1741− boolAnd = unsafeAggregate1 "bool_and"
1742− boolOr = unsafeAggregate1 "bool_or"
1743− every = unsafeAggregate1 "every"
1744− max_ = unsafeAggregate1 "max"
1745− min_ = unsafeAggregate1 "min"
1746− avg = unsafeAggregate1 "avg"
1747− corr = unsafeAggregate2 "corr"
1748− covarPop = unsafeAggregate2 "covar_pop"
1749− covarSamp = unsafeAggregate2 "covar_samp"
1750− regrAvgX = unsafeAggregate2 "regr_avgx"
1751− regrAvgY = unsafeAggregate2 "regr_avgy"
1752− regrCount = unsafeAggregate2 "regr_count"
1753− regrIntercept = unsafeAggregate2 "regr_intercept"
1754− regrR2 = unsafeAggregate2 "regr_r2"
1755− regrSlope = unsafeAggregate2 "regr_slope"
1756− regrSxx = unsafeAggregate2 "regr_sxx"
1757− regrSxy = unsafeAggregate2 "regr_sxy"
1758− regrSyy = unsafeAggregate2 "regr_syy"
1759− stddev = unsafeAggregate1 "stddev"
1760− stddevPop = unsafeAggregate1 "stddev_pop"
1761− stddevSamp = unsafeAggregate1 "stddev_samp"
1762− variance = unsafeAggregate1 "variance"
1763− varPop = unsafeAggregate1 "var_pop"
1764− varSamp = unsafeAggregate1 "var_samp"
1765−instance Aggregate
1766− (Expression outer grp commons schemas params from)
1767− (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1768− (WindowFunction outer grp commons schemas params from) where
1769− countStar = UnsafeWindowFunction "count(*)"
1770− count = unsafeWindowFunction1 "count"
1771− sum_ = unsafeWindowFunction1 "sum"
1772− arrayAgg = unsafeWindowFunction1 "array_agg"
1773− jsonAgg = unsafeWindowFunction1 "json_agg"
1774− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1775− bitAnd = unsafeWindowFunction1 "bit_and"
1776− bitOr = unsafeWindowFunction1 "bit_or"
1777− boolAnd = unsafeWindowFunction1 "bool_and"
1778− boolOr = unsafeWindowFunction1 "bool_or"
1779− every = unsafeWindowFunction1 "every"
1780− max_ = unsafeWindowFunction1 "max"
1781− min_ = unsafeWindowFunction1 "min"
1782− avg = unsafeWindowFunction1 "avg"
1783− corr = unsafeWindowFunction2 "corr"
1784− covarPop = unsafeWindowFunction2 "covar_pop"
1785− covarSamp = unsafeWindowFunction2 "covar_samp"
1786− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1787− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1788− regrCount = unsafeWindowFunction2 "regr_count"
1789− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1790− regrR2 = unsafeWindowFunction2 "regr_r2"
1791− regrSlope = unsafeWindowFunction2 "regr_slope"
1792− regrSxx = unsafeWindowFunction2 "regr_sxx"
1793− regrSxy = unsafeWindowFunction2 "regr_sxy"
1794− regrSyy = unsafeWindowFunction2 "regr_syy"
1795− stddev = unsafeWindowFunction1 "stddev"
1796− stddevPop = unsafeWindowFunction1 "stddev_pop"
1797− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1798− variance = unsafeWindowFunction1 "variance"
1799− varPop = unsafeWindowFunction1 "var_pop"
1800− varSamp = unsafeWindowFunction1 "var_samp"
1801−
1802−-- | escape hatch to define aggregate functions
1803−unsafeAggregate1
1804− :: ByteString -- ^ aggregate function
1805− -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1806− -> Expression outer ('Grouped bys) commons schemas params from yty
1807−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1808− [fun, "(", renderSQL x, ")"]
1809−
1810−-- | escape hatch to define aggregate binary functions
1811−unsafeAggregate2
1812− :: ByteString -- ^ aggregate function
1813− -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1814− -> Expression outer ('Grouped bys) commons schemas params from yty
1815−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1816− [fun, "(", renderSQL xx, ")"]
1817−
1818−-- | A type family that calculates `PGAvg` type of a `PGType`.
1819−type family PGAvg ty where
1820− PGAvg 'PGint2 = 'PGnumeric
1821− PGAvg 'PGint4 = 'PGnumeric
1822− PGAvg 'PGint8 = 'PGnumeric
1823− PGAvg 'PGnumeric = 'PGnumeric
1824− PGAvg 'PGfloat4 = 'PGfloat8
1825− PGAvg 'PGfloat8 = 'PGfloat8
1826− PGAvg 'PGinterval = 'PGinterval
1827− PGAvg pg = TypeError
1828− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1829−
1830−{-----------------------------------------
1831−type expressions
1832−-----------------------------------------}
1833−
1834−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1835−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1836− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1837− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1838−instance RenderSQL (TypeExpression schemas ty) where
1839− renderSQL = renderTypeExpression
1840−
1841−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1842−typedef
1843− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1844− => QualifiedAlias sch td
1845− -> TypeExpression schemas (nullity ty)
1846−typedef = UnsafeTypeExpression . renderSQL
1847−
1848−-- | The composite type corresponding to a `Table` definition can be expressed
1849−-- by its alias.
1850−typetable
1851− :: (Has sch schemas schema, Has tab schema ('Table table))
1852− => QualifiedAlias sch tab
1853− -> TypeExpression schemas (nullity ('PGcomposite (TableToRow table)))
1854−typetable = UnsafeTypeExpression . renderSQL
1855−
1856−-- | The composite type corresponding to a `View` definition can be expressed
1857−-- by its alias.
1858−typeview
1859− :: (Has sch schemas schema, Has vw schema ('View view))
1860− => QualifiedAlias sch vw
1861− -> TypeExpression schemas (nullity ('PGcomposite view))
1862−typeview = UnsafeTypeExpression . renderSQL
1863−
1864−-- | logical Boolean (true/false)
1865−bool :: TypeExpression schemas (nullity 'PGbool)
1866−bool = UnsafeTypeExpression "bool"
1867−-- | signed two-byte integer
1868−int2, smallint :: TypeExpression schemas (nullity 'PGint2)
1869−int2 = UnsafeTypeExpression "int2"
1870−smallint = UnsafeTypeExpression "smallint"
1871−-- | signed four-byte integer
1872−int4, int, integer :: TypeExpression schemas (nullity 'PGint4)
1873−int4 = UnsafeTypeExpression "int4"
1874−int = UnsafeTypeExpression "int"
1875−integer = UnsafeTypeExpression "integer"
1876−-- | signed eight-byte integer
1877−int8, bigint :: TypeExpression schemas (nullity 'PGint8)
1878−int8 = UnsafeTypeExpression "int8"
1879−bigint = UnsafeTypeExpression "bigint"
1880−-- | arbitrary precision numeric type
1881−numeric :: TypeExpression schemas (nullity 'PGnumeric)
1882−numeric = UnsafeTypeExpression "numeric"
1883−-- | single precision floating-point number (4 bytes)
1884−float4, real :: TypeExpression schemas (nullity 'PGfloat4)
1885−float4 = UnsafeTypeExpression "float4"
1886−real = UnsafeTypeExpression "real"
1887−-- | double precision floating-point number (8 bytes)
1888−float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
1889−float8 = UnsafeTypeExpression "float8"
1890−doublePrecision = UnsafeTypeExpression "double precision"
1891−-- | variable-length character string
1892−text :: TypeExpression schemas (nullity 'PGtext)
1893−text = UnsafeTypeExpression "text"
1894−-- | fixed-length character string
1895−char, character
1896− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1897− => TypeExpression schemas (nullity ('PGchar n))
1898−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
1899−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
1900−-- | variable-length character string
1901−varchar, characterVarying
1902− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1903− => TypeExpression schemas (nullity ('PGvarchar n))
1904−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
1905−characterVarying = UnsafeTypeExpression $
1906− "character varying(" <> renderNat @n <> ")"
1907−-- | binary data ("byte array")
1908−bytea :: TypeExpression schemas (nullity 'PGbytea)
1909−bytea = UnsafeTypeExpression "bytea"
1910−-- | date and time (no time zone)
1911−timestamp :: TypeExpression schemas (nullity 'PGtimestamp)
1912−timestamp = UnsafeTypeExpression "timestamp"
1913−-- | date and time, including time zone
1914−timestampWithTimeZone :: TypeExpression schemas (nullity 'PGtimestamptz)
1915−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1916−-- | calendar date (year, month, day)
1917−date :: TypeExpression schemas (nullity 'PGdate)
1918−date = UnsafeTypeExpression "date"
1919−-- | time of day (no time zone)
1920−time :: TypeExpression schemas (nullity 'PGtime)
1921−time = UnsafeTypeExpression "time"
1922−-- | time of day, including time zone
1923−timeWithTimeZone :: TypeExpression schemas (nullity 'PGtimetz)
1924−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1925−-- | time span
1926−interval :: TypeExpression schemas (nullity 'PGinterval)
1927−interval = UnsafeTypeExpression "interval"
1928−-- | universally unique identifier
1929−uuid :: TypeExpression schemas (nullity 'PGuuid)
1930−uuid = UnsafeTypeExpression "uuid"
1931−-- | IPv4 or IPv6 host address
1932−inet :: TypeExpression schemas (nullity 'PGinet)
1933−inet = UnsafeTypeExpression "inet"
1934−-- | textual JSON data
1935−json :: TypeExpression schemas (nullity 'PGjson)
1936−json = UnsafeTypeExpression "json"
1937−-- | binary JSON data, decomposed
1938−jsonb :: TypeExpression schemas (nullity 'PGjsonb)
1939−jsonb = UnsafeTypeExpression "jsonb"
1940−-- | variable length array
1941−vararray
1942− :: TypeExpression schemas pg
1943− -> TypeExpression schemas (nullity ('PGvararray pg))
1944−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
1945−-- | fixed length array
1946−--
1947−-- >>> renderSQL (fixarray @'[2] json)
1948−-- "json[2]"
1949−fixarray
1950− :: forall dims schemas nullity pg. All KnownNat dims
1951− => TypeExpression schemas pg
1952− -> TypeExpression schemas (nullity ('PGfixarray dims pg))
1953−fixarray ty = UnsafeTypeExpression $
1954− renderSQL ty <> renderDims @dims
1955− where
1956− renderDims :: forall ns. All KnownNat ns => ByteString
1957− renderDims =
1958− ("[" <>)
1959− . (<> "]")
1960− . ByteString.intercalate "]["
1961− . hcollapse
1962− $ hcmap (Proxy @KnownNat)
1963− (K . fromString . show . natVal)
1964− (hpure Proxy :: NP Proxy ns)
1965−
1966−-- | `pgtype` is a demoted version of a `PGType`
1967−class PGTyped schemas (ty :: NullityType) where
1968− pgtype :: TypeExpression schemas ty
1969−instance PGTyped schemas (nullity 'PGbool) where pgtype = bool
1970−instance PGTyped schemas (nullity 'PGint2) where pgtype = int2
1971−instance PGTyped schemas (nullity 'PGint4) where pgtype = int4
1972−instance PGTyped schemas (nullity 'PGint8) where pgtype = int8
1973−instance PGTyped schemas (nullity 'PGnumeric) where pgtype = numeric
1974−instance PGTyped schemas (nullity 'PGfloat4) where pgtype = float4
1975−instance PGTyped schemas (nullity 'PGfloat8) where pgtype = float8
1976−instance PGTyped schemas (nullity 'PGtext) where pgtype = text
1977−instance (KnownNat n, 1 <= n)
1978− => PGTyped schemas (nullity ('PGchar n)) where pgtype = char @n
1979−instance (KnownNat n, 1 <= n)
1980− => PGTyped schemas (nullity ('PGvarchar n)) where pgtype = varchar @n
1981−instance PGTyped schemas (nullity 'PGbytea) where pgtype = bytea
1982−instance PGTyped schemas (nullity 'PGtimestamp) where pgtype = timestamp
1983−instance PGTyped schemas (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
1984−instance PGTyped schemas (nullity 'PGdate) where pgtype = date
1985−instance PGTyped schemas (nullity 'PGtime) where pgtype = time
1986−instance PGTyped schemas (nullity 'PGtimetz) where pgtype = timeWithTimeZone
1987−instance PGTyped schemas (nullity 'PGinterval) where pgtype = interval
1988−instance PGTyped schemas (nullity 'PGuuid) where pgtype = uuid
1989−instance PGTyped schemas (nullity 'PGjson) where pgtype = json
1990−instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
1991−instance PGTyped schemas ty
1992− => PGTyped schemas (nullity ('PGvararray ty)) where
1993− pgtype = vararray (pgtype @schemas @ty)
1994−instance (All KnownNat dims, PGTyped schemas ty)
1995− => PGTyped schemas (nullity ('PGfixarray dims ty)) where
1996− pgtype = fixarray @dims (pgtype @schemas @ty)
1997−
1998−{-----------------------------------------
1999−Sorting
2000−-----------------------------------------}
2001−
2002−-- | `SortExpression`s are used by `sortBy` to optionally sort the results
2003−-- of a `Query`. `Asc` or `Desc` set the sort direction of a `NotNull` result
2004−-- column to ascending or descending. Ascending order puts smaller values
2005−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2006−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2007−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2008−-- determine whether nulls appear before or after non-null values in the sort
2009−-- ordering of a `Null` result column.
2010−data SortExpression outer grp commons schemas params from where
2011− Asc
2012− :: Expression outer grp commons schemas params from ('NotNull ty)
2013− -> SortExpression outer grp commons schemas params from
2014− Desc
2015− :: Expression outer grp commons schemas params from ('NotNull ty)
2016− -> SortExpression outer grp commons schemas params from
2017− AscNullsFirst
2018− :: Expression outer grp commons schemas params from ('Null ty)
2019− -> SortExpression outer grp commons schemas params from
2020− AscNullsLast
2021− :: Expression outer grp commons schemas params from ('Null ty)
2022− -> SortExpression outer grp commons schemas params from
2023− DescNullsFirst
2024− :: Expression outer grp commons schemas params from ('Null ty)
2025− -> SortExpression outer grp commons schemas params from
2026− DescNullsLast
2027− :: Expression outer grp commons schemas params from ('Null ty)
2028− -> SortExpression outer grp commons schemas params from
2029−deriving instance Show (SortExpression outer grp commons schemas params from)
2030−
2031−class OrderBy expr where
2032− orderBy
2033− :: [SortExpression outer grp commons schemas params from]
2034− -> expr outer grp commons schemas params from
2035− -> expr outer grp commons schemas params from
2036−
2037−-- | Render a `SortExpression`.
2038−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2039− renderSQL = \case
2040− Asc expression -> renderSQL expression <+> "ASC"
2041− Desc expression -> renderSQL expression <+> "DESC"
2042− AscNullsFirst expression -> renderSQL expression
2043− <+> "ASC NULLS FIRST"
2044− DescNullsFirst expression -> renderSQL expression
2045− <+> "DESC NULLS FIRST"
2046− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2047− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2048−
2049−data WindowDefinition outer grp commons schemas params from where
2050− WindowDefinition
2051− :: SListI bys
2052− => NP (Expression outer grp commons schemas params from) bys
2053− -> [SortExpression outer grp commons schemas params from]
2054− -> WindowDefinition outer grp commons schemas params from
2055−
2056−instance OrderBy WindowDefinition where
2057− orderBy sortsR (WindowDefinition parts sortsL)
2058− = WindowDefinition parts (sortsL ++ sortsR)
2059−
2060−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2061− renderSQL (WindowDefinition part ord) =
2062− renderPartitionByClause part <> renderOrderByClause ord
2063− where
2064− renderPartitionByClause = \case
2065− Nil -> ""
2066− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2067− renderOrderByClause = \case
2068− [] -> ""
2069− srts -> " ORDER" <+> "BY"
2070− <+> commaSeparated (renderSQL <$> srts)
2071−
2072−partitionBy
2073− :: SListI bys
2074− => NP (Expression outer grp commons schemas params from) bys
2075− -> WindowDefinition outer grp commons schemas params from
2076−partitionBy bys = WindowDefinition bys []
2077−
2078−newtype WindowFunction
2079− (outer :: FromType)
2080− (grp :: Grouping)
2081− (commons :: FromType)
2082− (schemas :: SchemasType)
2083− (params :: [NullityType])
2084− (from :: FromType)
2085− (ty :: NullityType)
2086− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2087− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2088−
2089−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2090− renderSQL = renderWindowFunction
2091−
2092−unsafeWindowFunction1
2093− :: ByteString
2094− -> Expression outer grp commons schemas params from ty0
2095− -> WindowFunction outer grp commons schemas params from ty1
2096−unsafeWindowFunction1 fun x
2097− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2098−
2099−unsafeWindowFunction2
2100− :: ByteString
2101− -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2102− -> WindowFunction outer grp commons schemas params from ty1
2103−unsafeWindowFunction2 fun (x :*: x')
2104− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2105−
2106−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2107−>>> printSQL rank
2108−rank()
2109−-}
2110−rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2111−rank = UnsafeWindowFunction "rank()"
2112−
2113−{- | number of the current row within its partition, counting from 1
2114−>>> printSQL rowNumber
2115−row_number()
2116−-}
2117−rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2118−rowNumber = UnsafeWindowFunction "row_number()"
2119−
2120−{- | rank of the current row without gaps; this function counts peer groups
2121−>>> printSQL denseRank
2122−dense_rank()
2123−-}
2124−denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2125−denseRank = UnsafeWindowFunction "dense_rank()"
2126−
2127−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2128−>>> printSQL percentRank
2129−percent_rank()
2130−-}
2131−percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2132−percentRank = UnsafeWindowFunction "percent_rank()"
2133−
2134−{- | cumulative distribution: (number of partition rows
2135−preceding or peer with current row) / total partition rows
2136−>>> printSQL cumeDist
2137−cume_dist()
2138−-}
2139−cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2140−cumeDist = UnsafeWindowFunction "cume_dist()"
2141−
2142−{- | integer ranging from 1 to the argument value,
2143−dividing the partition as equally as possible
2144−-}
2145−ntile
2146− :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2147− -- ^ num buckets
2148− -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2149−ntile = unsafeWindowFunction1 "ntile"
2150−
2151−{- | returns value evaluated at the row that is offset rows before the current
2152−row within the partition; if there is no such row, instead return default
2153−(which must be of the same type as value). Both offset and default are
2154−evaluated with respect to the current row.
2155−-}
2156−lag
2157− :: Expression outer grp commons schemas params from ty
2158− -- ^ value
2159− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2160− -- ^ offset
2161− -> Expression outer grp commons schemas params from ty
2162− -- ^ default
2163− -> WindowFunction outer grp commons schemas params from ty
2164−lag value offset def = UnsafeWindowFunction $ "lag"
2165− <> parenthesized
2166− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2167−
2168−{- | returns value evaluated at the row that is offset rows after the current
2169−row within the partition; if there is no such row, instead return default
2170−(which must be of the same type as value). Both offset and default are
2171−evaluated with respect to the current row.
2172−-}
2173−lead
2174− :: Expression outer grp commons schemas params from ty
2175− -- ^ value
2176− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2177− -- ^ offset
2178− -> Expression outer grp commons schemas params from ty
2179− -- ^ default
2180− -> WindowFunction outer grp commons schemas params from ty
2181−lead value offset def = UnsafeWindowFunction $ "lag"
2182− <> parenthesized
2183− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2184−
2185−{- | returns value evaluated at the row that is the
2186−first row of the window frame
2187−-}
2188−firstValue
2189− :: Expression outer grp commons schemas params from ty
2190− -- ^ value
2191− -> WindowFunction outer grp commons schemas params from ty
2192−firstValue = unsafeWindowFunction1 "first_value"
2193−
2194−{- | returns value evaluated at the row that is the
2195−last row of the window frame
2196−-}
2197−lastValue
2198− :: Expression outer grp commons schemas params from ty
2199− -- ^ value
2200− -> WindowFunction outer grp commons schemas params from ty
2201−lastValue = unsafeWindowFunction1 "last_value"
2202−
2203−{- | returns value evaluated at the row that is the nth
2204−row of the window frame (counting from 1); null if no such row
2205−-}
2206−nthValue
2207− :: Expression outer grp commons schemas params from (nullity ty)
2208− -- ^ value
2209− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2210− -- ^ nth
2211− -> WindowFunction outer grp commons schemas params from ('Null ty)
2212−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2213− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])