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