@@ -1,14 +1,13 @@
11{-|
22Module: Squeal.PostgreSQL.Expression
33Description: Squeal expressions
4−Copyright: (c) Eitan Chatav, 2017
4+Copyright: (c) Eitan Chatav, 2019
55Maintainer: eitan@morphism.tech
66Stability: experimental
77
88Squeal expressions are the atoms used to build statements.
99-}
1010
11−{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
1211{-# LANGUAGE
1312 AllowAmbiguousTypes
1413 , ConstraintKinds
@@ -34,298 +33,214 @@ Squeal expressions are the atoms used to build statements.
3433module Squeal.PostgreSQL.Expression
3534 ( -- * Expression
3635 Expression (..)
37− , HasParameter (parameter)
38− , param
39− -- ** Null
40− , null_
41− , notNull
42− , coalesce
43− , fromNull
44− , isNull
45− , isNotNull
46− , matchNull
47− , nullIf
48− -- ** Collections
49− , array
50− , cardinality
51− , index
52− , row
53− , field
54− -- ** Functions
55− , unsafeBinaryOp
56− , unsafeUnaryOp
36+ , Expr
37+ , type (-->)
38+ , FunctionDB
5739 , unsafeFunction
58− , unsafeVariadicFunction
59− , atan2_
60− , cast
61− , quot_
62− , rem_
63− , trunc
64− , round_
65− , ceiling_
66− , greatest
67− , least
68− -- ** Conditions
69− , true
70− , false
71− , not_
72− , (.&&)
73− , (.||)
74− , Condition
75− , caseWhenThenElse
76− , ifThenElse
77− , (.==)
78− , (./=)
79− , (.>=)
80− , (.<)
81− , (.<=)
82− , (.>)
83− -- ** Time
84− , currentDate
85− , currentTime
86− , currentTimestamp
87− , localTime
88− , localTimestamp
89− , TimeOp (..)
90− , makeDate
91− , makeTime
92− , makeTimestamp
93− , makeTimestamptz
94− -- ** Text
95− , lower
96− , upper
97− , charLength
98− , like
99− , ilike
100− -- ** Json
101− -- *** Json and Jsonb operators
102− , (.->)
103− , (.->>)
104− , (.#>)
105− , (.#>>)
106− -- *** Jsonb operators
107− , (.@>)
108− , (.<@)
109− , (.?)
110− , (.?|)
111− , (.?&)
112− , (.-.)
113− , (#-.)
114− -- *** Functions
115− , jsonLit
116− , jsonbLit
117− , toJson
118− , toJsonb
119− , arrayToJson
120− , rowToJson
121− , jsonBuildArray
122− , jsonbBuildArray
123− , jsonBuildObject
124− , jsonbBuildObject
125− , jsonObject
126− , jsonbObject
127− , jsonZipObject
128− , jsonbZipObject
129− , jsonArrayLength
130− , jsonbArrayLength
131− , jsonExtractPath
132− , jsonbExtractPath
133− , jsonExtractPathAsText
134− , jsonbExtractPathAsText
135− , jsonTypeof
136− , jsonbTypeof
137− , jsonStripNulls
138− , jsonbStripNulls
139− , jsonbSet
140− , jsonbInsert
141− , jsonbPretty
142− -- ** Aggregation
143− , Aggregate (..)
144− , Distinction (..)
145− , PGAvg
146− -- * Window Functions
147− , WindowDefinition (..)
148− , partitionBy
149− , WindowFunction (..)
150− , rank
151− , rowNumber
152− , denseRank
153− , percentRank
154− , cumeDist
155− , ntile
156− , lag
157− , lead
158− , firstValue
159− , lastValue
160− , nthValue
161− -- * Sorting
162− , SortExpression (..)
163− , OrderBy (..)
164− -- * Types
165− , TypeExpression (..)
166− , PGTyped (..)
167− , typedef
168− , typetable
169− , typeview
170− , bool
171− , int2
172− , smallint
173− , int4
174− , int
175− , integer
176− , int8
177− , bigint
178− , numeric
179− , float4
180− , real
181− , float8
182− , doublePrecision
183− , money
184− , text
185− , char
186− , character
187− , varchar
188− , characterVarying
189− , bytea
190− , timestamp
191− , timestampWithTimeZone
192− , date
193− , time
194− , timeWithTimeZone
195− , interval
196− , uuid
197− , inet
198− , json
199− , jsonb
200− , vararray
201− , 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 (..)
20257 -- * Re-export
20358 , (&)
204− , NP (..)
205− , (:*:) (..)
20659 , K (..)
60+ , unK
20761 ) where
20862
20963import Control.Category
21064import Control.DeepSeq
21165import Data.ByteString (ByteString)
212−import Data.ByteString.Lazy (toStrict)
21366import Data.Function ((&))
21467import Data.Semigroup hiding (All)
215−import qualified Data.Aeson as JSON
21668import Data.String
217−import Data.Word
21869import Generics.SOP hiding (All, from)
219−import GHC.Generics ((:*:) (..))
22070import GHC.OverloadedLabels
22171import GHC.TypeLits
22272import Numeric
22373import Prelude hiding (id, (.))
22474
225−import qualified Data.ByteString as ByteString
22675import qualified GHC.Generics as GHC
227−import qualified Generics.SOP as SOP
22876
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
22979import Squeal.PostgreSQL.Render
23080import Squeal.PostgreSQL.Schema
23181
82+-- $setup
83+-- >>> import Squeal.PostgreSQL
84+
23285{-----------------------------------------
23386column expressions
23487-----------------------------------------}
23588
23689{- | `Expression`s are used in a variety of contexts,
237−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,
23892as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
23993`Squeal.PostgreSQL.Manipulation.update`,
240−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
24195
24296The expression syntax allows the calculation of
24397values from primitive expression using arithmetic, logical,
24498and 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`.
245113-}
246114newtype Expression
247115 (outer :: FromType)
248− (grp :: Grouping)
249116 (commons :: FromType)
117+ (grp :: Grouping)
250118 (schemas :: SchemasType)
251119 (params :: [NullityType])
252120 (from :: FromType)
253121 (ty :: NullityType)
254122 = UnsafeExpression { renderExpression :: ByteString }
255123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
256−
257−instance RenderSQL (Expression outer grp commons schemas params from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
258125 renderSQL = renderExpression
259126
260−{- | A `HasParameter` constraint is used to indicate a value that is
261−supplied externally to a SQL statement.
262−`Squeal.PostgreSQL.PQ.manipulateParams`,
263−`Squeal.PostgreSQL.PQ.queryParams` and
264−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
265−separately from the SQL command string, in which case `param`s are used to
266−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)
267181-}
268−class KnownNat n => HasParameter
269− (n :: Nat)
270− (params :: [NullityType])
271− (ty :: NullityType)
272− | n params -> ty where
273− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
274− --
275− -- >>> let expr = parameter @1 int4 :: Expression outer grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
276− -- >>> printSQL expr
277− -- ($1 :: int4)
278− parameter
279− :: TypeExpression schemas ty
280− -> Expression outer grp commons schemas params from ty
281− parameter ty = UnsafeExpression $ parenthesized $
282− "$" <> renderNat @n <+> "::"
283− <+> renderSQL ty
284−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
285−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
286− => HasParameter n (ty' : params) ty
287−
288−-- | `param` takes a `Nat` using type application and for basic types,
289−-- infers a `TypeExpression`.
290−--
291−-- >>> let expr = param @1 :: Expression outer grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
292−-- >>> printSQL expr
293−-- ($1 :: int4)
294−param
295− :: forall n outer commons schemas params from grp ty
296− . (PGTyped schemas ty, HasParameter n params ty)
297− => Expression outer grp commons schemas params from ty -- ^ param
298−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)
299214
300215instance (HasUnique tab (Join outer from) row, Has col row ty)
301− => IsLabel col (Expression outer 'Ungrouped commons schemas params from ty) where
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
302217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
303218instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
304− => 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
305220 fromLabel = fromLabel @col :* Nil
306221instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
307222 => IsLabel col
308− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
309224 fromLabel = fromLabel @col `As` Alias
310225instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
311226 => IsLabel col
312− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
313228 fromLabel = fromLabel @col :* Nil
314229
315230instance (Has tab (Join outer from) row, Has col row ty)
316− => 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
317232 tab ! col = UnsafeExpression $
318233 renderSQL tab <> "." <> renderSQL col
319234instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
320− => 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
321236 tab ! col = tab ! col :* Nil
322237instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
323238 => IsQualified tab col
324− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
325240 tab ! col = tab ! col `As` col
326241instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
327242 => IsQualified tab col
328− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
329244 tab ! col = tab ! col :* Nil
330245
331246instance
@@ -333,7 +248,7 @@ instance
333248 , Has col row ty
334249 , GroupedBy tab col bys
335250 ) => IsLabel col
336− (Expression outer ('Grouped bys) commons schemas params from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
337252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
338253instance
339254 ( HasUnique tab (Join outer from) row
@@ -341,7 +256,7 @@ instance
341256 , GroupedBy tab col bys
342257 , tys ~ '[ty]
343258 ) => IsLabel col
344− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
345260 fromLabel = fromLabel @col :* Nil
346261instance
347262 ( HasUnique tab (Join outer from) row
@@ -349,7 +264,7 @@ instance
349264 , GroupedBy tab col bys
350265 , column ~ (col ::: ty)
351266 ) => IsLabel col
352− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
353268 fromLabel = fromLabel @col `As` Alias
354269instance
355270 ( HasUnique tab (Join outer from) row
@@ -357,7 +272,7 @@ instance
357272 , GroupedBy tab col bys
358273 , columns ~ '[col ::: ty]
359274 ) => IsLabel col
360− (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
361276 fromLabel = fromLabel @col :* Nil
362277
363278instance
@@ -365,7 +280,7 @@ instance
365280 , Has col row ty
366281 , GroupedBy tab col bys
367282 ) => IsQualified tab col
368− (Expression outer ('Grouped bys) commons schemas params from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
369284 tab ! col = UnsafeExpression $
370285 renderSQL tab <> "." <> renderSQL col
371286instance
@@ -374,7 +289,7 @@ instance
374289 , GroupedBy tab col bys
375290 , tys ~ '[ty]
376291 ) => IsQualified tab col
377− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
378293 tab ! col = tab ! col :* Nil
379294instance
380295 ( Has tab (Join outer from) row
@@ -382,7 +297,7 @@ instance
382297 , GroupedBy tab col bys
383298 , column ~ (col ::: ty)
384299 ) => IsQualified tab col
385− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
386301 tab ! col = tab ! col `As` col
387302instance
388303 ( Has tab (Join outer from) row
@@ -390,244 +305,78 @@ instance
390305 , GroupedBy tab col bys
391306 , columns ~ '[col ::: ty]
392307 ) => IsQualified tab col
393− (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
394309 tab ! col = tab ! col :* Nil
395310
396−-- | analagous to `Nothing`
397−--
398−-- >>> printSQL null_
399−-- NULL
400−null_ :: Expression outer grp commons schemas params from ('Null ty)
401−null_ = UnsafeExpression "NULL"
402−
403−-- | analagous to `Just`
404−--
405−-- >>> printSQL $ notNull true
406−-- TRUE
407−notNull
408− :: Expression outer grp commons schemas params from ('NotNull ty)
409− -> Expression outer grp commons schemas params from ('Null ty)
410−notNull = UnsafeExpression . renderSQL
411−
412−-- | return the leftmost value which is not NULL
413−--
414−-- >>> printSQL $ coalesce [null_, true] false
415−-- COALESCE(NULL, TRUE, FALSE)
416−coalesce
417− :: [Expression outer grp commons schemas params from ('Null ty)]
418− -- ^ @NULL@s may be present
419− -> Expression outer grp commons schemas params from ('NotNull ty)
420− -- ^ @NULL@ is absent
421− -> Expression outer grp commons schemas params from ('NotNull ty)
422−coalesce nullxs notNullx = UnsafeExpression $
423− "COALESCE" <> parenthesized (commaSeparated
424− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
425−
426−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
427−--
428−-- >>> printSQL $ fromNull true null_
429−-- COALESCE(NULL, TRUE)
430−fromNull
431− :: Expression outer grp commons schemas params from ('NotNull ty)
432− -- ^ what to convert @NULL@ to
433− -> Expression outer grp commons schemas params from ('Null ty)
434− -> Expression outer grp commons schemas params from ('NotNull ty)
435−fromNull notNullx nullx = coalesce [nullx] notNullx
436−
437−-- | >>> printSQL $ null_ & isNull
438−-- NULL IS NULL
439−isNull
440− :: Expression outer grp commons schemas params from ('Null ty)
441− -- ^ possibly @NULL@
442− -> Condition outer grp commons schemas params from
443−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
444−
445−-- | >>> printSQL $ null_ & isNotNull
446−-- NULL IS NOT NULL
447−isNotNull
448− :: Expression outer grp commons schemas params from ('Null ty)
449− -- ^ possibly @NULL@
450− -> Condition outer grp commons schemas params from
451−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
452−
453−-- | analagous to `maybe` using @IS NULL@
454−--
455−-- >>> printSQL $ matchNull true not_ null_
456−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
457−matchNull
458− :: Expression outer grp commons schemas params from (nullty)
459− -- ^ what to convert @NULL@ to
460− -> ( Expression outer grp commons schemas params from ('NotNull ty)
461− -> Expression outer grp commons schemas params from (nullty) )
462− -- ^ function to perform when @NULL@ is absent
463− -> Expression outer grp commons schemas params from ('Null ty)
464− -> Expression outer grp commons schemas params from (nullty)
465−matchNull y f x = ifThenElse (isNull x) y
466− (f (UnsafeExpression (renderSQL x)))
467−
468−{-| right inverse to `fromNull`, if its arguments are equal then
469−`nullIf` gives @NULL@.
470−
471−>>> :set -XTypeApplications -XDataKinds
472−>>> let expr = nullIf false (param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
473−>>> printSQL expr
474−NULL IF (FALSE, ($1 :: bool))
475−-}
476−nullIf
477− :: Expression outer grp commons schemas params from ('NotNull ty)
478− -- ^ @NULL@ is absent
479− -> Expression outer grp commons schemas params from ('NotNull ty)
480− -- ^ @NULL@ is absent
481− -> Expression outer grp commons schemas params from ('Null ty)
482−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
483− (renderSQL x <> ", " <> renderSQL y)
484−
485−-- | >>> printSQL $ array [null_, false, true]
486−-- ARRAY[NULL, FALSE, TRUE]
487−array
488− :: [Expression outer grp commons schemas params from ty]
489− -- ^ array elements
490− -> Expression outer grp commons schemas params from (nullity ('PGvararray ty))
491−array xs = UnsafeExpression $
492− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
493−
494−-- | >>> printSQL $ cardinality (array [null_, false, true])
495−-- cardinality(ARRAY[NULL, FALSE, TRUE])
496−cardinality
497− :: Expression outer grp commons schemas params from (nullity ('PGvararray ty))
498− -> Expression outer grp commons schemas params from (nullity 'PGint8)
499−cardinality = unsafeFunction "cardinality"
500−
501−-- | >>> printSQL $ array [null_, false, true] & index 2
502−-- (ARRAY[NULL, FALSE, TRUE])[2]
503−index
504− :: Word64 -- ^ index
505− -> Expression outer grp commons schemas params from (nullity ('PGvararray ty)) -- ^ array
506− -> Expression outer grp commons schemas params from (NullifyType ty)
507−index n expr = UnsafeExpression $
508− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
509−
510311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
511− (Expression outer grp commons schemas params from (nullity ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
512313 label = UnsafeExpression $ renderSQL (PGlabel @label)
513314
514−-- | A row constructor is an expression that builds a row value
515−-- (also called a composite value) using values for its member fields.
516−--
517−-- >>> :{
518−-- type Complex = 'PGcomposite
519−-- '[ "real" ::: 'NotNull 'PGfloat8
520−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
521−-- :}
522−--
523−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
524−-- >>> printSQL i
525−-- ROW(0, 1)
526−row
527− :: SListI row
528− => NP (Aliased (Expression outer grp commons schemas params from)) row
529− -- ^ zero or more expressions for the row field values
530− -> Expression outer grp commons schemas params from (nullity ('PGcomposite row))
531−row exprs = UnsafeExpression $ "ROW" <> parenthesized
532− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
533−
534−-- | >>> :{
535−-- type Complex = 'PGcomposite
536−-- '[ "real" ::: 'NotNull 'PGfloat8
537−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
538−-- type Schema = '["complex" ::: 'Typedef Complex]
539−-- :}
540−--
541−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
542−-- >>> printSQL $ i & field #complex #imaginary
543−-- (ROW(0, 1)::"complex")."imaginary"
544−field
545− :: ( Has sch schemas schema
546− , Has tydef schema ('Typedef ('PGcomposite row))
547− , Has field row ty)
548− => QualifiedAlias sch tydef -- ^ row type
549− -> Alias field -- ^ field name
550− -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
551− -> Expression outer grp commons schemas params from ty
552−field td fld expr = UnsafeExpression $
553− parenthesized (renderSQL expr <> "::" <> renderSQL td)
554− <> "." <> renderSQL fld
555−
556−instance Semigroup
557− (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
558− (<>) = unsafeBinaryOp "||"
559−
560−instance Monoid
561− (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
562− mempty = array []
563− mappend = (<>)
564−
565−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
566−-- >>> printSQL expr
567−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
568−greatest
569− :: Expression outer grp commons schemas params from (nullty)
570− -- ^ needs at least 1 argument
571− -> [Expression outer grp commons schemas params from (nullty)]
572− -- ^ or more
573− -> Expression outer grp commons schemas params from (nullty)
574−greatest x xs = UnsafeExpression $ "GREATEST("
575− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
576−
577−-- | >>> printSQL $ least currentTimestamp [null_]
578−-- LEAST(CURRENT_TIMESTAMP, NULL)
579−least
580− :: Expression outer grp commons schemas params from (nullty)
581− -- ^ needs at least 1 argument
582− -> [Expression outer grp commons schemas params from (nullty)]
583− -- ^ or more
584− -> Expression outer grp commons schemas params from (nullty)
585−least x xs = UnsafeExpression $ "LEAST("
586− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
587−
588315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
589316-- (TRUE OR FALSE)
590−unsafeBinaryOp
591− :: ByteString
592− -- ^ operator
593− -> Expression outer grp commons schemas params from (ty0)
594− -> Expression outer grp commons schemas params from (ty1)
595− -> Expression outer grp commons schemas params from (ty2)
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
596318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
597319 renderSQL x <+> op <+> renderSQL y
598320
599−-- | >>> 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
600329-- (NOT TRUE)
601−unsafeUnaryOp
602− :: ByteString
603− -- ^ operator
604− -> Expression outer grp commons schemas params from (ty0)
605− -> Expression outer grp commons schemas params from (ty1)
606−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
607− 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
608351
609352-- | >>> printSQL $ unsafeFunction "f" true
610353-- f(TRUE)
611−unsafeFunction
612− :: ByteString
613− -- ^ function
614− -> Expression outer grp commons schemas params from (xty)
615− -> Expression outer grp commons schemas params from (yty)
354+unsafeFunction :: ByteString -> x --> y
616355unsafeFunction fun x = UnsafeExpression $
617356 fun <> parenthesized (renderSQL x)
618357
619−-- | Helper for defining variadic functions.
620−unsafeVariadicFunction
621− :: SListI elems
622− => ByteString
623− -- ^ function
624− -> NP (Expression outer grp commons schemas params from) elems
625− -> Expression outer grp commons schemas params from ret
626−unsafeVariadicFunction fun x = UnsafeExpression $
627− 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
628377
629378instance ty `In` PGNum
630− => Num (Expression outer grp commons schemas params from (nullity ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
631380 (+) = unsafeBinaryOp "+"
632381 (-) = unsafeBinaryOp "-"
633382 (*) = unsafeBinaryOp "*"
@@ -639,7 +388,7 @@ instance ty `In` PGNum
639388 . show
640389
641390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
642− (Expression outer grp commons schemas params from (nullity ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
643392 (/) = unsafeBinaryOp "/"
644393 fromRational
645394 = UnsafeExpression
@@ -649,7 +398,7 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
649398 . fromRat @Double
650399
651400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
652− (Expression outer grp commons schemas params from (nullity ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
653402 pi = UnsafeExpression "pi()"
654403 exp = unsafeFunction "exp"
655404 log = unsafeFunction "ln"
@@ -670,1748 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
670419 acosh x = log (x + sqrt (x*x - 1))
671420 atanh x = log ((1 + x) / (1 - x)) / 2
672421
673−-- | >>> :{
674−-- let
675−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
676−-- expression = atan2_ pi 2
677−-- in printSQL expression
678−-- :}
679−-- atan2(pi(), 2)
680−atan2_
681− :: float `In` PGFloating
682− => Expression outer grp commons schemas params from (nullity float)
683− -- ^ numerator
684− -> Expression outer grp commons schemas params from (nullity float)
685− -- ^ denominator
686− -> Expression outer grp commons schemas params from (nullity float)
687−atan2_ y x = UnsafeExpression $
688− "atan2(" <> renderSQL y <> ", " <> renderSQL x <> ")"
689−
690−-- When a `cast` is applied to an `Expression` of a known type, it
691−-- represents a run-time type conversion. The cast will succeed only if a
692−-- suitable type conversion operation has been defined.
693−--
694−-- | >>> printSQL $ true & cast int4
695−-- (TRUE :: int4)
696−cast
697− :: TypeExpression schemas ty1
698− -- ^ type to cast as
699− -> Expression outer grp commons schemas params from ty0
700− -- ^ value to convert
701− -> Expression outer grp commons schemas params from ty1
702−cast ty x = UnsafeExpression $ parenthesized $
703− renderSQL x <+> "::" <+> renderSQL ty
704−
705−-- | integer division, truncates the result
706−--
707−-- >>> :{
708−-- let
709−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
710−-- expression = 5 `quot_` 2
711−-- in printSQL expression
712−-- :}
713−-- (5 / 2)
714−quot_
715− :: int `In` PGIntegral
716− => Expression outer grp commons schemas params from (nullity int)
717− -- ^ numerator
718− -> Expression outer grp commons schemas params from (nullity int)
719− -- ^ denominator
720− -> Expression outer grp commons schemas params from (nullity int)
721−quot_ = unsafeBinaryOp "/"
722−
723−-- | remainder upon integer division
724−--
725−-- >>> :{
726−-- let
727−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
728−-- expression = 5 `rem_` 2
729−-- in printSQL expression
730−-- :}
731−-- (5 % 2)
732−rem_
733− :: int `In` PGIntegral
734− => Expression outer grp commons schemas params from (nullity int)
735− -- ^ numerator
736− -> Expression outer grp commons schemas params from (nullity int)
737− -- ^ denominator
738− -> Expression outer grp commons schemas params from (nullity int)
739−rem_ = unsafeBinaryOp "%"
740−
741−-- | >>> :{
742−-- let
743−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
744−-- expression = trunc pi
745−-- in printSQL expression
746−-- :}
747−-- trunc(pi())
748−trunc
749− :: frac `In` PGFloating
750− => Expression outer grp commons schemas params from (nullity frac)
751− -- ^ fractional number
752− -> Expression outer grp commons schemas params from (nullity frac)
753−trunc = unsafeFunction "trunc"
754−
755−-- | >>> :{
756−-- let
757−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
758−-- expression = round_ pi
759−-- in printSQL expression
760−-- :}
761−-- round(pi())
762−round_
763− :: frac `In` PGFloating
764− => Expression outer grp commons schemas params from (nullity frac)
765− -- ^ fractional number
766− -> Expression outer grp commons schemas params from (nullity frac)
767−round_ = unsafeFunction "round"
768−
769−-- | >>> :{
770−-- let
771−-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
772−-- expression = ceiling_ pi
773−-- in printSQL expression
774−-- :}
775−-- ceiling(pi())
776−ceiling_
777− :: frac `In` PGFloating
778− => Expression outer grp commons schemas params from (nullity frac)
779− -- ^ fractional number
780− -> Expression outer grp commons schemas params from (nullity frac)
781−ceiling_ = unsafeFunction "ceiling"
782−
783−-- | A `Condition` is an `Expression`, which can evaluate
784−-- to `true`, `false` or `null_`. This is because SQL uses
785−-- a three valued logic.
786−type Condition outer grp commons schemas params from =
787− Expression outer grp commons schemas params from ('Null 'PGbool)
788−
789−-- | >>> printSQL true
790−-- TRUE
791−true :: Expression outer grp commons schemas params from (nullity 'PGbool)
792−true = UnsafeExpression "TRUE"
793−
794−-- | >>> printSQL false
795−-- FALSE
796−false :: Expression outer grp commons schemas params from (nullity 'PGbool)
797−false = UnsafeExpression "FALSE"
798−
799−-- | >>> printSQL $ not_ true
800−-- (NOT TRUE)
801−not_
802− :: Expression outer grp commons schemas params from (nullity 'PGbool)
803− -> Expression outer grp commons schemas params from (nullity 'PGbool)
804−not_ = unsafeUnaryOp "NOT"
805−
806−-- | >>> printSQL $ true .&& false
807−-- (TRUE AND FALSE)
808−(.&&)
809− :: Expression outer grp commons schemas params from (nullity 'PGbool)
810− -> Expression outer grp commons schemas params from (nullity 'PGbool)
811− -> Expression outer grp commons schemas params from (nullity 'PGbool)
812−infixr 3 .&&
813−(.&&) = unsafeBinaryOp "AND"
814−
815−-- | >>> printSQL $ true .|| false
816−-- (TRUE OR FALSE)
817−(.||)
818− :: Expression outer grp commons schemas params from (nullity 'PGbool)
819− -> Expression outer grp commons schemas params from (nullity 'PGbool)
820− -> Expression outer grp commons schemas params from (nullity 'PGbool)
821−infixr 2 .||
822−(.||) = unsafeBinaryOp "OR"
823−
824−-- | >>> :{
825−-- let
826−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
827−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
828−-- in printSQL expression
829−-- :}
830−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
831−caseWhenThenElse
832− :: [ ( Condition outer grp commons schemas params from
833− , Expression outer grp commons schemas params from ty
834− ) ]
835− -- ^ whens and thens
836− -> Expression outer grp commons schemas params from ty
837− -- ^ else
838− -> Expression outer grp commons schemas params from ty
839−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
840− [ "CASE"
841− , mconcat
842− [ mconcat
843− [ " WHEN ", renderSQL when_
844− , " THEN ", renderSQL then_
845− ]
846− | (when_,then_) <- whenThens
847− ]
848− , " ELSE ", renderSQL else_
849− , " END"
850− ]
851−
852−-- | >>> :{
853−-- let
854−-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
855−-- expression = ifThenElse true 1 0
856−-- in printSQL expression
857−-- :}
858−-- CASE WHEN TRUE THEN 1 ELSE 0 END
859−ifThenElse
860− :: Condition outer grp commons schemas params from
861− -> Expression outer grp commons schemas params from ty -- ^ then
862− -> Expression outer grp commons schemas params from ty -- ^ else
863− -> Expression outer grp commons schemas params from ty
864−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
865−
866−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
867−-- will produce @NULL@s if one of their arguments is @NULL@.
868−--
869−-- >>> printSQL $ true .== null_
870−-- (TRUE = NULL)
871−(.==)
872− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
873− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
874− -> Condition outer grp commons schemas params from
875−(.==) = unsafeBinaryOp "="
876−infix 4 .==
877−
878−-- | >>> printSQL $ true ./= null_
879−-- (TRUE <> NULL)
880−(./=)
881− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
882− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
883− -> Condition outer grp commons schemas params from
884−(./=) = unsafeBinaryOp "<>"
885−infix 4 ./=
886−
887−-- | >>> printSQL $ true .>= null_
888−-- (TRUE >= NULL)
889−(.>=)
890− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
891− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
892− -> Condition outer grp commons schemas params from
893−(.>=) = unsafeBinaryOp ">="
894−infix 4 .>=
895−
896−-- | >>> printSQL $ true .< null_
897−-- (TRUE < NULL)
898−(.<)
899− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
900− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
901− -> Condition outer grp commons schemas params from
902−(.<) = unsafeBinaryOp "<"
903−infix 4 .<
904−
905−-- | >>> printSQL $ true .<= null_
906−-- (TRUE <= NULL)
907−(.<=)
908− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
909− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
910− -> Condition outer grp commons schemas params from
911−(.<=) = unsafeBinaryOp "<="
912−infix 4 .<=
913−
914−-- | >>> printSQL $ true .> null_
915−-- (TRUE > NULL)
916−(.>)
917− :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
918− -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
919− -> Condition outer grp commons schemas params from
920−(.>) = unsafeBinaryOp ">"
921−infix 4 .>
922−
923−-- | >>> printSQL currentDate
924−-- CURRENT_DATE
925−currentDate
926− :: Expression outer grp commons schemas params from (nullity 'PGdate)
927−currentDate = UnsafeExpression "CURRENT_DATE"
928−
929−-- | >>> printSQL currentTime
930−-- CURRENT_TIME
931−currentTime
932− :: Expression outer grp commons schemas params from (nullity 'PGtimetz)
933−currentTime = UnsafeExpression "CURRENT_TIME"
934−
935−-- | >>> printSQL currentTimestamp
936−-- CURRENT_TIMESTAMP
937−currentTimestamp
938− :: Expression outer grp commons schemas params from (nullity 'PGtimestamptz)
939−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
940−
941−-- | >>> printSQL localTime
942−-- LOCALTIME
943−localTime
944− :: Expression outer grp commons schemas params from (nullity 'PGtime)
945−localTime = UnsafeExpression "LOCALTIME"
946−
947−-- | >>> printSQL localTimestamp
948−-- LOCALTIMESTAMP
949−localTimestamp
950− :: Expression outer grp commons schemas params from (nullity 'PGtimestamp)
951−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
952−
953−{-----------------------------------------
954−text
955−-----------------------------------------}
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)
956438
957439instance IsString
958− (Expression outer grp commons schemas params from (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
959441 fromString str = UnsafeExpression $
960442 "E\'" <> fromString (escape =<< str) <> "\'"
961− where
962− escape = \case
963− '\NUL' -> "\\0"
964− '\'' -> "''"
965− '"' -> "\\\""
966− '\b' -> "\\b"
967− '\n' -> "\\n"
968− '\r' -> "\\r"
969− '\t' -> "\\t"
970− '\\' -> "\\\\"
971− 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) <> "\'"
972451
973452instance Semigroup
974− (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
975463 (<>) = unsafeBinaryOp "||"
976464
977465instance Monoid
978− (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
979471 mempty = fromString ""
980472 mappend = (<>)
981−
982−-- | >>> printSQL $ lower "ARRRGGG"
983−-- lower(E'ARRRGGG')
984−lower
985− :: Expression outer grp commons schemas params from (nullity 'PGtext)
986− -- ^ string to lower case
987− -> Expression outer grp commons schemas params from (nullity 'PGtext)
988−lower = unsafeFunction "lower"
989−
990−-- | >>> printSQL $ upper "eeee"
991−-- upper(E'eeee')
992−upper
993− :: Expression outer grp commons schemas params from (nullity 'PGtext)
994− -- ^ string to upper case
995− -> Expression outer grp commons schemas params from (nullity 'PGtext)
996−upper = unsafeFunction "upper"
997−
998−-- | >>> printSQL $ charLength "four"
999−-- char_length(E'four')
1000−charLength
1001− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1002− -- ^ string to measure
1003− -> Expression outer grp commons schemas params from (nullity 'PGint4)
1004−charLength = unsafeFunction "char_length"
1005−
1006−-- | The `like` expression returns true if the @string@ matches
1007−-- the supplied @pattern@. If @pattern@ does not contain percent signs
1008−-- or underscores, then the pattern only represents the string itself;
1009−-- in that case `like` acts like the equals operator. An underscore (_)
1010−-- in pattern stands for (matches) any single character; a percent sign (%)
1011−-- matches any sequence of zero or more characters.
1012−--
1013−-- >>> printSQL $ "abc" `like` "a%"
1014−-- (E'abc' LIKE E'a%')
1015−like
1016− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1017− -- ^ string
1018− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1019− -- ^ pattern
1020− -> Expression outer grp commons schemas params from (nullity 'PGbool)
1021−like = unsafeBinaryOp "LIKE"
1022−
1023−-- | The key word ILIKE can be used instead of LIKE to make the
1024−-- match case-insensitive according to the active locale.
1025−--
1026−-- >>> printSQL $ "abc" `ilike` "a%"
1027−-- (E'abc' ILIKE E'a%')
1028−ilike
1029− :: Expression outer grp commons schemas params from (nullity 'PGtext)
1030− -- ^ string
1031− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1032− -- ^ pattern
1033− -> Expression outer grp commons schemas params from (nullity 'PGbool)
1034−ilike = unsafeBinaryOp "ILIKE"
1035−
1036−{-----------------------------------------
1037− -- json and jsonb support
1038−
1039−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1040−comments lifted directly from this page.
1041−
1042−Table 9.44: json and jsonb operators
1043−-----------------------------------------}
1044−
1045−-- | Get JSON value (object field or array element) at a key.
1046−(.->)
1047− :: (json `In` PGJsonType, key `In` PGJsonKey)
1048− => Expression outer grp commons schemas params from (nullity json)
1049− -> Expression outer grp commons schemas params from (nullity key)
1050− -> Expression outer grp commons schemas params from ('Null json)
1051−infixl 8 .->
1052−(.->) = unsafeBinaryOp "->"
1053−
1054−-- | Get JSON value (object field or array element) at a key, as text.
1055−(.->>)
1056− :: (json `In` PGJsonType, key `In` PGJsonKey)
1057− => Expression outer grp commons schemas params from (nullity json)
1058− -> Expression outer grp commons schemas params from (nullity key)
1059− -> Expression outer grp commons schemas params from ('Null 'PGtext)
1060−infixl 8 .->>
1061−(.->>) = unsafeBinaryOp "->>"
1062−
1063−-- | Get JSON value at a specified path.
1064−(.#>)
1065− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1066− => Expression outer grp commons schemas params from (nullity json)
1067− -> Expression outer grp commons schemas params from (nullity path)
1068− -> Expression outer grp commons schemas params from ('Null json)
1069−infixl 8 .#>
1070−(.#>) = unsafeBinaryOp "#>"
1071−
1072−-- | Get JSON value at a specified path as text.
1073−(.#>>)
1074− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1075− => Expression outer grp commons schemas params from (nullity json)
1076− -> Expression outer grp commons schemas params from (nullity path)
1077− -> Expression outer grp commons schemas params from ('Null 'PGtext)
1078−infixl 8 .#>>
1079−(.#>>) = unsafeBinaryOp "#>>"
1080−
1081−-- Additional jsonb operators
1082−
1083−-- | Does the left JSON value contain the right JSON path/value entries at the
1084−-- top level?
1085−(.@>)
1086− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1087− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1088− -> Condition outer grp commons schemas params from
1089−infixl 9 .@>
1090−(.@>) = unsafeBinaryOp "@>"
1091−
1092−-- | Are the left JSON path/value entries contained at the top level within the
1093−-- right JSON value?
1094−(.<@)
1095− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1096− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1097− -> Condition outer grp commons schemas params from
1098−infixl 9 .<@
1099−(.<@) = unsafeBinaryOp "<@"
1100−
1101−-- | Does the string exist as a top-level key within the JSON value?
1102−(.?)
1103− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1104− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1105− -> Condition outer grp commons schemas params from
1106−infixl 9 .?
1107−(.?) = unsafeBinaryOp "?"
1108−
1109−-- | Do any of these array strings exist as top-level keys?
1110−(.?|)
1111− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1112− -> Expression outer grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1113− -> Condition outer grp commons schemas params from
1114−infixl 9 .?|
1115−(.?|) = unsafeBinaryOp "?|"
1116−
1117−-- | Do all of these array strings exist as top-level keys?
1118−(.?&)
1119− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1120− -> Expression outer grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1121− -> Condition outer grp commons schemas params from
1122−infixl 9 .?&
1123−(.?&) = unsafeBinaryOp "?&"
1124−
1125−-- | Concatenate two jsonb values into a new jsonb value.
1126−instance Semigroup
1127− (Expression outer grp commons schemas params from (nullity 'PGjsonb)) where
1128− (<>) = unsafeBinaryOp "||"
1129−
1130−-- | Delete a key or keys from a JSON object, or remove an array element.
1131−--
1132−-- If the right operand is..
1133−--
1134−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1135−-- are matched based on their key value.
1136−--
1137−-- @ text[] @: Delete multiple key/value pairs or string elements
1138−-- from left operand. Key/value pairs are matched based on their key value.
1139−--
1140−-- @ integer @: Delete the array element with specified index (Negative integers
1141−-- count from the end). Throws an error if top level container is not an array.
1142−(.-.)
1143− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1144− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1145− -> Expression outer grp commons schemas params from (nullity key)
1146− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1147−infixl 6 .-.
1148−(.-.) = unsafeBinaryOp "-"
1149−
1150−-- | Delete the field or element with specified path (for JSON arrays, negative
1151−-- integers count from the end)
1152−(#-.)
1153− :: PGTextArray "(#-.)" arrayty
1154− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1155− -> Expression outer grp commons schemas params from (nullity arrayty)
1156− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1157−infixl 6 #-.
1158−(#-.) = unsafeBinaryOp "#-"
1159−
1160−{-----------------------------------------
1161−Table 9.45: JSON creation functions
1162−-----------------------------------------}
1163−
1164−-- | Literal binary JSON
1165−jsonbLit
1166− :: JSON.ToJSON x
1167− => x -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1168−jsonbLit = cast jsonb . UnsafeExpression
1169− . singleQuotedUtf8 . toStrict . JSON.encode
1170−
1171−-- | Literal JSON
1172−jsonLit
1173− :: JSON.ToJSON x
1174− => x -> Expression outer grp commons schemas params from (nullity 'PGjson)
1175−jsonLit = cast json . UnsafeExpression
1176− . singleQuotedUtf8 . toStrict . JSON.encode
1177−
1178−-- | Returns the value as json. Arrays and composites are converted
1179−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1180−-- type to json, the cast function will be used to perform the conversion;
1181−-- otherwise, a scalar value is produced. For any scalar type other than a
1182−-- number, a Boolean, or a null value, the text representation will be used, in
1183−-- such a fashion that it is a valid json value.
1184−toJson
1185− :: Expression outer grp commons schemas params from (nullity ty)
1186− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1187−toJson = unsafeFunction "to_json"
1188−
1189−-- | Returns the value as jsonb. Arrays and composites are converted
1190−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1191−-- type to json, the cast function will be used to perform the conversion;
1192−-- otherwise, a scalar value is produced. For any scalar type other than a
1193−-- number, a Boolean, or a null value, the text representation will be used, in
1194−-- such a fashion that it is a valid jsonb value.
1195−toJsonb
1196− :: Expression outer grp commons schemas params from (nullity ty)
1197− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1198−toJsonb = unsafeFunction "to_jsonb"
1199−
1200−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1201−-- becomes a JSON array of arrays.
1202−arrayToJson
1203− :: PGArray "arrayToJson" arr
1204− => Expression outer grp commons schemas params from (nullity arr)
1205− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1206−arrayToJson = unsafeFunction "array_to_json"
1207−
1208−-- | Returns the row as a JSON object.
1209−rowToJson
1210− :: Expression outer grp commons schemas params from (nullity ('PGcomposite ty))
1211− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1212−rowToJson = unsafeFunction "row_to_json"
1213−
1214−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1215−-- argument list.
1216−jsonBuildArray
1217− :: SListI elems
1218− => NP (Expression outer grp commons schemas params from) elems
1219− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1220−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1221−
1222−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1223−-- variadic argument list.
1224−jsonbBuildArray
1225− :: SListI elems
1226− => NP (Expression outer grp commons schemas params from) elems
1227− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1228−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1229−
1230−unsafeRowFunction
1231− :: SOP.SListI elems
1232− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1233− -> [ByteString]
1234−unsafeRowFunction =
1235− (`appEndo` []) . hcfoldMap (Proxy :: SOP.Proxy SOP.Top)
1236− (\(col `As` name) -> Endo $ \xs ->
1237− renderAliasString name : renderSQL col : xs)
1238− where
1239− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1240− renderAliasString = singleQuotedText . fromString . symbolVal
1241−
1242−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1243−-- argument list. The elements of the argument list must alternate between text
1244−-- and values.
1245−jsonBuildObject
1246− :: SOP.SListI elems
1247− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1248− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1249−jsonBuildObject
1250− = unsafeFunction "json_build_object"
1251− . UnsafeExpression
1252− . commaSeparated
1253− . unsafeRowFunction
1254−
1255−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1256−-- variadic argument list. The elements of the argument list must alternate
1257−-- between text and values.
1258−jsonbBuildObject
1259− :: SOP.SListI elems
1260− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1261− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1262−jsonbBuildObject
1263− = unsafeFunction "jsonb_build_object"
1264− . UnsafeExpression
1265− . commaSeparated
1266− . unsafeRowFunction
1267−
1268−-- | Builds a JSON object out of a text array. The array must have either
1269−-- exactly one dimension with an even number of members, in which case they are
1270−-- taken as alternating key/value pairs, or two dimensions such that each inner
1271−-- array has exactly two elements, which are taken as a key/value pair.
1272−jsonObject
1273− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1274− => Expression outer grp commons schemas params from (nullity arr)
1275− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1276−jsonObject = unsafeFunction "json_object"
1277−
1278−-- | Builds a binary JSON object out of a text array. The array must have either
1279−-- exactly one dimension with an even number of members, in which case they are
1280−-- taken as alternating key/value pairs, or two dimensions such that each inner
1281−-- array has exactly two elements, which are taken as a key/value pair.
1282−jsonbObject
1283− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1284− => Expression outer grp commons schemas params from (nullity arr)
1285− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1286−jsonbObject = unsafeFunction "jsonb_object"
1287−
1288−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1289−-- keys and one for values, that are zipped pairwise to create a JSON object.
1290−jsonZipObject
1291− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1292− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1293− => Expression outer grp commons schemas params from (nullity keysArray)
1294− -> Expression outer grp commons schemas params from (nullity valuesArray)
1295− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1296−jsonZipObject ks vs =
1297− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1298−
1299−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1300−-- keys and one for values, that are zipped pairwise to create a binary JSON
1301−-- object.
1302−jsonbZipObject
1303− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1304− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1305− => Expression outer grp commons schemas params from (nullity keysArray)
1306− -> Expression outer grp commons schemas params from (nullity valuesArray)
1307− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1308−jsonbZipObject ks vs =
1309− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1310−
1311−{-----------------------------------------
1312−Table 9.46: JSON processing functions
1313−-----------------------------------------}
1314−
1315−-- | Returns the number of elements in the outermost JSON array.
1316−jsonArrayLength
1317− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1318− -> Expression outer grp commons schemas params from (nullity 'PGint4)
1319−jsonArrayLength = unsafeFunction "json_array_length"
1320−
1321−-- | Returns the number of elements in the outermost binary JSON array.
1322−jsonbArrayLength
1323− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1324− -> Expression outer grp commons schemas params from (nullity 'PGint4)
1325−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1326−
1327−-- | Returns JSON value pointed to by the given path (equivalent to #>
1328−-- operator).
1329−jsonExtractPath
1330− :: SListI elems
1331− => Expression outer grp commons schemas params from (nullity 'PGjson)
1332− -> NP (Expression outer grp commons schemas params from) elems
1333− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1334−jsonExtractPath x xs =
1335− unsafeVariadicFunction "json_extract_path" (x :* xs)
1336−
1337−-- | Returns JSON value pointed to by the given path (equivalent to #>
1338−-- operator).
1339−jsonbExtractPath
1340− :: SListI elems
1341− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1342− -> NP (Expression outer grp commons schemas params from) elems
1343− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1344−jsonbExtractPath x xs =
1345− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1346−
1347−-- | Returns JSON value pointed to by the given path (equivalent to #>
1348−-- operator), as text.
1349−jsonExtractPathAsText
1350− :: SListI elems
1351− => Expression outer grp commons schemas params from (nullity 'PGjson)
1352− -> NP (Expression outer grp commons schemas params from) elems
1353− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1354−jsonExtractPathAsText x xs =
1355− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1356−
1357−-- | Returns JSON value pointed to by the given path (equivalent to #>
1358−-- operator), as text.
1359−jsonbExtractPathAsText
1360− :: SListI elems
1361− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1362− -> NP (Expression outer grp commons schemas params from) elems
1363− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1364−jsonbExtractPathAsText x xs =
1365− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1366−
1367−-- | Returns the type of the outermost JSON value as a text string. Possible
1368−-- types are object, array, string, number, boolean, and null.
1369−jsonTypeof
1370− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1371− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1372−jsonTypeof = unsafeFunction "json_typeof"
1373−
1374−-- | Returns the type of the outermost binary JSON value as a text string.
1375−-- Possible types are object, array, string, number, boolean, and null.
1376−jsonbTypeof
1377− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1378− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1379−jsonbTypeof = unsafeFunction "jsonb_typeof"
1380−
1381−-- | Returns its argument with all object fields that have null values omitted.
1382−-- Other null values are untouched.
1383−jsonStripNulls
1384− :: Expression outer grp commons schemas params from (nullity 'PGjson)
1385− -> Expression outer grp commons schemas params from (nullity 'PGjson)
1386−jsonStripNulls = unsafeFunction "json_strip_nulls"
1387−
1388−-- | Returns its argument with all object fields that have null values omitted.
1389−-- Other null values are untouched.
1390−jsonbStripNulls
1391− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1392− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1393−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1394−
1395−-- | @ jsonbSet target path new_value create_missing @
1396−--
1397−-- Returns target with the section designated by path replaced by new_value,
1398−-- or with new_value added if create_missing is true ( default is true) and the
1399−-- item designated by path does not exist. As with the path orientated
1400−-- operators, negative integers that appear in path count from the end of JSON
1401−-- arrays.
1402−jsonbSet
1403− :: PGTextArray "jsonbSet" 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−jsonbSet tgt path val createMissing = case createMissing of
1410− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1411− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1412−
1413−-- | @ jsonbInsert target path new_value insert_after @
1414−--
1415−-- Returns target with new_value inserted. If target section designated by
1416−-- path is in a JSONB array, new_value will be inserted before target or after
1417−-- if insert_after is true (default is false). If target section designated by
1418−-- path is in JSONB object, new_value will be inserted only if target does not
1419−-- exist. As with the path orientated operators, negative integers that appear
1420−-- in path count from the end of JSON arrays.
1421−jsonbInsert
1422− :: PGTextArray "jsonbInsert" arr
1423− => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1424− -> Expression outer grp commons schemas params from (nullity arr)
1425− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1426− -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1427− -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1428−jsonbInsert tgt path val insertAfter = case insertAfter of
1429− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1430− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1431−
1432−-- | Returns its argument as indented JSON text.
1433−jsonbPretty
1434− :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1435− -> Expression outer grp commons schemas params from (nullity 'PGtext)
1436−jsonbPretty = unsafeFunction "jsonb_pretty"
1437−
1438−{-----------------------------------------
1439−aggregation
1440−-----------------------------------------}
1441−
1442−{- |
1443−`Aggregate` functions compute a single result from a set of input values.
1444−`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1445−as `WindowFunction`s.
1446−-}
1447−class Aggregate expr1 expr2 aggr
1448− | aggr -> expr1, aggr -> expr2 where
1449−
1450− -- | A special aggregation that does not require an input
1451− --
1452− -- >>> :{
1453− -- let
1454− -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1455− -- expression = countStar
1456− -- in printSQL expression
1457− -- :}
1458− -- count(*)
1459− countStar :: aggr ('NotNull 'PGint8)
1460−
1461− -- | >>> :{
1462− -- let
1463− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1464− -- expression = count (All #col)
1465− -- in printSQL expression
1466− -- :}
1467− -- count(ALL "col")
1468− count
1469− :: expr1 ty
1470− -- ^ what to count
1471− -> aggr ('NotNull 'PGint8)
1472−
1473− -- | >>> :{
1474− -- let
1475− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('NotNull 'PGnumeric)
1476− -- expression = sum_ (Distinct #col)
1477− -- in printSQL expression
1478− -- :}
1479− -- sum(DISTINCT "col")
1480− sum_
1481− :: ty `In` PGNum
1482− => expr1 (nullity ty)
1483− -> aggr ('NotNull ty)
1484−
1485− -- | input values, including nulls, concatenated into an array
1486− arrayAgg
1487− :: expr1 ty
1488− -> aggr ('Null ('PGvararray ty))
1489−
1490− -- | aggregates values as a JSON array
1491− jsonAgg
1492− :: expr1 ty
1493− -> aggr ('Null 'PGjson)
1494−
1495− -- | aggregates values as a JSON array
1496− jsonbAgg
1497− :: expr1 ty
1498− -> aggr ('Null 'PGjsonb)
1499−
1500− {- |
1501− the bitwise AND of all non-null input values, or null if none
1502− >>> :{
1503− let
1504− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] ('Null 'PGint4)
1505− expression = bitAnd (Distinct #col)
1506− in printSQL expression
1507− :}
1508− bit_and(DISTINCT "col")
1509− -}
1510− bitAnd
1511− :: int `In` PGIntegral
1512− => expr1 (nullity int)
1513− -- ^ what to aggregate
1514− -> aggr ('Null int)
1515−
1516− {- |
1517− the bitwise OR of all non-null input values, or null if none
1518−
1519− >>> :{
1520− let
1521− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] ('Null 'PGint4)
1522− expression = bitOr (All #col)
1523− in printSQL expression
1524− :}
1525− bit_or(ALL "col")
1526− -}
1527− bitOr
1528− :: int `In` PGIntegral
1529− => expr1 (nullity int)
1530− -- ^ what to aggregate
1531− -> aggr ('Null int)
1532−
1533− {- |
1534− true if all input values are true, otherwise false
1535−
1536− >>> :{
1537− let
1538− winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] ('Null 'PGbool)
1539− winFun = boolAnd #col
1540− in printSQL winFun
1541− :}
1542− bool_and("col")
1543− -}
1544− boolAnd
1545− :: expr1 (nullity 'PGbool)
1546− -- ^ what to aggregate
1547− -> aggr ('Null 'PGbool)
1548−
1549− {- |
1550− true if at least one input value is true, otherwise false
1551−
1552− >>> :{
1553− let
1554− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] ('Null 'PGbool)
1555− expression = boolOr (All #col)
1556− in printSQL expression
1557− :}
1558− bool_or(ALL "col")
1559− -}
1560− boolOr
1561− :: expr1(nullity 'PGbool)
1562− -- ^ what to aggregate
1563− -> aggr ('Null 'PGbool)
1564−
1565− {- |
1566− equivalent to `boolAnd`
1567−
1568− >>> :{
1569− let
1570− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] ('Null 'PGbool)
1571− expression = every (Distinct #col)
1572− in printSQL expression
1573− :}
1574− every(DISTINCT "col")
1575− -}
1576− every
1577− :: expr1 (nullity 'PGbool)
1578− -- ^ what to aggregate
1579− -> aggr ('Null 'PGbool)
1580−
1581− {- |maximum value of expression across all input values-}
1582− max_
1583− :: expr1 (nullity ty)
1584− -- ^ what to maximize
1585− -> aggr ('Null ty)
1586−
1587− -- | minimum value of expression across all input values
1588− min_
1589− :: expr1 (nullity ty)
1590− -- ^ what to minimize
1591− -> aggr ('Null ty)
1592−
1593− -- | the average (arithmetic mean) of all input values
1594− avg
1595− :: expr1 (nullity ty)
1596− -- ^ what to average
1597− -> aggr ('Null (PGAvg ty))
1598−
1599− {- | correlation coefficient
1600− >>> :{
1601− let
1602− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1603− expression = corr (All (#y :*: #x))
1604− in printSQL expression
1605− :}
1606− corr(ALL "y", "x")
1607− -}
1608− corr
1609− :: expr2 (nullity 'PGfloat8)
1610− -> aggr ('Null 'PGfloat8)
1611−
1612− {- | population covariance
1613− >>> :{
1614− let
1615− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1616− expression = covarPop (All (#y :*: #x))
1617− in printSQL expression
1618− :}
1619− covar_pop(ALL "y", "x")
1620− -}
1621− covarPop
1622− :: expr2 (nullity 'PGfloat8)
1623− -> aggr ('Null 'PGfloat8)
1624−
1625− {- | sample covariance
1626− >>> :{
1627− let
1628− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1629− winFun = covarSamp (#y :*: #x)
1630− in printSQL winFun
1631− :}
1632− covar_samp("y", "x")
1633− -}
1634− covarSamp
1635− :: expr2 (nullity 'PGfloat8)
1636− -> aggr ('Null 'PGfloat8)
1637−
1638− {- | average of the independent variable (sum(X)/N)
1639− >>> :{
1640− let
1641− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1642− expression = regrAvgX (All (#y :*: #x))
1643− in printSQL expression
1644− :}
1645− regr_avgx(ALL "y", "x")
1646− -}
1647− regrAvgX
1648− :: expr2 (nullity 'PGfloat8)
1649− -> aggr ('Null 'PGfloat8)
1650−
1651− {- | average of the dependent variable (sum(Y)/N)
1652− >>> :{
1653− let
1654− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1655− winFun = regrAvgY (#y :*: #x)
1656− in printSQL winFun
1657− :}
1658− regr_avgy("y", "x")
1659− -}
1660− regrAvgY
1661− :: expr2 (nullity 'PGfloat8)
1662− -> aggr ('Null 'PGfloat8)
1663−
1664− {- | number of input rows in which both expressions are nonnull
1665− >>> :{
1666− let
1667− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGint8)
1668− winFun = regrCount (#y :*: #x)
1669− in printSQL winFun
1670− :}
1671− regr_count("y", "x")
1672− -}
1673− regrCount
1674− :: expr2 (nullity 'PGfloat8)
1675− -> aggr ('Null 'PGint8)
1676−
1677− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1678− >>> :{
1679− let
1680− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1681− expression = regrIntercept (All (#y :*: #x))
1682− in printSQL expression
1683− :}
1684− regr_intercept(ALL "y", "x")
1685− -}
1686− regrIntercept
1687− :: expr2 (nullity 'PGfloat8)
1688− -> aggr ('Null 'PGfloat8)
1689−
1690− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1691− regrR2
1692− :: expr2 (nullity 'PGfloat8)
1693− -> aggr ('Null 'PGfloat8)
1694−
1695− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1696− -- determined by the (X, Y) pairs
1697− regrSlope
1698− :: expr2 (nullity 'PGfloat8)
1699− -> aggr ('Null 'PGfloat8)
1700−
1701− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1702− -- (“sum of squares” of the independent variable)
1703− regrSxx
1704− :: expr2 (nullity 'PGfloat8)
1705− -> aggr ('Null 'PGfloat8)
1706−
1707− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1708− -- (“sum of products” of independent times dependent variable)
1709− regrSxy
1710− :: expr2 (nullity 'PGfloat8)
1711− -> aggr ('Null 'PGfloat8)
1712−
1713− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1714− -- (“sum of squares” of the dependent variable)
1715− regrSyy
1716− :: expr2 (nullity 'PGfloat8)
1717− -> aggr ('Null 'PGfloat8)
1718−
1719− -- | historical alias for `stddevSamp`
1720− stddev
1721− :: expr1 (nullity ty)
1722− -> aggr ('Null (PGAvg ty))
1723−
1724− -- | population standard deviation of the input values
1725− stddevPop
1726− :: expr1 (nullity ty)
1727− -> aggr ('Null (PGAvg ty))
1728−
1729− -- | sample standard deviation of the input values
1730− stddevSamp
1731− :: expr1 (nullity ty)
1732− -> aggr ('Null (PGAvg ty))
1733−
1734− -- | historical alias for `varSamp`
1735− variance
1736− :: expr1 (nullity ty)
1737− -> aggr ('Null (PGAvg ty))
1738−
1739− -- | population variance of the input values
1740− -- (square of the population standard deviation)
1741− varPop
1742− :: expr1 (nullity ty)
1743− -> aggr ('Null (PGAvg ty))
1744−
1745− -- | sample variance of the input values
1746− -- (square of the sample standard deviation)
1747− varSamp
1748− :: expr1 (nullity ty)
1749− -> aggr ('Null (PGAvg ty))
1750−
1751−{- |
1752−`Distinction`s are used for the input of `Aggregate` `Expression`s.
1753−`All` invokes the aggregate once for each input row.
1754−`Distinct` invokes the aggregate once for each distinct value of the expression
1755−(or distinct set of values, for multiple expressions) found in the input
1756−-}
1757−data Distinction expr ty
1758− = All (expr ty)
1759− | Distinct (expr ty)
1760− deriving (GHC.Generic,Show,Eq,Ord)
1761−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1762−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1763− renderSQL = \case
1764− All x -> "ALL" <+> renderSQL x
1765− Distinct x -> "DISTINCT" <+> renderSQL x
1766−instance RenderSQL
1767− (Distinction
1768− ( Expression outer grp commons schemas params from
1769− :*:
1770− Expression outer grp commons schemas params from) xty ) where
1771− renderSQL = \case
1772− All (x :*: x') ->
1773− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1774− Distinct (x :*: x') ->
1775− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1776−
1777−instance Aggregate
1778− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1779− (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1780− (Expression outer ('Grouped bys) commons schemas params from) where
1781− countStar = UnsafeExpression "count(*)"
1782− count = unsafeAggregate1 "count"
1783− sum_ = unsafeAggregate1 "sum"
1784− arrayAgg = unsafeAggregate1 "array_agg"
1785− jsonAgg = unsafeAggregate1 "json_agg"
1786− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1787− bitAnd = unsafeAggregate1 "bit_and"
1788− bitOr = unsafeAggregate1 "bit_or"
1789− boolAnd = unsafeAggregate1 "bool_and"
1790− boolOr = unsafeAggregate1 "bool_or"
1791− every = unsafeAggregate1 "every"
1792− max_ = unsafeAggregate1 "max"
1793− min_ = unsafeAggregate1 "min"
1794− avg = unsafeAggregate1 "avg"
1795− corr = unsafeAggregate2 "corr"
1796− covarPop = unsafeAggregate2 "covar_pop"
1797− covarSamp = unsafeAggregate2 "covar_samp"
1798− regrAvgX = unsafeAggregate2 "regr_avgx"
1799− regrAvgY = unsafeAggregate2 "regr_avgy"
1800− regrCount = unsafeAggregate2 "regr_count"
1801− regrIntercept = unsafeAggregate2 "regr_intercept"
1802− regrR2 = unsafeAggregate2 "regr_r2"
1803− regrSlope = unsafeAggregate2 "regr_slope"
1804− regrSxx = unsafeAggregate2 "regr_sxx"
1805− regrSxy = unsafeAggregate2 "regr_sxy"
1806− regrSyy = unsafeAggregate2 "regr_syy"
1807− stddev = unsafeAggregate1 "stddev"
1808− stddevPop = unsafeAggregate1 "stddev_pop"
1809− stddevSamp = unsafeAggregate1 "stddev_samp"
1810− variance = unsafeAggregate1 "variance"
1811− varPop = unsafeAggregate1 "var_pop"
1812− varSamp = unsafeAggregate1 "var_samp"
1813−instance Aggregate
1814− (Expression outer grp commons schemas params from)
1815− (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1816− (WindowFunction outer grp commons schemas params from) where
1817− countStar = UnsafeWindowFunction "count(*)"
1818− count = unsafeWindowFunction1 "count"
1819− sum_ = unsafeWindowFunction1 "sum"
1820− arrayAgg = unsafeWindowFunction1 "array_agg"
1821− jsonAgg = unsafeWindowFunction1 "json_agg"
1822− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1823− bitAnd = unsafeWindowFunction1 "bit_and"
1824− bitOr = unsafeWindowFunction1 "bit_or"
1825− boolAnd = unsafeWindowFunction1 "bool_and"
1826− boolOr = unsafeWindowFunction1 "bool_or"
1827− every = unsafeWindowFunction1 "every"
1828− max_ = unsafeWindowFunction1 "max"
1829− min_ = unsafeWindowFunction1 "min"
1830− avg = unsafeWindowFunction1 "avg"
1831− corr = unsafeWindowFunction2 "corr"
1832− covarPop = unsafeWindowFunction2 "covar_pop"
1833− covarSamp = unsafeWindowFunction2 "covar_samp"
1834− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1835− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1836− regrCount = unsafeWindowFunction2 "regr_count"
1837− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1838− regrR2 = unsafeWindowFunction2 "regr_r2"
1839− regrSlope = unsafeWindowFunction2 "regr_slope"
1840− regrSxx = unsafeWindowFunction2 "regr_sxx"
1841− regrSxy = unsafeWindowFunction2 "regr_sxy"
1842− regrSyy = unsafeWindowFunction2 "regr_syy"
1843− stddev = unsafeWindowFunction1 "stddev"
1844− stddevPop = unsafeWindowFunction1 "stddev_pop"
1845− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1846− variance = unsafeWindowFunction1 "variance"
1847− varPop = unsafeWindowFunction1 "var_pop"
1848− varSamp = unsafeWindowFunction1 "var_samp"
1849−
1850−-- | escape hatch to define aggregate functions
1851−unsafeAggregate1
1852− :: ByteString -- ^ aggregate function
1853− -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1854− -> Expression outer ('Grouped bys) commons schemas params from yty
1855−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1856− [fun, "(", renderSQL x, ")"]
1857−
1858−-- | escape hatch to define aggregate binary functions
1859−unsafeAggregate2
1860− :: ByteString -- ^ aggregate function
1861− -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1862− -> Expression outer ('Grouped bys) commons schemas params from yty
1863−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1864− [fun, "(", renderSQL xx, ")"]
1865−
1866−-- | A type family that calculates `PGAvg` type of a `PGType`.
1867−type family PGAvg ty where
1868− PGAvg 'PGint2 = 'PGnumeric
1869− PGAvg 'PGint4 = 'PGnumeric
1870− PGAvg 'PGint8 = 'PGnumeric
1871− PGAvg 'PGnumeric = 'PGnumeric
1872− PGAvg 'PGfloat4 = 'PGfloat8
1873− PGAvg 'PGfloat8 = 'PGfloat8
1874− PGAvg 'PGinterval = 'PGinterval
1875− PGAvg pg = TypeError
1876− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1877−
1878−{-----------------------------------------
1879−type expressions
1880−-----------------------------------------}
1881−
1882−-- | `TypeExpression`s are used in `cast`s and
1883−-- `Squeal.PostgreSQL.Definition.createTable` commands.
1884−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1885− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1886− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1887−instance RenderSQL (TypeExpression schemas ty) where
1888− renderSQL = renderTypeExpression
1889−
1890−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1891−typedef
1892− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1893− => QualifiedAlias sch td
1894− -> TypeExpression schemas (nullity ty)
1895−typedef = UnsafeTypeExpression . renderSQL
1896−
1897−-- | The composite type corresponding to a `Table` definition can be expressed
1898−-- by its alias.
1899−typetable
1900− :: (Has sch schemas schema, Has tab schema ('Table table))
1901− => QualifiedAlias sch tab
1902− -> TypeExpression schemas (nullity ('PGcomposite (TableToRow table)))
1903−typetable = UnsafeTypeExpression . renderSQL
1904−
1905−-- | The composite type corresponding to a `View` definition can be expressed
1906−-- by its alias.
1907−typeview
1908− :: (Has sch schemas schema, Has vw schema ('View view))
1909− => QualifiedAlias sch vw
1910− -> TypeExpression schemas (nullity ('PGcomposite view))
1911−typeview = UnsafeTypeExpression . renderSQL
1912−
1913−-- | logical Boolean (true/false)
1914−bool :: TypeExpression schemas (nullity 'PGbool)
1915−bool = UnsafeTypeExpression "bool"
1916−-- | signed two-byte integer
1917−int2, smallint :: TypeExpression schemas (nullity 'PGint2)
1918−int2 = UnsafeTypeExpression "int2"
1919−smallint = UnsafeTypeExpression "smallint"
1920−-- | signed four-byte integer
1921−int4, int, integer :: TypeExpression schemas (nullity 'PGint4)
1922−int4 = UnsafeTypeExpression "int4"
1923−int = UnsafeTypeExpression "int"
1924−integer = UnsafeTypeExpression "integer"
1925−-- | signed eight-byte integer
1926−int8, bigint :: TypeExpression schemas (nullity 'PGint8)
1927−int8 = UnsafeTypeExpression "int8"
1928−bigint = UnsafeTypeExpression "bigint"
1929−-- | arbitrary precision numeric type
1930−numeric :: TypeExpression schemas (nullity 'PGnumeric)
1931−numeric = UnsafeTypeExpression "numeric"
1932−-- | single precision floating-point number (4 bytes)
1933−float4, real :: TypeExpression schemas (nullity 'PGfloat4)
1934−float4 = UnsafeTypeExpression "float4"
1935−real = UnsafeTypeExpression "real"
1936−-- | double precision floating-point number (8 bytes)
1937−float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
1938−float8 = UnsafeTypeExpression "float8"
1939−doublePrecision = UnsafeTypeExpression "double precision"
1940−-- | currency amount
1941−money :: TypeExpression schema (nullity 'PGmoney)
1942−money = UnsafeTypeExpression "money"
1943−-- | variable-length character string
1944−text :: TypeExpression schemas (nullity 'PGtext)
1945−text = UnsafeTypeExpression "text"
1946−-- | fixed-length character string
1947−char, character
1948− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1949− => TypeExpression schemas (nullity ('PGchar n))
1950−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
1951−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
1952−-- | variable-length character string
1953−varchar, characterVarying
1954− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1955− => TypeExpression schemas (nullity ('PGvarchar n))
1956−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
1957−characterVarying = UnsafeTypeExpression $
1958− "character varying(" <> renderNat @n <> ")"
1959−-- | binary data ("byte array")
1960−bytea :: TypeExpression schemas (nullity 'PGbytea)
1961−bytea = UnsafeTypeExpression "bytea"
1962−-- | date and time (no time zone)
1963−timestamp :: TypeExpression schemas (nullity 'PGtimestamp)
1964−timestamp = UnsafeTypeExpression "timestamp"
1965−-- | date and time, including time zone
1966−timestampWithTimeZone :: TypeExpression schemas (nullity 'PGtimestamptz)
1967−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1968−-- | calendar date (year, month, day)
1969−date :: TypeExpression schemas (nullity 'PGdate)
1970−date = UnsafeTypeExpression "date"
1971−-- | time of day (no time zone)
1972−time :: TypeExpression schemas (nullity 'PGtime)
1973−time = UnsafeTypeExpression "time"
1974−-- | time of day, including time zone
1975−timeWithTimeZone :: TypeExpression schemas (nullity 'PGtimetz)
1976−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1977−-- | time span
1978−interval :: TypeExpression schemas (nullity 'PGinterval)
1979−interval = UnsafeTypeExpression "interval"
1980−-- | universally unique identifier
1981−uuid :: TypeExpression schemas (nullity 'PGuuid)
1982−uuid = UnsafeTypeExpression "uuid"
1983−-- | IPv4 or IPv6 host address
1984−inet :: TypeExpression schemas (nullity 'PGinet)
1985−inet = UnsafeTypeExpression "inet"
1986−-- | textual JSON data
1987−json :: TypeExpression schemas (nullity 'PGjson)
1988−json = UnsafeTypeExpression "json"
1989−-- | binary JSON data, decomposed
1990−jsonb :: TypeExpression schemas (nullity 'PGjsonb)
1991−jsonb = UnsafeTypeExpression "jsonb"
1992−-- | variable length array
1993−vararray
1994− :: TypeExpression schemas pg
1995− -> TypeExpression schemas (nullity ('PGvararray pg))
1996−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
1997−-- | fixed length array
1998−--
1999−-- >>> renderSQL (fixarray @'[2] json)
2000−-- "json[2]"
2001−fixarray
2002− :: forall dims schemas nullity pg. SOP.All KnownNat dims
2003− => TypeExpression schemas pg
2004− -> TypeExpression schemas (nullity ('PGfixarray dims pg))
2005−fixarray ty = UnsafeTypeExpression $
2006− renderSQL ty <> renderDims @dims
2007− where
2008− renderDims :: forall ns. SOP.All KnownNat ns => ByteString
2009− renderDims =
2010− ("[" <>)
2011− . (<> "]")
2012− . ByteString.intercalate "]["
2013− . hcollapse
2014− $ hcmap (SOP.Proxy @KnownNat)
2015− (K . fromString . show . natVal)
2016− (hpure SOP.Proxy :: NP SOP.Proxy ns)
2017−
2018−-- | `pgtype` is a demoted version of a `PGType`
2019−class PGTyped schemas (ty :: NullityType) where
2020− pgtype :: TypeExpression schemas ty
2021−instance PGTyped schemas (nullity 'PGbool) where pgtype = bool
2022−instance PGTyped schemas (nullity 'PGint2) where pgtype = int2
2023−instance PGTyped schemas (nullity 'PGint4) where pgtype = int4
2024−instance PGTyped schemas (nullity 'PGint8) where pgtype = int8
2025−instance PGTyped schemas (nullity 'PGnumeric) where pgtype = numeric
2026−instance PGTyped schemas (nullity 'PGfloat4) where pgtype = float4
2027−instance PGTyped schemas (nullity 'PGfloat8) where pgtype = float8
2028−instance PGTyped schemas (nullity 'PGtext) where pgtype = text
2029−instance (KnownNat n, 1 <= n)
2030− => PGTyped schemas (nullity ('PGchar n)) where pgtype = char @n
2031−instance (KnownNat n, 1 <= n)
2032− => PGTyped schemas (nullity ('PGvarchar n)) where pgtype = varchar @n
2033−instance PGTyped schemas (nullity 'PGbytea) where pgtype = bytea
2034−instance PGTyped schemas (nullity 'PGtimestamp) where pgtype = timestamp
2035−instance PGTyped schemas (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
2036−instance PGTyped schemas (nullity 'PGdate) where pgtype = date
2037−instance PGTyped schemas (nullity 'PGtime) where pgtype = time
2038−instance PGTyped schemas (nullity 'PGtimetz) where pgtype = timeWithTimeZone
2039−instance PGTyped schemas (nullity 'PGinterval) where pgtype = interval
2040−instance PGTyped schemas (nullity 'PGuuid) where pgtype = uuid
2041−instance PGTyped schemas (nullity 'PGjson) where pgtype = json
2042−instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
2043−instance PGTyped schemas ty
2044− => PGTyped schemas (nullity ('PGvararray ty)) where
2045− pgtype = vararray (pgtype @schemas @ty)
2046−instance (SOP.All KnownNat dims, PGTyped schemas ty)
2047− => PGTyped schemas (nullity ('PGfixarray dims ty)) where
2048− pgtype = fixarray @dims (pgtype @schemas @ty)
2049−
2050−{-----------------------------------------
2051−Sorting
2052−-----------------------------------------}
2053−
2054−-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2055−-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2056−-- set the sort direction of a `NotNull` result
2057−-- column to ascending or descending. Ascending order puts smaller values
2058−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2059−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2060−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2061−-- determine whether nulls appear before or after non-null values in the sort
2062−-- ordering of a `Null` result column.
2063−data SortExpression outer grp commons schemas params from where
2064− Asc
2065− :: Expression outer grp commons schemas params from ('NotNull ty)
2066− -> SortExpression outer grp commons schemas params from
2067− Desc
2068− :: Expression outer grp commons schemas params from ('NotNull ty)
2069− -> SortExpression outer grp commons schemas params from
2070− AscNullsFirst
2071− :: Expression outer grp commons schemas params from ('Null ty)
2072− -> SortExpression outer grp commons schemas params from
2073− AscNullsLast
2074− :: Expression outer grp commons schemas params from ('Null ty)
2075− -> SortExpression outer grp commons schemas params from
2076− DescNullsFirst
2077− :: Expression outer grp commons schemas params from ('Null ty)
2078− -> SortExpression outer grp commons schemas params from
2079− DescNullsLast
2080− :: Expression outer grp commons schemas params from ('Null ty)
2081− -> SortExpression outer grp commons schemas params from
2082−deriving instance Show (SortExpression outer grp commons schemas params from)
2083−
2084−{- |
2085−The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2086−to be sorted according to the specified `SortExpression`(s).
2087−If two rows are equal according to the leftmost expression,
2088−they are compared according to the next expression and so on.
2089−If they are equal according to all specified expressions,
2090−they are returned in an implementation-dependent order.
2091−
2092−You can also control the order in which rows are processed by window functions
2093−using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2094−-}
2095−class OrderBy expr where
2096− orderBy
2097− :: [SortExpression outer grp commons schemas params from]
2098− -> expr outer grp commons schemas params from
2099− -> expr outer grp commons schemas params from
2100−
2101−-- | Render a `SortExpression`.
2102−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2103− renderSQL = \case
2104− Asc expression -> renderSQL expression <+> "ASC"
2105− Desc expression -> renderSQL expression <+> "DESC"
2106− AscNullsFirst expression -> renderSQL expression
2107− <+> "ASC NULLS FIRST"
2108− DescNullsFirst expression -> renderSQL expression
2109− <+> "DESC NULLS FIRST"
2110− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2111− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2112−
2113−-- | A `WindowDefinition` is a set of table rows that are somehow related
2114−-- to the current row
2115−data WindowDefinition outer grp commons schemas params from where
2116− WindowDefinition
2117− :: SListI bys
2118− => NP (Expression outer grp commons schemas params from) bys
2119− -> [SortExpression outer grp commons schemas params from]
2120− -> WindowDefinition outer grp commons schemas params from
2121−
2122−instance OrderBy WindowDefinition where
2123− orderBy sortsR (WindowDefinition parts sortsL)
2124− = WindowDefinition parts (sortsL ++ sortsR)
2125−
2126−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2127− renderSQL (WindowDefinition part ord) =
2128− renderPartitionByClause part <> renderOrderByClause ord
2129− where
2130− renderPartitionByClause = \case
2131− Nil -> ""
2132− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2133− renderOrderByClause = \case
2134− [] -> ""
2135− srts -> " ORDER" <+> "BY"
2136− <+> commaSeparated (renderSQL <$> srts)
2137−
2138−{- |
2139−The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2140−or partitions, that share the same values of the `partitionBy` `Expression`(s).
2141−For each row, the window function is computed across the rows that fall into
2142−the same partition as the current row.
2143−-}
2144−partitionBy
2145− :: SListI bys
2146− => NP (Expression outer grp commons schemas params from) bys
2147− -> WindowDefinition outer grp commons schemas params from
2148−partitionBy bys = WindowDefinition bys []
2149−
2150−{- |
2151−A window function performs a calculation across a set of table rows
2152−that are somehow related to the current row. This is comparable to the type
2153−of calculation that can be done with an aggregate function.
2154−However, window functions do not cause rows to become grouped into a single
2155−output row like non-window aggregate calls would.
2156−Instead, the rows retain their separate identities.
2157−Behind the scenes, the window function is able to access more than
2158−just the current row of the query result.
2159−-}
2160−newtype WindowFunction
2161− (outer :: FromType)
2162− (grp :: Grouping)
2163− (commons :: FromType)
2164− (schemas :: SchemasType)
2165− (params :: [NullityType])
2166− (from :: FromType)
2167− (ty :: NullityType)
2168− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2169− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2170−
2171−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2172− renderSQL = renderWindowFunction
2173−
2174−unsafeWindowFunction1
2175− :: ByteString
2176− -> Expression outer grp commons schemas params from ty0
2177− -> WindowFunction outer grp commons schemas params from ty1
2178−unsafeWindowFunction1 fun x
2179− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2180−
2181−unsafeWindowFunction2
2182− :: ByteString
2183− -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2184− -> WindowFunction outer grp commons schemas params from ty1
2185−unsafeWindowFunction2 fun (x :*: x')
2186− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2187−
2188−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2189−>>> printSQL rank
2190−rank()
2191−-}
2192−rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2193−rank = UnsafeWindowFunction "rank()"
2194−
2195−{- | number of the current row within its partition, counting from 1
2196−>>> printSQL rowNumber
2197−row_number()
2198−-}
2199−rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2200−rowNumber = UnsafeWindowFunction "row_number()"
2201−
2202−{- | rank of the current row without gaps; this function counts peer groups
2203−>>> printSQL denseRank
2204−dense_rank()
2205−-}
2206−denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2207−denseRank = UnsafeWindowFunction "dense_rank()"
2208−
2209−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2210−>>> printSQL percentRank
2211−percent_rank()
2212−-}
2213−percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2214−percentRank = UnsafeWindowFunction "percent_rank()"
2215−
2216−{- | cumulative distribution: (number of partition rows
2217−preceding or peer with current row) / total partition rows
2218−>>> printSQL cumeDist
2219−cume_dist()
2220−-}
2221−cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2222−cumeDist = UnsafeWindowFunction "cume_dist()"
2223−
2224−{- | integer ranging from 1 to the argument value,
2225−dividing the partition as equally as possible
2226−-}
2227−ntile
2228− :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2229− -- ^ num buckets
2230− -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2231−ntile = unsafeWindowFunction1 "ntile"
2232−
2233−{- | returns value evaluated at the row that is offset rows before the current
2234−row within the partition; if there is no such row, instead return default
2235−(which must be of the same type as value). Both offset and default are
2236−evaluated with respect to the current row.
2237−-}
2238−lag
2239− :: Expression outer grp commons schemas params from ty
2240− -- ^ value
2241− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2242− -- ^ offset
2243− -> Expression outer grp commons schemas params from ty
2244− -- ^ default
2245− -> WindowFunction outer grp commons schemas params from ty
2246−lag value offset def = UnsafeWindowFunction $ "lag"
2247− <> parenthesized
2248− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2249−
2250−{- | returns value evaluated at the row that is offset rows after the current
2251−row within the partition; if there is no such row, instead return default
2252−(which must be of the same type as value). Both offset and default are
2253−evaluated with respect to the current row.
2254−-}
2255−lead
2256− :: Expression outer grp commons schemas params from ty
2257− -- ^ value
2258− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2259− -- ^ offset
2260− -> Expression outer grp commons schemas params from ty
2261− -- ^ default
2262− -> WindowFunction outer grp commons schemas params from ty
2263−lead value offset def = UnsafeWindowFunction $ "lag"
2264− <> parenthesized
2265− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2266−
2267−{- | returns value evaluated at the row that is the
2268−first row of the window frame
2269−-}
2270−firstValue
2271− :: Expression outer grp commons schemas params from ty
2272− -- ^ value
2273− -> WindowFunction outer grp commons schemas params from ty
2274−firstValue = unsafeWindowFunction1 "first_value"
2275−
2276−{- | returns value evaluated at the row that is the
2277−last row of the window frame
2278−-}
2279−lastValue
2280− :: Expression outer grp commons schemas params from ty
2281− -- ^ value
2282− -> WindowFunction outer grp commons schemas params from ty
2283−lastValue = unsafeWindowFunction1 "last_value"
2284−
2285−{- | returns value evaluated at the row that is the nth
2286−row of the window frame (counting from 1); null if no such row
2287−-}
2288−nthValue
2289− :: Expression outer grp commons schemas params from (nullity ty)
2290− -- ^ value
2291− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2292− -- ^ nth
2293− -> WindowFunction outer grp commons schemas params from ('Null ty)
2294−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2295− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])
2296−
2297−{-|
2298−Create date from year, month and day fields
2299−
2300−>>> printSQL (makeDate 1984 7 3)
2301−make_date(1984, 7, 3)
2302−-}
2303−makeDate
2304− :: Expression outer grp commons schemas params from (nullity 'PGint4)
2305− -- ^ year
2306− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2307− -- ^ month
2308− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2309− -- ^ day
2310− -> Expression outer grp commons schemas params from (nullity 'PGdate)
2311−makeDate y m d = UnsafeExpression $ "make_date" <>
2312− parenthesized (renderCommaSeparated renderSQL (y :* m :* d :* Nil))
2313−
2314−{-|
2315−Create time from hour, minute and seconds fields
2316−
2317−>>> printSQL (makeTime 8 15 23.5)
2318−make_time(8, 15, 23.5)
2319−-}
2320−makeTime
2321− :: Expression outer grp commons schemas params from (nullity 'PGint4)
2322− -- ^ hour
2323− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2324− -- ^ min
2325− -> Expression outer grp commons schemas params from (nullity 'PGfloat8)
2326− -- ^ sec
2327− -> Expression outer grp commons schemas params from (nullity 'PGtime)
2328−makeTime h m s = UnsafeExpression $ "make_time" <>
2329− parenthesized (renderCommaSeparated renderSQL (h :* m :* s :* Nil))
2330−
2331−{-|
2332−Create timestamp from year, month, day, hour, minute and seconds fields
2333−
2334−>>> printSQL (makeTimestamp 2013 7 15 8 15 23.5)
2335−make_timestamp(2013, 7, 15, 8, 15, 23.5)
2336−-}
2337−makeTimestamp
2338− :: Expression outer grp commons schemas params from (nullity 'PGint4)
2339− -- ^ year
2340− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2341− -- ^ month
2342− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2343− -- ^ day
2344− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2345− -- ^ hour
2346− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2347− -- ^ min
2348− -> Expression outer grp commons schemas params from (nullity 'PGfloat8)
2349− -- ^ sec
2350− -> Expression outer grp commons schemas params from (nullity 'PGtimestamp)
2351−makeTimestamp y mon d h m s =
2352− UnsafeExpression $ "make_timestamp" <> parenthesized
2353− (renderCommaSeparated renderSQL (y :* mon :* d :* h :* m :* s :* Nil))
2354−
2355−{-|
2356−Create timestamp with time zone from
2357−year, month, day, hour, minute and seconds fields;
2358−the current time zone is used
2359−
2360−>>> printSQL (makeTimestamptz 2013 7 15 8 15 23.5)
2361−make_timestamptz(2013, 7, 15, 8, 15, 23.5)
2362−-}
2363−makeTimestamptz
2364− :: Expression outer grp commons schemas params from (nullity 'PGint4)
2365− -- ^ year
2366− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2367− -- ^ month
2368− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2369− -- ^ day
2370− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2371− -- ^ hour
2372− -> Expression outer grp commons schemas params from (nullity 'PGint4)
2373− -- ^ min
2374− -> Expression outer grp commons schemas params from (nullity 'PGfloat8)
2375− -- ^ sec
2376− -> Expression outer grp commons schemas params from (nullity 'PGtimestamptz)
2377−makeTimestamptz y mon d h m s =
2378− UnsafeExpression $ "make_timestamptz" <> parenthesized
2379− (renderCommaSeparated renderSQL (y :* mon :* d :* h :* m :* s :* Nil))
2380−
2381−{-|
2382−Affine space operations on time types.
2383−-}
2384−class TimeOp time diff | time -> diff where
2385− {-|
2386− >>> printSQL (makeDate 1984 7 3 !+ 365)
2387− (make_date(1984, 7, 3) + 365)
2388− -}
2389− (!+)
2390− :: Expression outer grp commons schemas params from (nullity time)
2391− -> Expression outer grp commons schemas params from (nullity diff)
2392− -> Expression outer grp commons schemas params from (nullity time)
2393− (!+) = unsafeBinaryOp "+"
2394− {-|
2395− >>> printSQL (365 +! makeDate 1984 7 3)
2396− (365 + make_date(1984, 7, 3))
2397− -}
2398− (+!)
2399− :: Expression outer grp commons schemas params from (nullity diff)
2400− -> Expression outer grp commons schemas params from (nullity time)
2401− -> Expression outer grp commons schemas params from (nullity time)
2402− (+!) = unsafeBinaryOp "+"
2403− {-|
2404− >>> printSQL (makeDate 1984 7 3 !-! currentDate)
2405− (make_date(1984, 7, 3) - CURRENT_DATE)
2406− -}
2407− (!-!)
2408− :: Expression outer grp commons schemas params from (nullity time)
2409− -> Expression outer grp commons schemas params from (nullity time)
2410− -> Expression outer grp commons schemas params from (nullity diff)
2411− (!-!) = unsafeBinaryOp "-"
2412−instance TimeOp 'PGtimestamp 'PGinterval
2413−instance TimeOp 'PGtimestamptz 'PGinterval
2414−instance TimeOp 'PGtime 'PGinterval
2415−instance TimeOp 'PGtimetz 'PGinterval
2416−instance TimeOp 'PGinterval 'PGinterval
2417−instance TimeOp 'PGdate 'PGint4