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