@@ -1,14 +1,13 @@
2Module: Squeal.PostgreSQL.Expression
2Module: Squeal.PostgreSQL.Expression
3Description: Squeal expressions
3Description: Squeal expressions
4−Copyright: (c) Eitan Chatav, 2017
4+Copyright: (c) Eitan Chatav, 2019
5Maintainer: eitan@morphism.tech
5Maintainer: eitan@morphism.tech
6Stability: experimental
6Stability: experimental
8Squeal expressions are the atoms used to build statements.
8Squeal expressions are the atoms used to build statements.
11−{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
12{-# LANGUAGE
11{-# LANGUAGE
13 AllowAmbiguousTypes
12 AllowAmbiguousTypes
14 , ConstraintKinds
13 , ConstraintKinds
@@ -35,377 +34,213 @@ module Squeal.PostgreSQL.Expression
35 ( -- * Expression
34 ( -- * Expression
36 Expression (..)
35 Expression (..)
38 , Operator
45 , Operator
39− , (:-->)
46+ , OperatorDB
40− , HasParameter (parameter)
59 , unsafeBinaryOp
47 , unsafeBinaryOp
60− , unsafeUnaryOpL
48+ , binaryOp
61− , unsafeFunction
49+ , FunctionVar
62− , unsafeVariadicFunction
50+ , unsafeFunctionVar
63− , atan2_
51+ , type (--->)
64− , cast
52+ , FunctionNDB
65− , quot_
53+ , unsafeFunctionN
66− , rem_
54+ , functionN
67− , trunc
55+ , PGSubset (..)
68− , round_
56+ , PGIntersect (..)
91− , notBetweenSymmetric
118− -- *** Json and Jsonb operators
123− -- *** Jsonb operators
148− , jsonExtractPathAsText
149− , jsonbExtractPathAsText
168− , websearchToTSquery
183− -- * Window Functions
184− , WindowDefinition (..)
186− , WindowFunction (..)
199− , SortExpression (..)
202− , TypeExpression (..)
228− , timestampWithTimeZone
241 -- * Re-export
57 -- * Re-export
248import Control.Category
63import Control.Category
249import Control.DeepSeq
64import Control.DeepSeq
250import Data.ByteString (ByteString)
65import Data.ByteString (ByteString)
251−import Data.ByteString.Lazy (toStrict)
252import Data.Function ((&))
66import Data.Function ((&))
253import Data.Semigroup hiding (All)
67import Data.Semigroup hiding (All)
254−import qualified Data.Aeson as JSON
255import Data.String
68import Data.String
257import Generics.SOP hiding (All, from)
69import Generics.SOP hiding (All, from)
258−import GHC.Generics ((:*:) (..))
259import GHC.OverloadedLabels
70import GHC.OverloadedLabels
260import GHC.TypeLits
71import GHC.TypeLits
261import Numeric
72import Numeric
262import Prelude hiding (id, (.))
73import Prelude hiding (id, (.))
264−import qualified Data.ByteString as ByteString
265import qualified GHC.Generics as GHC
75import qualified GHC.Generics as GHC
266−import qualified Generics.SOP as SOP
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
268import Squeal.PostgreSQL.Render
79import Squeal.PostgreSQL.Render
269import Squeal.PostgreSQL.Schema
80import Squeal.PostgreSQL.Schema
83+-- >>> import Squeal.PostgreSQL
271{-----------------------------------------
85{-----------------------------------------
272column expressions
86column expressions
273-----------------------------------------}
87-----------------------------------------}
275{- | `Expression`s are used in a variety of contexts,
89{- | `Expression`s are used in a variety of contexts,
90+such as in the target `Squeal.PostgreSQL.Query.List` of the
276−such as in the target list of the `Squeal.PostgreSQL.Query.select` command,
91+`Squeal.PostgreSQL.Query.select` command,
277as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
92as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
278`Squeal.PostgreSQL.Manipulation.update`,
93`Squeal.PostgreSQL.Manipulation.update`,
279−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
281The expression syntax allows the calculation of
96The expression syntax allows the calculation of
282values from primitive expression using arithmetic, logical,
97values from primitive expression using arithmetic, logical,
283and other operations.
98and other operations.
100+The type parameters of `Expression` are
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`.
285newtype Expression
114newtype Expression
286 (outer :: FromType)
115 (outer :: FromType)
288 (commons :: FromType)
116 (commons :: FromType)
289 (schemas :: SchemasType)
118 (schemas :: SchemasType)
290 (params :: [NullityType])
119 (params :: [NullityType])
291 (from :: FromType)
120 (from :: FromType)
292 (ty :: NullityType)
121 (ty :: NullityType)
293 = UnsafeExpression { renderExpression :: ByteString }
122 = UnsafeExpression { renderExpression :: ByteString }
294 deriving (GHC.Generic,Show,Eq,Ord,NFData)
123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
295−instance RenderSQL (Expression outer grp commons schemas params from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
296 renderSQL = renderExpression
125 renderSQL = renderExpression
298-- | An `Expr` is a closed `Expression`.
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.
299type Expr x
133type Expr x
300− = forall outer grp commons schemas params from
134+ = forall outer commons grp schemas params from
301− . Expression outer grp commons schemas params from x
135+ . Expression outer commons grp schemas params from x
302 -- ^ cannot reference aliases
136 -- ^ cannot reference aliases
138+-- | A @RankNType@ for binary operators.
304type Operator x1 x2 y
139type Operator x1 x2 y
305− = forall outer grp commons schemas params from
140+ = forall outer commons grp schemas params from
306− . Expression outer grp commons schemas params from x1
141+ . Expression outer commons grp schemas params from x1
307 -- ^ left input
142 -- ^ left input
308− -> Expression outer grp commons schemas params from x2
143+ -> Expression outer commons grp schemas params from x2
309 -- ^ right input
144 -- ^ right input
310− -> Expression outer grp commons schemas params from y
145+ -> Expression outer commons grp schemas params from y
311 -- ^ output
146 -- ^ output
313−type (:-->) x y
148+type OperatorDB schemas x1 x2 y
149+ = forall outer commons grp params from
150+ . Expression outer commons grp schemas params from x1
152+ -> Expression outer commons grp schemas params from x2
154+ -> Expression outer commons grp schemas params from y
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`.
314− = forall outer grp commons schemas params from
163+ = forall outer commons grp schemas params from
315− . Expression outer grp commons schemas params from x
164+ . Expression outer commons grp schemas params from x
316 -- ^ input
165 -- ^ input
317− -> Expression outer grp commons schemas params from y
166+ -> Expression outer commons grp schemas params from y
318 -- ^ output
167 -- ^ output
320−type FunctionHet xs y
169+type FunctionDB schemas x y
321− = forall outer grp commons schemas params from
170+ = forall outer commons grp params from
322− . NP (Expression outer grp commons schemas params from) xs
171+ . Expression outer commons grp schemas params from x
323− -- ^ inputs
172+ -- ^ input
324− -> Expression outer grp commons schemas params from y
173+ -> Expression outer commons grp schemas params from y
325 -- ^ output
174 -- ^ output
327−type FunctionHom x0 x1 y
176+{- | A @RankNType@ for functions with a fixed-length list of heterogeneous arguments.
177+Use the `*:` operator to end your argument lists, like so.
179+>>> printSQL (unsafeFunctionN "fun" (true :* false :* localTime *: true))
180+fun(TRUE, FALSE, LOCALTIME, TRUE)
328− = forall outer grp commons schemas params from
183+ = forall outer commons grp schemas params from
329− . [Expression outer grp commons schemas params from x0]
184+ . NP (Expression outer commons grp schemas params from) xs
330 -- ^ inputs
185 -- ^ inputs
331− -> Expression outer grp commons schemas params from x1
186+ -> Expression outer commons grp schemas params from y
332− -- ^ must have at least 1 input
333− -> Expression outer grp commons schemas params from y
334 -- ^ output
187 -- ^ output
336−unsafeFunctionHom :: ByteString -> FunctionHom x0 x1 y
189+type FunctionNDB schemas xs y
337−unsafeFunctionHom fun xs x = UnsafeExpression $ fun <> parenthesized
190+ = forall outer commons grp params from
338− (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
191+ . NP (Expression outer commons grp schemas params from) xs
193+ -> Expression outer commons grp schemas params from y
340−{- | A `HasParameter` constraint is used to indicate a value that is
196+{- | A @RankNType@ for functions with a variable-length list of
341−supplied externally to a SQL statement.
197+homogeneous arguments and at least 1 more argument.
342−`Squeal.PostgreSQL.PQ.manipulateParams`,
343−`Squeal.PostgreSQL.PQ.queryParams` and
344−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
345−separately from the SQL command string, in which case `param`s are used to
346−refer to the out-of-line data values.
348−class KnownNat n => HasParameter
199+type FunctionVar x0 x1 y
349− (n :: Nat)
200+ = forall outer commons grp schemas params from
350− (params :: [NullityType])
352− | n params -> ty where
353− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
355− -- >>> let expr = parameter @1 int4 :: Expression outer grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
201+ . [Expression outer commons grp schemas params from x0]
356− -- >>> printSQL expr
202+ -- ^ inputs
359− :: TypeExpression schemas ty
360− -> Expression outer grp commons schemas params from ty
203+ -> Expression outer commons grp schemas params from x1
361− parameter ty = UnsafeExpression $ parenthesized $
204+ -- ^ must have at least 1 input
362− "$" <> renderNat @n <+> "::"
205+ -> Expression outer commons grp schemas params from y
363− <+> renderSQL ty
206+ -- ^ output
364−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
365−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
366− => HasParameter n (ty' : params) ty
368−-- | `param` takes a `Nat` using type application and for basic types,
208+{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
369−-- infers a `TypeExpression`.
209+greatest(TRUE, NULL, FALSE)
371−-- >>> let expr = param @1 :: Expression outer grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
211+unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
372−-- >>> printSQL expr
212+unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
373−-- ($1 :: int4)
213+ (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
375− :: forall n outer commons schemas params from grp ty
376− . (PGTyped schemas ty, HasParameter n params ty)
377− => Expression outer grp commons schemas params from ty -- ^ param
378−param = parameter @n (pgtype @schemas)
380instance (HasUnique tab (Join outer from) row, Has col row ty)
215instance (HasUnique tab (Join outer from) row, Has col row ty)
381− => IsLabel col (Expression outer 'Ungrouped commons schemas params from ty) where
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
382 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
383instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
218instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
384− => IsLabel col (NP (Expression outer 'Ungrouped commons schemas params from) tys) where
219+ => IsLabel col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
385 fromLabel = fromLabel @col :* Nil
220 fromLabel = fromLabel @col :* Nil
386instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
221instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
387 => IsLabel col
222 => IsLabel col
388− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
389 fromLabel = fromLabel @col `As` Alias
224 fromLabel = fromLabel @col `As` Alias
390instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
225instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
391 => IsLabel col
226 => IsLabel col
392− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
393 fromLabel = fromLabel @col :* Nil
228 fromLabel = fromLabel @col :* Nil
395instance (Has tab (Join outer from) row, Has col row ty)
230instance (Has tab (Join outer from) row, Has col row ty)
396− => IsQualified tab col (Expression outer 'Ungrouped commons schemas params from ty) where
231+ => IsQualified tab col (Expression outer commons 'Ungrouped schemas params from ty) where
397 tab ! col = UnsafeExpression $
232 tab ! col = UnsafeExpression $
398 renderSQL tab <> "." <> renderSQL col
233 renderSQL tab <> "." <> renderSQL col
399instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
234instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
400− => IsQualified tab col (NP (Expression outer 'Ungrouped commons schemas params from) tys) where
235+ => IsQualified tab col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
401 tab ! col = tab ! col :* Nil
236 tab ! col = tab ! col :* Nil
402instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
237instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
403 => IsQualified tab col
238 => IsQualified tab col
404− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
405 tab ! col = tab ! col `As` col
240 tab ! col = tab ! col `As` col
406instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
241instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
407 => IsQualified tab col
242 => IsQualified tab col
408− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
409 tab ! col = tab ! col :* Nil
244 tab ! col = tab ! col :* Nil
@@ -413,7 +248,7 @@ instance
413 , Has col row ty
248 , Has col row ty
414 , GroupedBy tab col bys
249 , GroupedBy tab col bys
415 ) => IsLabel col
250 ) => IsLabel col
416− (Expression outer ('Grouped bys) commons schemas params from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
417 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
419 ( HasUnique tab (Join outer from) row
254 ( HasUnique tab (Join outer from) row
@@ -421,7 +256,7 @@ instance
421 , GroupedBy tab col bys
256 , GroupedBy tab col bys
422 , tys ~ '[ty]
257 , tys ~ '[ty]
423 ) => IsLabel col
258 ) => IsLabel col
424− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
425 fromLabel = fromLabel @col :* Nil
260 fromLabel = fromLabel @col :* Nil
427 ( HasUnique tab (Join outer from) row
262 ( HasUnique tab (Join outer from) row
@@ -429,7 +264,7 @@ instance
429 , GroupedBy tab col bys
264 , GroupedBy tab col bys
430 , column ~ (col ::: ty)
265 , column ~ (col ::: ty)
431 ) => IsLabel col
266 ) => IsLabel col
432− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
433 fromLabel = fromLabel @col `As` Alias
268 fromLabel = fromLabel @col `As` Alias
435 ( HasUnique tab (Join outer from) row
270 ( HasUnique tab (Join outer from) row
@@ -437,7 +272,7 @@ instance
437 , GroupedBy tab col bys
272 , GroupedBy tab col bys
438 , columns ~ '[col ::: ty]
273 , columns ~ '[col ::: ty]
439 ) => IsLabel col
274 ) => IsLabel col
440− (NP (Aliased (Expression outer ('Grouped bys) commons schemas params from)) columns) where
275+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
441 fromLabel = fromLabel @col :* Nil
276 fromLabel = fromLabel @col :* Nil
@@ -445,7 +280,7 @@ instance
445 , Has col row ty
280 , Has col row ty
446 , GroupedBy tab col bys
281 , GroupedBy tab col bys
447 ) => IsQualified tab col
282 ) => IsQualified tab col
448− (Expression outer ('Grouped bys) commons schemas params from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
449 tab ! col = UnsafeExpression $
284 tab ! col = UnsafeExpression $
450 renderSQL tab <> "." <> renderSQL col
285 renderSQL tab <> "." <> renderSQL col
@@ -454,7 +289,7 @@ instance
454 , GroupedBy tab col bys
289 , GroupedBy tab col bys
455 , tys ~ '[ty]
290 , tys ~ '[ty]
456 ) => IsQualified tab col
291 ) => IsQualified tab col
457− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
458 tab ! col = tab ! col :* Nil
293 tab ! col = tab ! col :* Nil
460 ( Has tab (Join outer from) row
295 ( Has tab (Join outer from) row
@@ -462,7 +297,7 @@ instance
462 , GroupedBy tab col bys
297 , GroupedBy tab col bys
463 , column ~ (col ::: ty)
298 , column ~ (col ::: ty)
464 ) => IsQualified tab col
299 ) => IsQualified tab col
465− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
466 tab ! col = tab ! col `As` col
301 tab ! col = tab ! col `As` col
468 ( Has tab (Join outer from) row
303 ( Has tab (Join outer from) row
@@ -470,206 +305,78 @@ instance
470 , GroupedBy tab col bys
305 , GroupedBy tab col bys
471 , columns ~ '[col ::: ty]
306 , columns ~ '[col ::: ty]
472 ) => IsQualified tab col
307 ) => IsQualified tab col
473− (NP (Aliased (Expression outer ('Grouped bys) commons schemas params from)) columns) where
308+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
474 tab ! col = tab ! col :* Nil
309 tab ! col = tab ! col :* Nil
476−-- | analagous to `Nothing`
478−-- >>> printSQL null_
480−null_ :: Expr ('Null ty)
481−null_ = UnsafeExpression "NULL"
483−-- | analagous to `Just`
485−-- >>> printSQL $ notNull true
487−notNull :: 'NotNull ty :--> 'Null ty
488−notNull = UnsafeExpression . renderSQL
490−-- | return the leftmost value which is not NULL
492−-- >>> printSQL $ coalesce [null_, true] false
493−-- COALESCE(NULL, TRUE, FALSE)
494−coalesce :: FunctionHom ('Null ty) ('NotNull ty) ('NotNull ty)
495−coalesce nullxs notNullx = UnsafeExpression $
496− "COALESCE" <> parenthesized (commaSeparated
497− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
499−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
501−-- >>> printSQL $ fromNull true null_
502−-- COALESCE(NULL, TRUE)
504− :: Expression outer grp commons schemas params from ('NotNull ty)
505− -- ^ what to convert @NULL@ to
506− -> Expression outer grp commons schemas params from ('Null ty)
507− -> Expression outer grp commons schemas params from ('NotNull ty)
508−fromNull notNullx nullx = coalesce [nullx] notNullx
510−-- | >>> printSQL $ null_ & isNull
512−isNull :: 'Null ty :--> null 'PGbool
513−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
515−-- | >>> printSQL $ null_ & isNotNull
517−isNotNull :: 'Null ty :--> null 'PGbool
518−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
520−-- | analagous to `maybe` using @IS NULL@
522−-- >>> printSQL $ matchNull true not_ null_
523−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
525− :: Expression outer grp commons schemas params from (nullty)
526− -- ^ what to convert @NULL@ to
527− -> ( Expression outer grp commons schemas params from ('NotNull ty)
528− -> Expression outer grp commons schemas params from (nullty) )
529− -- ^ function to perform when @NULL@ is absent
530− -> Expression outer grp commons schemas params from ('Null ty)
531− -> Expression outer grp commons schemas params from (nullty)
532−matchNull y f x = ifThenElse (isNull x) y
533− (f (UnsafeExpression (renderSQL x)))
535−{-| right inverse to `fromNull`, if its arguments are equal then
536−`nullIf` gives @NULL@.
538−>>> :set -XTypeApplications -XDataKinds
539−>>> let expr = nullIf (false *: param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
541−NULLIF(FALSE, ($1 :: bool))
543−nullIf :: FunctionHet '[ 'NotNull ty, 'NotNull ty] ('Null ty)
544−nullIf = unsafeFunctionHet "NULLIF"
546−-- | >>> printSQL $ array [null_, false, true]
547−-- ARRAY[NULL, FALSE, TRUE]
549− :: [Expression outer grp commons schemas params from ty]
551− -> Expression outer grp commons schemas params from (null ('PGvararray ty))
552−array xs = UnsafeExpression $
553− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
555−-- | >>> printSQL $ cardinality (array [null_, false, true])
556−-- cardinality(ARRAY[NULL, FALSE, TRUE])
557−cardinality :: null ('PGvararray ty) :--> null 'PGint8
558−cardinality = unsafeFunction "cardinality"
560−-- | >>> printSQL $ array [null_, false, true] & index 2
561−-- (ARRAY[NULL, FALSE, TRUE])[2]
563− :: Word64 -- ^ index
564− -> null ('PGvararray ty) :--> NullifyType ty
565−index n expr = UnsafeExpression $
566− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
568instance (KnownSymbol label, label `In` labels) => IsPGlabel label
311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
569− (Expression outer grp commons schemas params from (null ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
570 label = UnsafeExpression $ renderSQL (PGlabel @label)
313 label = UnsafeExpression $ renderSQL (PGlabel @label)
572−-- | A row constructor is an expression that builds a row value
573−-- (also called a composite value) using values for its member fields.
576−-- type Complex = 'PGcomposite
577−-- '[ "real" ::: 'NotNull 'PGfloat8
578−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
581−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
586− => NP (Aliased (Expression outer grp commons schemas params from)) row
587− -- ^ zero or more expressions for the row field values
588− -> Expression outer grp commons schemas params from (null ('PGcomposite row))
589−row exprs = UnsafeExpression $ "ROW" <> parenthesized
590− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
593−-- type Complex = 'PGcomposite
594−-- '[ "real" ::: 'NotNull 'PGfloat8
595−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
596−-- type Schema = '["complex" ::: 'Typedef Complex]
599−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
600−-- >>> printSQL $ i & field #complex #imaginary
601−-- (ROW(0, 1)::"complex")."imaginary"
603− :: ( Has sch schemas schema
604− , Has tydef schema ('Typedef ('PGcomposite row))
606− => QualifiedAlias sch tydef -- ^ row type
607− -> Alias field -- ^ field name
608− -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
609− -> Expression outer grp commons schemas params from ty
610−field td fld expr = UnsafeExpression $
611− parenthesized (renderSQL expr <> "::" <> renderSQL td)
612− <> "." <> renderSQL fld
615− (Expression outer grp commons schemas params from (null ('PGvararray ty))) where
616− (<>) = unsafeBinaryOp "||"
619− (Expression outer grp commons schemas params from (null ('PGvararray ty))) where
623−-- | >>> let expr = greatest [param @1] currentTimestamp :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
625−-- GREATEST(($1 :: timestamp with time zone), CURRENT_TIMESTAMP)
626−greatest :: FunctionHom ty ty ty
627−greatest = unsafeFunctionHom "GREATEST"
629−-- | >>> printSQL $ least [null_] currentTimestamp
630−-- LEAST(NULL, CURRENT_TIMESTAMP)
631−least :: FunctionHom ty ty ty
632−least = unsafeFunctionHom "LEAST"
634-- | >>> printSQL $ unsafeBinaryOp "OR" true false
315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
635-- (TRUE OR FALSE)
316-- (TRUE OR FALSE)
636−unsafeBinaryOp :: ByteString {- ^ operator -} -> Operator ty0 ty1 ty2
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
637unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
638 renderSQL x <+> op <+> renderSQL y
319 renderSQL x <+> op <+> renderSQL y
640−-- | >>> printSQL $ unsafeUnaryOpL "NOT" true
321+binaryOp
641−-- (NOT TRUE)
322+ :: forall op sch schemas schema x y z.
642−unsafeUnaryOpL :: ByteString {- ^ operator -} -> x :--> y
323+ ( Has sch schemas schema
643−unsafeUnaryOpL op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
324+ , Has op schema ('Operator ('BinaryOp x y z)) )
325+ => OperatorDB schemas x y z
326+binaryOp = unsafeBinaryOp $ renderSymbol @op
645−unsafeUnaryOpR :: ByteString {- ^ operator -} -> x :--> y
328+-- | >>> printSQL $ unsafeLeftOp "NOT" true
330+unsafeLeftOp :: ByteString -> x --> y
331+unsafeLeftOp op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
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
340+-- | >>> printSQL $ true & unsafeRightOp "IS NOT TRUE"
341+-- (TRUE IS NOT TRUE)
342+unsafeRightOp :: ByteString -> x --> y
646−unsafeUnaryOpR op x = UnsafeExpression $ parenthesized $ renderSQL x <+> op
343+unsafeRightOp op x = UnsafeExpression $ parenthesized $ renderSQL x <+> op
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
648-- | >>> printSQL $ unsafeFunction "f" true
352-- | >>> printSQL $ unsafeFunction "f" true
649-- f(TRUE)
353-- f(TRUE)
650−unsafeFunction :: ByteString {- ^ function -} -> x :--> y
354+unsafeFunction :: ByteString -> x --> y
651unsafeFunction fun x = UnsafeExpression $
355unsafeFunction fun x = UnsafeExpression $
652 fun <> parenthesized (renderSQL x)
356 fun <> parenthesized (renderSQL x)
654−unsafeFunctionHet
358+function
655− :: SListI xs
359+ :: (Has sch schemas schema, Has fun schema ('Function ('[x] :=> 'Returns y)))
656− => ByteString {- ^ function -}
360+ => QualifiedAlias sch fun
657− -> FunctionHet xs y
361+ -> FunctionDB schemas x y
362+function = unsafeFunction . renderSQL
364+-- | >>> printSQL $ unsafeFunctionN "f" (currentTime :* localTimestamp :* false *: literal 'a')
365+-- f(CURRENT_TIME, LOCALTIMESTAMP, FALSE, E'a')
366+unsafeFunctionN :: SListI xs => ByteString -> xs ---> y
658−unsafeFunctionHet fun xs = UnsafeExpression $
367+unsafeFunctionN fun xs = UnsafeExpression $
659 fun <> parenthesized (renderCommaSeparated renderSQL xs)
368 fun <> parenthesized (renderCommaSeparated renderSQL xs)
661−-- | Helper for defining variadic functions.
370+functionN
662−unsafeVariadicFunction
371+ :: ( Has sch schemas schema
372+ , Has fun schema ('Function (xs :=> 'Returns y))
663− :: SListI elems
373+ , SListI xs )
664− => ByteString
374+ => QualifiedAlias sch fun
665− -- ^ function
375+ -> FunctionNDB schemas xs y
666− -> NP (Expression outer grp commons schemas params from) elems
376+functionN = unsafeFunctionN . renderSQL
667− -> Expression outer grp commons schemas params from ret
668−unsafeVariadicFunction fun x = UnsafeExpression $
669− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderSQL) x)))
671instance ty `In` PGNum
378instance ty `In` PGNum
672− => Num (Expression outer grp commons schemas params from (null ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
673 (+) = unsafeBinaryOp "+"
380 (+) = unsafeBinaryOp "+"
674 (-) = unsafeBinaryOp "-"
381 (-) = unsafeBinaryOp "-"
675 (*) = unsafeBinaryOp "*"
382 (*) = unsafeBinaryOp "*"
@@ -681,7 +388,7 @@ instance ty `In` PGNum
683instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
684− (Expression outer grp commons schemas params from (null ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
685 (/) = unsafeBinaryOp "/"
392 (/) = unsafeBinaryOp "/"
686 fromRational
393 fromRational
687 = UnsafeExpression
394 = UnsafeExpression
@@ -691,7 +398,7 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
691 . fromRat @Double
398 . fromRat @Double
693instance (ty `In` PGNum, ty `In` PGFloating) => Floating
400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
694− (Expression outer grp commons schemas params from (null ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
695 pi = UnsafeExpression "pi()"
402 pi = UnsafeExpression "pi()"
696 exp = unsafeFunction "exp"
403 exp = unsafeFunction "exp"
697 log = unsafeFunction "ln"
404 log = unsafeFunction "ln"
@@ -712,1791 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
712 acosh x = log (x + sqrt (x*x - 1))
419 acosh x = log (x + sqrt (x*x - 1))
713 atanh x = log ((1 + x) / (1 - x)) / 2
420 atanh x = log ((1 + x) / (1 - x)) / 2
715−-- | >>> :{
422+-- | Contained by operators
716−-- let
423+class PGSubset ty where
717−-- expression :: Expr (null 'PGfloat4)
424+ (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
718−-- expression = atan2_ (pi *: 2)
425+ (@>) = unsafeBinaryOp "@>"
719−-- in printSQL expression
426+ (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
720−-- :}
427+ (<@) = unsafeBinaryOp "<@"
721−-- atan2(pi(), 2)
428+instance PGSubset 'PGjsonb
722−atan2_
429+instance PGSubset 'PGtsquery
723− :: float `In` PGFloating
430+instance PGSubset ('PGvararray ty)
724− => FunctionHet '[ null float, null float] (null float)
431+instance PGSubset ('PGrange ty)
725−atan2_ = unsafeFunctionHet "atan2"
727−-- When a `cast` is applied to an `Expression` of a known type, it
728−-- represents a run-time type conversion. The cast will succeed only if a
729−-- suitable type conversion operation has been defined.
731−-- | >>> printSQL $ true & cast int4
734− :: TypeExpression schemas ty1
735− -- ^ type to cast as
736− -> Expression outer grp commons schemas params from ty0
737− -- ^ value to convert
738− -> Expression outer grp commons schemas params from ty1
739−cast ty x = UnsafeExpression $ parenthesized $
740− renderSQL x <+> "::" <+> renderSQL ty
742−-- | integer division, truncates the result
746−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
747−-- expression = 5 `quot_` 2
748−-- in printSQL expression
752− :: int `In` PGIntegral
753− => Operator (null int) (null int) (null int)
754−quot_ = unsafeBinaryOp "/"
756−-- | remainder upon integer division
760−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
761−-- expression = 5 `rem_` 2
762−-- in printSQL expression
766− :: int `In` PGIntegral
767− => Operator (null int) (null int) (null int)
768−rem_ = unsafeBinaryOp "%"
772−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
773−-- expression = trunc pi
774−-- in printSQL expression
777−trunc :: frac `In` PGFloating => null frac :--> null frac
778−trunc = unsafeFunction "trunc"
782−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
783−-- expression = round_ pi
784−-- in printSQL expression
787−round_ :: frac `In` PGFloating => null frac :--> null frac
788−round_ = unsafeFunction "round"
792−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
793−-- expression = ceiling_ pi
794−-- in printSQL expression
797−ceiling_ :: frac `In` PGFloating => null frac :--> null frac
798−ceiling_ = unsafeFunction "ceiling"
800−-- | A `Condition` is an `Expression`, which can evaluate
801−-- to `true`, `false` or `null_`. This is because SQL uses
802−-- a three valued logic.
803−type Condition outer grp commons schemas params from =
804− Expression outer grp commons schemas params from ('Null 'PGbool)
806−-- | >>> printSQL true
808−true :: Expr (null 'PGbool)
809−true = UnsafeExpression "TRUE"
811−-- | >>> printSQL false
813−false :: Expr (null 'PGbool)
814−false = UnsafeExpression "FALSE"
816−-- | >>> printSQL $ not_ true
818−not_ :: null 'PGbool :--> null 'PGbool
819−not_ = unsafeUnaryOpL "NOT"
821−-- | >>> printSQL $ true .&& false
823−(.&&) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
825−(.&&) = unsafeBinaryOp "AND"
827−-- | >>> printSQL $ true .|| false
829−(.||) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
831−(.||) = unsafeBinaryOp "OR"
835−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
836−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
837−-- in printSQL expression
839−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
841− :: [ ( Condition outer grp commons schemas params from
842− , Expression outer grp commons schemas params from ty
844− -- ^ whens and thens
845− -> Expression outer grp commons schemas params from ty
847− -> Expression outer grp commons schemas params from ty
848−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
852− [ " WHEN ", renderSQL when_
853− , " THEN ", renderSQL then_
855− | (when_,then_) <- whenThens
857− , " ELSE ", renderSQL else_
863−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
864−-- expression = ifThenElse true 1 0
865−-- in printSQL expression
867−-- CASE WHEN TRUE THEN 1 ELSE 0 END
869− :: Condition outer grp commons schemas params from
870− -> Expression outer grp commons schemas params from ty -- ^ then
871− -> Expression outer grp commons schemas params from ty -- ^ else
872− -> Expression outer grp commons schemas params from ty
873−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
875−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
876−-- will produce @NULL@s if one of their arguments is @NULL@.
878−-- >>> printSQL $ true .== null_
880−(.==) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
881−(.==) = unsafeBinaryOp "="
884−-- | >>> printSQL $ true ./= null_
886−(./=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
887−(./=) = unsafeBinaryOp "<>"
890−-- | >>> printSQL $ true .>= null_
892−(.>=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
893−(.>=) = unsafeBinaryOp ">="
896−-- | >>> printSQL $ true .< null_
898−(.<) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
899−(.<) = unsafeBinaryOp "<"
902−-- | >>> printSQL $ true .<= null_
904−(.<=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
905−(.<=) = unsafeBinaryOp "<="
908−-- | >>> printSQL $ true .> null_
910−(.>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
911−(.>) = unsafeBinaryOp ">"
915−>>> printSQL $ true `between` (null_, false)
916−TRUE BETWEEN NULL AND FALSE
919− :: Expression outer grp commons schemas params from (null ty)
920− -> ( Expression outer grp commons schemas params from (null ty)
921− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
922− -> Condition outer grp commons schemas params from
923−between a (x,y) = UnsafeExpression $ renderSQL a <+> "BETWEEN"
924− <+> renderSQL x <+> "AND" <+> renderSQL y
927−>>> printSQL $ true `notBetween` (null_, false)
928−TRUE NOT BETWEEN NULL AND FALSE
931− :: Expression outer grp commons schemas params from (null ty)
932− -> ( Expression outer grp commons schemas params from (null ty)
933− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
934− -> Condition outer grp commons schemas params from
935−notBetween a (x,y) = UnsafeExpression $ renderSQL a <+> "NOT BETWEEN"
936− <+> renderSQL x <+> "AND" <+> renderSQL y
938−{- | between, after sorting the comparison values
939−>>> printSQL $ true `betweenSymmetric` (null_, false)
940−TRUE BETWEEN SYMMETRIC NULL AND FALSE
943− :: Expression outer grp commons schemas params from (null ty)
944− -> ( Expression outer grp commons schemas params from (null ty)
945− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
946− -> Condition outer grp commons schemas params from
947−betweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
948− <+> "BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
950−{- | not between, after sorting the comparison values
951−>>> printSQL $ true `notBetweenSymmetric` (null_, false)
952−TRUE NOT BETWEEN SYMMETRIC NULL AND FALSE
955− :: Expression outer grp commons schemas params from (null ty)
956− -> ( Expression outer grp commons schemas params from (null ty)
957− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
958− -> Condition outer grp commons schemas params from
959−notBetweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
960− <+> "NOT BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
962−{- | not equal, treating null like an ordinary value
963−>>> printSQL $ true `isDistinctFrom` null_
964−(TRUE IS DISTINCT FROM NULL)
966−isDistinctFrom :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
967−isDistinctFrom = unsafeBinaryOp "IS DISTINCT FROM"
969−{- | equal, treating null like an ordinary value
970−>>> printSQL $ true `isNotDistinctFrom` null_
971−(TRUE IS NOT DISTINCT FROM NULL)
973−isNotDistinctFrom :: Operator (null0 ty) (null1 ty) ('NotNull 'PGbool)
974−isNotDistinctFrom = unsafeBinaryOp "IS NOT DISTINCT FROM"
977−>>> printSQL $ true & isTrue
980−isTrue :: null0 'PGbool :--> null1 'PGbool
981−isTrue = unsafeUnaryOpR "IS TRUE"
983−{- | is false or unknown
984−>>> printSQL $ true & isNotTrue
987−isNotTrue :: null0 'PGbool :--> null1 'PGbool
988−isNotTrue = unsafeUnaryOpR "IS NOT TRUE"
991−>>> printSQL $ true & isFalse
994−isFalse :: null0 'PGbool :--> null1 'PGbool
995−isFalse = unsafeUnaryOpR "IS FALSE"
997−{- | is true or unknown
998−>>> printSQL $ true & isNotFalse
1001−isNotFalse :: null0 'PGbool :--> null1 'PGbool
1002−isNotFalse = unsafeUnaryOpR "IS NOT FALSE"
1005−>>> printSQL $ true & isUnknown
1008−isUnknown :: null0 'PGbool :--> null1 'PGbool
1009−isUnknown = unsafeUnaryOpR "IS UNKNOWN"
1011−{- | is true or false
1012−>>> printSQL $ true & isNotUnknown
1013−(TRUE IS NOT UNKNOWN)
1015−isNotUnknown :: null0 'PGbool :--> null1 'PGbool
1016−isNotUnknown = unsafeUnaryOpR "IS NOT UNKNOWN"
1018−-- | >>> printSQL currentDate
1020−currentDate :: Expr (null 'PGdate)
1021−currentDate = UnsafeExpression "CURRENT_DATE"
1023−-- | >>> printSQL currentTime
1025−currentTime :: Expr (null 'PGtimetz)
1026−currentTime = UnsafeExpression "CURRENT_TIME"
1028−-- | >>> printSQL currentTimestamp
1029−-- CURRENT_TIMESTAMP
1030−currentTimestamp :: Expr (null 'PGtimestamptz)
1031−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
1033−-- | >>> printSQL localTime
1035−localTime :: Expr (null 'PGtime)
1036−localTime = UnsafeExpression "LOCALTIME"
1038−-- | >>> printSQL localTimestamp
1040−localTimestamp :: Expr (null 'PGtimestamp)
1041−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
1043−{-----------------------------------------
1045−-----------------------------------------}
1047−escape :: Char -> String
433+class PGIntersect ty where
1048−escape = \case
434+ (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
1049− '\NUL' -> "\\0"
435+ (@&&) = unsafeBinaryOp "&&"
1050− '\'' -> "''"
436+instance PGIntersect ('PGvararray ty)
1051− '"' -> "\\\""
437+instance PGIntersect ('PGrange ty)
1059instance IsString
439instance IsString
1060− (Expression outer grp commons schemas params from (null 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1061 fromString str = UnsafeExpression $
441 fromString str = UnsafeExpression $
1062 "E\'" <> fromString (escape =<< str) <> "\'"
442 "E\'" <> fromString (escape =<< str) <> "\'"
1063instance IsString
443instance IsString
1064− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1065− fromString str = cast tsvector . UnsafeExpression $
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
1066 "E\'" <> fromString (escape =<< str) <> "\'"
446 "E\'" <> fromString (escape =<< str) <> "\'"
1067instance IsString
447instance IsString
1068− (Expression outer grp commons schemas params from (null 'PGtsquery)) where
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
1069− fromString str = cast tsquery . UnsafeExpression $
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
1070 "E\'" <> fromString (escape =<< str) <> "\'"
450 "E\'" <> fromString (escape =<< str) <> "\'"
1072instance Semigroup
452instance Semigroup
453+ (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
454+ (<>) = unsafeBinaryOp "||"
456+ (Expression outer commons grp schemas params from (null 'PGjsonb)) where
457+ (<>) = unsafeBinaryOp "||"
1073− (Expression outer grp commons schemas params from (null 'PGtext)) where
459+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1074 (<>) = unsafeBinaryOp "||"
460 (<>) = unsafeBinaryOp "||"
1075instance Semigroup
461instance Semigroup
1076− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
462+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1077 (<>) = unsafeBinaryOp "||"
463 (<>) = unsafeBinaryOp "||"
1079instance Monoid
465instance Monoid
1080− (Expression outer grp commons schemas params from (null 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1081 mempty = fromString ""
467 mempty = fromString ""
1082 mappend = (<>)
468 mappend = (<>)
1083instance Monoid
469instance Monoid
1084− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1085 mempty = fromString ""
471 mempty = fromString ""
1086 mappend = (<>)
472 mappend = (<>)
1088−-- | >>> printSQL $ lower "ARRRGGG"
1089−-- lower(E'ARRRGGG')
1090−lower :: null 'PGtext :--> null 'PGtext
1091−lower = unsafeFunction "lower"
1093−-- | >>> printSQL $ upper "eeee"
1095−upper :: null 'PGtext :--> null 'PGtext
1096−upper = unsafeFunction "upper"
1098−-- | >>> printSQL $ charLength "four"
1099−-- char_length(E'four')
1100−charLength :: null 'PGtext :--> null 'PGint4
1101−charLength = unsafeFunction "char_length"
1103−-- | The `like` expression returns true if the @string@ matches
1104−-- the supplied @pattern@. If @pattern@ does not contain percent signs
1105−-- or underscores, then the pattern only represents the string itself;
1106−-- in that case `like` acts like the equals operator. An underscore (_)
1107−-- in pattern stands for (matches) any single character; a percent sign (%)
1108−-- matches any sequence of zero or more characters.
1110−-- >>> printSQL $ "abc" `like` "a%"
1111−-- (E'abc' LIKE E'a%')
1112−like :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1113−like = unsafeBinaryOp "LIKE"
1115−-- | The key word ILIKE can be used instead of LIKE to make the
1116−-- match case-insensitive according to the active locale.
1118−-- >>> printSQL $ "abc" `ilike` "a%"
1119−-- (E'abc' ILIKE E'a%')
1120−ilike :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1121−ilike = unsafeBinaryOp "ILIKE"
1123−{-----------------------------------------
1124− -- json and jsonb support
1126−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1127−comments lifted directly from this page.
1129−Table 9.44: json and jsonb operators
1130−-----------------------------------------}
1132−-- | Get JSON value (object field or array element) at a key.
1134− :: (json `In` PGJsonType, key `In` PGJsonKey)
1135− => Operator (null json) (null key) ('Null json)
1137−(.->) = unsafeBinaryOp "->"
1139−-- | Get JSON value (object field or array element) at a key, as text.
1141− :: (json `In` PGJsonType, key `In` PGJsonKey)
1142− => Operator (null json) (null key) ('Null 'PGtext)
1144−(.->>) = unsafeBinaryOp "->>"
1146−-- | Get JSON value at a specified path.
1148− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1149− => Operator (null json) (null path) ('Null json)
1151−(.#>) = unsafeBinaryOp "#>"
1153−-- | Get JSON value at a specified path as text.
1155− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1156− => Operator (null json) (null path) ('Null 'PGtext)
1158−(.#>>) = unsafeBinaryOp "#>>"
1160−-- Additional jsonb operators
1162−class PGSubset container where
1163− (@>) :: Operator (null0 container) (null1 container) ('Null 'PGbool)
1164− (@>) = unsafeBinaryOp "@>"
1165− (<@) :: Operator (null0 container) (null1 container) ('Null 'PGbool)
1166− (<@) = unsafeBinaryOp "<@"
1167−instance PGSubset 'PGjsonb
1168−instance PGSubset 'PGtsquery
1169−instance PGSubset ('PGvararray ty)
1171−-- | Does the string exist as a top-level key within the JSON value?
1172−(.?) :: Operator (null 'PGjsonb) (null 'PGtext) ('Null 'PGbool)
1174−(.?) = unsafeBinaryOp "?"
1176−-- | Do any of these array strings exist as top-level keys?
1179− (null ('PGvararray ('NotNull 'PGtext)))
1182−(.?|) = unsafeBinaryOp "?|"
1184−-- | Do all of these array strings exist as top-level keys?
1187− (null ('PGvararray ('NotNull 'PGtext)))
1190−(.?&) = unsafeBinaryOp "?&"
1192−-- | Concatenate two jsonb values into a new jsonb value.
1194− (Expression outer grp commons schemas params from (null 'PGjsonb)) where
1195− (<>) = unsafeBinaryOp "||"
1197−-- | Delete a key or keys from a JSON object, or remove an array element.
1199−-- If the right operand is..
1201−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1202−-- are matched based on their key value.
1204−-- @ text[] @: Delete multiple key/value pairs or string elements
1205−-- from left operand. Key/value pairs are matched based on their key value.
1207−-- @ integer @: Delete the array element with specified index (Negative integers
1208−-- count from the end). Throws an error if top level container is not an array.
1210− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1211− => Operator (null 'PGjsonb) (null key) (null 'PGjsonb)
1213−(.-.) = unsafeBinaryOp "-"
1215−-- | Delete the field or element with specified path (for JSON arrays, negative
1216−-- integers count from the end)
1218− :: PGTextArray "(#-.)" arrayty
1219− => Operator (null 'PGjsonb) (null arrayty)(null 'PGjsonb)
1221−(#-.) = unsafeBinaryOp "#-"
1223−{-----------------------------------------
1224−Table 9.45: JSON creation functions
1225−-----------------------------------------}
1227−-- | Literal binary JSON
1228−jsonbLit :: JSON.ToJSON x => x -> Expr (null 'PGjsonb)
1229−jsonbLit = cast jsonb . UnsafeExpression
1230− . singleQuotedUtf8 . toStrict . JSON.encode
1233−jsonLit :: JSON.ToJSON x => x -> Expr (null 'PGjson)
1234−jsonLit = cast json . UnsafeExpression
1235− . singleQuotedUtf8 . toStrict . JSON.encode
1237−-- | Returns the value as json. Arrays and composites are converted
1238−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1239−-- type to json, the cast function will be used to perform the conversion;
1240−-- otherwise, a scalar value is produced. For any scalar type other than a
1241−-- number, a Boolean, or a null value, the text representation will be used, in
1242−-- such a fashion that it is a valid json value.
1243−toJson :: null ty :--> null 'PGjson
1244−toJson = unsafeFunction "to_json"
1246−-- | Returns the value as jsonb. Arrays and composites are converted
1247−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1248−-- type to json, the cast function will be used to perform the conversion;
1249−-- otherwise, a scalar value is produced. For any scalar type other than a
1250−-- number, a Boolean, or a null value, the text representation will be used, in
1251−-- such a fashion that it is a valid jsonb value.
1252−toJsonb :: null ty :--> null 'PGjsonb
1253−toJsonb = unsafeFunction "to_jsonb"
1255−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1256−-- becomes a JSON array of arrays.
1258− :: PGArray "arrayToJson" arr
1259− => null arr :--> null 'PGjson
1260−arrayToJson = unsafeFunction "array_to_json"
1262−-- | Returns the row as a JSON object.
1263−rowToJson :: null ('PGcomposite ty) :--> null 'PGjson
1264−rowToJson = unsafeFunction "row_to_json"
1266−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1270− => NP (Expression outer grp commons schemas params from) elems
1271− -> Expression outer grp commons schemas params from (null 'PGjson)
1272−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1274−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1275−-- variadic argument list.
1278− => NP (Expression outer grp commons schemas params from) elems
1279− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1280−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1283− :: SOP.SListI elems
1284− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1287− (`appEndo` []) . hcfoldMap (Proxy :: SOP.Proxy SOP.Top)
1288− (\(col `As` name) -> Endo $ \xs ->
1289− renderAliasString name : renderSQL col : xs)
1291− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1292− renderAliasString = singleQuotedText . fromString . symbolVal
1294−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1295−-- argument list. The elements of the argument list must alternate between text
1298− :: SOP.SListI elems
1299− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1300− -> Expression outer grp commons schemas params from (null 'PGjson)
1302− = unsafeFunction "json_build_object"
1305− . unsafeRowFunction
1307−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1308−-- variadic argument list. The elements of the argument list must alternate
1309−-- between text and values.
1311− :: SOP.SListI elems
1312− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1313− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1315− = unsafeFunction "jsonb_build_object"
1318− . unsafeRowFunction
1320−-- | Builds a JSON object out of a text array. The array must have either
1321−-- exactly one dimension with an even number of members, in which case they are
1322−-- taken as alternating key/value pairs, or two dimensions such that each inner
1323−-- array has exactly two elements, which are taken as a key/value pair.
1325− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1326− => null arr :--> null 'PGjson
1327−jsonObject = unsafeFunction "json_object"
1329−-- | Builds a binary JSON object out of a text array. The array must have either
1330−-- exactly one dimension with an even number of members, in which case they are
1331−-- taken as alternating key/value pairs, or two dimensions such that each inner
1332−-- array has exactly two elements, which are taken as a key/value pair.
1334− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1335− => null arr :--> null 'PGjsonb
1336−jsonbObject = unsafeFunction "jsonb_object"
1338−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1339−-- keys and one for values, that are zipped pairwise to create a JSON object.
1341− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1342− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1343− => Expression outer grp commons schemas params from (null keysArray)
1344− -> Expression outer grp commons schemas params from (null valuesArray)
1345− -> Expression outer grp commons schemas params from (null 'PGjson)
1346−jsonZipObject ks vs =
1347− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1349−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1350−-- keys and one for values, that are zipped pairwise to create a binary JSON
1353− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1354− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1355− => Expression outer grp commons schemas params from (null keysArray)
1356− -> Expression outer grp commons schemas params from (null valuesArray)
1357− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1358−jsonbZipObject ks vs =
1359− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1361−{-----------------------------------------
1362−Table 9.46: JSON processing functions
1363−-----------------------------------------}
1365−-- | Returns the number of elements in the outermost JSON array.
1366−jsonArrayLength :: null 'PGjson :--> null 'PGint4
1367−jsonArrayLength = unsafeFunction "json_array_length"
1369−-- | Returns the number of elements in the outermost binary JSON array.
1370−jsonbArrayLength :: null 'PGjsonb :--> null 'PGint4
1371−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1373−-- | Returns JSON value pointed to by the given path (equivalent to #>
1377− => Expression outer grp commons schemas params from (null 'PGjson)
1378− -> NP (Expression outer grp commons schemas params from) elems
1379− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1380−jsonExtractPath x xs =
1381− unsafeVariadicFunction "json_extract_path" (x :* xs)
1383−-- | Returns JSON value pointed to by the given path (equivalent to #>
1387− => Expression outer grp commons schemas params from (null 'PGjsonb)
1388− -> NP (Expression outer grp commons schemas params from) elems
1389− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1390−jsonbExtractPath x xs =
1391− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1393−-- | Returns JSON value pointed to by the given path (equivalent to #>
1394−-- operator), as text.
1395−jsonExtractPathAsText
1397− => Expression outer grp commons schemas params from (null 'PGjson)
1398− -> NP (Expression outer grp commons schemas params from) elems
1399− -> Expression outer grp commons schemas params from (null 'PGjson)
1400−jsonExtractPathAsText x xs =
1401− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1403−-- | Returns JSON value pointed to by the given path (equivalent to #>
1404−-- operator), as text.
1405−jsonbExtractPathAsText
1407− => Expression outer grp commons schemas params from (null 'PGjsonb)
1408− -> NP (Expression outer grp commons schemas params from) elems
1409− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1410−jsonbExtractPathAsText x xs =
1411− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1413−-- | Returns the type of the outermost JSON value as a text string. Possible
1414−-- types are object, array, string, number, boolean, and null.
1415−jsonTypeof :: null 'PGjson :--> null 'PGtext
1416−jsonTypeof = unsafeFunction "json_typeof"
1418−-- | Returns the type of the outermost binary JSON value as a text string.
1419−-- Possible types are object, array, string, number, boolean, and null.
1420−jsonbTypeof :: null 'PGjsonb :--> null 'PGtext
1421−jsonbTypeof = unsafeFunction "jsonb_typeof"
1423−-- | Returns its argument with all object fields that have null values omitted.
1424−-- Other null values are untouched.
1425−jsonStripNulls :: null 'PGjson :--> null 'PGjson
1426−jsonStripNulls = unsafeFunction "json_strip_nulls"
1428−-- | Returns its argument with all object fields that have null values omitted.
1429−-- Other null values are untouched.
1430−jsonbStripNulls :: null 'PGjsonb :--> null 'PGjsonb
1431−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1433−-- | @ jsonbSet target path new_value create_missing @
1435−-- Returns target with the section designated by path replaced by new_value,
1436−-- or with new_value added if create_missing is true ( default is true) and the
1437−-- item designated by path does not exist. As with the path orientated
1438−-- operators, negative integers that appear in path count from the end of JSON
1441− :: PGTextArray "jsonbSet" arr
1442− => Expression outer grp commons schemas params from (null 'PGjsonb)
1443− -> Expression outer grp commons schemas params from (null arr)
1444− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1445− -> Maybe (Expression outer grp commons schemas params from (null 'PGbool))
1446− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1447−jsonbSet tgt path val createMissing = case createMissing of
1448− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1449− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1451−-- | @ jsonbInsert target path new_value insert_after @
1453−-- Returns target with new_value inserted. If target section designated by
1454−-- path is in a JSONB array, new_value will be inserted before target or after
1455−-- if insert_after is true (default is false). If target section designated by
1456−-- path is in JSONB object, new_value will be inserted only if target does not
1457−-- exist. As with the path orientated operators, negative integers that appear
1458−-- in path count from the end of JSON arrays.
1460− :: PGTextArray "jsonbInsert" arr
1461− => Expression outer grp commons schemas params from (null 'PGjsonb)
1462− -> Expression outer grp commons schemas params from (null arr)
1463− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1464− -> Maybe (Expression outer grp commons schemas params from (null 'PGbool))
1465− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1466−jsonbInsert tgt path val insertAfter = case insertAfter of
1467− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1468− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1470−-- | Returns its argument as indented JSON text.
1471−jsonbPretty :: null 'PGjsonb :--> null 'PGtext
1472−jsonbPretty = unsafeFunction "jsonb_pretty"
1474−(@@) :: Operator (null 'PGtsvector) (null 'PGtsquery) ('Null 'PGbool)
1475−(@@) = unsafeBinaryOp "@@"
1477−(.&) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1478−(.&) = unsafeBinaryOp "&&"
1480−(.|) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1481−(.|) = unsafeBinaryOp "||"
1483−(.!) :: null 'PGtsquery :--> null 'PGtsquery
1484−(.!) = unsafeUnaryOpL "!!"
1486−(<->) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1487−(<->) = unsafeBinaryOp "<->"
1490− :: null ('PGvararray ('NotNull 'PGtext))
1491− :--> null 'PGtsvector
1492−arrayToTSvector = unsafeFunction "array_to_tsvector"
1494−tsvectorLength :: null 'PGtsvector :--> null 'PGint4
1495−tsvectorLength = unsafeFunction "length"
1497−numnode :: null 'PGtsquery :--> null 'PGint4
1498−numnode = unsafeFunction "numnode"
1500−plainToTSquery :: null 'PGtext :--> null 'PGtsquery
1501−plainToTSquery = unsafeFunction "plainto_tsquery"
1503−phraseToTSquery :: null 'PGtext :--> null 'PGtsquery
1504−phraseToTSquery = unsafeFunction "phraseto_tsquery"
1506−websearchToTSquery :: null 'PGtext :--> null 'PGtsquery
1507−websearchToTSquery = unsafeFunction "websearch_to_tsquery"
1509−queryTree :: null 'PGtsquery :--> null 'PGtext
1510−queryTree = unsafeFunction "query_tree"
1512−toTSquery :: null 'PGtext :--> null 'PGtsquery
1513−toTSquery = unsafeFunction "to_tsquery"
1516− :: ty `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1517− => null ty :--> null 'PGtsquery
1518−toTSvector = unsafeFunction "to_tsvector"
1521− :: FunctionHet '[null 'PGtsvector, null ('PGchar 1)] (null 'PGtsvector)
1522−setWeight = unsafeFunctionHet "set_weight"
1524−litChar :: Char -> Expr (null ('PGchar 1))
1525−litChar chr = UnsafeExpression $
1526− "E\'" <> fromString (escape =<< [chr]) <> "\'"
1528−strip :: null 'PGtsvector :--> null 'PGtsvector
1529−strip = unsafeFunction "strip"
1531−jsonToTSvector :: FunctionHet '[null 'PGjson, null 'PGjson] (null 'PGtsvector)
1532−jsonToTSvector = unsafeFunctionHet "json_to_tsvector"
1534−jsonbToTSvector :: FunctionHet '[null 'PGjsonb, null 'PGjsonb] (null 'PGtsvector)
1535−jsonbToTSvector = unsafeFunctionHet "jsonb_to_tsvector"
1537−tsDelete :: FunctionHet
1538− '[null 'PGtsvector, null ('PGvararray ('NotNull 'PGtext))]
1540−tsDelete = unsafeFunctionHet "ts_delete"
1542−tsFilter :: FunctionHet
1543− '[null 'PGtsvector, null ('PGvararray ('NotNull ('PGchar 1)))]
1545−tsFilter = unsafeFunctionHet "ts_filter"
1548− :: document `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1549− => FunctionHet '[null document, null 'PGtsquery] (null 'PGtext)
1550−tsHeadline = unsafeFunctionHet "ts_headline"
1551−{-----------------------------------------
1553−-----------------------------------------}
1556−`Aggregate` functions compute a single result from a set of input values.
1557−`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1558−as `WindowFunction`s.
1560−class Aggregate expr1 expr2 aggr
1561− | aggr -> expr1, aggr -> expr2 where
1563− -- | A special aggregation that does not require an input
1567− -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1568− -- expression = countStar
1569− -- in printSQL expression
1572− countStar :: aggr ('NotNull 'PGint8)
1576− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null ty]] ('NotNull 'PGint8)
1577− -- expression = count (All #col)
1578− -- in printSQL expression
1580− -- count(ALL "col")
1584− -> aggr ('NotNull 'PGint8)
1588− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('NotNull 'PGnumeric)
1589− -- expression = sum_ (Distinct #col)
1590− -- in printSQL expression
1592− -- sum(DISTINCT "col")
1596− -> aggr ('NotNull ty)
1598− -- | input values, including nulls, concatenated into an array
1601− -> aggr ('Null ('PGvararray ty))
1603− -- | aggregates values as a JSON array
1606− -> aggr ('Null 'PGjson)
1608− -- | aggregates values as a JSON array
1611− -> aggr ('Null 'PGjsonb)
1614− the bitwise AND of all non-null input values, or null if none
1617− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1618− expression = bitAnd (Distinct #col)
1619− in printSQL expression
1621− bit_and(DISTINCT "col")
1624− :: int `In` PGIntegral
1625− => expr1 (null int)
1626− -- ^ what to aggregate
1627− -> aggr ('Null int)
1630− the bitwise OR of all non-null input values, or null if none
1634− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1635− expression = bitOr (All #col)
1636− in printSQL expression
1641− :: int `In` PGIntegral
1642− => expr1 (null int)
1643− -- ^ what to aggregate
1644− -> aggr ('Null int)
1647− true if all input values are true, otherwise false
1651− winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1652− winFun = boolAnd #col
1658− :: expr1 (null 'PGbool)
1659− -- ^ what to aggregate
1660− -> aggr ('Null 'PGbool)
1663− true if at least one input value is true, otherwise false
1667− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1668− expression = boolOr (All #col)
1669− in printSQL expression
1674− :: expr1(null 'PGbool)
1675− -- ^ what to aggregate
1676− -> aggr ('Null 'PGbool)
1679− equivalent to `boolAnd`
1683− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1684− expression = every (Distinct #col)
1685− in printSQL expression
1687− every(DISTINCT "col")
1690− :: expr1 (null 'PGbool)
1691− -- ^ what to aggregate
1692− -> aggr ('Null 'PGbool)
1694− {- |maximum value of expression across all input values-}
1697− -- ^ what to maximize
1700− -- | minimum value of expression across all input values
1703− -- ^ what to minimize
1706− -- | the average (arithmetic mean) of all input values
1709− -- ^ what to average
1710− -> aggr ('Null (PGAvg ty))
1712− {- | correlation coefficient
1715− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1716− expression = corr (All (#y :*: #x))
1717− in printSQL expression
1722− :: expr2 (null 'PGfloat8)
1723− -> aggr ('Null 'PGfloat8)
1725− {- | population covariance
1728− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1729− expression = covarPop (All (#y :*: #x))
1730− in printSQL expression
1732− covar_pop(ALL "y", "x")
1735− :: expr2 (null 'PGfloat8)
1736− -> aggr ('Null 'PGfloat8)
1738− {- | sample covariance
1741− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1742− winFun = covarSamp (#y :*: #x)
1745− covar_samp("y", "x")
1748− :: expr2 (null 'PGfloat8)
1749− -> aggr ('Null 'PGfloat8)
1751− {- | average of the independent variable (sum(X)/N)
1754− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1755− expression = regrAvgX (All (#y :*: #x))
1756− in printSQL expression
1758− regr_avgx(ALL "y", "x")
1761− :: expr2 (null 'PGfloat8)
1762− -> aggr ('Null 'PGfloat8)
1764− {- | average of the dependent variable (sum(Y)/N)
1767− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1768− winFun = regrAvgY (#y :*: #x)
1771− regr_avgy("y", "x")
1774− :: expr2 (null 'PGfloat8)
1775− -> aggr ('Null 'PGfloat8)
1777− {- | number of input rows in which both expressions are nonnull
1780− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGint8)
1781− winFun = regrCount (#y :*: #x)
1784− regr_count("y", "x")
1787− :: expr2 (null 'PGfloat8)
1788− -> aggr ('Null 'PGint8)
1790− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1793− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1794− expression = regrIntercept (All (#y :*: #x))
1795− in printSQL expression
1797− regr_intercept(ALL "y", "x")
1800− :: expr2 (null 'PGfloat8)
1801− -> aggr ('Null 'PGfloat8)
1803− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1805− :: expr2 (null 'PGfloat8)
1806− -> aggr ('Null 'PGfloat8)
1808− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1809− -- determined by the (X, Y) pairs
1811− :: expr2 (null 'PGfloat8)
1812− -> aggr ('Null 'PGfloat8)
1814− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1815− -- (“sum of squares” of the independent variable)
1817− :: expr2 (null 'PGfloat8)
1818− -> aggr ('Null 'PGfloat8)
1820− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1821− -- (“sum of products” of independent times dependent variable)
1823− :: expr2 (null 'PGfloat8)
1824− -> aggr ('Null 'PGfloat8)
1826− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1827− -- (“sum of squares” of the dependent variable)
1829− :: expr2 (null 'PGfloat8)
1830− -> aggr ('Null 'PGfloat8)
1832− -- | historical alias for `stddevSamp`
1835− -> aggr ('Null (PGAvg ty))
1837− -- | population standard deviation of the input values
1840− -> aggr ('Null (PGAvg ty))
1842− -- | sample standard deviation of the input values
1845− -> aggr ('Null (PGAvg ty))
1847− -- | historical alias for `varSamp`
1850− -> aggr ('Null (PGAvg ty))
1852− -- | population variance of the input values
1853− -- (square of the population standard deviation)
1856− -> aggr ('Null (PGAvg ty))
1858− -- | sample variance of the input values
1859− -- (square of the sample standard deviation)
1862− -> aggr ('Null (PGAvg ty))
1865−`Distinction`s are used for the input of `Aggregate` `Expression`s.
1866−`All` invokes the aggregate once for each input row.
1867−`Distinct` invokes the aggregate once for each distinct value of the expression
1868−(or distinct set of values, for multiple expressions) found in the input
1870−data Distinction expr ty
1872− | Distinct (expr ty)
1873− deriving (GHC.Generic,Show,Eq,Ord)
1874−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1875−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1877− All x -> "ALL" <+> renderSQL x
1878− Distinct x -> "DISTINCT" <+> renderSQL x
1881− ( Expression outer grp commons schemas params from
1883− Expression outer grp commons schemas params from) xty ) where
1886− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1887− Distinct (x :*: x') ->
1888− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1891− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1892− (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1893− (Expression outer ('Grouped bys) commons schemas params from) where
1894− countStar = UnsafeExpression "count(*)"
1895− count = unsafeAggregate1 "count"
1896− sum_ = unsafeAggregate1 "sum"
1897− arrayAgg = unsafeAggregate1 "array_agg"
1898− jsonAgg = unsafeAggregate1 "json_agg"
1899− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1900− bitAnd = unsafeAggregate1 "bit_and"
1901− bitOr = unsafeAggregate1 "bit_or"
1902− boolAnd = unsafeAggregate1 "bool_and"
1903− boolOr = unsafeAggregate1 "bool_or"
1904− every = unsafeAggregate1 "every"
1905− max_ = unsafeAggregate1 "max"
1906− min_ = unsafeAggregate1 "min"
1907− avg = unsafeAggregate1 "avg"
1908− corr = unsafeAggregate2 "corr"
1909− covarPop = unsafeAggregate2 "covar_pop"
1910− covarSamp = unsafeAggregate2 "covar_samp"
1911− regrAvgX = unsafeAggregate2 "regr_avgx"
1912− regrAvgY = unsafeAggregate2 "regr_avgy"
1913− regrCount = unsafeAggregate2 "regr_count"
1914− regrIntercept = unsafeAggregate2 "regr_intercept"
1915− regrR2 = unsafeAggregate2 "regr_r2"
1916− regrSlope = unsafeAggregate2 "regr_slope"
1917− regrSxx = unsafeAggregate2 "regr_sxx"
1918− regrSxy = unsafeAggregate2 "regr_sxy"
1919− regrSyy = unsafeAggregate2 "regr_syy"
1920− stddev = unsafeAggregate1 "stddev"
1921− stddevPop = unsafeAggregate1 "stddev_pop"
1922− stddevSamp = unsafeAggregate1 "stddev_samp"
1923− variance = unsafeAggregate1 "variance"
1924− varPop = unsafeAggregate1 "var_pop"
1925− varSamp = unsafeAggregate1 "var_samp"
1927− (Expression outer grp commons schemas params from)
1928− (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1929− (WindowFunction outer grp commons schemas params from) where
1930− countStar = UnsafeWindowFunction "count(*)"
1931− count = unsafeWindowFunction1 "count"
1932− sum_ = unsafeWindowFunction1 "sum"
1933− arrayAgg = unsafeWindowFunction1 "array_agg"
1934− jsonAgg = unsafeWindowFunction1 "json_agg"
1935− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1936− bitAnd = unsafeWindowFunction1 "bit_and"
1937− bitOr = unsafeWindowFunction1 "bit_or"
1938− boolAnd = unsafeWindowFunction1 "bool_and"
1939− boolOr = unsafeWindowFunction1 "bool_or"
1940− every = unsafeWindowFunction1 "every"
1941− max_ = unsafeWindowFunction1 "max"
1942− min_ = unsafeWindowFunction1 "min"
1943− avg = unsafeWindowFunction1 "avg"
1944− corr = unsafeWindowFunction2 "corr"
1945− covarPop = unsafeWindowFunction2 "covar_pop"
1946− covarSamp = unsafeWindowFunction2 "covar_samp"
1947− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1948− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1949− regrCount = unsafeWindowFunction2 "regr_count"
1950− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1951− regrR2 = unsafeWindowFunction2 "regr_r2"
1952− regrSlope = unsafeWindowFunction2 "regr_slope"
1953− regrSxx = unsafeWindowFunction2 "regr_sxx"
1954− regrSxy = unsafeWindowFunction2 "regr_sxy"
1955− regrSyy = unsafeWindowFunction2 "regr_syy"
1956− stddev = unsafeWindowFunction1 "stddev"
1957− stddevPop = unsafeWindowFunction1 "stddev_pop"
1958− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1959− variance = unsafeWindowFunction1 "variance"
1960− varPop = unsafeWindowFunction1 "var_pop"
1961− varSamp = unsafeWindowFunction1 "var_samp"
1963−-- | escape hatch to define aggregate functions
1965− :: ByteString -- ^ aggregate function
1966− -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1967− -> Expression outer ('Grouped bys) commons schemas params from yty
1968−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1969− [fun, "(", renderSQL x, ")"]
1971−-- | escape hatch to define aggregate binary functions
1973− :: ByteString -- ^ aggregate function
1974− -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1975− -> Expression outer ('Grouped bys) commons schemas params from yty
1976−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1977− [fun, "(", renderSQL xx, ")"]
1979−-- | A type family that calculates `PGAvg` type of a `PGType`.
1980−type family PGAvg ty where
1981− PGAvg 'PGint2 = 'PGnumeric
1982− PGAvg 'PGint4 = 'PGnumeric
1983− PGAvg 'PGint8 = 'PGnumeric
1984− PGAvg 'PGnumeric = 'PGnumeric
1985− PGAvg 'PGfloat4 = 'PGfloat8
1986− PGAvg 'PGfloat8 = 'PGfloat8
1987− PGAvg 'PGinterval = 'PGinterval
1988− PGAvg pg = TypeError
1989− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1991−{-----------------------------------------
1993−-----------------------------------------}
1995−-- | `TypeExpression`s are used in `cast`s and
1996−-- `Squeal.PostgreSQL.Definition.createTable` commands.
1997−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1998− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1999− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2000−instance RenderSQL (TypeExpression schemas ty) where
2001− renderSQL = renderTypeExpression
2003−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
2005− :: (Has sch schemas schema, Has td schema ('Typedef ty))
2006− => QualifiedAlias sch td
2007− -> TypeExpression schemas (null ty)
2008−typedef = UnsafeTypeExpression . renderSQL
2010−-- | The composite type corresponding to a `Table` definition can be expressed
2013− :: (Has sch schemas schema, Has tab schema ('Table table))
2014− => QualifiedAlias sch tab
2015− -> TypeExpression schemas (null ('PGcomposite (TableToRow table)))
2016−typetable = UnsafeTypeExpression . renderSQL
2018−-- | The composite type corresponding to a `View` definition can be expressed
2021− :: (Has sch schemas schema, Has vw schema ('View view))
2022− => QualifiedAlias sch vw
2023− -> TypeExpression schemas (null ('PGcomposite view))
2024−typeview = UnsafeTypeExpression . renderSQL
2026−-- | logical Boolean (true/false)
2027−bool :: TypeExpression schemas (null 'PGbool)
2028−bool = UnsafeTypeExpression "bool"
2029−-- | signed two-byte integer
2030−int2, smallint :: TypeExpression schemas (null 'PGint2)
2031−int2 = UnsafeTypeExpression "int2"
2032−smallint = UnsafeTypeExpression "smallint"
2033−-- | signed four-byte integer
2034−int4, int, integer :: TypeExpression schemas (null 'PGint4)
2035−int4 = UnsafeTypeExpression "int4"
2036−int = UnsafeTypeExpression "int"
2037−integer = UnsafeTypeExpression "integer"
2038−-- | signed eight-byte integer
2039−int8, bigint :: TypeExpression schemas (null 'PGint8)
2040−int8 = UnsafeTypeExpression "int8"
2041−bigint = UnsafeTypeExpression "bigint"
2042−-- | arbitrary precision numeric type
2043−numeric :: TypeExpression schemas (null 'PGnumeric)
2044−numeric = UnsafeTypeExpression "numeric"
2045−-- | single precision floating-point number (4 bytes)
2046−float4, real :: TypeExpression schemas (null 'PGfloat4)
2047−float4 = UnsafeTypeExpression "float4"
2048−real = UnsafeTypeExpression "real"
2049−-- | double precision floating-point number (8 bytes)
2050−float8, doublePrecision :: TypeExpression schemas (null 'PGfloat8)
2051−float8 = UnsafeTypeExpression "float8"
2052−doublePrecision = UnsafeTypeExpression "double precision"
2053−-- | currency amount
2054−money :: TypeExpression schema (null 'PGmoney)
2055−money = UnsafeTypeExpression "money"
2056−-- | variable-length character string
2057−text :: TypeExpression schemas (null 'PGtext)
2058−text = UnsafeTypeExpression "text"
2059−-- | fixed-length character string
2061− :: forall n schemas null. (KnownNat n, 1 <= n)
2062− => TypeExpression schemas (null ('PGchar n))
2063−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
2064−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
2065−-- | variable-length character string
2066−varchar, characterVarying
2067− :: forall n schemas null. (KnownNat n, 1 <= n)
2068− => TypeExpression schemas (null ('PGvarchar n))
2069−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
2070−characterVarying = UnsafeTypeExpression $
2071− "character varying(" <> renderNat @n <> ")"
2072−-- | binary data ("byte array")
2073−bytea :: TypeExpression schemas (null 'PGbytea)
2074−bytea = UnsafeTypeExpression "bytea"
2075−-- | date and time (no time zone)
2076−timestamp :: TypeExpression schemas (null 'PGtimestamp)
2077−timestamp = UnsafeTypeExpression "timestamp"
2078−-- | date and time, including time zone
2079−timestampWithTimeZone :: TypeExpression schemas (null 'PGtimestamptz)
2080−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
2081−-- | calendar date (year, month, day)
2082−date :: TypeExpression schemas (null 'PGdate)
2083−date = UnsafeTypeExpression "date"
2084−-- | time of day (no time zone)
2085−time :: TypeExpression schemas (null 'PGtime)
2086−time = UnsafeTypeExpression "time"
2087−-- | time of day, including time zone
2088−timeWithTimeZone :: TypeExpression schemas (null 'PGtimetz)
2089−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
2091−interval :: TypeExpression schemas (null 'PGinterval)
2092−interval = UnsafeTypeExpression "interval"
2093−-- | universally unique identifier
2094−uuid :: TypeExpression schemas (null 'PGuuid)
2095−uuid = UnsafeTypeExpression "uuid"
2096−-- | IPv4 or IPv6 host address
2097−inet :: TypeExpression schemas (null 'PGinet)
2098−inet = UnsafeTypeExpression "inet"
2099−-- | textual JSON data
2100−json :: TypeExpression schemas (null 'PGjson)
2101−json = UnsafeTypeExpression "json"
2102−-- | binary JSON data, decomposed
2103−jsonb :: TypeExpression schemas (null 'PGjsonb)
2104−jsonb = UnsafeTypeExpression "jsonb"
2105−-- | variable length array
2107− :: TypeExpression schemas pg
2108− -> TypeExpression schemas (null ('PGvararray pg))
2109−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
2110−-- | fixed length array
2112−-- >>> renderSQL (fixarray @'[2] json)
2115− :: forall dims schemas null pg. SOP.All KnownNat dims
2116− => TypeExpression schemas pg
2117− -> TypeExpression schemas (null ('PGfixarray dims pg))
2118−fixarray ty = UnsafeTypeExpression $
2119− renderSQL ty <> renderDims @dims
2121− renderDims :: forall ns. SOP.All KnownNat ns => ByteString
2125− . ByteString.intercalate "]["
2127− $ hcmap (SOP.Proxy @KnownNat)
2128− (K . fromString . show . natVal)
2129− (hpure SOP.Proxy :: NP SOP.Proxy ns)
2130−tsvector :: TypeExpression schemas (null 'PGtsvector)
2131−tsvector = UnsafeTypeExpression "tsvector"
2132−tsquery :: TypeExpression schemas (null 'PGtsquery)
2133−tsquery = UnsafeTypeExpression "tsquery"
2135−-- | `pgtype` is a demoted version of a `PGType`
2136−class PGTyped schemas (ty :: NullityType) where
2137− pgtype :: TypeExpression schemas ty
2138−instance PGTyped schemas (null 'PGbool) where pgtype = bool
2139−instance PGTyped schemas (null 'PGint2) where pgtype = int2
2140−instance PGTyped schemas (null 'PGint4) where pgtype = int4
2141−instance PGTyped schemas (null 'PGint8) where pgtype = int8
2142−instance PGTyped schemas (null 'PGnumeric) where pgtype = numeric
2143−instance PGTyped schemas (null 'PGfloat4) where pgtype = float4
2144−instance PGTyped schemas (null 'PGfloat8) where pgtype = float8
2145−instance PGTyped schemas (null 'PGmoney) where pgtype = money
2146−instance PGTyped schemas (null 'PGtext) where pgtype = text
2147−instance (KnownNat n, 1 <= n)
2148− => PGTyped schemas (null ('PGchar n)) where pgtype = char @n
2149−instance (KnownNat n, 1 <= n)
2150− => PGTyped schemas (null ('PGvarchar n)) where pgtype = varchar @n
2151−instance PGTyped schemas (null 'PGbytea) where pgtype = bytea
2152−instance PGTyped schemas (null 'PGtimestamp) where pgtype = timestamp
2153−instance PGTyped schemas (null 'PGtimestamptz) where pgtype = timestampWithTimeZone
2154−instance PGTyped schemas (null 'PGdate) where pgtype = date
2155−instance PGTyped schemas (null 'PGtime) where pgtype = time
2156−instance PGTyped schemas (null 'PGtimetz) where pgtype = timeWithTimeZone
2157−instance PGTyped schemas (null 'PGinterval) where pgtype = interval
2158−instance PGTyped schemas (null 'PGuuid) where pgtype = uuid
2159−instance PGTyped schemas (null 'PGjson) where pgtype = json
2160−instance PGTyped schemas (null 'PGjsonb) where pgtype = jsonb
2161−instance PGTyped schemas ty
2162− => PGTyped schemas (null ('PGvararray ty)) where
2163− pgtype = vararray (pgtype @schemas @ty)
2164−instance (SOP.All KnownNat dims, PGTyped schemas ty)
2165− => PGTyped schemas (null ('PGfixarray dims ty)) where
2166− pgtype = fixarray @dims (pgtype @schemas @ty)
2167−instance PGTyped schemas (null 'PGtsvector) where pgtype = tsvector
2168−instance PGTyped schemas (null 'PGtsquery) where pgtype = tsquery
2170−{-----------------------------------------
2172−-----------------------------------------}
2174−-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2175−-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2176−-- set the sort direction of a `NotNull` result
2177−-- column to ascending or descending. Ascending order puts smaller values
2178−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2179−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2180−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2181−-- determine whether nulls appear before or after non-null values in the sort
2182−-- ordering of a `Null` result column.
2183−data SortExpression outer grp commons schemas params from where
2185− :: Expression outer grp commons schemas params from ('NotNull ty)
2186− -> SortExpression outer grp commons schemas params from
2188− :: Expression outer grp commons schemas params from ('NotNull ty)
2189− -> SortExpression outer grp commons schemas params from
2191− :: Expression outer grp commons schemas params from ('Null ty)
2192− -> SortExpression outer grp commons schemas params from
2194− :: Expression outer grp commons schemas params from ('Null ty)
2195− -> SortExpression outer grp commons schemas params from
2197− :: Expression outer grp commons schemas params from ('Null ty)
2198− -> SortExpression outer grp commons schemas params from
2200− :: Expression outer grp commons schemas params from ('Null ty)
2201− -> SortExpression outer grp commons schemas params from
2202−deriving instance Show (SortExpression outer grp commons schemas params from)
2205−The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2206−to be sorted according to the specified `SortExpression`(s).
2207−If two rows are equal according to the leftmost expression,
2208−they are compared according to the next expression and so on.
2209−If they are equal according to all specified expressions,
2210−they are returned in an implementation-dependent order.
2212−You can also control the order in which rows are processed by window functions
2213−using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2215−class OrderBy expr where
2217− :: [SortExpression outer grp commons schemas params from]
2218− -> expr outer grp commons schemas params from
2219− -> expr outer grp commons schemas params from
2221−-- | Render a `SortExpression`.
2222−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2224− Asc expression -> renderSQL expression <+> "ASC"
2225− Desc expression -> renderSQL expression <+> "DESC"
2226− AscNullsFirst expression -> renderSQL expression
2227− <+> "ASC NULLS FIRST"
2228− DescNullsFirst expression -> renderSQL expression
2229− <+> "DESC NULLS FIRST"
2230− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2231− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2233−-- | A `WindowDefinition` is a set of table rows that are somehow related
2234−-- to the current row
2235−data WindowDefinition outer grp commons schemas params from where
2238− => NP (Expression outer grp commons schemas params from) bys
2239− -> [SortExpression outer grp commons schemas params from]
2240− -> WindowDefinition outer grp commons schemas params from
2242−instance OrderBy WindowDefinition where
2243− orderBy sortsR (WindowDefinition parts sortsL)
2244− = WindowDefinition parts (sortsL ++ sortsR)
2246−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2247− renderSQL (WindowDefinition part ord) =
2248− renderPartitionByClause part <> renderOrderByClause ord
2250− renderPartitionByClause = \case
2252− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2253− renderOrderByClause = \case
2255− srts -> " ORDER" <+> "BY"
2256− <+> commaSeparated (renderSQL <$> srts)
2259−The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2260−or partitions, that share the same values of the `partitionBy` `Expression`(s).
2261−For each row, the window function is computed across the rows that fall into
2262−the same partition as the current row.
2266− => NP (Expression outer grp commons schemas params from) bys
2267− -> WindowDefinition outer grp commons schemas params from
2268−partitionBy bys = WindowDefinition bys []
2271−A window function performs a calculation across a set of table rows
2272−that are somehow related to the current row. This is comparable to the type
2273−of calculation that can be done with an aggregate function.
2274−However, window functions do not cause rows to become grouped into a single
2275−output row like non-window aggregate calls would.
2276−Instead, the rows retain their separate identities.
2277−Behind the scenes, the window function is able to access more than
2278−just the current row of the query result.
2280−newtype WindowFunction
2281− (outer :: FromType)
2283− (commons :: FromType)
2284− (schemas :: SchemasType)
2285− (params :: [NullityType])
2287− (ty :: NullityType)
2288− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2289− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2291−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2292− renderSQL = renderWindowFunction
2294−unsafeWindowFunction1
2296− -> Expression outer grp commons schemas params from ty0
2297− -> WindowFunction outer grp commons schemas params from ty1
2298−unsafeWindowFunction1 fun x
2299− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2301−unsafeWindowFunction2
2303− -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2304− -> WindowFunction outer grp commons schemas params from ty1
2305−unsafeWindowFunction2 fun (x :*: x')
2306− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2308−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2312−rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2313−rank = UnsafeWindowFunction "rank()"
2315−{- | number of the current row within its partition, counting from 1
2316−>>> printSQL rowNumber
2319−rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2320−rowNumber = UnsafeWindowFunction "row_number()"
2322−{- | rank of the current row without gaps; this function counts peer groups
2323−>>> printSQL denseRank
2326−denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2327−denseRank = UnsafeWindowFunction "dense_rank()"
2329−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2330−>>> printSQL percentRank
2333−percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2334−percentRank = UnsafeWindowFunction "percent_rank()"
2336−{- | cumulative distribution: (number of partition rows
2337−preceding or peer with current row) / total partition rows
2338−>>> printSQL cumeDist
2341−cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2342−cumeDist = UnsafeWindowFunction "cume_dist()"
2344−{- | integer ranging from 1 to the argument value,
2345−dividing the partition as equally as possible
2348− :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2350− -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2351−ntile = unsafeWindowFunction1 "ntile"
2353−{- | returns value evaluated at the row that is offset rows before the current
2354−row within the partition; if there is no such row, instead return default
2355−(which must be of the same type as value). Both offset and default are
2356−evaluated with respect to the current row.
2359− :: Expression outer grp commons schemas params from ty
2361− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2363− -> Expression outer grp commons schemas params from ty
2365− -> WindowFunction outer grp commons schemas params from ty
2366−lag value offset def = UnsafeWindowFunction $ "lag"
2368− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2370−{- | returns value evaluated at the row that is offset rows after the current
2371−row within the partition; if there is no such row, instead return default
2372−(which must be of the same type as value). Both offset and default are
2373−evaluated with respect to the current row.
2376− :: Expression outer grp commons schemas params from ty
2378− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2380− -> Expression outer grp commons schemas params from ty
2382− -> WindowFunction outer grp commons schemas params from ty
2383−lead value offset def = UnsafeWindowFunction $ "lag"
2385− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2387−{- | returns value evaluated at the row that is the
2388−first row of the window frame
2391− :: Expression outer grp commons schemas params from ty
2393− -> WindowFunction outer grp commons schemas params from ty
2394−firstValue = unsafeWindowFunction1 "first_value"
2396−{- | returns value evaluated at the row that is the
2397−last row of the window frame
2400− :: Expression outer grp commons schemas params from ty
2402− -> WindowFunction outer grp commons schemas params from ty
2403−lastValue = unsafeWindowFunction1 "last_value"
2405−{- | returns value evaluated at the row that is the nth
2406−row of the window frame (counting from 1); null if no such row
2409− :: Expression outer grp commons schemas params from (null ty)
2411− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2413− -> WindowFunction outer grp commons schemas params from ('Null ty)
2414−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2415− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])
2418−Create date from year, month and day fields
2420−>>> printSQL (makeDate (1984 :* 7 *: 3))
2421−make_date(1984, 7, 3)
2423−makeDate :: FunctionHet
2424− '[ null 'PGint4, null 'PGint4, null 'PGint4 ]
2426−makeDate = unsafeFunctionHet "make_date"
2429−Create time from hour, minute and seconds fields
2431−>>> printSQL (makeTime (8 :* 15 *: 23.5))
2432−make_time(8, 15, 23.5)
2434−makeTime :: FunctionHet
2435− '[ null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2437−makeTime = unsafeFunctionHet "make_time"
2440−Create timestamp from year, month, day, hour, minute and seconds fields
2442−>>> printSQL (makeTimestamp (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2443−make_timestamp(2013, 7, 15, 8, 15, 23.5)
2445−makeTimestamp :: FunctionHet
2446− '[ null 'PGint4, null 'PGint4, null 'PGint4
2447− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2448− ( null 'PGtimestamp )
2449−makeTimestamp = unsafeFunctionHet "make_timestamp"
2452−Create timestamp with time zone from
2453−year, month, day, hour, minute and seconds fields;
2454−the current time zone is used
2456−>>> printSQL (makeTimestamptz (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2457−make_timestamptz(2013, 7, 15, 8, 15, 23.5)
2459−makeTimestamptz :: FunctionHet
2460− '[ null 'PGint4, null 'PGint4, null 'PGint4
2461− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2462− ( null 'PGtimestamptz )
2463−makeTimestamptz = unsafeFunctionHet "make_timestamptz"
2466−Affine space operations on time types.
2468−class TimeOp time diff | time -> diff where
2470− >>> printSQL (makeDate (1984 :* 7 *: 3) !+ 365)
2471− (make_date(1984, 7, 3) + 365)
2473− (!+) :: Operator (null time) (null diff) (null time)
2474− (!+) = unsafeBinaryOp "+"
2476− >>> printSQL (365 +! makeDate (1984 :* 7 *: 3))
2477− (365 + make_date(1984, 7, 3))
2479− (+!) :: Operator (null diff) (null time) (null time)
2480− (+!) = unsafeBinaryOp "+"
2482− >>> printSQL (makeDate (1984 :* 7 *: 3) !- 365)
2483− (make_date(1984, 7, 3) - 365)
2485− (!-) :: Operator (null time) (null diff) (null time)
2486− (!-) = unsafeBinaryOp "-"
2488− >>> printSQL (makeDate (1984 :* 7 *: 3) !-! currentDate)
2489− (make_date(1984, 7, 3) - CURRENT_DATE)
2491− (!-!) :: Operator (null time) (null time) (null diff)
2492− (!-!) = unsafeBinaryOp "-"
2493−instance TimeOp 'PGtimestamp 'PGinterval
2494−instance TimeOp 'PGtimestamptz 'PGinterval
2495−instance TimeOp 'PGtime 'PGinterval
2496−instance TimeOp 'PGtimetz 'PGinterval
2497−instance TimeOp 'PGinterval 'PGinterval
2498−instance TimeOp 'PGdate 'PGint4