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