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