@@ -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,242 +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−cardinality
488− :: Expression outer grp commons schemas params from (nullity ('PGvararray ty))
489− -> Expression outer grp commons schemas params from (nullity 'PGint8)
490−cardinality = unsafeFunction "cardinality"
491−
492−-- | >>> printSQL $ array [null_, false, true] & index 2
493−-- (ARRAY[NULL, FALSE, TRUE])[2]
494−index
495− :: Word64 -- ^ index
496− -> Expression outer grp commons schemas params from (nullity ('PGvararray ty)) -- ^ array
497− -> Expression outer grp commons schemas params from (NullifyType ty)
498−index n expr = UnsafeExpression $
499− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
500−
501311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
502− (Expression outer grp commons schemas params from (nullity ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
503313 label = UnsafeExpression $ renderSQL (PGlabel @label)
504314
505−-- | A row constructor is an expression that builds a row value
506−-- (also called a composite value) using values for its member fields.
507−--
508−-- >>> :{
509−-- type Complex = 'PGcomposite
510−-- '[ "real" ::: 'NotNull 'PGfloat8
511−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
512−-- :}
513−--
514−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
515−-- >>> printSQL i
516−-- ROW(0, 1)
517−row
518− :: SListI row
519− => NP (Aliased (Expression outer grp commons schemas params from)) row
520− -- ^ zero or more expressions for the row field values
521− -> Expression outer grp commons schemas params from (nullity ('PGcomposite row))
522−row exprs = UnsafeExpression $ "ROW" <> parenthesized
523− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
524−
525−-- | >>> :{
526−-- type Complex = 'PGcomposite
527−-- '[ "real" ::: 'NotNull 'PGfloat8
528−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
529−-- type Schema = '["complex" ::: 'Typedef Complex]
530−-- :}
531−--
532−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
533−-- >>> printSQL $ i & field #complex #imaginary
534−-- (ROW(0, 1)::"complex")."imaginary"
535−field
536− :: ( Has sch schemas schema
537− , Has tydef schema ('Typedef ('PGcomposite row))
538− , Has field row ty)
539− => QualifiedAlias sch tydef -- ^ row type
540− -> Alias field -- ^ field name
541− -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
542− -> Expression outer grp commons schemas params from ty
543−field td fld expr = UnsafeExpression $
544− parenthesized (renderSQL expr <> "::" <> renderSQL td)
545− <> "." <> renderSQL fld
546−
547−instance Semigroup
548− (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
549− (<>) = unsafeBinaryOp "||"
550−
551−instance Monoid
552− (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
553− mempty = array []
554− mappend = (<>)
555−
556−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
557−-- >>> printSQL expr
558−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
559−greatest
560− :: Expression outer grp commons schemas params from (nullty)
561− -- ^ needs at least 1 argument
562− -> [Expression outer grp commons schemas params from (nullty)]
563− -- ^ or more
564− -> Expression outer grp commons schemas params from (nullty)
565−greatest x xs = UnsafeExpression $ "GREATEST("
566− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
567−
568−-- | >>> printSQL $ least currentTimestamp [null_]
569−-- LEAST(CURRENT_TIMESTAMP, NULL)
570−least
571− :: Expression outer grp commons schemas params from (nullty)
572− -- ^ needs at least 1 argument
573− -> [Expression outer grp commons schemas params from (nullty)]
574− -- ^ or more
575− -> Expression outer grp commons schemas params from (nullty)
576−least x xs = UnsafeExpression $ "LEAST("
577− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
578−
579315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
580316-- (TRUE OR FALSE)
581−unsafeBinaryOp
582− :: ByteString
583− -- ^ operator
584− -> Expression outer grp commons schemas params from (ty0)
585− -> Expression outer grp commons schemas params from (ty1)
586− -> Expression outer grp commons schemas params from (ty2)
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
587318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
588319 renderSQL x <+> op <+> renderSQL y
589320
590−-- | >>> 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
591329-- (NOT TRUE)
592−unsafeUnaryOp
593− :: ByteString
594− -- ^ operator
595− -> Expression outer grp commons schemas params from (ty0)
596− -> Expression outer grp commons schemas params from (ty1)
597−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
598− 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
599351
600352-- | >>> printSQL $ unsafeFunction "f" true
601353-- f(TRUE)
602−unsafeFunction
603− :: ByteString
604− -- ^ function
605− -> Expression outer grp commons schemas params from (xty)
606− -> Expression outer grp commons schemas params from (yty)
354+unsafeFunction :: ByteString -> x --> y
607355unsafeFunction fun x = UnsafeExpression $
608356 fun <> parenthesized (renderSQL x)
609357
610−-- | Helper for defining variadic functions.
611−unsafeVariadicFunction
612− :: SListI elems
613− => ByteString
614− -- ^ function
615− -> NP (Expression outer grp commons schemas params from) elems
616− -> Expression outer grp commons schemas params from ret
617−unsafeVariadicFunction fun x = UnsafeExpression $
618− 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
619377
620378instance ty `In` PGNum
621− => Num (Expression outer grp commons schemas params from (nullity ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
622380 (+) = unsafeBinaryOp "+"
623381 (-) = unsafeBinaryOp "-"
624382 (*) = unsafeBinaryOp "*"
@@ -630,12 +388,17 @@ instance ty `In` PGNum
630388 . show
631389
632390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
633− (Expression outer grp commons schemas params from (nullity ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
634392 (/) = unsafeBinaryOp "/"
635− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
393+ fromRational
394+ = UnsafeExpression
395+ . fromString
396+ . ($ "")
397+ . showFFloat Nothing
398+ . fromRat @Double
636399
637400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
638− (Expression outer grp commons schemas params from (nullity ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
639402 pi = UnsafeExpression "pi()"
640403 exp = unsafeFunction "exp"
641404 log = unsafeFunction "ln"
@@ -656,1564 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
656419 acosh x = log (x + sqrt (x*x - 1))
657420 atanh x = log ((1 + x) / (1 - x)) / 2
658421
659−-- | >>> :{
660−-- let
661−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
662−-- expression = atan2_ pi 2
663−-- in printSQL expression
664−-- :}
665−-- atan2(pi(), 2)
666−atan2_
667− :: float `In` PGFloating
668− => Expression outer grp commons schemas params from (nullity float)
669− -- ^ numerator
670− -> Expression outer grp commons schemas params from (nullity float)
671− -- ^ denominator
672− -> Expression outer grp commons schemas params from (nullity float)
673−atan2_ y x = UnsafeExpression $
674− "atan2(" <> renderSQL y <> ", " <> renderSQL x <> ")"
675−
676−-- When a `cast` is applied to an `Expression` of a known type, it
677−-- represents a run-time type conversion. The cast will succeed only if a
678−-- suitable type conversion operation has been defined.
679−--
680−-- | >>> printSQL $ true & cast int4
681−-- (TRUE :: int4)
682−cast
683− :: TypeExpression schemas ty1
684− -- ^ type to cast as
685− -> Expression outer grp commons schemas params from ty0
686− -- ^ value to convert
687− -> Expression outer grp commons schemas params from ty1
688−cast ty x = UnsafeExpression $ parenthesized $
689− renderSQL x <+> "::" <+> renderSQL ty
690−
691−-- | integer division, truncates the result
692−--
693−-- >>> :{
694−-- let
695−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
696−-- expression = 5 `quot_` 2
697−-- in printSQL expression
698−-- :}
699−-- (5 / 2)
700−quot_
701− :: int `In` PGIntegral
702− => Expression outer grp commons schemas params from (nullity int)
703− -- ^ numerator
704− -> Expression outer grp commons schemas params from (nullity int)
705− -- ^ denominator
706− -> Expression outer grp commons schemas params from (nullity int)
707−quot_ = unsafeBinaryOp "/"
708−
709−-- | remainder upon integer division
710−--
711−-- >>> :{
712−-- let
713−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
714−-- expression = 5 `rem_` 2
715−-- in printSQL expression
716−-- :}
717−-- (5 % 2)
718−rem_
719− :: int `In` PGIntegral
720− => Expression outer grp commons schemas params from (nullity int)
721− -- ^ numerator
722− -> Expression outer grp commons schemas params from (nullity int)
723− -- ^ denominator
724− -> Expression outer grp commons schemas params from (nullity int)
725−rem_ = unsafeBinaryOp "%"
726−
727−-- | >>> :{
728−-- let
729−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
730−-- expression = trunc pi
731−-- in printSQL expression
732−-- :}
733−-- trunc(pi())
734−trunc
735− :: frac `In` PGFloating
736− => Expression outer grp commons schemas params from (nullity frac)
737− -- ^ fractional number
738− -> Expression outer grp commons schemas params from (nullity frac)
739−trunc = unsafeFunction "trunc"
740−
741−-- | >>> :{
742−-- let
743−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
744−-- expression = round_ pi
745−-- in printSQL expression
746−-- :}
747−-- round(pi())
748−round_
749− :: frac `In` PGFloating
750− => Expression outer grp commons schemas params from (nullity frac)
751− -- ^ fractional number
752− -> Expression outer grp commons schemas params from (nullity frac)
753−round_ = unsafeFunction "round"
754−
755−-- | >>> :{
756−-- let
757−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
758−-- expression = ceiling_ pi
759−-- in printSQL expression
760−-- :}
761−-- ceiling(pi())
762−ceiling_
763− :: frac `In` PGFloating
764− => Expression outer grp commons schemas params from (nullity frac)
765− -- ^ fractional number
766− -> Expression outer grp commons schemas params from (nullity frac)
767−ceiling_ = unsafeFunction "ceiling"
768−
769−-- | A `Condition` is an `Expression`, which can evaluate
770−-- to `true`, `false` or `null_`. This is because SQL uses
771−-- a three valued logic.
772−type Condition outer grp commons schemas params from =
773− Expression outer grp commons schemas params from ('Null 'PGbool)
774−
775−-- | >>> printSQL true
776−-- TRUE
777−true :: Expression outer grp commons schemas params from (nullity 'PGbool)
778−true = UnsafeExpression "TRUE"
779−
780−-- | >>> printSQL false
781−-- FALSE
782−false :: Expression outer grp commons schemas params from (nullity 'PGbool)
783−false = UnsafeExpression "FALSE"
784−
785−-- | >>> printSQL $ not_ true
786−-- (NOT TRUE)
787−not_
788− :: Expression outer grp commons schemas params from (nullity 'PGbool)
789− -> Expression outer grp commons schemas params from (nullity 'PGbool)
790−not_ = unsafeUnaryOp "NOT"
791−
792−-- | >>> printSQL $ true .&& false
793−-- (TRUE AND FALSE)
794−(.&&)
795− :: Expression outer grp commons schemas params from (nullity 'PGbool)
796− -> Expression outer grp commons schemas params from (nullity 'PGbool)
797− -> Expression outer grp commons schemas params from (nullity 'PGbool)
798−infixr 3 .&&
799−(.&&) = unsafeBinaryOp "AND"
800−
801−-- | >>> printSQL $ true .|| false
802−-- (TRUE OR FALSE)
803−(.||)
804− :: Expression outer grp commons schemas params from (nullity 'PGbool)
805− -> Expression outer grp commons schemas params from (nullity 'PGbool)
806− -> Expression outer grp commons schemas params from (nullity 'PGbool)
807−infixr 2 .||
808−(.||) = unsafeBinaryOp "OR"
809−
810−-- | >>> :{
811−-- let
812−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
813−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
814−-- in printSQL expression
815−-- :}
816−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
817−caseWhenThenElse
818− :: [ ( Condition outer grp commons schemas params from
819− , Expression outer grp commons schemas params from ty
820− ) ]
821− -- ^ whens and thens
822− -> Expression outer grp commons schemas params from ty
823− -- ^ else
824− -> Expression outer grp commons schemas params from ty
825−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
826− [ "CASE"
827− , mconcat
828− [ mconcat
829− [ " WHEN ", renderSQL when_
830− , " THEN ", renderSQL then_
831− ]
832− | (when_,then_) <- whenThens
833− ]
834− , " ELSE ", renderSQL else_
835− , " END"
836− ]
837−
838−-- | >>> :{
839−-- let
840−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
841−-- expression = ifThenElse true 1 0
842−-- in printSQL expression
843−-- :}
844−-- CASE WHEN TRUE THEN 1 ELSE 0 END
845−ifThenElse
846− :: Condition outer grp commons schemas params from
847− -> Expression outer grp commons schemas params from ty -- ^ then
848− -> Expression outer grp commons schemas params from ty -- ^ else
849− -> Expression outer grp commons schemas params from ty
850−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
851−
852−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
853−-- will produce @NULL@s if one of their arguments is @NULL@.
854−--
855−-- >>> printSQL $ true .== null_
856−-- (TRUE = NULL)
857−(.==)
858− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
859− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
860− -> Condition outer grp commons schemas params from
861−(.==) = unsafeBinaryOp "="
862−infix 4 .==
863−
864−-- | >>> printSQL $ true ./= null_
865−-- (TRUE <> NULL)
866−(./=)
867− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
868− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
869− -> Condition outer grp commons schemas params from
870−(./=) = unsafeBinaryOp "<>"
871−infix 4 ./=
872−
873−-- | >>> printSQL $ true .>= null_
874−-- (TRUE >= NULL)
875−(.>=)
876− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
877− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
878− -> Condition outer grp commons schemas params from
879−(.>=) = unsafeBinaryOp ">="
880−infix 4 .>=
881−
882−-- | >>> printSQL $ true .< null_
883−-- (TRUE < NULL)
884−(.<)
885− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
886− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
887− -> Condition outer grp commons schemas params from
888−(.<) = unsafeBinaryOp "<"
889−infix 4 .<
890−
891−-- | >>> printSQL $ true .<= null_
892−-- (TRUE <= NULL)
893−(.<=)
894− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
895− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
896− -> Condition outer grp commons schemas params from
897−(.<=) = unsafeBinaryOp "<="
898−infix 4 .<=
899−
900−-- | >>> printSQL $ true .> null_
901−-- (TRUE > NULL)
902−(.>)
903− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
904− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
905− -> Condition outer grp commons schemas params from
906−(.>) = unsafeBinaryOp ">"
907−infix 4 .>
908−
909−-- | >>> printSQL currentDate
910−-- CURRENT_DATE
911−currentDate
912− :: Expression outer grp commons schemas params from (nullity 'PGdate)
913−currentDate = UnsafeExpression "CURRENT_DATE"
914−
915−-- | >>> printSQL currentTime
916−-- CURRENT_TIME
917−currentTime
918− :: Expression outer grp commons schemas params from (nullity 'PGtimetz)
919−currentTime = UnsafeExpression "CURRENT_TIME"
920−
921−-- | >>> printSQL currentTimestamp
922−-- CURRENT_TIMESTAMP
923−currentTimestamp
924− :: Expression outer grp commons schemas params from (nullity 'PGtimestamptz)
925−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
926−
927−-- | >>> printSQL localTime
928−-- LOCALTIME
929−localTime
930− :: Expression outer grp commons schemas params from (nullity 'PGtime)
931−localTime = UnsafeExpression "LOCALTIME"
932−
933−-- | >>> printSQL localTimestamp
934−-- LOCALTIMESTAMP
935−localTimestamp
936− :: Expression outer grp commons schemas params from (nullity 'PGtimestamp)
937−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
938−
939−{-----------------------------------------
940−text
941−-----------------------------------------}
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)
942438
943439instance IsString
944− (Expression outer grp commons schemas params from (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
945441 fromString str = UnsafeExpression $
946442 "E\'" <> fromString (escape =<< str) <> "\'"
947− where
948− escape = \case
949− '\NUL' -> "\\0"
950− '\'' -> "''"
951− '"' -> "\\\""
952− '\b' -> "\\b"
953− '\n' -> "\\n"
954− '\r' -> "\\r"
955− '\t' -> "\\t"
956− '\\' -> "\\\\"
957− 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) <> "\'"
958451
959452instance Semigroup
960− (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
961463 (<>) = unsafeBinaryOp "||"
962464
963465instance Monoid
964− (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
965471 mempty = fromString ""
966472 mappend = (<>)
967−
968−-- | >>> printSQL $ lower "ARRRGGG"
969−-- lower(E'ARRRGGG')
970−lower
971− :: Expression outer grp commons schemas params from (nullity 'PGtext)
972− -- ^ string to lower case
973− -> Expression outer grp commons schemas params from (nullity 'PGtext)
974−lower = unsafeFunction "lower"
975−
976−-- | >>> printSQL $ upper "eeee"
977−-- upper(E'eeee')
978−upper
979− :: Expression outer grp commons schemas params from (nullity 'PGtext)
980− -- ^ string to upper case
981− -> Expression outer grp commons schemas params from (nullity 'PGtext)
982−upper = unsafeFunction "upper"
983−
984−-- | >>> printSQL $ charLength "four"
985−-- char_length(E'four')
986−charLength
987− :: Expression outer grp commons schemas params from (nullity 'PGtext)
988− -- ^ string to measure
989− -> Expression outer grp commons schemas params from (nullity 'PGint4)
990−charLength = unsafeFunction "char_length"
991−
992−-- | The `like` expression returns true if the @string@ matches
993−-- the supplied @pattern@. If @pattern@ does not contain percent signs
994−-- or underscores, then the pattern only represents the string itself;
995−-- in that case `like` acts like the equals operator. An underscore (_)
996−-- in pattern stands for (matches) any single character; a percent sign (%)
997−-- matches any sequence of zero or more characters.
998−--
999−-- >>> printSQL $ "abc" `like` "a%"
1000−-- (E'abc' LIKE E'a%')
1001−like
1002− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1003− -- ^ string
1004− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1005− -- ^ pattern
1006− -> Expression outer grp commons schemas params from (nullity 'PGbool)
1007−like = unsafeBinaryOp "LIKE"
1008−
1009−-- | The key word ILIKE can be used instead of LIKE to make the
1010−-- match case-insensitive according to the active locale.
1011−--
1012−-- >>> printSQL $ "abc" `ilike` "a%"
1013−-- (E'abc' ILIKE E'a%')
1014−ilike
1015− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1016− -- ^ string
1017− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1018− -- ^ pattern
1019− -> Expression outer grp commons schemas params from (nullity 'PGbool)
1020−ilike = unsafeBinaryOp "ILIKE"
1021−
1022−{-----------------------------------------
1023− -- json and jsonb support
1024−
1025−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1026−comments lifted directly from this page.
1027−
1028−Table 9.44: json and jsonb operators
1029−-----------------------------------------}
1030−
1031−-- | Get JSON value (object field or array element) at a key.
1032−(.->)
1033− :: (json `In` PGJsonType, key `In` PGJsonKey)
1034− => Expression outer grp commons schemas params from (nullity json)
1035− -> Expression outer grp commons schemas params from (nullity key)
1036− -> Expression outer grp commons schemas params from ('Null json)
1037−infixl 8 .->
1038−(.->) = unsafeBinaryOp "->"
1039−
1040−-- | Get JSON value (object field or array element) at a key, as text.
1041−(.->>)
1042− :: (json `In` PGJsonType, key `In` PGJsonKey)
1043− => Expression outer grp commons schemas params from (nullity json)
1044− -> Expression outer grp commons schemas params from (nullity key)
1045− -> Expression outer grp commons schemas params from ('Null 'PGtext)
1046−infixl 8 .->>
1047−(.->>) = unsafeBinaryOp "->>"
1048−
1049−-- | Get JSON value at a specified path.
1050−(.#>)
1051− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1052− => Expression outer grp commons schemas params from (nullity json)
1053− -> Expression outer grp commons schemas params from (nullity path)
1054− -> Expression outer grp commons schemas params from ('Null json)
1055−infixl 8 .#>
1056−(.#>) = unsafeBinaryOp "#>"
1057−
1058−-- | Get JSON value at a specified path as text.
1059−(.#>>)
1060− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1061− => Expression outer grp commons schemas params from (nullity json)
1062− -> Expression outer grp commons schemas params from (nullity path)
1063− -> Expression outer grp commons schemas params from ('Null 'PGtext)
1064−infixl 8 .#>>
1065−(.#>>) = unsafeBinaryOp "#>>"
1066−
1067−-- Additional jsonb operators
1068−
1069−-- | Does the left JSON value contain the right JSON path/value entries at the
1070−-- top level?
1071−(.@>)
1072− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1073− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1074− -> Condition outer grp commons schemas params from
1075−infixl 9 .@>
1076−(.@>) = unsafeBinaryOp "@>"
1077−
1078−-- | Are the left JSON path/value entries contained at the top level within the
1079−-- right JSON value?
1080−(.<@)
1081− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1082− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1083− -> Condition outer grp commons schemas params from
1084−infixl 9 .<@
1085−(.<@) = unsafeBinaryOp "<@"
1086−
1087−-- | Does the string exist as a top-level key within the JSON value?
1088−(.?)
1089− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1090− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1091− -> Condition outer grp commons schemas params from
1092−infixl 9 .?
1093−(.?) = unsafeBinaryOp "?"
1094−
1095−-- | Do any of these array strings exist as top-level keys?
1096−(.?|)
1097− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1098− -> Expression outer grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1099− -> Condition outer grp commons schemas params from
1100−infixl 9 .?|
1101−(.?|) = unsafeBinaryOp "?|"
1102−
1103−-- | Do all of these array strings exist as top-level keys?
1104−(.?&)
1105− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1106− -> Expression outer grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1107− -> Condition outer grp commons schemas params from
1108−infixl 9 .?&
1109−(.?&) = unsafeBinaryOp "?&"
1110−
1111−-- | Concatenate two jsonb values into a new jsonb value.
1112−instance Semigroup
1113− (Expression outer grp commons schemas params from (nullity 'PGjsonb)) where
1114− (<>) = unsafeBinaryOp "||"
1115−
1116−-- | Delete a key or keys from a JSON object, or remove an array element.
1117−--
1118−-- If the right operand is..
1119−--
1120−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1121−-- are matched based on their key value.
1122−--
1123−-- @ text[] @: Delete multiple key/value pairs or string elements
1124−-- from left operand. Key/value pairs are matched based on their key value.
1125−--
1126−-- @ integer @: Delete the array element with specified index (Negative integers
1127−-- count from the end). Throws an error if top level container is not an array.
1128−(.-.)
1129− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1130− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1131− -> Expression outer grp commons schemas params from (nullity key)
1132− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1133−infixl 6 .-.
1134−(.-.) = unsafeBinaryOp "-"
1135−
1136−-- | Delete the field or element with specified path (for JSON arrays, negative
1137−-- integers count from the end)
1138−(#-.)
1139− :: PGTextArray "(#-.)" arrayty
1140− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1141− -> Expression outer grp commons schemas params from (nullity arrayty)
1142− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1143−infixl 6 #-.
1144−(#-.) = unsafeBinaryOp "#-"
1145−
1146−{-----------------------------------------
1147−Table 9.45: JSON creation functions
1148−-----------------------------------------}
1149−
1150−-- | Literal binary JSON
1151−jsonbLit
1152− :: JSON.ToJSON x
1153− => x -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1154−jsonbLit = cast jsonb . UnsafeExpression
1155− . singleQuotedUtf8 . toStrict . JSON.encode
1156−
1157−-- | Literal JSON
1158−jsonLit
1159− :: JSON.ToJSON x
1160− => x -> Expression outer grp commons schemas params from (nullity 'PGjson)
1161−jsonLit = cast json . UnsafeExpression
1162− . singleQuotedUtf8 . toStrict . JSON.encode
1163−
1164−-- | Returns the value as json. Arrays and composites are converted
1165−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1166−-- type to json, the cast function will be used to perform the conversion;
1167−-- otherwise, a scalar value is produced. For any scalar type other than a
1168−-- number, a Boolean, or a null value, the text representation will be used, in
1169−-- such a fashion that it is a valid json value.
1170−toJson
1171− :: Expression outer grp commons schemas params from (nullity ty)
1172− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1173−toJson = unsafeFunction "to_json"
1174−
1175−-- | Returns the value as jsonb. Arrays and composites are converted
1176−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1177−-- type to json, the cast function will be used to perform the conversion;
1178−-- otherwise, a scalar value is produced. For any scalar type other than a
1179−-- number, a Boolean, or a null value, the text representation will be used, in
1180−-- such a fashion that it is a valid jsonb value.
1181−toJsonb
1182− :: Expression outer grp commons schemas params from (nullity ty)
1183− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1184−toJsonb = unsafeFunction "to_jsonb"
1185−
1186−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1187−-- becomes a JSON array of arrays.
1188−arrayToJson
1189− :: PGArray "arrayToJson" arr
1190− => Expression outer grp commons schemas params from (nullity arr)
1191− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1192−arrayToJson = unsafeFunction "array_to_json"
1193−
1194−-- | Returns the row as a JSON object.
1195−rowToJson
1196− :: Expression outer grp commons schemas params from (nullity ('PGcomposite ty))
1197− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1198−rowToJson = unsafeFunction "row_to_json"
1199−
1200−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1201−-- argument list.
1202−jsonBuildArray
1203− :: SListI elems
1204− => NP (Expression outer grp commons schemas params from) elems
1205− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1206−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1207−
1208−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1209−-- variadic argument list.
1210−jsonbBuildArray
1211− :: SListI elems
1212− => NP (Expression outer grp commons schemas params from) elems
1213− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1214−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1215−
1216−unsafeRowFunction
1217− :: All Top elems
1218− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1219− -> [ByteString]
1220−unsafeRowFunction =
1221− (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1222− (\(col `As` name) -> Endo $ \xs ->
1223− renderAliasString name : renderSQL col : xs)
1224− where
1225− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1226− renderAliasString = singleQuotedText . fromString . symbolVal
1227−
1228−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1229−-- argument list. The elements of the argument list must alternate between text
1230−-- and values.
1231−jsonBuildObject
1232− :: All Top elems
1233− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1234− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1235−jsonBuildObject
1236− = unsafeFunction "json_build_object"
1237− . UnsafeExpression
1238− . commaSeparated
1239− . unsafeRowFunction
1240−
1241−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1242−-- variadic argument list. The elements of the argument list must alternate
1243−-- between text and values.
1244−jsonbBuildObject
1245− :: All Top elems
1246− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1247− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1248−jsonbBuildObject
1249− = unsafeFunction "jsonb_build_object"
1250− . UnsafeExpression
1251− . commaSeparated
1252− . unsafeRowFunction
1253−
1254−-- | Builds a JSON object out of a text array. The array must have either
1255−-- exactly one dimension with an even number of members, in which case they are
1256−-- taken as alternating key/value pairs, or two dimensions such that each inner
1257−-- array has exactly two elements, which are taken as a key/value pair.
1258−jsonObject
1259− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1260− => Expression outer grp commons schemas params from (nullity arr)
1261− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1262−jsonObject = unsafeFunction "json_object"
1263−
1264−-- | Builds a binary JSON object out of a text array. The array must have either
1265−-- exactly one dimension with an even number of members, in which case they are
1266−-- taken as alternating key/value pairs, or two dimensions such that each inner
1267−-- array has exactly two elements, which are taken as a key/value pair.
1268−jsonbObject
1269− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1270− => Expression outer grp commons schemas params from (nullity arr)
1271− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1272−jsonbObject = unsafeFunction "jsonb_object"
1273−
1274−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1275−-- keys and one for values, that are zipped pairwise to create a JSON object.
1276−jsonZipObject
1277− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1278− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1279− => Expression outer grp commons schemas params from (nullity keysArray)
1280− -> Expression outer grp commons schemas params from (nullity valuesArray)
1281− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1282−jsonZipObject ks vs =
1283− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1284−
1285−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1286−-- keys and one for values, that are zipped pairwise to create a binary JSON
1287−-- object.
1288−jsonbZipObject
1289− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1290− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1291− => Expression outer grp commons schemas params from (nullity keysArray)
1292− -> Expression outer grp commons schemas params from (nullity valuesArray)
1293− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1294−jsonbZipObject ks vs =
1295− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1296−
1297−{-----------------------------------------
1298−Table 9.46: JSON processing functions
1299−-----------------------------------------}
1300−
1301−-- | Returns the number of elements in the outermost JSON array.
1302−jsonArrayLength
1303− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1304− -> Expression outer grp commons schemas params from (nullity 'PGint4)
1305−jsonArrayLength = unsafeFunction "json_array_length"
1306−
1307−-- | Returns the number of elements in the outermost binary JSON array.
1308−jsonbArrayLength
1309− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1310− -> Expression outer grp commons schemas params from (nullity 'PGint4)
1311−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1312−
1313−-- | Returns JSON value pointed to by the given path (equivalent to #>
1314−-- operator).
1315−jsonExtractPath
1316− :: SListI elems
1317− => Expression outer grp commons schemas params from (nullity 'PGjson)
1318− -> NP (Expression outer grp commons schemas params from) elems
1319− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1320−jsonExtractPath x xs =
1321− unsafeVariadicFunction "json_extract_path" (x :* xs)
1322−
1323−-- | Returns JSON value pointed to by the given path (equivalent to #>
1324−-- operator).
1325−jsonbExtractPath
1326− :: SListI elems
1327− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1328− -> NP (Expression outer grp commons schemas params from) elems
1329− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1330−jsonbExtractPath x xs =
1331− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1332−
1333−-- | Returns JSON value pointed to by the given path (equivalent to #>
1334−-- operator), as text.
1335−jsonExtractPathAsText
1336− :: SListI elems
1337− => Expression outer grp commons schemas params from (nullity 'PGjson)
1338− -> NP (Expression outer grp commons schemas params from) elems
1339− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1340−jsonExtractPathAsText x xs =
1341− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1342−
1343−-- | Returns JSON value pointed to by the given path (equivalent to #>
1344−-- operator), as text.
1345−jsonbExtractPathAsText
1346− :: SListI elems
1347− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1348− -> NP (Expression outer grp commons schemas params from) elems
1349− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1350−jsonbExtractPathAsText x xs =
1351− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1352−
1353−-- | Returns the type of the outermost JSON value as a text string. Possible
1354−-- types are object, array, string, number, boolean, and null.
1355−jsonTypeof
1356− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1357− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1358−jsonTypeof = unsafeFunction "json_typeof"
1359−
1360−-- | Returns the type of the outermost binary JSON value as a text string.
1361−-- Possible types are object, array, string, number, boolean, and null.
1362−jsonbTypeof
1363− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1364− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1365−jsonbTypeof = unsafeFunction "jsonb_typeof"
1366−
1367−-- | Returns its argument with all object fields that have null values omitted.
1368−-- Other null values are untouched.
1369−jsonStripNulls
1370− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1371− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1372−jsonStripNulls = unsafeFunction "json_strip_nulls"
1373−
1374−-- | Returns its argument with all object fields that have null values omitted.
1375−-- Other null values are untouched.
1376−jsonbStripNulls
1377− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1378− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1379−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1380−
1381−-- | @ jsonbSet target path new_value create_missing @
1382−--
1383−-- Returns target with the section designated by path replaced by new_value,
1384−-- or with new_value added if create_missing is true ( default is true) and the
1385−-- item designated by path does not exist. As with the path orientated
1386−-- operators, negative integers that appear in path count from the end of JSON
1387−-- arrays.
1388−jsonbSet
1389− :: PGTextArray "jsonbSet" arr
1390− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1391− -> Expression outer grp commons schemas params from (nullity arr)
1392− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1393− -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1394− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1395−jsonbSet tgt path val createMissing = case createMissing of
1396− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1397− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1398−
1399−-- | @ jsonbInsert target path new_value insert_after @
1400−--
1401−-- Returns target with new_value inserted. If target section designated by
1402−-- path is in a JSONB array, new_value will be inserted before target or after
1403−-- if insert_after is true (default is false). If target section designated by
1404−-- path is in JSONB object, new_value will be inserted only if target does not
1405−-- exist. As with the path orientated operators, negative integers that appear
1406−-- in path count from the end of JSON arrays.
1407−jsonbInsert
1408− :: PGTextArray "jsonbInsert" arr
1409− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1410− -> Expression outer grp commons schemas params from (nullity arr)
1411− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1412− -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1413− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1414−jsonbInsert tgt path val insertAfter = case insertAfter of
1415− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1416− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1417−
1418−-- | Returns its argument as indented JSON text.
1419−jsonbPretty
1420− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1421− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1422−jsonbPretty = unsafeFunction "jsonb_pretty"
1423−
1424−{-----------------------------------------
1425−aggregation
1426−-----------------------------------------}
1427−
1428−class Aggregate expr1 expr2 aggr
1429− | aggr -> expr1, aggr -> expr2 where
1430−
1431− -- | A special aggregation that does not require an input
1432− --
1433− -- >>> :{
1434− -- let
1435− -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1436− -- expression = countStar
1437− -- in printSQL expression
1438− -- :}
1439− -- count(*)
1440− countStar :: aggr ('NotNull 'PGint8)
1441−
1442− -- | >>> :{
1443− -- let
1444− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1445− -- expression = count (All #col)
1446− -- in printSQL expression
1447− -- :}
1448− -- count(ALL "col")
1449− count
1450− :: expr1 ty
1451− -- ^ what to count
1452− -> aggr ('NotNull 'PGint8)
1453−
1454− -- | >>> :{
1455− -- let
1456− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Null 'PGnumeric)
1457− -- expression = sum_ (Distinct #col)
1458− -- in printSQL expression
1459− -- :}
1460− -- sum(DISTINCT "col")
1461− sum_
1462− :: ty `In` PGNum
1463− => expr1 (nullity ty)
1464− -> aggr (nullity ty)
1465−
1466− -- | input values, including nulls, concatenated into an array
1467− arrayAgg
1468− :: expr1 ty
1469− -> aggr ('NotNull ('PGvararray ty))
1470−
1471− -- | aggregates values as a JSON array
1472− jsonAgg
1473− :: expr1 ty
1474− -> aggr ('NotNull 'PGjson)
1475−
1476− -- | aggregates values as a JSON array
1477− jsonbAgg
1478− :: expr1 ty
1479− -> aggr ('NotNull 'PGjsonb)
1480−
1481− -- | >>> :{
1482− -- let
1483− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1484− -- expression = bitAnd (Distinct #col)
1485− -- in printSQL expression
1486− -- :}
1487− -- bit_and(DISTINCT "col")
1488− bitAnd
1489− :: int `In` PGIntegral
1490− => expr1 (nullity int)
1491− -- ^ what to aggregate
1492− -> aggr (nullity int)
1493−
1494− -- | >>> :{
1495− -- let
1496− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1497− -- expression = bitOr (All #col)
1498− -- in printSQL expression
1499− -- :}
1500− -- bit_or(ALL "col")
1501− bitOr
1502− :: int `In` PGIntegral
1503− => expr1 (nullity int)
1504− -- ^ what to aggregate
1505− -> aggr (nullity int)
1506−
1507− -- | >>> :{
1508− -- let
1509− -- winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1510− -- winFun = boolAnd #col
1511− -- in printSQL winFun
1512− -- :}
1513− -- bool_and("col")
1514− boolAnd
1515− :: expr1 (nullity 'PGbool)
1516− -- ^ what to aggregate
1517− -> aggr (nullity 'PGbool)
1518−
1519− -- | >>> :{
1520− -- let
1521− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1522− -- expression = boolOr (All #col)
1523− -- in printSQL expression
1524− -- :}
1525− -- bool_or(ALL "col")
1526− boolOr
1527− :: expr1(nullity 'PGbool)
1528− -- ^ what to aggregate
1529− -> aggr (nullity 'PGbool)
1530−
1531− -- | synonym for `boolAnd`
1532− --
1533− -- >>> :{
1534− -- let
1535− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1536− -- expression = every (Distinct #col)
1537− -- in printSQL expression
1538− -- :}
1539− -- every(DISTINCT "col")
1540− every
1541− :: expr1 (nullity 'PGbool)
1542− -- ^ what to aggregate
1543− -> aggr (nullity 'PGbool)
1544−
1545− -- | maximum value of expression across all input values
1546− max_
1547− :: expr1 (nullity ty)
1548− -- ^ what to maximize
1549− -> aggr (nullity ty)
1550−
1551− -- | minimum value of expression across all input values
1552− min_
1553− :: expr1 (nullity ty)
1554− -- ^ what to minimize
1555− -> aggr (nullity ty)
1556−
1557− -- | average aggregation
1558− avg
1559− :: expr1 (nullity ty)
1560− -- ^ what to average
1561− -> aggr (nullity (PGAvg ty))
1562−
1563− {- | correlation coefficient
1564− >>> :{
1565− let
1566− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1567− expression = corr (All (#y :*: #x))
1568− in printSQL expression
1569− :}
1570− corr(ALL "y", "x")
1571− -}
1572− corr
1573− :: expr2 (nullity 'PGfloat8)
1574− -> aggr (nullity 'PGfloat8)
1575−
1576− {- | population covariance
1577− >>> :{
1578− let
1579− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1580− expression = covarPop (All (#y :*: #x))
1581− in printSQL expression
1582− :}
1583− covar_pop(ALL "y", "x")
1584− -}
1585− covarPop
1586− :: expr2 (nullity 'PGfloat8)
1587− -> aggr (nullity 'PGfloat8)
1588−
1589− {- | sample covariance
1590− >>> :{
1591− let
1592− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1593− winFun = covarSamp (#y :*: #x)
1594− in printSQL winFun
1595− :}
1596− covar_samp("y", "x")
1597− -}
1598− covarSamp
1599− :: expr2 (nullity 'PGfloat8)
1600− -> aggr (nullity 'PGfloat8)
1601−
1602− {- | average of the independent variable (sum(X)/N)
1603− >>> :{
1604− let
1605− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1606− expression = regrAvgX (All (#y :*: #x))
1607− in printSQL expression
1608− :}
1609− regr_avgx(ALL "y", "x")
1610− -}
1611− regrAvgX
1612− :: expr2 (nullity 'PGfloat8)
1613− -> aggr (nullity 'PGfloat8)
1614−
1615− {- | average of the dependent variable (sum(Y)/N)
1616− >>> :{
1617− let
1618− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1619− winFun = regrAvgY (#y :*: #x)
1620− in printSQL winFun
1621− :}
1622− regr_avgy("y", "x")
1623− -}
1624− regrAvgY
1625− :: expr2 (nullity 'PGfloat8)
1626− -> aggr (nullity 'PGfloat8)
1627−
1628− {- | number of input rows in which both expressions are nonnull
1629− >>> :{
1630− let
1631− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGint8)
1632− winFun = regrCount (#y :*: #x)
1633− in printSQL winFun
1634− :}
1635− regr_count("y", "x")
1636− -}
1637− regrCount
1638− :: expr2 (nullity 'PGfloat8)
1639− -> aggr (nullity 'PGint8)
1640−
1641− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1642− >>> :{
1643− let
1644− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1645− expression = regrIntercept (All (#y :*: #x))
1646− in printSQL expression
1647− :}
1648− regr_intercept(ALL "y", "x")
1649− -}
1650− regrIntercept
1651− :: expr2 (nullity 'PGfloat8)
1652− -> aggr (nullity 'PGfloat8)
1653−
1654− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1655− regrR2
1656− :: expr2 (nullity 'PGfloat8)
1657− -> aggr (nullity 'PGfloat8)
1658−
1659− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1660− -- determined by the (X, Y) pairs
1661− regrSlope
1662− :: expr2 (nullity 'PGfloat8)
1663− -> aggr (nullity 'PGfloat8)
1664−
1665− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1666− -- (“sum of squares” of the independent variable)
1667− regrSxx
1668− :: expr2 (nullity 'PGfloat8)
1669− -> aggr (nullity 'PGfloat8)
1670−
1671− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1672− -- (“sum of products” of independent times dependent variable)
1673− regrSxy
1674− :: expr2 (nullity 'PGfloat8)
1675− -> aggr (nullity 'PGfloat8)
1676−
1677− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1678− -- (“sum of squares” of the dependent variable)
1679− regrSyy
1680− :: expr2 (nullity 'PGfloat8)
1681− -> aggr (nullity 'PGfloat8)
1682−
1683− -- | historical alias for `stddevSamp`
1684− stddev
1685− :: expr1 (nullity ty)
1686− -> aggr (nullity (PGAvg ty))
1687−
1688− -- | population standard deviation of the input values
1689− stddevPop
1690− :: expr1 (nullity ty)
1691− -> aggr (nullity (PGAvg ty))
1692−
1693− -- | sample standard deviation of the input values
1694− stddevSamp
1695− :: expr1 (nullity ty)
1696− -> aggr (nullity (PGAvg ty))
1697−
1698− -- | historical alias for `varSamp`
1699− variance
1700− :: expr1 (nullity ty)
1701− -> aggr (nullity (PGAvg ty))
1702−
1703− -- | population variance of the input values
1704− -- (square of the population standard deviation)
1705− varPop
1706− :: expr1 (nullity ty)
1707− -> aggr (nullity (PGAvg ty))
1708−
1709− -- | sample variance of the input values
1710− -- (square of the sample standard deviation)
1711− varSamp
1712− :: expr1 (nullity ty)
1713− -> aggr (nullity (PGAvg ty))
1714−
1715−data Distinction expr ty
1716− = All (expr ty)
1717− | Distinct (expr ty)
1718− deriving (GHC.Generic,Show,Eq,Ord)
1719−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1720−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1721− renderSQL = \case
1722− All x -> "ALL" <+> renderSQL x
1723− Distinct x -> "DISTINCT" <+> renderSQL x
1724−instance RenderSQL
1725− (Distinction
1726− ( Expression outer grp commons schemas params from
1727− :*:
1728− Expression outer grp commons schemas params from) xty ) where
1729− renderSQL = \case
1730− All (x :*: x') ->
1731− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1732− Distinct (x :*: x') ->
1733− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1734−
1735−instance Aggregate
1736− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1737− (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1738− (Expression outer ('Grouped bys) commons schemas params from) where
1739− countStar = UnsafeExpression "count(*)"
1740− count = unsafeAggregate1 "count"
1741− sum_ = unsafeAggregate1 "sum"
1742− arrayAgg = unsafeAggregate1 "array_agg"
1743− jsonAgg = unsafeAggregate1 "json_agg"
1744− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1745− bitAnd = unsafeAggregate1 "bit_and"
1746− bitOr = unsafeAggregate1 "bit_or"
1747− boolAnd = unsafeAggregate1 "bool_and"
1748− boolOr = unsafeAggregate1 "bool_or"
1749− every = unsafeAggregate1 "every"
1750− max_ = unsafeAggregate1 "max"
1751− min_ = unsafeAggregate1 "min"
1752− avg = unsafeAggregate1 "avg"
1753− corr = unsafeAggregate2 "corr"
1754− covarPop = unsafeAggregate2 "covar_pop"
1755− covarSamp = unsafeAggregate2 "covar_samp"
1756− regrAvgX = unsafeAggregate2 "regr_avgx"
1757− regrAvgY = unsafeAggregate2 "regr_avgy"
1758− regrCount = unsafeAggregate2 "regr_count"
1759− regrIntercept = unsafeAggregate2 "regr_intercept"
1760− regrR2 = unsafeAggregate2 "regr_r2"
1761− regrSlope = unsafeAggregate2 "regr_slope"
1762− regrSxx = unsafeAggregate2 "regr_sxx"
1763− regrSxy = unsafeAggregate2 "regr_sxy"
1764− regrSyy = unsafeAggregate2 "regr_syy"
1765− stddev = unsafeAggregate1 "stddev"
1766− stddevPop = unsafeAggregate1 "stddev_pop"
1767− stddevSamp = unsafeAggregate1 "stddev_samp"
1768− variance = unsafeAggregate1 "variance"
1769− varPop = unsafeAggregate1 "var_pop"
1770− varSamp = unsafeAggregate1 "var_samp"
1771−instance Aggregate
1772− (Expression outer grp commons schemas params from)
1773− (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1774− (WindowFunction outer grp commons schemas params from) where
1775− countStar = UnsafeWindowFunction "count(*)"
1776− count = unsafeWindowFunction1 "count"
1777− sum_ = unsafeWindowFunction1 "sum"
1778− arrayAgg = unsafeWindowFunction1 "array_agg"
1779− jsonAgg = unsafeWindowFunction1 "json_agg"
1780− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1781− bitAnd = unsafeWindowFunction1 "bit_and"
1782− bitOr = unsafeWindowFunction1 "bit_or"
1783− boolAnd = unsafeWindowFunction1 "bool_and"
1784− boolOr = unsafeWindowFunction1 "bool_or"
1785− every = unsafeWindowFunction1 "every"
1786− max_ = unsafeWindowFunction1 "max"
1787− min_ = unsafeWindowFunction1 "min"
1788− avg = unsafeWindowFunction1 "avg"
1789− corr = unsafeWindowFunction2 "corr"
1790− covarPop = unsafeWindowFunction2 "covar_pop"
1791− covarSamp = unsafeWindowFunction2 "covar_samp"
1792− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1793− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1794− regrCount = unsafeWindowFunction2 "regr_count"
1795− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1796− regrR2 = unsafeWindowFunction2 "regr_r2"
1797− regrSlope = unsafeWindowFunction2 "regr_slope"
1798− regrSxx = unsafeWindowFunction2 "regr_sxx"
1799− regrSxy = unsafeWindowFunction2 "regr_sxy"
1800− regrSyy = unsafeWindowFunction2 "regr_syy"
1801− stddev = unsafeWindowFunction1 "stddev"
1802− stddevPop = unsafeWindowFunction1 "stddev_pop"
1803− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1804− variance = unsafeWindowFunction1 "variance"
1805− varPop = unsafeWindowFunction1 "var_pop"
1806− varSamp = unsafeWindowFunction1 "var_samp"
1807−
1808−-- | escape hatch to define aggregate functions
1809−unsafeAggregate1
1810− :: ByteString -- ^ aggregate function
1811− -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1812− -> Expression outer ('Grouped bys) commons schemas params from yty
1813−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1814− [fun, "(", renderSQL x, ")"]
1815−
1816−-- | escape hatch to define aggregate binary functions
1817−unsafeAggregate2
1818− :: ByteString -- ^ aggregate function
1819− -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1820− -> Expression outer ('Grouped bys) commons schemas params from yty
1821−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1822− [fun, "(", renderSQL xx, ")"]
1823−
1824−-- | A type family that calculates `PGAvg` type of a `PGType`.
1825−type family PGAvg ty where
1826− PGAvg 'PGint2 = 'PGnumeric
1827− PGAvg 'PGint4 = 'PGnumeric
1828− PGAvg 'PGint8 = 'PGnumeric
1829− PGAvg 'PGnumeric = 'PGnumeric
1830− PGAvg 'PGfloat4 = 'PGfloat8
1831− PGAvg 'PGfloat8 = 'PGfloat8
1832− PGAvg 'PGinterval = 'PGinterval
1833− PGAvg pg = TypeError
1834− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1835−
1836−{-----------------------------------------
1837−type expressions
1838−-----------------------------------------}
1839−
1840−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1841−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1842− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1843− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1844−instance RenderSQL (TypeExpression schemas ty) where
1845− renderSQL = renderTypeExpression
1846−
1847−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1848−typedef
1849− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1850− => QualifiedAlias sch td
1851− -> TypeExpression schemas (nullity ty)
1852−typedef = UnsafeTypeExpression . renderSQL
1853−
1854−-- | The composite type corresponding to a `Table` definition can be expressed
1855−-- by its alias.
1856−typetable
1857− :: (Has sch schemas schema, Has tab schema ('Table table))
1858− => QualifiedAlias sch tab
1859− -> TypeExpression schemas (nullity ('PGcomposite (TableToRow table)))
1860−typetable = UnsafeTypeExpression . renderSQL
1861−
1862−-- | The composite type corresponding to a `View` definition can be expressed
1863−-- by its alias.
1864−typeview
1865− :: (Has sch schemas schema, Has vw schema ('View view))
1866− => QualifiedAlias sch vw
1867− -> TypeExpression schemas (nullity ('PGcomposite view))
1868−typeview = UnsafeTypeExpression . renderSQL
1869−
1870−-- | logical Boolean (true/false)
1871−bool :: TypeExpression schemas (nullity 'PGbool)
1872−bool = UnsafeTypeExpression "bool"
1873−-- | signed two-byte integer
1874−int2, smallint :: TypeExpression schemas (nullity 'PGint2)
1875−int2 = UnsafeTypeExpression "int2"
1876−smallint = UnsafeTypeExpression "smallint"
1877−-- | signed four-byte integer
1878−int4, int, integer :: TypeExpression schemas (nullity 'PGint4)
1879−int4 = UnsafeTypeExpression "int4"
1880−int = UnsafeTypeExpression "int"
1881−integer = UnsafeTypeExpression "integer"
1882−-- | signed eight-byte integer
1883−int8, bigint :: TypeExpression schemas (nullity 'PGint8)
1884−int8 = UnsafeTypeExpression "int8"
1885−bigint = UnsafeTypeExpression "bigint"
1886−-- | arbitrary precision numeric type
1887−numeric :: TypeExpression schemas (nullity 'PGnumeric)
1888−numeric = UnsafeTypeExpression "numeric"
1889−-- | single precision floating-point number (4 bytes)
1890−float4, real :: TypeExpression schemas (nullity 'PGfloat4)
1891−float4 = UnsafeTypeExpression "float4"
1892−real = UnsafeTypeExpression "real"
1893−-- | double precision floating-point number (8 bytes)
1894−float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
1895−float8 = UnsafeTypeExpression "float8"
1896−doublePrecision = UnsafeTypeExpression "double precision"
1897−-- | variable-length character string
1898−text :: TypeExpression schemas (nullity 'PGtext)
1899−text = UnsafeTypeExpression "text"
1900−-- | fixed-length character string
1901−char, character
1902− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1903− => TypeExpression schemas (nullity ('PGchar n))
1904−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
1905−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
1906−-- | variable-length character string
1907−varchar, characterVarying
1908− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1909− => TypeExpression schemas (nullity ('PGvarchar n))
1910−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
1911−characterVarying = UnsafeTypeExpression $
1912− "character varying(" <> renderNat @n <> ")"
1913−-- | binary data ("byte array")
1914−bytea :: TypeExpression schemas (nullity 'PGbytea)
1915−bytea = UnsafeTypeExpression "bytea"
1916−-- | date and time (no time zone)
1917−timestamp :: TypeExpression schemas (nullity 'PGtimestamp)
1918−timestamp = UnsafeTypeExpression "timestamp"
1919−-- | date and time, including time zone
1920−timestampWithTimeZone :: TypeExpression schemas (nullity 'PGtimestamptz)
1921−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1922−-- | calendar date (year, month, day)
1923−date :: TypeExpression schemas (nullity 'PGdate)
1924−date = UnsafeTypeExpression "date"
1925−-- | time of day (no time zone)
1926−time :: TypeExpression schemas (nullity 'PGtime)
1927−time = UnsafeTypeExpression "time"
1928−-- | time of day, including time zone
1929−timeWithTimeZone :: TypeExpression schemas (nullity 'PGtimetz)
1930−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1931−-- | time span
1932−interval :: TypeExpression schemas (nullity 'PGinterval)
1933−interval = UnsafeTypeExpression "interval"
1934−-- | universally unique identifier
1935−uuid :: TypeExpression schemas (nullity 'PGuuid)
1936−uuid = UnsafeTypeExpression "uuid"
1937−-- | IPv4 or IPv6 host address
1938−inet :: TypeExpression schemas (nullity 'PGinet)
1939−inet = UnsafeTypeExpression "inet"
1940−-- | textual JSON data
1941−json :: TypeExpression schemas (nullity 'PGjson)
1942−json = UnsafeTypeExpression "json"
1943−-- | binary JSON data, decomposed
1944−jsonb :: TypeExpression schemas (nullity 'PGjsonb)
1945−jsonb = UnsafeTypeExpression "jsonb"
1946−-- | variable length array
1947−vararray
1948− :: TypeExpression schemas pg
1949− -> TypeExpression schemas (nullity ('PGvararray pg))
1950−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
1951−-- | fixed length array
1952−--
1953−-- >>> renderSQL (fixarray @'[2] json)
1954−-- "json[2]"
1955−fixarray
1956− :: forall dims schemas nullity pg. All KnownNat dims
1957− => TypeExpression schemas pg
1958− -> TypeExpression schemas (nullity ('PGfixarray dims pg))
1959−fixarray ty = UnsafeTypeExpression $
1960− renderSQL ty <> renderDims @dims
1961− where
1962− renderDims :: forall ns. All KnownNat ns => ByteString
1963− renderDims =
1964− ("[" <>)
1965− . (<> "]")
1966− . ByteString.intercalate "]["
1967− . hcollapse
1968− $ hcmap (Proxy @KnownNat)
1969− (K . fromString . show . natVal)
1970− (hpure Proxy :: NP Proxy ns)
1971−
1972−-- | `pgtype` is a demoted version of a `PGType`
1973−class PGTyped schemas (ty :: NullityType) where
1974− pgtype :: TypeExpression schemas ty
1975−instance PGTyped schemas (nullity 'PGbool) where pgtype = bool
1976−instance PGTyped schemas (nullity 'PGint2) where pgtype = int2
1977−instance PGTyped schemas (nullity 'PGint4) where pgtype = int4
1978−instance PGTyped schemas (nullity 'PGint8) where pgtype = int8
1979−instance PGTyped schemas (nullity 'PGnumeric) where pgtype = numeric
1980−instance PGTyped schemas (nullity 'PGfloat4) where pgtype = float4
1981−instance PGTyped schemas (nullity 'PGfloat8) where pgtype = float8
1982−instance PGTyped schemas (nullity 'PGtext) where pgtype = text
1983−instance (KnownNat n, 1 <= n)
1984− => PGTyped schemas (nullity ('PGchar n)) where pgtype = char @n
1985−instance (KnownNat n, 1 <= n)
1986− => PGTyped schemas (nullity ('PGvarchar n)) where pgtype = varchar @n
1987−instance PGTyped schemas (nullity 'PGbytea) where pgtype = bytea
1988−instance PGTyped schemas (nullity 'PGtimestamp) where pgtype = timestamp
1989−instance PGTyped schemas (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
1990−instance PGTyped schemas (nullity 'PGdate) where pgtype = date
1991−instance PGTyped schemas (nullity 'PGtime) where pgtype = time
1992−instance PGTyped schemas (nullity 'PGtimetz) where pgtype = timeWithTimeZone
1993−instance PGTyped schemas (nullity 'PGinterval) where pgtype = interval
1994−instance PGTyped schemas (nullity 'PGuuid) where pgtype = uuid
1995−instance PGTyped schemas (nullity 'PGjson) where pgtype = json
1996−instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
1997−instance PGTyped schemas ty
1998− => PGTyped schemas (nullity ('PGvararray ty)) where
1999− pgtype = vararray (pgtype @schemas @ty)
2000−instance (All KnownNat dims, PGTyped schemas ty)
2001− => PGTyped schemas (nullity ('PGfixarray dims ty)) where
2002− pgtype = fixarray @dims (pgtype @schemas @ty)
2003−
2004−{-----------------------------------------
2005−Sorting
2006−-----------------------------------------}
2007−
2008−-- | `SortExpression`s are used by `sortBy` to optionally sort the results
2009−-- of a `Query`. `Asc` or `Desc` set the sort direction of a `NotNull` result
2010−-- column to ascending or descending. Ascending order puts smaller values
2011−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2012−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2013−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2014−-- determine whether nulls appear before or after non-null values in the sort
2015−-- ordering of a `Null` result column.
2016−data SortExpression outer grp commons schemas params from where
2017− Asc
2018− :: Expression outer grp commons schemas params from ('NotNull ty)
2019− -> SortExpression outer grp commons schemas params from
2020− Desc
2021− :: Expression outer grp commons schemas params from ('NotNull ty)
2022− -> SortExpression outer grp commons schemas params from
2023− AscNullsFirst
2024− :: Expression outer grp commons schemas params from ('Null ty)
2025− -> SortExpression outer grp commons schemas params from
2026− AscNullsLast
2027− :: Expression outer grp commons schemas params from ('Null ty)
2028− -> SortExpression outer grp commons schemas params from
2029− DescNullsFirst
2030− :: Expression outer grp commons schemas params from ('Null ty)
2031− -> SortExpression outer grp commons schemas params from
2032− DescNullsLast
2033− :: Expression outer grp commons schemas params from ('Null ty)
2034− -> SortExpression outer grp commons schemas params from
2035−deriving instance Show (SortExpression outer grp commons schemas params from)
2036−
2037−class OrderBy expr where
2038− orderBy
2039− :: [SortExpression outer grp commons schemas params from]
2040− -> expr outer grp commons schemas params from
2041− -> expr outer grp commons schemas params from
2042−
2043−-- | Render a `SortExpression`.
2044−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2045− renderSQL = \case
2046− Asc expression -> renderSQL expression <+> "ASC"
2047− Desc expression -> renderSQL expression <+> "DESC"
2048− AscNullsFirst expression -> renderSQL expression
2049− <+> "ASC NULLS FIRST"
2050− DescNullsFirst expression -> renderSQL expression
2051− <+> "DESC NULLS FIRST"
2052− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2053− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2054−
2055−data WindowDefinition outer grp commons schemas params from where
2056− WindowDefinition
2057− :: SListI bys
2058− => NP (Expression outer grp commons schemas params from) bys
2059− -> [SortExpression outer grp commons schemas params from]
2060− -> WindowDefinition outer grp commons schemas params from
2061−
2062−instance OrderBy WindowDefinition where
2063− orderBy sortsR (WindowDefinition parts sortsL)
2064− = WindowDefinition parts (sortsL ++ sortsR)
2065−
2066−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2067− renderSQL (WindowDefinition part ord) =
2068− renderPartitionByClause part <> renderOrderByClause ord
2069− where
2070− renderPartitionByClause = \case
2071− Nil -> ""
2072− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2073− renderOrderByClause = \case
2074− [] -> ""
2075− srts -> " ORDER" <+> "BY"
2076− <+> commaSeparated (renderSQL <$> srts)
2077−
2078−partitionBy
2079− :: SListI bys
2080− => NP (Expression outer grp commons schemas params from) bys
2081− -> WindowDefinition outer grp commons schemas params from
2082−partitionBy bys = WindowDefinition bys []
2083−
2084−newtype WindowFunction
2085− (outer :: FromType)
2086− (grp :: Grouping)
2087− (commons :: FromType)
2088− (schemas :: SchemasType)
2089− (params :: [NullityType])
2090− (from :: FromType)
2091− (ty :: NullityType)
2092− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2093− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2094−
2095−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2096− renderSQL = renderWindowFunction
2097−
2098−unsafeWindowFunction1
2099− :: ByteString
2100− -> Expression outer grp commons schemas params from ty0
2101− -> WindowFunction outer grp commons schemas params from ty1
2102−unsafeWindowFunction1 fun x
2103− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2104−
2105−unsafeWindowFunction2
2106− :: ByteString
2107− -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2108− -> WindowFunction outer grp commons schemas params from ty1
2109−unsafeWindowFunction2 fun (x :*: x')
2110− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2111−
2112−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2113−>>> printSQL rank
2114−rank()
2115−-}
2116−rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2117−rank = UnsafeWindowFunction "rank()"
2118−
2119−{- | number of the current row within its partition, counting from 1
2120−>>> printSQL rowNumber
2121−row_number()
2122−-}
2123−rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2124−rowNumber = UnsafeWindowFunction "row_number()"
2125−
2126−{- | rank of the current row without gaps; this function counts peer groups
2127−>>> printSQL denseRank
2128−dense_rank()
2129−-}
2130−denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2131−denseRank = UnsafeWindowFunction "dense_rank()"
2132−
2133−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2134−>>> printSQL percentRank
2135−percent_rank()
2136−-}
2137−percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2138−percentRank = UnsafeWindowFunction "percent_rank()"
2139−
2140−{- | cumulative distribution: (number of partition rows
2141−preceding or peer with current row) / total partition rows
2142−>>> printSQL cumeDist
2143−cume_dist()
2144−-}
2145−cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2146−cumeDist = UnsafeWindowFunction "cume_dist()"
2147−
2148−{- | integer ranging from 1 to the argument value,
2149−dividing the partition as equally as possible
2150−-}
2151−ntile
2152− :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2153− -- ^ num buckets
2154− -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2155−ntile = unsafeWindowFunction1 "ntile"
2156−
2157−{- | returns value evaluated at the row that is offset rows before the current
2158−row within the partition; if there is no such row, instead return default
2159−(which must be of the same type as value). Both offset and default are
2160−evaluated with respect to the current row.
2161−-}
2162−lag
2163− :: Expression outer grp commons schemas params from ty
2164− -- ^ value
2165− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2166− -- ^ offset
2167− -> Expression outer grp commons schemas params from ty
2168− -- ^ default
2169− -> WindowFunction outer grp commons schemas params from ty
2170−lag value offset def = UnsafeWindowFunction $ "lag"
2171− <> parenthesized
2172− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2173−
2174−{- | returns value evaluated at the row that is offset rows after the current
2175−row within the partition; if there is no such row, instead return default
2176−(which must be of the same type as value). Both offset and default are
2177−evaluated with respect to the current row.
2178−-}
2179−lead
2180− :: Expression outer grp commons schemas params from ty
2181− -- ^ value
2182− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2183− -- ^ offset
2184− -> Expression outer grp commons schemas params from ty
2185− -- ^ default
2186− -> WindowFunction outer grp commons schemas params from ty
2187−lead value offset def = UnsafeWindowFunction $ "lag"
2188− <> parenthesized
2189− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2190−
2191−{- | returns value evaluated at the row that is the
2192−first row of the window frame
2193−-}
2194−firstValue
2195− :: Expression outer grp commons schemas params from ty
2196− -- ^ value
2197− -> WindowFunction outer grp commons schemas params from ty
2198−firstValue = unsafeWindowFunction1 "first_value"
2199−
2200−{- | returns value evaluated at the row that is the
2201−last row of the window frame
2202−-}
2203−lastValue
2204− :: Expression outer grp commons schemas params from ty
2205− -- ^ value
2206− -> WindowFunction outer grp commons schemas params from ty
2207−lastValue = unsafeWindowFunction1 "last_value"
2208−
2209−{- | returns value evaluated at the row that is the nth
2210−row of the window frame (counting from 1); null if no such row
2211−-}
2212−nthValue
2213− :: Expression outer grp commons schemas params from (nullity ty)
2214− -- ^ value
2215− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2216− -- ^ nth
2217− -> WindowFunction outer grp commons schemas params from ('Null ty)
2218−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2219− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])