@@ -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,1606 +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.All SOP.Top 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.All SOP.Top 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.All SOP.Top 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]] ('Null '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 (nullity ty)
1473−
1474− -- | input values, including nulls, concatenated into an array
1475− arrayAgg
1476− :: expr1 ty
1477− -> aggr ('NotNull ('PGvararray ty))
1478−
1479− -- | aggregates values as a JSON array
1480− jsonAgg
1481− :: expr1 ty
1482− -> aggr ('NotNull 'PGjson)
1483−
1484− -- | aggregates values as a JSON array
1485− jsonbAgg
1486− :: expr1 ty
1487− -> aggr ('NotNull 'PGjsonb)
1488−
1489− -- | >>> :{
1490− -- let
1491− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1492− -- expression = bitAnd (Distinct #col)
1493− -- in printSQL expression
1494− -- :}
1495− -- bit_and(DISTINCT "col")
1496− bitAnd
1497− :: int `In` PGIntegral
1498− => expr1 (nullity int)
1499− -- ^ what to aggregate
1500− -> aggr (nullity int)
1501−
1502− -- | >>> :{
1503− -- let
1504− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1505− -- expression = bitOr (All #col)
1506− -- in printSQL expression
1507− -- :}
1508− -- bit_or(ALL "col")
1509− bitOr
1510− :: int `In` PGIntegral
1511− => expr1 (nullity int)
1512− -- ^ what to aggregate
1513− -> aggr (nullity int)
1514−
1515− -- | >>> :{
1516− -- let
1517− -- winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1518− -- winFun = boolAnd #col
1519− -- in printSQL winFun
1520− -- :}
1521− -- bool_and("col")
1522− boolAnd
1523− :: expr1 (nullity 'PGbool)
1524− -- ^ what to aggregate
1525− -> aggr (nullity 'PGbool)
1526−
1527− -- | >>> :{
1528− -- let
1529− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1530− -- expression = boolOr (All #col)
1531− -- in printSQL expression
1532− -- :}
1533− -- bool_or(ALL "col")
1534− boolOr
1535− :: expr1(nullity 'PGbool)
1536− -- ^ what to aggregate
1537− -> aggr (nullity 'PGbool)
1538−
1539− -- | synonym for `boolAnd`
1540− --
1541− -- >>> :{
1542− -- let
1543− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1544− -- expression = every (Distinct #col)
1545− -- in printSQL expression
1546− -- :}
1547− -- every(DISTINCT "col")
1548− every
1549− :: expr1 (nullity 'PGbool)
1550− -- ^ what to aggregate
1551− -> aggr (nullity 'PGbool)
1552−
1553− -- | maximum value of expression across all input values
1554− max_
1555− :: expr1 (nullity ty)
1556− -- ^ what to maximize
1557− -> aggr (nullity ty)
1558−
1559− -- | minimum value of expression across all input values
1560− min_
1561− :: expr1 (nullity ty)
1562− -- ^ what to minimize
1563− -> aggr (nullity ty)
1564−
1565− -- | average aggregation
1566− avg
1567− :: expr1 (nullity ty)
1568− -- ^ what to average
1569− -> aggr (nullity (PGAvg ty))
1570−
1571− {- | correlation coefficient
1572− >>> :{
1573− let
1574− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1575− expression = corr (All (#y :*: #x))
1576− in printSQL expression
1577− :}
1578− corr(ALL "y", "x")
1579− -}
1580− corr
1581− :: expr2 (nullity 'PGfloat8)
1582− -> aggr (nullity 'PGfloat8)
1583−
1584− {- | population covariance
1585− >>> :{
1586− let
1587− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1588− expression = covarPop (All (#y :*: #x))
1589− in printSQL expression
1590− :}
1591− covar_pop(ALL "y", "x")
1592− -}
1593− covarPop
1594− :: expr2 (nullity 'PGfloat8)
1595− -> aggr (nullity 'PGfloat8)
1596−
1597− {- | sample covariance
1598− >>> :{
1599− let
1600− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1601− winFun = covarSamp (#y :*: #x)
1602− in printSQL winFun
1603− :}
1604− covar_samp("y", "x")
1605− -}
1606− covarSamp
1607− :: expr2 (nullity 'PGfloat8)
1608− -> aggr (nullity 'PGfloat8)
1609−
1610− {- | average of the independent variable (sum(X)/N)
1611− >>> :{
1612− let
1613− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1614− expression = regrAvgX (All (#y :*: #x))
1615− in printSQL expression
1616− :}
1617− regr_avgx(ALL "y", "x")
1618− -}
1619− regrAvgX
1620− :: expr2 (nullity 'PGfloat8)
1621− -> aggr (nullity 'PGfloat8)
1622−
1623− {- | average of the dependent variable (sum(Y)/N)
1624− >>> :{
1625− let
1626− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1627− winFun = regrAvgY (#y :*: #x)
1628− in printSQL winFun
1629− :}
1630− regr_avgy("y", "x")
1631− -}
1632− regrAvgY
1633− :: expr2 (nullity 'PGfloat8)
1634− -> aggr (nullity 'PGfloat8)
1635−
1636− {- | number of input rows in which both expressions are nonnull
1637− >>> :{
1638− let
1639− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGint8)
1640− winFun = regrCount (#y :*: #x)
1641− in printSQL winFun
1642− :}
1643− regr_count("y", "x")
1644− -}
1645− regrCount
1646− :: expr2 (nullity 'PGfloat8)
1647− -> aggr (nullity 'PGint8)
1648−
1649− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1650− >>> :{
1651− let
1652− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1653− expression = regrIntercept (All (#y :*: #x))
1654− in printSQL expression
1655− :}
1656− regr_intercept(ALL "y", "x")
1657− -}
1658− regrIntercept
1659− :: expr2 (nullity 'PGfloat8)
1660− -> aggr (nullity 'PGfloat8)
1661−
1662− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1663− regrR2
1664− :: expr2 (nullity 'PGfloat8)
1665− -> aggr (nullity 'PGfloat8)
1666−
1667− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1668− -- determined by the (X, Y) pairs
1669− regrSlope
1670− :: expr2 (nullity 'PGfloat8)
1671− -> aggr (nullity 'PGfloat8)
1672−
1673− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1674− -- (“sum of squares” of the independent variable)
1675− regrSxx
1676− :: expr2 (nullity 'PGfloat8)
1677− -> aggr (nullity 'PGfloat8)
1678−
1679− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1680− -- (“sum of products” of independent times dependent variable)
1681− regrSxy
1682− :: expr2 (nullity 'PGfloat8)
1683− -> aggr (nullity 'PGfloat8)
1684−
1685− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1686− -- (“sum of squares” of the dependent variable)
1687− regrSyy
1688− :: expr2 (nullity 'PGfloat8)
1689− -> aggr (nullity 'PGfloat8)
1690−
1691− -- | historical alias for `stddevSamp`
1692− stddev
1693− :: expr1 (nullity ty)
1694− -> aggr (nullity (PGAvg ty))
1695−
1696− -- | population standard deviation of the input values
1697− stddevPop
1698− :: expr1 (nullity ty)
1699− -> aggr (nullity (PGAvg ty))
1700−
1701− -- | sample standard deviation of the input values
1702− stddevSamp
1703− :: expr1 (nullity ty)
1704− -> aggr (nullity (PGAvg ty))
1705−
1706− -- | historical alias for `varSamp`
1707− variance
1708− :: expr1 (nullity ty)
1709− -> aggr (nullity (PGAvg ty))
1710−
1711− -- | population variance of the input values
1712− -- (square of the population standard deviation)
1713− varPop
1714− :: expr1 (nullity ty)
1715− -> aggr (nullity (PGAvg ty))
1716−
1717− -- | sample variance of the input values
1718− -- (square of the sample standard deviation)
1719− varSamp
1720− :: expr1 (nullity ty)
1721− -> aggr (nullity (PGAvg ty))
1722−
1723−{- |
1724−`Distinction`s are used for the input of `Aggregate` `Expression`s.
1725−`All` invokes the aggregate once for each input row.
1726−`Distinct` invokes the aggregate once for each distinct value of the expression
1727−(or distinct set of values, for multiple expressions) found in the input
1728−-}
1729−data Distinction expr ty
1730− = All (expr ty)
1731− | Distinct (expr ty)
1732− deriving (GHC.Generic,Show,Eq,Ord)
1733−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1734−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1735− renderSQL = \case
1736− All x -> "ALL" <+> renderSQL x
1737− Distinct x -> "DISTINCT" <+> renderSQL x
1738−instance RenderSQL
1739− (Distinction
1740− ( Expression outer grp commons schemas params from
1741− :*:
1742− Expression outer grp commons schemas params from) xty ) where
1743− renderSQL = \case
1744− All (x :*: x') ->
1745− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1746− Distinct (x :*: x') ->
1747− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1748−
1749−instance Aggregate
1750− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1751− (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1752− (Expression outer ('Grouped bys) commons schemas params from) where
1753− countStar = UnsafeExpression "count(*)"
1754− count = unsafeAggregate1 "count"
1755− sum_ = unsafeAggregate1 "sum"
1756− arrayAgg = unsafeAggregate1 "array_agg"
1757− jsonAgg = unsafeAggregate1 "json_agg"
1758− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1759− bitAnd = unsafeAggregate1 "bit_and"
1760− bitOr = unsafeAggregate1 "bit_or"
1761− boolAnd = unsafeAggregate1 "bool_and"
1762− boolOr = unsafeAggregate1 "bool_or"
1763− every = unsafeAggregate1 "every"
1764− max_ = unsafeAggregate1 "max"
1765− min_ = unsafeAggregate1 "min"
1766− avg = unsafeAggregate1 "avg"
1767− corr = unsafeAggregate2 "corr"
1768− covarPop = unsafeAggregate2 "covar_pop"
1769− covarSamp = unsafeAggregate2 "covar_samp"
1770− regrAvgX = unsafeAggregate2 "regr_avgx"
1771− regrAvgY = unsafeAggregate2 "regr_avgy"
1772− regrCount = unsafeAggregate2 "regr_count"
1773− regrIntercept = unsafeAggregate2 "regr_intercept"
1774− regrR2 = unsafeAggregate2 "regr_r2"
1775− regrSlope = unsafeAggregate2 "regr_slope"
1776− regrSxx = unsafeAggregate2 "regr_sxx"
1777− regrSxy = unsafeAggregate2 "regr_sxy"
1778− regrSyy = unsafeAggregate2 "regr_syy"
1779− stddev = unsafeAggregate1 "stddev"
1780− stddevPop = unsafeAggregate1 "stddev_pop"
1781− stddevSamp = unsafeAggregate1 "stddev_samp"
1782− variance = unsafeAggregate1 "variance"
1783− varPop = unsafeAggregate1 "var_pop"
1784− varSamp = unsafeAggregate1 "var_samp"
1785−instance Aggregate
1786− (Expression outer grp commons schemas params from)
1787− (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1788− (WindowFunction outer grp commons schemas params from) where
1789− countStar = UnsafeWindowFunction "count(*)"
1790− count = unsafeWindowFunction1 "count"
1791− sum_ = unsafeWindowFunction1 "sum"
1792− arrayAgg = unsafeWindowFunction1 "array_agg"
1793− jsonAgg = unsafeWindowFunction1 "json_agg"
1794− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1795− bitAnd = unsafeWindowFunction1 "bit_and"
1796− bitOr = unsafeWindowFunction1 "bit_or"
1797− boolAnd = unsafeWindowFunction1 "bool_and"
1798− boolOr = unsafeWindowFunction1 "bool_or"
1799− every = unsafeWindowFunction1 "every"
1800− max_ = unsafeWindowFunction1 "max"
1801− min_ = unsafeWindowFunction1 "min"
1802− avg = unsafeWindowFunction1 "avg"
1803− corr = unsafeWindowFunction2 "corr"
1804− covarPop = unsafeWindowFunction2 "covar_pop"
1805− covarSamp = unsafeWindowFunction2 "covar_samp"
1806− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1807− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1808− regrCount = unsafeWindowFunction2 "regr_count"
1809− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1810− regrR2 = unsafeWindowFunction2 "regr_r2"
1811− regrSlope = unsafeWindowFunction2 "regr_slope"
1812− regrSxx = unsafeWindowFunction2 "regr_sxx"
1813− regrSxy = unsafeWindowFunction2 "regr_sxy"
1814− regrSyy = unsafeWindowFunction2 "regr_syy"
1815− stddev = unsafeWindowFunction1 "stddev"
1816− stddevPop = unsafeWindowFunction1 "stddev_pop"
1817− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1818− variance = unsafeWindowFunction1 "variance"
1819− varPop = unsafeWindowFunction1 "var_pop"
1820− varSamp = unsafeWindowFunction1 "var_samp"
1821−
1822−-- | escape hatch to define aggregate functions
1823−unsafeAggregate1
1824− :: ByteString -- ^ aggregate function
1825− -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1826− -> Expression outer ('Grouped bys) commons schemas params from yty
1827−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1828− [fun, "(", renderSQL x, ")"]
1829−
1830−-- | escape hatch to define aggregate binary functions
1831−unsafeAggregate2
1832− :: ByteString -- ^ aggregate function
1833− -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1834− -> Expression outer ('Grouped bys) commons schemas params from yty
1835−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1836− [fun, "(", renderSQL xx, ")"]
1837−
1838−-- | A type family that calculates `PGAvg` type of a `PGType`.
1839−type family PGAvg ty where
1840− PGAvg 'PGint2 = 'PGnumeric
1841− PGAvg 'PGint4 = 'PGnumeric
1842− PGAvg 'PGint8 = 'PGnumeric
1843− PGAvg 'PGnumeric = 'PGnumeric
1844− PGAvg 'PGfloat4 = 'PGfloat8
1845− PGAvg 'PGfloat8 = 'PGfloat8
1846− PGAvg 'PGinterval = 'PGinterval
1847− PGAvg pg = TypeError
1848− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1849−
1850−{-----------------------------------------
1851−type expressions
1852−-----------------------------------------}
1853−
1854−-- | `TypeExpression`s are used in `cast`s and
1855−-- `Squeal.PostgreSQL.Definition.createTable` commands.
1856−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1857− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1858− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1859−instance RenderSQL (TypeExpression schemas ty) where
1860− renderSQL = renderTypeExpression
1861−
1862−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1863−typedef
1864− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1865− => QualifiedAlias sch td
1866− -> TypeExpression schemas (nullity ty)
1867−typedef = UnsafeTypeExpression . renderSQL
1868−
1869−-- | The composite type corresponding to a `Table` definition can be expressed
1870−-- by its alias.
1871−typetable
1872− :: (Has sch schemas schema, Has tab schema ('Table table))
1873− => QualifiedAlias sch tab
1874− -> TypeExpression schemas (nullity ('PGcomposite (TableToRow table)))
1875−typetable = UnsafeTypeExpression . renderSQL
1876−
1877−-- | The composite type corresponding to a `View` definition can be expressed
1878−-- by its alias.
1879−typeview
1880− :: (Has sch schemas schema, Has vw schema ('View view))
1881− => QualifiedAlias sch vw
1882− -> TypeExpression schemas (nullity ('PGcomposite view))
1883−typeview = UnsafeTypeExpression . renderSQL
1884−
1885−-- | logical Boolean (true/false)
1886−bool :: TypeExpression schemas (nullity 'PGbool)
1887−bool = UnsafeTypeExpression "bool"
1888−-- | signed two-byte integer
1889−int2, smallint :: TypeExpression schemas (nullity 'PGint2)
1890−int2 = UnsafeTypeExpression "int2"
1891−smallint = UnsafeTypeExpression "smallint"
1892−-- | signed four-byte integer
1893−int4, int, integer :: TypeExpression schemas (nullity 'PGint4)
1894−int4 = UnsafeTypeExpression "int4"
1895−int = UnsafeTypeExpression "int"
1896−integer = UnsafeTypeExpression "integer"
1897−-- | signed eight-byte integer
1898−int8, bigint :: TypeExpression schemas (nullity 'PGint8)
1899−int8 = UnsafeTypeExpression "int8"
1900−bigint = UnsafeTypeExpression "bigint"
1901−-- | arbitrary precision numeric type
1902−numeric :: TypeExpression schemas (nullity 'PGnumeric)
1903−numeric = UnsafeTypeExpression "numeric"
1904−-- | single precision floating-point number (4 bytes)
1905−float4, real :: TypeExpression schemas (nullity 'PGfloat4)
1906−float4 = UnsafeTypeExpression "float4"
1907−real = UnsafeTypeExpression "real"
1908−-- | double precision floating-point number (8 bytes)
1909−float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
1910−float8 = UnsafeTypeExpression "float8"
1911−doublePrecision = UnsafeTypeExpression "double precision"
1912−-- | variable-length character string
1913−text :: TypeExpression schemas (nullity 'PGtext)
1914−text = UnsafeTypeExpression "text"
1915−-- | fixed-length character string
1916−char, character
1917− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1918− => TypeExpression schemas (nullity ('PGchar n))
1919−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
1920−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
1921−-- | variable-length character string
1922−varchar, characterVarying
1923− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1924− => TypeExpression schemas (nullity ('PGvarchar n))
1925−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
1926−characterVarying = UnsafeTypeExpression $
1927− "character varying(" <> renderNat @n <> ")"
1928−-- | binary data ("byte array")
1929−bytea :: TypeExpression schemas (nullity 'PGbytea)
1930−bytea = UnsafeTypeExpression "bytea"
1931−-- | date and time (no time zone)
1932−timestamp :: TypeExpression schemas (nullity 'PGtimestamp)
1933−timestamp = UnsafeTypeExpression "timestamp"
1934−-- | date and time, including time zone
1935−timestampWithTimeZone :: TypeExpression schemas (nullity 'PGtimestamptz)
1936−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1937−-- | calendar date (year, month, day)
1938−date :: TypeExpression schemas (nullity 'PGdate)
1939−date = UnsafeTypeExpression "date"
1940−-- | time of day (no time zone)
1941−time :: TypeExpression schemas (nullity 'PGtime)
1942−time = UnsafeTypeExpression "time"
1943−-- | time of day, including time zone
1944−timeWithTimeZone :: TypeExpression schemas (nullity 'PGtimetz)
1945−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1946−-- | time span
1947−interval :: TypeExpression schemas (nullity 'PGinterval)
1948−interval = UnsafeTypeExpression "interval"
1949−-- | universally unique identifier
1950−uuid :: TypeExpression schemas (nullity 'PGuuid)
1951−uuid = UnsafeTypeExpression "uuid"
1952−-- | IPv4 or IPv6 host address
1953−inet :: TypeExpression schemas (nullity 'PGinet)
1954−inet = UnsafeTypeExpression "inet"
1955−-- | textual JSON data
1956−json :: TypeExpression schemas (nullity 'PGjson)
1957−json = UnsafeTypeExpression "json"
1958−-- | binary JSON data, decomposed
1959−jsonb :: TypeExpression schemas (nullity 'PGjsonb)
1960−jsonb = UnsafeTypeExpression "jsonb"
1961−-- | variable length array
1962−vararray
1963− :: TypeExpression schemas pg
1964− -> TypeExpression schemas (nullity ('PGvararray pg))
1965−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
1966−-- | fixed length array
1967−--
1968−-- >>> renderSQL (fixarray @'[2] json)
1969−-- "json[2]"
1970−fixarray
1971− :: forall dims schemas nullity pg. SOP.All KnownNat dims
1972− => TypeExpression schemas pg
1973− -> TypeExpression schemas (nullity ('PGfixarray dims pg))
1974−fixarray ty = UnsafeTypeExpression $
1975− renderSQL ty <> renderDims @dims
1976− where
1977− renderDims :: forall ns. SOP.All KnownNat ns => ByteString
1978− renderDims =
1979− ("[" <>)
1980− . (<> "]")
1981− . ByteString.intercalate "]["
1982− . hcollapse
1983− $ hcmap (SOP.Proxy @KnownNat)
1984− (K . fromString . show . natVal)
1985− (hpure SOP.Proxy :: NP SOP.Proxy ns)
1986−
1987−-- | `pgtype` is a demoted version of a `PGType`
1988−class PGTyped schemas (ty :: NullityType) where
1989− pgtype :: TypeExpression schemas ty
1990−instance PGTyped schemas (nullity 'PGbool) where pgtype = bool
1991−instance PGTyped schemas (nullity 'PGint2) where pgtype = int2
1992−instance PGTyped schemas (nullity 'PGint4) where pgtype = int4
1993−instance PGTyped schemas (nullity 'PGint8) where pgtype = int8
1994−instance PGTyped schemas (nullity 'PGnumeric) where pgtype = numeric
1995−instance PGTyped schemas (nullity 'PGfloat4) where pgtype = float4
1996−instance PGTyped schemas (nullity 'PGfloat8) where pgtype = float8
1997−instance PGTyped schemas (nullity 'PGtext) where pgtype = text
1998−instance (KnownNat n, 1 <= n)
1999− => PGTyped schemas (nullity ('PGchar n)) where pgtype = char @n
2000−instance (KnownNat n, 1 <= n)
2001− => PGTyped schemas (nullity ('PGvarchar n)) where pgtype = varchar @n
2002−instance PGTyped schemas (nullity 'PGbytea) where pgtype = bytea
2003−instance PGTyped schemas (nullity 'PGtimestamp) where pgtype = timestamp
2004−instance PGTyped schemas (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
2005−instance PGTyped schemas (nullity 'PGdate) where pgtype = date
2006−instance PGTyped schemas (nullity 'PGtime) where pgtype = time
2007−instance PGTyped schemas (nullity 'PGtimetz) where pgtype = timeWithTimeZone
2008−instance PGTyped schemas (nullity 'PGinterval) where pgtype = interval
2009−instance PGTyped schemas (nullity 'PGuuid) where pgtype = uuid
2010−instance PGTyped schemas (nullity 'PGjson) where pgtype = json
2011−instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
2012−instance PGTyped schemas ty
2013− => PGTyped schemas (nullity ('PGvararray ty)) where
2014− pgtype = vararray (pgtype @schemas @ty)
2015−instance (SOP.All KnownNat dims, PGTyped schemas ty)
2016− => PGTyped schemas (nullity ('PGfixarray dims ty)) where
2017− pgtype = fixarray @dims (pgtype @schemas @ty)
2018−
2019−{-----------------------------------------
2020−Sorting
2021−-----------------------------------------}
2022−
2023−-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2024−-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2025−-- set the sort direction of a `NotNull` result
2026−-- column to ascending or descending. Ascending order puts smaller values
2027−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2028−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2029−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2030−-- determine whether nulls appear before or after non-null values in the sort
2031−-- ordering of a `Null` result column.
2032−data SortExpression outer grp commons schemas params from where
2033− Asc
2034− :: Expression outer grp commons schemas params from ('NotNull ty)
2035− -> SortExpression outer grp commons schemas params from
2036− Desc
2037− :: Expression outer grp commons schemas params from ('NotNull ty)
2038− -> SortExpression outer grp commons schemas params from
2039− AscNullsFirst
2040− :: Expression outer grp commons schemas params from ('Null ty)
2041− -> SortExpression outer grp commons schemas params from
2042− AscNullsLast
2043− :: Expression outer grp commons schemas params from ('Null ty)
2044− -> SortExpression outer grp commons schemas params from
2045− DescNullsFirst
2046− :: Expression outer grp commons schemas params from ('Null ty)
2047− -> SortExpression outer grp commons schemas params from
2048− DescNullsLast
2049− :: Expression outer grp commons schemas params from ('Null ty)
2050− -> SortExpression outer grp commons schemas params from
2051−deriving instance Show (SortExpression outer grp commons schemas params from)
2052−
2053−{- |
2054−The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2055−to be sorted according to the specified `SortExpression`(s).
2056−If two rows are equal according to the leftmost expression,
2057−they are compared according to the next expression and so on.
2058−If they are equal according to all specified expressions,
2059−they are returned in an implementation-dependent order.
2060−
2061−You can also control the order in which rows are processed by window functions
2062−using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2063−-}
2064−class OrderBy expr where
2065− orderBy
2066− :: [SortExpression outer grp commons schemas params from]
2067− -> expr outer grp commons schemas params from
2068− -> expr outer grp commons schemas params from
2069−
2070−-- | Render a `SortExpression`.
2071−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2072− renderSQL = \case
2073− Asc expression -> renderSQL expression <+> "ASC"
2074− Desc expression -> renderSQL expression <+> "DESC"
2075− AscNullsFirst expression -> renderSQL expression
2076− <+> "ASC NULLS FIRST"
2077− DescNullsFirst expression -> renderSQL expression
2078− <+> "DESC NULLS FIRST"
2079− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2080− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2081−
2082−-- | A `WindowDefinition` is a set of table rows that are somehow related
2083−-- to the current row
2084−data WindowDefinition outer grp commons schemas params from where
2085− WindowDefinition
2086− :: SListI bys
2087− => NP (Expression outer grp commons schemas params from) bys
2088− -> [SortExpression outer grp commons schemas params from]
2089− -> WindowDefinition outer grp commons schemas params from
2090−
2091−instance OrderBy WindowDefinition where
2092− orderBy sortsR (WindowDefinition parts sortsL)
2093− = WindowDefinition parts (sortsL ++ sortsR)
2094−
2095−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2096− renderSQL (WindowDefinition part ord) =
2097− renderPartitionByClause part <> renderOrderByClause ord
2098− where
2099− renderPartitionByClause = \case
2100− Nil -> ""
2101− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2102− renderOrderByClause = \case
2103− [] -> ""
2104− srts -> " ORDER" <+> "BY"
2105− <+> commaSeparated (renderSQL <$> srts)
2106−
2107−{- |
2108−The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2109−or partitions, that share the same values of the `partitionBy` `Expression`(s).
2110−For each row, the window function is computed across the rows that fall into
2111−the same partition as the current row.
2112−-}
2113−partitionBy
2114− :: SListI bys
2115− => NP (Expression outer grp commons schemas params from) bys
2116− -> WindowDefinition outer grp commons schemas params from
2117−partitionBy bys = WindowDefinition bys []
2118−
2119−{- |
2120−A window function performs a calculation across a set of table rows
2121−that are somehow related to the current row. This is comparable to the type
2122−of calculation that can be done with an aggregate function.
2123−However, window functions do not cause rows to become grouped into a single
2124−output row like non-window aggregate calls would.
2125−Instead, the rows retain their separate identities.
2126−Behind the scenes, the window function is able to access more than
2127−just the current row of the query result.
2128−-}
2129−newtype WindowFunction
2130− (outer :: FromType)
2131− (grp :: Grouping)
2132− (commons :: FromType)
2133− (schemas :: SchemasType)
2134− (params :: [NullityType])
2135− (from :: FromType)
2136− (ty :: NullityType)
2137− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2138− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2139−
2140−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2141− renderSQL = renderWindowFunction
2142−
2143−unsafeWindowFunction1
2144− :: ByteString
2145− -> Expression outer grp commons schemas params from ty0
2146− -> WindowFunction outer grp commons schemas params from ty1
2147−unsafeWindowFunction1 fun x
2148− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2149−
2150−unsafeWindowFunction2
2151− :: ByteString
2152− -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2153− -> WindowFunction outer grp commons schemas params from ty1
2154−unsafeWindowFunction2 fun (x :*: x')
2155− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2156−
2157−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2158−>>> printSQL rank
2159−rank()
2160−-}
2161−rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2162−rank = UnsafeWindowFunction "rank()"
2163−
2164−{- | number of the current row within its partition, counting from 1
2165−>>> printSQL rowNumber
2166−row_number()
2167−-}
2168−rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2169−rowNumber = UnsafeWindowFunction "row_number()"
2170−
2171−{- | rank of the current row without gaps; this function counts peer groups
2172−>>> printSQL denseRank
2173−dense_rank()
2174−-}
2175−denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2176−denseRank = UnsafeWindowFunction "dense_rank()"
2177−
2178−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2179−>>> printSQL percentRank
2180−percent_rank()
2181−-}
2182−percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2183−percentRank = UnsafeWindowFunction "percent_rank()"
2184−
2185−{- | cumulative distribution: (number of partition rows
2186−preceding or peer with current row) / total partition rows
2187−>>> printSQL cumeDist
2188−cume_dist()
2189−-}
2190−cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2191−cumeDist = UnsafeWindowFunction "cume_dist()"
2192−
2193−{- | integer ranging from 1 to the argument value,
2194−dividing the partition as equally as possible
2195−-}
2196−ntile
2197− :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2198− -- ^ num buckets
2199− -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2200−ntile = unsafeWindowFunction1 "ntile"
2201−
2202−{- | returns value evaluated at the row that is offset rows before the current
2203−row within the partition; if there is no such row, instead return default
2204−(which must be of the same type as value). Both offset and default are
2205−evaluated with respect to the current row.
2206−-}
2207−lag
2208− :: Expression outer grp commons schemas params from ty
2209− -- ^ value
2210− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2211− -- ^ offset
2212− -> Expression outer grp commons schemas params from ty
2213− -- ^ default
2214− -> WindowFunction outer grp commons schemas params from ty
2215−lag value offset def = UnsafeWindowFunction $ "lag"
2216− <> parenthesized
2217− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2218−
2219−{- | returns value evaluated at the row that is offset rows after 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−lead
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−lead 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 the
2237−first row of the window frame
2238−-}
2239−firstValue
2240− :: Expression outer grp commons schemas params from ty
2241− -- ^ value
2242− -> WindowFunction outer grp commons schemas params from ty
2243−firstValue = unsafeWindowFunction1 "first_value"
2244−
2245−{- | returns value evaluated at the row that is the
2246−last row of the window frame
2247−-}
2248−lastValue
2249− :: Expression outer grp commons schemas params from ty
2250− -- ^ value
2251− -> WindowFunction outer grp commons schemas params from ty
2252−lastValue = unsafeWindowFunction1 "last_value"
2253−
2254−{- | returns value evaluated at the row that is the nth
2255−row of the window frame (counting from 1); null if no such row
2256−-}
2257−nthValue
2258− :: Expression outer grp commons schemas params from (nullity ty)
2259− -- ^ value
2260− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2261− -- ^ nth
2262− -> WindowFunction outer grp commons schemas params from ('Null ty)
2263−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2264− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])