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