@@ -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,358 +34,213 @@ module Squeal.PostgreSQL.Expression
35 ( -- * Expression
34 ( -- * Expression
36 Expression (..)
35 Expression (..)
38 , Operator
45 , Operator
39− , (:-->)
46+ , OperatorDB
40− , HasParameter (parameter)
58 , unsafeBinaryOp
47 , unsafeBinaryOp
59− , unsafeUnaryOpL
48+ , binaryOp
60− , unsafeFunction
49+ , FunctionVar
61− , unsafeVariadicFunction
50+ , unsafeFunctionVar
62− , atan2_
51+ , type (--->)
63− , cast
52+ , FunctionNDB
64− , quot_
53+ , unsafeFunctionN
65− , rem_
54+ , functionN
66− , trunc
55+ , PGSubset (..)
67− , round_
56+ , PGIntersect (..)
89− , notBetweenSymmetric
116− -- *** Json and Jsonb operators
121− -- *** Jsonb operators
148− , jsonExtractPathAsText
149− , jsonbExtractPathAsText
167− -- * Window Functions
168− , WindowDefinition (..)
170− , WindowFunction (..)
183− , SortExpression (..)
186− , TypeExpression (..)
212− , timestampWithTimeZone
230− , websearchToTSquery
234 -- * Re-export
57 -- * Re-export
241import Control.Category
63import Control.Category
242import Control.DeepSeq
64import Control.DeepSeq
243import Data.ByteString (ByteString)
65import Data.ByteString (ByteString)
244−import Data.ByteString.Lazy (toStrict)
245import Data.Function ((&))
66import Data.Function ((&))
246import Data.Semigroup hiding (All)
67import Data.Semigroup hiding (All)
247−import qualified Data.Aeson as JSON
248import Data.String
68import Data.String
250import Generics.SOP hiding (All, from)
69import Generics.SOP hiding (All, from)
251−import GHC.Generics ((:*:) (..))
252import GHC.OverloadedLabels
70import GHC.OverloadedLabels
253import GHC.TypeLits
71import GHC.TypeLits
254import Numeric
72import Numeric
255import Prelude hiding (id, (.))
73import Prelude hiding (id, (.))
257−import qualified Data.ByteString as ByteString
258import qualified GHC.Generics as GHC
75import qualified GHC.Generics as GHC
259−import qualified Generics.SOP as SOP
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
261import Squeal.PostgreSQL.Render
79import Squeal.PostgreSQL.Render
262import Squeal.PostgreSQL.Schema
80import Squeal.PostgreSQL.Schema
83+-- >>> import Squeal.PostgreSQL
264{-----------------------------------------
85{-----------------------------------------
265column expressions
86column expressions
266-----------------------------------------}
87-----------------------------------------}
268{- | `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
269−such as in the target list of the `Squeal.PostgreSQL.Query.select` command,
91+`Squeal.PostgreSQL.Query.select` command,
270as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
92as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
271`Squeal.PostgreSQL.Manipulation.update`,
93`Squeal.PostgreSQL.Manipulation.update`,
272−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
274The expression syntax allows the calculation of
96The expression syntax allows the calculation of
275values from primitive expression using arithmetic, logical,
97values from primitive expression using arithmetic, logical,
276and 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`.
278newtype Expression
114newtype Expression
279 (outer :: FromType)
115 (outer :: FromType)
281 (commons :: FromType)
116 (commons :: FromType)
282 (schemas :: SchemasType)
118 (schemas :: SchemasType)
283 (params :: [NullityType])
119 (params :: [NullityType])
284 (from :: FromType)
120 (from :: FromType)
285 (ty :: NullityType)
121 (ty :: NullityType)
286 = UnsafeExpression { renderExpression :: ByteString }
122 = UnsafeExpression { renderExpression :: ByteString }
287 deriving (GHC.Generic,Show,Eq,Ord,NFData)
123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
288−instance RenderSQL (Expression outer grp commons schemas params from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
289 renderSQL = renderExpression
125 renderSQL = renderExpression
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.
291type Expr x
133type Expr x
292− = forall outer grp commons schemas params from
134+ = forall outer commons grp schemas params from
293− . Expression outer grp commons schemas params from x
135+ . Expression outer commons grp schemas params from x
136+ -- ^ cannot reference aliases
138+-- | A @RankNType@ for binary operators.
295type Operator x1 x2 y
139type Operator x1 x2 y
296− = forall outer grp commons schemas params from
140+ = forall outer commons grp schemas params from
297− . Expression outer grp commons schemas params from x1
141+ . Expression outer commons grp schemas params from x1
298− -> Expression outer grp commons schemas params from x2
143+ -> Expression outer commons grp schemas params from x2
299− -> Expression outer grp commons schemas params from y
145+ -> Expression outer commons grp schemas params from y
148+type OperatorDB schemas x1 x2 y
302− = forall outer grp commons schemas params from
149+ = forall outer commons grp params from
303− . Expression outer grp commons schemas params from x
150+ . Expression outer commons grp schemas params from x1
304− -> Expression outer grp commons schemas params from y
152+ -> Expression outer commons grp schemas params from x2
305−
153+ -- ^ right input
306−type FunctionHet xs y
307− = forall outer grp commons schemas params from
154+ -> Expression outer commons grp schemas params from y
308− . NP (Expression outer grp commons schemas params from) xs
155+ -- ^ output
309− -> Expression outer grp commons schemas params from y
156+
310−
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`.
311−type FunctionHom x y
162+type (-->) x y
312− = forall outer grp commons schemas params from
163+ = forall outer commons grp schemas params from
313− . [Expression outer grp commons schemas params from x]
164+ . Expression outer commons grp schemas params from x
314− -> Expression outer grp commons schemas params from x
166+ -> Expression outer commons grp schemas params from y
169+type FunctionDB schemas x y
170+ = forall outer commons grp params from
171+ . Expression outer commons grp schemas params from x
315− -> Expression outer grp commons schemas params from y
173+ -> Expression outer commons grp schemas params from y
317−unsafeFunctionHom :: ByteString -> FunctionHom x y
175+
176+{- | A @RankNType@ for functions with a fixed-length list of heterogeneous arguments.
177+Use the `*:` operator to end your argument lists, like so.
179+>>> printSQL (unsafeFunctionN "fun" (true :* false :* localTime *: true))
180+fun(TRUE, FALSE, LOCALTIME, TRUE)
183+ = forall outer commons grp schemas params from
184+ . NP (Expression outer commons grp schemas params from) xs
186+ -> Expression outer commons grp schemas params from y
189+type FunctionNDB schemas xs y
190+ = forall outer commons grp params from
191+ . NP (Expression outer commons grp schemas params from) xs
193+ -> Expression outer commons grp schemas params from y
196+{- | A @RankNType@ for functions with a variable-length list of
197+homogeneous arguments and at least 1 more argument.
199+type FunctionVar x0 x1 y
200+ = forall outer commons grp schemas params from
201+ . [Expression outer commons grp schemas params from x0]
203+ -> Expression outer commons grp schemas params from x1
204+ -- ^ must have at least 1 input
205+ -> Expression outer commons grp schemas params from y
208+{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
209+greatest(TRUE, NULL, FALSE)
211+unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
318−unsafeFunctionHom fun xs x = UnsafeExpression $ fun <> parenthesized
212+unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
319 (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
213 (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
321−{- | A `HasParameter` constraint is used to indicate a value that is
322−supplied externally to a SQL statement.
323−`Squeal.PostgreSQL.PQ.manipulateParams`,
324−`Squeal.PostgreSQL.PQ.queryParams` and
325−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
326−separately from the SQL command string, in which case `param`s are used to
327−refer to the out-of-line data values.
329−class KnownNat n => HasParameter
331− (params :: [NullityType])
333− | n params -> ty where
334− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
336− -- >>> let expr = parameter @1 int4 :: Expression outer grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
337− -- >>> printSQL expr
340− :: TypeExpression schemas ty
341− -> Expression outer grp commons schemas params from ty
342− parameter ty = UnsafeExpression $ parenthesized $
343− "$" <> renderNat @n <+> "::"
345−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
346−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
347− => HasParameter n (ty' : params) ty
349−-- | `param` takes a `Nat` using type application and for basic types,
350−-- infers a `TypeExpression`.
352−-- >>> let expr = param @1 :: Expression outer grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
356− :: forall n outer commons schemas params from grp ty
357− . (PGTyped schemas ty, HasParameter n params ty)
358− => Expression outer grp commons schemas params from ty -- ^ param
359−param = parameter @n (pgtype @schemas)
361instance (HasUnique tab (Join outer from) row, Has col row ty)
215instance (HasUnique tab (Join outer from) row, Has col row ty)
362− => IsLabel col (Expression outer 'Ungrouped commons schemas params from ty) where
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
363 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
364instance (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])
365− => 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
366 fromLabel = fromLabel @col :* Nil
220 fromLabel = fromLabel @col :* Nil
367instance (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))
368 => IsLabel col
222 => IsLabel col
369− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
370 fromLabel = fromLabel @col `As` Alias
224 fromLabel = fromLabel @col `As` Alias
371instance (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])
372 => IsLabel col
226 => IsLabel col
373− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
374 fromLabel = fromLabel @col :* Nil
228 fromLabel = fromLabel @col :* Nil
376instance (Has tab (Join outer from) row, Has col row ty)
230instance (Has tab (Join outer from) row, Has col row ty)
377− => 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
378 tab ! col = UnsafeExpression $
232 tab ! col = UnsafeExpression $
379 renderSQL tab <> "." <> renderSQL col
233 renderSQL tab <> "." <> renderSQL col
380instance (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])
381− => 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
382 tab ! col = tab ! col :* Nil
236 tab ! col = tab ! col :* Nil
383instance (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))
384 => IsQualified tab col
238 => IsQualified tab col
385− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
386 tab ! col = tab ! col `As` col
240 tab ! col = tab ! col `As` col
387instance (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])
388 => IsQualified tab col
242 => IsQualified tab col
389− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
390 tab ! col = tab ! col :* Nil
244 tab ! col = tab ! col :* Nil
@@ -394,7 +248,7 @@ instance
394 , Has col row ty
248 , Has col row ty
395 , GroupedBy tab col bys
249 , GroupedBy tab col bys
396 ) => IsLabel col
250 ) => IsLabel col
397− (Expression outer ('Grouped bys) commons schemas params from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
398 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
400 ( HasUnique tab (Join outer from) row
254 ( HasUnique tab (Join outer from) row
@@ -402,7 +256,7 @@ instance
402 , GroupedBy tab col bys
256 , GroupedBy tab col bys
403 , tys ~ '[ty]
257 , tys ~ '[ty]
404 ) => IsLabel col
258 ) => IsLabel col
405− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
406 fromLabel = fromLabel @col :* Nil
260 fromLabel = fromLabel @col :* Nil
408 ( HasUnique tab (Join outer from) row
262 ( HasUnique tab (Join outer from) row
@@ -410,7 +264,7 @@ instance
410 , GroupedBy tab col bys
264 , GroupedBy tab col bys
411 , column ~ (col ::: ty)
265 , column ~ (col ::: ty)
412 ) => IsLabel col
266 ) => IsLabel col
413− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
414 fromLabel = fromLabel @col `As` Alias
268 fromLabel = fromLabel @col `As` Alias
416 ( HasUnique tab (Join outer from) row
270 ( HasUnique tab (Join outer from) row
@@ -418,7 +272,7 @@ instance
418 , GroupedBy tab col bys
272 , GroupedBy tab col bys
419 , columns ~ '[col ::: ty]
273 , columns ~ '[col ::: ty]
420 ) => IsLabel col
274 ) => IsLabel col
421− (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
422 fromLabel = fromLabel @col :* Nil
276 fromLabel = fromLabel @col :* Nil
@@ -426,7 +280,7 @@ instance
426 , Has col row ty
280 , Has col row ty
427 , GroupedBy tab col bys
281 , GroupedBy tab col bys
428 ) => IsQualified tab col
282 ) => IsQualified tab col
429− (Expression outer ('Grouped bys) commons schemas params from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
430 tab ! col = UnsafeExpression $
284 tab ! col = UnsafeExpression $
431 renderSQL tab <> "." <> renderSQL col
285 renderSQL tab <> "." <> renderSQL col
@@ -435,7 +289,7 @@ instance
435 , GroupedBy tab col bys
289 , GroupedBy tab col bys
436 , tys ~ '[ty]
290 , tys ~ '[ty]
437 ) => IsQualified tab col
291 ) => IsQualified tab col
438− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
439 tab ! col = tab ! col :* Nil
293 tab ! col = tab ! col :* Nil
441 ( Has tab (Join outer from) row
295 ( Has tab (Join outer from) row
@@ -443,7 +297,7 @@ instance
443 , GroupedBy tab col bys
297 , GroupedBy tab col bys
444 , column ~ (col ::: ty)
298 , column ~ (col ::: ty)
445 ) => IsQualified tab col
299 ) => IsQualified tab col
446− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
447 tab ! col = tab ! col `As` col
301 tab ! col = tab ! col `As` col
449 ( Has tab (Join outer from) row
303 ( Has tab (Join outer from) row
@@ -451,223 +305,78 @@ instance
451 , GroupedBy tab col bys
305 , GroupedBy tab col bys
452 , columns ~ '[col ::: ty]
306 , columns ~ '[col ::: ty]
453 ) => IsQualified tab col
307 ) => IsQualified tab col
454− (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
455 tab ! col = tab ! col :* Nil
309 tab ! col = tab ! col :* Nil
457−-- | analagous to `Nothing`
459−-- >>> printSQL null_
461−null_ :: Expr ('Null ty)
462−null_ = UnsafeExpression "NULL"
464−-- | analagous to `Just`
466−-- >>> printSQL $ notNull true
468−notNull :: 'NotNull ty :--> 'Null ty
469−notNull = UnsafeExpression . renderSQL
471−-- | return the leftmost value which is not NULL
473−-- >>> printSQL $ coalesce [null_, true] false
474−-- COALESCE(NULL, TRUE, FALSE)
476− :: [Expression outer grp commons schemas params from ('Null ty)]
477− -- ^ @NULL@s may be present
478− -> Expression outer grp commons schemas params from ('NotNull ty)
479− -- ^ @NULL@ is absent
480− -> Expression outer grp commons schemas params from ('NotNull ty)
481−coalesce nullxs notNullx = UnsafeExpression $
482− "COALESCE" <> parenthesized (commaSeparated
483− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
485−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
487−-- >>> printSQL $ fromNull true null_
488−-- COALESCE(NULL, TRUE)
490− :: Expression outer grp commons schemas params from ('NotNull ty)
491− -- ^ what to convert @NULL@ to
492− -> Expression outer grp commons schemas params from ('Null ty)
493− -> Expression outer grp commons schemas params from ('NotNull ty)
494−fromNull notNullx nullx = coalesce [nullx] notNullx
496−-- | >>> printSQL $ null_ & isNull
499− :: Expression outer grp commons schemas params from ('Null ty)
500− -- ^ possibly @NULL@
501− -> Condition outer grp commons schemas params from
502−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
504−-- | >>> printSQL $ null_ & isNotNull
507− :: Expression outer grp commons schemas params from ('Null ty)
508− -- ^ possibly @NULL@
509− -> Condition outer grp commons schemas params from
510−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
512−-- | analagous to `maybe` using @IS NULL@
514−-- >>> printSQL $ matchNull true not_ null_
515−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
517− :: Expression outer grp commons schemas params from (nullty)
518− -- ^ what to convert @NULL@ to
519− -> ( Expression outer grp commons schemas params from ('NotNull ty)
520− -> Expression outer grp commons schemas params from (nullty) )
521− -- ^ function to perform when @NULL@ is absent
522− -> Expression outer grp commons schemas params from ('Null ty)
523− -> Expression outer grp commons schemas params from (nullty)
524−matchNull y f x = ifThenElse (isNull x) y
525− (f (UnsafeExpression (renderSQL x)))
527−{-| right inverse to `fromNull`, if its arguments are equal then
528−`nullIf` gives @NULL@.
530−>>> :set -XTypeApplications -XDataKinds
531−>>> let expr = nullIf false (param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
533−NULL IF (FALSE, ($1 :: bool))
536− :: Expression outer grp commons schemas params from ('NotNull ty)
537− -- ^ @NULL@ is absent
538− -> Expression outer grp commons schemas params from ('NotNull ty)
539− -- ^ @NULL@ is absent
540− -> Expression outer grp commons schemas params from ('Null ty)
541−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
542− (renderSQL x <> ", " <> renderSQL y)
544−-- | >>> printSQL $ array [null_, false, true]
545−-- ARRAY[NULL, FALSE, TRUE]
547− :: [Expression outer grp commons schemas params from ty]
549− -> Expression outer grp commons schemas params from (null ('PGvararray ty))
550−array xs = UnsafeExpression $
551− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
553−-- | >>> printSQL $ cardinality (array [null_, false, true])
554−-- cardinality(ARRAY[NULL, FALSE, TRUE])
555−cardinality :: null ('PGvararray ty) :--> null 'PGint8
556−cardinality = unsafeFunction "cardinality"
558−-- | >>> printSQL $ array [null_, false, true] & index 2
559−-- (ARRAY[NULL, FALSE, TRUE])[2]
561− :: Word64 -- ^ index
562− -> null ('PGvararray ty) :--> NullifyType ty
563−index n expr = UnsafeExpression $
564− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
566instance (KnownSymbol label, label `In` labels) => IsPGlabel label
311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
567− (Expression outer grp commons schemas params from (null ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
568 label = UnsafeExpression $ renderSQL (PGlabel @label)
313 label = UnsafeExpression $ renderSQL (PGlabel @label)
570−-- | A row constructor is an expression that builds a row value
571−-- (also called a composite value) using values for its member fields.
574−-- type Complex = 'PGcomposite
575−-- '[ "real" ::: 'NotNull 'PGfloat8
576−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
579−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
584− => NP (Aliased (Expression outer grp commons schemas params from)) row
585− -- ^ zero or more expressions for the row field values
586− -> Expression outer grp commons schemas params from (null ('PGcomposite row))
587−row exprs = UnsafeExpression $ "ROW" <> parenthesized
588− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
591−-- type Complex = 'PGcomposite
592−-- '[ "real" ::: 'NotNull 'PGfloat8
593−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
594−-- type Schema = '["complex" ::: 'Typedef Complex]
597−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
598−-- >>> printSQL $ i & field #complex #imaginary
599−-- (ROW(0, 1)::"complex")."imaginary"
601− :: ( Has sch schemas schema
602− , Has tydef schema ('Typedef ('PGcomposite row))
604− => QualifiedAlias sch tydef -- ^ row type
605− -> Alias field -- ^ field name
606− -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
607− -> Expression outer grp commons schemas params from ty
608−field td fld expr = UnsafeExpression $
609− parenthesized (renderSQL expr <> "::" <> renderSQL td)
610− <> "." <> renderSQL fld
613− (Expression outer grp commons schemas params from (null ('PGvararray ty))) where
614− (<>) = unsafeBinaryOp "||"
617− (Expression outer grp commons schemas params from (null ('PGvararray ty))) where
621−-- | >>> let expr = greatest [param @1] currentTimestamp :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
623−-- GREATEST(($1 :: timestamp with time zone), CURRENT_TIMESTAMP)
624−greatest :: FunctionHom ty ty
625−greatest = unsafeFunctionHom "GREATEST"
627−-- | >>> printSQL $ least [null_] currentTimestamp
628−-- LEAST(NULL, CURRENT_TIMESTAMP)
629−least :: FunctionHom ty ty
630−least = unsafeFunctionHom "LEAST"
632-- | >>> printSQL $ unsafeBinaryOp "OR" true false
315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
633-- (TRUE OR FALSE)
316-- (TRUE OR FALSE)
634−unsafeBinaryOp :: ByteString {- ^ operator -} -> Operator ty0 ty1 ty2
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
635unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
636 renderSQL x <+> op <+> renderSQL y
319 renderSQL x <+> op <+> renderSQL y
638−-- | >>> printSQL $ unsafeUnaryOpL "NOT" true
321+binaryOp
639−-- (NOT TRUE)
322+ :: forall op sch schemas schema x y z.
640−unsafeUnaryOpL :: ByteString {- ^ operator -} -> x :--> y
323+ ( Has sch schemas schema
641−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
643−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
644−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
646-- | >>> printSQL $ unsafeFunction "f" true
352-- | >>> printSQL $ unsafeFunction "f" true
647-- f(TRUE)
353-- f(TRUE)
648−unsafeFunction :: ByteString {- ^ function -} -> x :--> y
354+unsafeFunction :: ByteString -> x --> y
649unsafeFunction fun x = UnsafeExpression $
355unsafeFunction fun x = UnsafeExpression $
650 fun <> parenthesized (renderSQL x)
356 fun <> parenthesized (renderSQL x)
652−unsafeFunctionHet
358+function
653− :: SListI xs
359+ :: (Has sch schemas schema, Has fun schema ('Function ('[x] :=> 'Returns y)))
654− => ByteString {- ^ function -}
360+ => QualifiedAlias sch fun
655− -> 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
656−unsafeFunctionHet fun xs = UnsafeExpression $
367+unsafeFunctionN fun xs = UnsafeExpression $
657 fun <> parenthesized (renderCommaSeparated renderSQL xs)
368 fun <> parenthesized (renderCommaSeparated renderSQL xs)
659−-- | Helper for defining variadic functions.
370+functionN
660−unsafeVariadicFunction
371+ :: ( Has sch schemas schema
372+ , Has fun schema ('Function (xs :=> 'Returns y))
661− :: SListI elems
373+ , SListI xs )
662− => ByteString
374+ => QualifiedAlias sch fun
663− -- ^ function
375+ -> FunctionNDB schemas xs y
664− -> NP (Expression outer grp commons schemas params from) elems
376+functionN = unsafeFunctionN . renderSQL
665− -> Expression outer grp commons schemas params from ret
666−unsafeVariadicFunction fun x = UnsafeExpression $
667− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderSQL) x)))
669instance ty `In` PGNum
378instance ty `In` PGNum
670− => Num (Expression outer grp commons schemas params from (null ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
671 (+) = unsafeBinaryOp "+"
380 (+) = unsafeBinaryOp "+"
672 (-) = unsafeBinaryOp "-"
381 (-) = unsafeBinaryOp "-"
673 (*) = unsafeBinaryOp "*"
382 (*) = unsafeBinaryOp "*"
@@ -679,7 +388,7 @@ instance ty `In` PGNum
681instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
682− (Expression outer grp commons schemas params from (null ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
683 (/) = unsafeBinaryOp "/"
392 (/) = unsafeBinaryOp "/"
684 fromRational
393 fromRational
685 = UnsafeExpression
394 = UnsafeExpression
@@ -689,7 +398,7 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
689 . fromRat @Double
398 . fromRat @Double
691instance (ty `In` PGNum, ty `In` PGFloating) => Floating
400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
692− (Expression outer grp commons schemas params from (null ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
693 pi = UnsafeExpression "pi()"
402 pi = UnsafeExpression "pi()"
694 exp = unsafeFunction "exp"
403 exp = unsafeFunction "exp"
695 log = unsafeFunction "ln"
404 log = unsafeFunction "ln"
@@ -710,1768 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
710 acosh x = log (x + sqrt (x*x - 1))
419 acosh x = log (x + sqrt (x*x - 1))
711 atanh x = log ((1 + x) / (1 - x)) / 2
420 atanh x = log ((1 + x) / (1 - x)) / 2
713−-- | >>> :{
422+-- | Contained by operators
714−-- let
423+class PGSubset ty where
715−-- expression :: Expr (null 'PGfloat4)
424+ (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
716−-- expression = atan2_ (pi *: 2)
425+ (@>) = unsafeBinaryOp "@>"
717−-- in printSQL expression
426+ (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
718−-- :}
427+ (<@) = unsafeBinaryOp "<@"
719−-- atan2(pi(), 2)
428+instance PGSubset 'PGjsonb
720−atan2_
429+instance PGSubset 'PGtsquery
721− :: float `In` PGFloating
430+instance PGSubset ('PGvararray ty)
722− => FunctionHet '[ null float, null float] (null float)
431+instance PGSubset ('PGrange ty)
723−atan2_ = unsafeFunctionHet "atan2"
432+
724−
433+class PGIntersect ty where
725−-- When a `cast` is applied to an `Expression` of a known type, it
434+ (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
726−-- represents a run-time type conversion. The cast will succeed only if a
435+ (@&&) = unsafeBinaryOp "&&"
727−-- suitable type conversion operation has been defined.
436+instance PGIntersect ('PGvararray ty)
728−--
437+instance PGIntersect ('PGrange ty)
729−-- | >>> printSQL $ true & cast int4
732− :: TypeExpression schemas ty1
733− -- ^ type to cast as
734− -> Expression outer grp commons schemas params from ty0
735− -- ^ value to convert
736− -> Expression outer grp commons schemas params from ty1
737−cast ty x = UnsafeExpression $ parenthesized $
738− renderSQL x <+> "::" <+> renderSQL ty
740−-- | integer division, truncates the result
744−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
745−-- expression = 5 `quot_` 2
746−-- in printSQL expression
750− :: int `In` PGIntegral
751− => Operator (null int) (null int) (null int)
752−quot_ = unsafeBinaryOp "/"
754−-- | remainder upon integer division
758−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
759−-- expression = 5 `rem_` 2
760−-- in printSQL expression
764− :: int `In` PGIntegral
765− => Operator (null int) (null int) (null int)
766−rem_ = unsafeBinaryOp "%"
770−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
771−-- expression = trunc pi
772−-- in printSQL expression
775−trunc :: frac `In` PGFloating => null frac :--> null frac
776−trunc = unsafeFunction "trunc"
780−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
781−-- expression = round_ pi
782−-- in printSQL expression
785−round_ :: frac `In` PGFloating => null frac :--> null frac
786−round_ = unsafeFunction "round"
790−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
791−-- expression = ceiling_ pi
792−-- in printSQL expression
795−ceiling_ :: frac `In` PGFloating => null frac :--> null frac
796−ceiling_ = unsafeFunction "ceiling"
798−-- | A `Condition` is an `Expression`, which can evaluate
799−-- to `true`, `false` or `null_`. This is because SQL uses
800−-- a three valued logic.
801−type Condition outer grp commons schemas params from =
802− Expression outer grp commons schemas params from ('Null 'PGbool)
804−-- | >>> printSQL true
806−true :: Expr (null 'PGbool)
807−true = UnsafeExpression "TRUE"
809−-- | >>> printSQL false
811−false :: Expr (null 'PGbool)
812−false = UnsafeExpression "FALSE"
814−-- | >>> printSQL $ not_ true
816−not_ :: null 'PGbool :--> null 'PGbool
817−not_ = unsafeUnaryOpL "NOT"
819−-- | >>> printSQL $ true .&& false
821−(.&&) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
823−(.&&) = unsafeBinaryOp "AND"
825−-- | >>> printSQL $ true .|| false
827−(.||) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
829−(.||) = unsafeBinaryOp "OR"
833−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
834−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
835−-- in printSQL expression
837−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
839− :: [ ( Condition outer grp commons schemas params from
840− , Expression outer grp commons schemas params from ty
842− -- ^ whens and thens
843− -> Expression outer grp commons schemas params from ty
845− -> Expression outer grp commons schemas params from ty
846−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
850− [ " WHEN ", renderSQL when_
851− , " THEN ", renderSQL then_
853− | (when_,then_) <- whenThens
855− , " ELSE ", renderSQL else_
861−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
862−-- expression = ifThenElse true 1 0
863−-- in printSQL expression
865−-- CASE WHEN TRUE THEN 1 ELSE 0 END
867− :: Condition outer grp commons schemas params from
868− -> Expression outer grp commons schemas params from ty -- ^ then
869− -> Expression outer grp commons schemas params from ty -- ^ else
870− -> Expression outer grp commons schemas params from ty
871−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
873−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
874−-- will produce @NULL@s if one of their arguments is @NULL@.
876−-- >>> printSQL $ true .== null_
878−(.==) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
879−(.==) = unsafeBinaryOp "="
882−-- | >>> printSQL $ true ./= null_
884−(./=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
885−(./=) = unsafeBinaryOp "<>"
888−-- | >>> printSQL $ true .>= null_
890−(.>=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
891−(.>=) = unsafeBinaryOp ">="
894−-- | >>> printSQL $ true .< null_
896−(.<) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
897−(.<) = unsafeBinaryOp "<"
900−-- | >>> printSQL $ true .<= null_
902−(.<=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
903−(.<=) = unsafeBinaryOp "<="
906−-- | >>> printSQL $ true .> null_
908−(.>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
909−(.>) = unsafeBinaryOp ">"
913−>>> printSQL $ true `between` (null_, false)
914−TRUE BETWEEN NULL AND FALSE
917− :: Expression outer grp commons schemas params from (null ty)
918− -> ( Expression outer grp commons schemas params from (null ty)
919− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
920− -> Condition outer grp commons schemas params from
921−between a (x,y) = UnsafeExpression $ renderSQL a <+> "BETWEEN"
922− <+> renderSQL x <+> "AND" <+> renderSQL y
925−>>> printSQL $ true `notBetween` (null_, false)
926−TRUE NOT BETWEEN NULL AND FALSE
929− :: Expression outer grp commons schemas params from (null ty)
930− -> ( Expression outer grp commons schemas params from (null ty)
931− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
932− -> Condition outer grp commons schemas params from
933−notBetween a (x,y) = UnsafeExpression $ renderSQL a <+> "NOT BETWEEN"
934− <+> renderSQL x <+> "AND" <+> renderSQL y
936−{- | between, after sorting the comparison values
937−>>> printSQL $ true `betweenSymmetric` (null_, false)
938−TRUE BETWEEN SYMMETRIC NULL AND FALSE
941− :: Expression outer grp commons schemas params from (null ty)
942− -> ( Expression outer grp commons schemas params from (null ty)
943− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
944− -> Condition outer grp commons schemas params from
945−betweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
946− <+> "BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
948−{- | not between, after sorting the comparison values
949−>>> printSQL $ true `notBetweenSymmetric` (null_, false)
950−TRUE NOT BETWEEN SYMMETRIC NULL AND FALSE
953− :: Expression outer grp commons schemas params from (null ty)
954− -> ( Expression outer grp commons schemas params from (null ty)
955− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
956− -> Condition outer grp commons schemas params from
957−notBetweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
958− <+> "NOT BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
960−{- | not equal, treating null like an ordinary value
961−>>> printSQL $ true `isDistinctFrom` null_
962−(TRUE IS DISTINCT FROM NULL)
964−isDistinctFrom :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
965−isDistinctFrom = unsafeBinaryOp "IS DISTINCT FROM"
967−{- | equal, treating null like an ordinary value
968−>>> printSQL $ true `isNotDistinctFrom` null_
969−(TRUE IS NOT DISTINCT FROM NULL)
971−isNotDistinctFrom :: Operator (null0 ty) (null1 ty) ('NotNull 'PGbool)
972−isNotDistinctFrom = unsafeBinaryOp "IS NOT DISTINCT FROM"
975−>>> printSQL $ true & isTrue
978−isTrue :: null 'PGbool :--> 'NotNull 'PGbool
979−isTrue = unsafeUnaryOpR "IS TRUE"
981−{- | is false or unknown
982−>>> printSQL $ true & isNotTrue
985−isNotTrue :: null 'PGbool :--> 'NotNull 'PGbool
986−isNotTrue = unsafeUnaryOpR "IS NOT TRUE"
989−>>> printSQL $ true & isFalse
992−isFalse :: null 'PGbool :--> 'NotNull 'PGbool
993−isFalse = unsafeUnaryOpR "IS FALSE"
995−{- | is true or unknown
996−>>> printSQL $ true & isNotFalse
999−isNotFalse :: null 'PGbool :--> 'NotNull 'PGbool
1000−isNotFalse = unsafeUnaryOpR "IS NOT FALSE"
1003−>>> printSQL $ true & isUnknown
1006−isUnknown :: null 'PGbool :--> 'NotNull 'PGbool
1007−isUnknown = unsafeUnaryOpR "IS UNKNOWN"
1009−{- | is true or false
1010−>>> printSQL $ true & isNotUnknown
1011−(TRUE IS NOT UNKNOWN)
1013−isNotUnknown :: null 'PGbool :--> 'NotNull 'PGbool
1014−isNotUnknown = unsafeUnaryOpR "IS NOT UNKNOWN"
1016−-- | >>> printSQL currentDate
1018−currentDate :: Expr (null 'PGdate)
1019−currentDate = UnsafeExpression "CURRENT_DATE"
1021−-- | >>> printSQL currentTime
1023−currentTime :: Expr (null 'PGtimetz)
1024−currentTime = UnsafeExpression "CURRENT_TIME"
1026−-- | >>> printSQL currentTimestamp
1027−-- CURRENT_TIMESTAMP
1028−currentTimestamp :: Expr (null 'PGtimestamptz)
1029−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
1031−-- | >>> printSQL localTime
1033−localTime :: Expr (null 'PGtime)
1034−localTime = UnsafeExpression "LOCALTIME"
1036−-- | >>> printSQL localTimestamp
1038−localTimestamp :: Expr (null 'PGtimestamp)
1039−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
1041−{-----------------------------------------
1043−-----------------------------------------}
1045−escape :: Char -> String
1057instance IsString
439instance IsString
1058− (Expression outer grp commons schemas params from (null 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1059 fromString str = UnsafeExpression $
441 fromString str = UnsafeExpression $
1060 "E\'" <> fromString (escape =<< str) <> "\'"
442 "E\'" <> fromString (escape =<< str) <> "\'"
1061instance IsString
443instance IsString
1062− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1063− fromString str = cast tsvector . UnsafeExpression $
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
1064 "E\'" <> fromString (escape =<< str) <> "\'"
446 "E\'" <> fromString (escape =<< str) <> "\'"
1065instance IsString
447instance IsString
1066− (Expression outer grp commons schemas params from (null 'PGtsquery)) where
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
1067− fromString str = cast tsquery . UnsafeExpression $
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
1068 "E\'" <> fromString (escape =<< str) <> "\'"
450 "E\'" <> fromString (escape =<< str) <> "\'"
1070instance Semigroup
452instance Semigroup
1071− (Expression outer grp commons schemas params from (null 'PGtext)) where
453+ (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
1072 (<>) = unsafeBinaryOp "||"
454 (<>) = unsafeBinaryOp "||"
1073instance Semigroup
455instance Semigroup
456+ (Expression outer commons grp schemas params from (null 'PGjsonb)) where
457+ (<>) = unsafeBinaryOp "||"
459+ (Expression outer commons grp schemas params from (null 'PGtext)) where
460+ (<>) = unsafeBinaryOp "||"
1074− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
462+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1075 (<>) = unsafeBinaryOp "||"
463 (<>) = unsafeBinaryOp "||"
1077instance Monoid
465instance Monoid
1078− (Expression outer grp commons schemas params from (null 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1079 mempty = fromString ""
467 mempty = fromString ""
1080 mappend = (<>)
468 mappend = (<>)
1081instance Monoid
469instance Monoid
1082− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1083 mempty = fromString ""
471 mempty = fromString ""
1084 mappend = (<>)
472 mappend = (<>)
1086−-- | >>> printSQL $ lower "ARRRGGG"
1087−-- lower(E'ARRRGGG')
1088−lower :: null 'PGtext :--> null 'PGtext
1089−lower = unsafeFunction "lower"
1091−-- | >>> printSQL $ upper "eeee"
1093−upper :: null 'PGtext :--> null 'PGtext
1094−upper = unsafeFunction "upper"
1096−-- | >>> printSQL $ charLength "four"
1097−-- char_length(E'four')
1098−charLength :: null 'PGtext :--> null 'PGint4
1099−charLength = unsafeFunction "char_length"
1101−-- | The `like` expression returns true if the @string@ matches
1102−-- the supplied @pattern@. If @pattern@ does not contain percent signs
1103−-- or underscores, then the pattern only represents the string itself;
1104−-- in that case `like` acts like the equals operator. An underscore (_)
1105−-- in pattern stands for (matches) any single character; a percent sign (%)
1106−-- matches any sequence of zero or more characters.
1108−-- >>> printSQL $ "abc" `like` "a%"
1109−-- (E'abc' LIKE E'a%')
1110−like :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1111−like = unsafeBinaryOp "LIKE"
1113−-- | The key word ILIKE can be used instead of LIKE to make the
1114−-- match case-insensitive according to the active locale.
1116−-- >>> printSQL $ "abc" `ilike` "a%"
1117−-- (E'abc' ILIKE E'a%')
1118−ilike :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1119−ilike = unsafeBinaryOp "ILIKE"
1121−{-----------------------------------------
1122− -- json and jsonb support
1124−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1125−comments lifted directly from this page.
1127−Table 9.44: json and jsonb operators
1128−-----------------------------------------}
1130−-- | Get JSON value (object field or array element) at a key.
1132− :: (json `In` PGJsonType, key `In` PGJsonKey)
1133− => Operator (null json) (null key) ('Null json)
1135−(.->) = unsafeBinaryOp "->"
1137−-- | Get JSON value (object field or array element) at a key, as text.
1139− :: (json `In` PGJsonType, key `In` PGJsonKey)
1140− => Operator (null json) (null key) ('Null 'PGtext)
1142−(.->>) = unsafeBinaryOp "->>"
1144−-- | Get JSON value at a specified path.
1146− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1147− => Operator (null json) (null path) ('Null json)
1149−(.#>) = unsafeBinaryOp "#>"
1151−-- | Get JSON value at a specified path as text.
1153− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1154− => Operator (null json) (null path) ('Null 'PGtext)
1156−(.#>>) = unsafeBinaryOp "#>>"
1158−-- Additional jsonb operators
1160−-- | Does the left JSON value contain the right JSON path/value entries at the
1163− :: Operator (null 'PGjsonb) (null 'PGjsonb) ('Null 'PGbool)
1165−(.@>) = unsafeBinaryOp "@>"
1167−-- | Are the left JSON path/value entries contained at the top level within the
1168−-- right JSON value?
1169−(.<@) :: Operator (null 'PGjsonb) (null 'PGjsonb) ('Null 'PGbool)
1171−(.<@) = unsafeBinaryOp "<@"
1173−-- | Does the string exist as a top-level key within the JSON value?
1174−(.?) :: Operator (null 'PGjsonb) (null 'PGtext) ('Null 'PGbool)
1176−(.?) = unsafeBinaryOp "?"
1178−-- | Do any of these array strings exist as top-level keys?
1181− (null ('PGvararray ('NotNull 'PGtext)))
1184−(.?|) = unsafeBinaryOp "?|"
1186−-- | Do all of these array strings exist as top-level keys?
1189− (null ('PGvararray ('NotNull 'PGtext)))
1192−(.?&) = unsafeBinaryOp "?&"
1194−-- | Concatenate two jsonb values into a new jsonb value.
1196− (Expression outer grp commons schemas params from (null 'PGjsonb)) where
1197− (<>) = unsafeBinaryOp "||"
1199−-- | Delete a key or keys from a JSON object, or remove an array element.
1201−-- If the right operand is..
1203−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1204−-- are matched based on their key value.
1206−-- @ text[] @: Delete multiple key/value pairs or string elements
1207−-- from left operand. Key/value pairs are matched based on their key value.
1209−-- @ integer @: Delete the array element with specified index (Negative integers
1210−-- count from the end). Throws an error if top level container is not an array.
1212− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1213− => Operator (null 'PGjsonb) (null key) (null 'PGjsonb)
1215−(.-.) = unsafeBinaryOp "-"
1217−-- | Delete the field or element with specified path (for JSON arrays, negative
1218−-- integers count from the end)
1220− :: PGTextArray "(#-.)" arrayty
1221− => Operator (null 'PGjsonb) (null arrayty)(null 'PGjsonb)
1223−(#-.) = unsafeBinaryOp "#-"
1225−{-----------------------------------------
1226−Table 9.45: JSON creation functions
1227−-----------------------------------------}
1229−-- | Literal binary JSON
1230−jsonbLit :: JSON.ToJSON x => x -> Expr (null 'PGjsonb)
1231−jsonbLit = cast jsonb . UnsafeExpression
1232− . singleQuotedUtf8 . toStrict . JSON.encode
1235−jsonLit :: JSON.ToJSON x => x -> Expr (null 'PGjson)
1236−jsonLit = cast json . UnsafeExpression
1237− . singleQuotedUtf8 . toStrict . JSON.encode
1239−-- | Returns the value as json. Arrays and composites are converted
1240−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1241−-- type to json, the cast function will be used to perform the conversion;
1242−-- otherwise, a scalar value is produced. For any scalar type other than a
1243−-- number, a Boolean, or a null value, the text representation will be used, in
1244−-- such a fashion that it is a valid json value.
1245−toJson :: null ty :--> null 'PGjson
1246−toJson = unsafeFunction "to_json"
1248−-- | Returns the value as jsonb. Arrays and composites are converted
1249−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1250−-- type to json, the cast function will be used to perform the conversion;
1251−-- otherwise, a scalar value is produced. For any scalar type other than a
1252−-- number, a Boolean, or a null value, the text representation will be used, in
1253−-- such a fashion that it is a valid jsonb value.
1254−toJsonb :: null ty :--> null 'PGjsonb
1255−toJsonb = unsafeFunction "to_jsonb"
1257−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1258−-- becomes a JSON array of arrays.
1260− :: PGArray "arrayToJson" arr
1261− => null arr :--> null 'PGjson
1262−arrayToJson = unsafeFunction "array_to_json"
1264−-- | Returns the row as a JSON object.
1265−rowToJson :: null ('PGcomposite ty) :--> null 'PGjson
1266−rowToJson = unsafeFunction "row_to_json"
1268−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1272− => NP (Expression outer grp commons schemas params from) elems
1273− -> Expression outer grp commons schemas params from (null 'PGjson)
1274−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1276−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1277−-- variadic argument list.
1280− => NP (Expression outer grp commons schemas params from) elems
1281− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1282−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1285− :: SOP.SListI elems
1286− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1289− (`appEndo` []) . hcfoldMap (Proxy :: SOP.Proxy SOP.Top)
1290− (\(col `As` name) -> Endo $ \xs ->
1291− renderAliasString name : renderSQL col : xs)
1293− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1294− renderAliasString = singleQuotedText . fromString . symbolVal
1296−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1297−-- argument list. The elements of the argument list must alternate between text
1300− :: SOP.SListI elems
1301− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1302− -> Expression outer grp commons schemas params from (null 'PGjson)
1304− = unsafeFunction "json_build_object"
1307− . unsafeRowFunction
1309−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1310−-- variadic argument list. The elements of the argument list must alternate
1311−-- between text and values.
1313− :: SOP.SListI elems
1314− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1315− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1317− = unsafeFunction "jsonb_build_object"
1320− . unsafeRowFunction
1322−-- | Builds a JSON object out of a text array. The array must have either
1323−-- exactly one dimension with an even number of members, in which case they are
1324−-- taken as alternating key/value pairs, or two dimensions such that each inner
1325−-- array has exactly two elements, which are taken as a key/value pair.
1327− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1328− => null arr :--> null 'PGjson
1329−jsonObject = unsafeFunction "json_object"
1331−-- | Builds a binary JSON object out of a text array. The array must have either
1332−-- exactly one dimension with an even number of members, in which case they are
1333−-- taken as alternating key/value pairs, or two dimensions such that each inner
1334−-- array has exactly two elements, which are taken as a key/value pair.
1336− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1337− => null arr :--> null 'PGjsonb
1338−jsonbObject = unsafeFunction "jsonb_object"
1340−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1341−-- keys and one for values, that are zipped pairwise to create a JSON object.
1343− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1344− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1345− => Expression outer grp commons schemas params from (null keysArray)
1346− -> Expression outer grp commons schemas params from (null valuesArray)
1347− -> Expression outer grp commons schemas params from (null 'PGjson)
1348−jsonZipObject ks vs =
1349− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1351−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1352−-- keys and one for values, that are zipped pairwise to create a binary JSON
1355− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1356− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1357− => Expression outer grp commons schemas params from (null keysArray)
1358− -> Expression outer grp commons schemas params from (null valuesArray)
1359− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1360−jsonbZipObject ks vs =
1361− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1363−{-----------------------------------------
1364−Table 9.46: JSON processing functions
1365−-----------------------------------------}
1367−-- | Returns the number of elements in the outermost JSON array.
1368−jsonArrayLength :: null 'PGjson :--> null 'PGint4
1369−jsonArrayLength = unsafeFunction "json_array_length"
1371−-- | Returns the number of elements in the outermost binary JSON array.
1372−jsonbArrayLength :: null 'PGjsonb :--> null 'PGint4
1373−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1375−-- | Returns JSON value pointed to by the given path (equivalent to #>
1379− => Expression outer grp commons schemas params from (null 'PGjson)
1380− -> NP (Expression outer grp commons schemas params from) elems
1381− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1382−jsonExtractPath x xs =
1383− unsafeVariadicFunction "json_extract_path" (x :* xs)
1385−-- | Returns JSON value pointed to by the given path (equivalent to #>
1389− => Expression outer grp commons schemas params from (null 'PGjsonb)
1390− -> NP (Expression outer grp commons schemas params from) elems
1391− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1392−jsonbExtractPath x xs =
1393− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1395−-- | Returns JSON value pointed to by the given path (equivalent to #>
1396−-- operator), as text.
1397−jsonExtractPathAsText
1399− => Expression outer grp commons schemas params from (null 'PGjson)
1400− -> NP (Expression outer grp commons schemas params from) elems
1401− -> Expression outer grp commons schemas params from (null 'PGjson)
1402−jsonExtractPathAsText x xs =
1403− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1405−-- | Returns JSON value pointed to by the given path (equivalent to #>
1406−-- operator), as text.
1407−jsonbExtractPathAsText
1409− => Expression outer grp commons schemas params from (null 'PGjsonb)
1410− -> NP (Expression outer grp commons schemas params from) elems
1411− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1412−jsonbExtractPathAsText x xs =
1413− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1415−-- | Returns the type of the outermost JSON value as a text string. Possible
1416−-- types are object, array, string, number, boolean, and null.
1417−jsonTypeof :: null 'PGjson :--> null 'PGtext
1418−jsonTypeof = unsafeFunction "json_typeof"
1420−-- | Returns the type of the outermost binary JSON value as a text string.
1421−-- Possible types are object, array, string, number, boolean, and null.
1422−jsonbTypeof :: null 'PGjsonb :--> null 'PGtext
1423−jsonbTypeof = unsafeFunction "jsonb_typeof"
1425−-- | Returns its argument with all object fields that have null values omitted.
1426−-- Other null values are untouched.
1427−jsonStripNulls :: null 'PGjson :--> null 'PGjson
1428−jsonStripNulls = unsafeFunction "json_strip_nulls"
1430−-- | Returns its argument with all object fields that have null values omitted.
1431−-- Other null values are untouched.
1432−jsonbStripNulls :: null 'PGjsonb :--> null 'PGjsonb
1433−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1435−-- | @ jsonbSet target path new_value create_missing @
1437−-- Returns target with the section designated by path replaced by new_value,
1438−-- or with new_value added if create_missing is true ( default is true) and the
1439−-- item designated by path does not exist. As with the path orientated
1440−-- operators, negative integers that appear in path count from the end of JSON
1443− :: PGTextArray "jsonbSet" arr
1444− => Expression outer grp commons schemas params from (null 'PGjsonb)
1445− -> Expression outer grp commons schemas params from (null arr)
1446− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1447− -> Maybe (Expression outer grp commons schemas params from (null 'PGbool))
1448− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1449−jsonbSet tgt path val createMissing = case createMissing of
1450− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1451− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1453−-- | @ jsonbInsert target path new_value insert_after @
1455−-- Returns target with new_value inserted. If target section designated by
1456−-- path is in a JSONB array, new_value will be inserted before target or after
1457−-- if insert_after is true (default is false). If target section designated by
1458−-- path is in JSONB object, new_value will be inserted only if target does not
1459−-- exist. As with the path orientated operators, negative integers that appear
1460−-- in path count from the end of JSON arrays.
1462− :: PGTextArray "jsonbInsert" arr
1463− => Expression outer grp commons schemas params from (null 'PGjsonb)
1464− -> Expression outer grp commons schemas params from (null arr)
1465− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1466− -> Maybe (Expression outer grp commons schemas params from (null 'PGbool))
1467− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1468−jsonbInsert tgt path val insertAfter = case insertAfter of
1469− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1470− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1472−-- | Returns its argument as indented JSON text.
1473−jsonbPretty :: null 'PGjsonb :--> null 'PGtext
1474−jsonbPretty = unsafeFunction "jsonb_pretty"
1476−(@@) :: Operator (null 'PGtsvector) (null 'PGtsquery) ('Null 'PGbool)
1477−(@@) = unsafeBinaryOp "@@"
1479−(.&) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1480−(.&) = unsafeBinaryOp "&&"
1482−(.|) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1483−(.|) = unsafeBinaryOp "||"
1485−(.!) :: null 'PGtsquery :--> null 'PGtsquery
1486−(.!) = unsafeUnaryOpL "!!"
1488−(<->) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1489−(<->) = unsafeBinaryOp "<->"
1492− :: null ('PGvararray ('NotNull 'PGtext))
1493− :--> null 'PGtsvector
1494−arrayToTSvector = unsafeFunction "array_to_tsvector"
1496−tsvectorLength :: null 'PGtsvector :--> null 'PGint4
1497−tsvectorLength = unsafeFunction "length"
1499−numnode :: null 'PGtsquery :--> null 'PGint4
1500−numnode = unsafeFunction "numnode"
1503− :: FunctionHet '[null 'PGtext, null 'PGtext] (null 'PGtsquery)
1504−plainToTSquery = unsafeFunctionHet "plainto_tsquery"
1507− :: FunctionHet '[null 'PGtext, null 'PGtext] (null 'PGtsquery)
1508−phraseToTSquery = unsafeFunctionHet "phraseto_tsquery"
1511− :: FunctionHet '[null 'PGtext, null 'PGtext] (null 'PGtsquery)
1512−websearchToTSquery = unsafeFunctionHet "websearch_to_tsquery"
1514−queryTree :: null 'PGtsquery :--> null 'PGtext
1515−queryTree = unsafeFunction "query_tree"
1518− :: FunctionHet '[null 'PGtext, null 'PGtext] (null 'PGtsquery)
1519−toTSquery = unsafeFunctionHet "to_tsquery"
1522− :: ty `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1523− => FunctionHet '[null 'PGtext, null ty] (null 'PGtsquery)
1524−toTSvector = unsafeFunctionHet "to_tsvector"
1526−{-----------------------------------------
1528−-----------------------------------------}
1531−`Aggregate` functions compute a single result from a set of input values.
1532−`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1533−as `WindowFunction`s.
1535−class Aggregate expr1 expr2 aggr
1536− | aggr -> expr1, aggr -> expr2 where
1538− -- | A special aggregation that does not require an input
1542− -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1543− -- expression = countStar
1544− -- in printSQL expression
1547− countStar :: aggr ('NotNull 'PGint8)
1551− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null ty]] ('NotNull 'PGint8)
1552− -- expression = count (All #col)
1553− -- in printSQL expression
1555− -- count(ALL "col")
1559− -> aggr ('NotNull 'PGint8)
1563− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('NotNull 'PGnumeric)
1564− -- expression = sum_ (Distinct #col)
1565− -- in printSQL expression
1567− -- sum(DISTINCT "col")
1571− -> aggr ('NotNull ty)
1573− -- | input values, including nulls, concatenated into an array
1576− -> aggr ('Null ('PGvararray ty))
1578− -- | aggregates values as a JSON array
1581− -> aggr ('Null 'PGjson)
1583− -- | aggregates values as a JSON array
1586− -> aggr ('Null 'PGjsonb)
1589− the bitwise AND of all non-null input values, or null if none
1592− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1593− expression = bitAnd (Distinct #col)
1594− in printSQL expression
1596− bit_and(DISTINCT "col")
1599− :: int `In` PGIntegral
1600− => expr1 (null int)
1601− -- ^ what to aggregate
1602− -> aggr ('Null int)
1605− the bitwise OR of all non-null input values, or null if none
1609− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1610− expression = bitOr (All #col)
1611− in printSQL expression
1616− :: int `In` PGIntegral
1617− => expr1 (null int)
1618− -- ^ what to aggregate
1619− -> aggr ('Null int)
1622− true if all input values are true, otherwise false
1626− winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1627− winFun = boolAnd #col
1633− :: expr1 (null 'PGbool)
1634− -- ^ what to aggregate
1635− -> aggr ('Null 'PGbool)
1638− true if at least one input value is true, otherwise false
1642− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1643− expression = boolOr (All #col)
1644− in printSQL expression
1649− :: expr1(null 'PGbool)
1650− -- ^ what to aggregate
1651− -> aggr ('Null 'PGbool)
1654− equivalent to `boolAnd`
1658− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1659− expression = every (Distinct #col)
1660− in printSQL expression
1662− every(DISTINCT "col")
1665− :: expr1 (null 'PGbool)
1666− -- ^ what to aggregate
1667− -> aggr ('Null 'PGbool)
1669− {- |maximum value of expression across all input values-}
1672− -- ^ what to maximize
1675− -- | minimum value of expression across all input values
1678− -- ^ what to minimize
1681− -- | the average (arithmetic mean) of all input values
1684− -- ^ what to average
1685− -> aggr ('Null (PGAvg ty))
1687− {- | correlation coefficient
1690− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1691− expression = corr (All (#y :*: #x))
1692− in printSQL expression
1697− :: expr2 (null 'PGfloat8)
1698− -> aggr ('Null 'PGfloat8)
1700− {- | population covariance
1703− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1704− expression = covarPop (All (#y :*: #x))
1705− in printSQL expression
1707− covar_pop(ALL "y", "x")
1710− :: expr2 (null 'PGfloat8)
1711− -> aggr ('Null 'PGfloat8)
1713− {- | sample covariance
1716− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1717− winFun = covarSamp (#y :*: #x)
1720− covar_samp("y", "x")
1723− :: expr2 (null 'PGfloat8)
1724− -> aggr ('Null 'PGfloat8)
1726− {- | average of the independent variable (sum(X)/N)
1729− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1730− expression = regrAvgX (All (#y :*: #x))
1731− in printSQL expression
1733− regr_avgx(ALL "y", "x")
1736− :: expr2 (null 'PGfloat8)
1737− -> aggr ('Null 'PGfloat8)
1739− {- | average of the dependent variable (sum(Y)/N)
1742− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1743− winFun = regrAvgY (#y :*: #x)
1746− regr_avgy("y", "x")
1749− :: expr2 (null 'PGfloat8)
1750− -> aggr ('Null 'PGfloat8)
1752− {- | number of input rows in which both expressions are nonnull
1755− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGint8)
1756− winFun = regrCount (#y :*: #x)
1759− regr_count("y", "x")
1762− :: expr2 (null 'PGfloat8)
1763− -> aggr ('Null 'PGint8)
1765− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1768− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1769− expression = regrIntercept (All (#y :*: #x))
1770− in printSQL expression
1772− regr_intercept(ALL "y", "x")
1775− :: expr2 (null 'PGfloat8)
1776− -> aggr ('Null 'PGfloat8)
1778− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1780− :: expr2 (null 'PGfloat8)
1781− -> aggr ('Null 'PGfloat8)
1783− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1784− -- determined by the (X, Y) pairs
1786− :: expr2 (null 'PGfloat8)
1787− -> aggr ('Null 'PGfloat8)
1789− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1790− -- (“sum of squares” of the independent variable)
1792− :: expr2 (null 'PGfloat8)
1793− -> aggr ('Null 'PGfloat8)
1795− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1796− -- (“sum of products” of independent times dependent variable)
1798− :: expr2 (null 'PGfloat8)
1799− -> aggr ('Null 'PGfloat8)
1801− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1802− -- (“sum of squares” of the dependent variable)
1804− :: expr2 (null 'PGfloat8)
1805− -> aggr ('Null 'PGfloat8)
1807− -- | historical alias for `stddevSamp`
1810− -> aggr ('Null (PGAvg ty))
1812− -- | population standard deviation of the input values
1815− -> aggr ('Null (PGAvg ty))
1817− -- | sample standard deviation of the input values
1820− -> aggr ('Null (PGAvg ty))
1822− -- | historical alias for `varSamp`
1825− -> aggr ('Null (PGAvg ty))
1827− -- | population variance of the input values
1828− -- (square of the population standard deviation)
1831− -> aggr ('Null (PGAvg ty))
1833− -- | sample variance of the input values
1834− -- (square of the sample standard deviation)
1837− -> aggr ('Null (PGAvg ty))
1840−`Distinction`s are used for the input of `Aggregate` `Expression`s.
1841−`All` invokes the aggregate once for each input row.
1842−`Distinct` invokes the aggregate once for each distinct value of the expression
1843−(or distinct set of values, for multiple expressions) found in the input
1845−data Distinction expr ty
1847− | Distinct (expr ty)
1848− deriving (GHC.Generic,Show,Eq,Ord)
1849−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1850−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1852− All x -> "ALL" <+> renderSQL x
1853− Distinct x -> "DISTINCT" <+> renderSQL x
1856− ( Expression outer grp commons schemas params from
1858− Expression outer grp commons schemas params from) xty ) where
1861− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1862− Distinct (x :*: x') ->
1863− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1866− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1867− (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1868− (Expression outer ('Grouped bys) commons schemas params from) where
1869− countStar = UnsafeExpression "count(*)"
1870− count = unsafeAggregate1 "count"
1871− sum_ = unsafeAggregate1 "sum"
1872− arrayAgg = unsafeAggregate1 "array_agg"
1873− jsonAgg = unsafeAggregate1 "json_agg"
1874− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1875− bitAnd = unsafeAggregate1 "bit_and"
1876− bitOr = unsafeAggregate1 "bit_or"
1877− boolAnd = unsafeAggregate1 "bool_and"
1878− boolOr = unsafeAggregate1 "bool_or"
1879− every = unsafeAggregate1 "every"
1880− max_ = unsafeAggregate1 "max"
1881− min_ = unsafeAggregate1 "min"
1882− avg = unsafeAggregate1 "avg"
1883− corr = unsafeAggregate2 "corr"
1884− covarPop = unsafeAggregate2 "covar_pop"
1885− covarSamp = unsafeAggregate2 "covar_samp"
1886− regrAvgX = unsafeAggregate2 "regr_avgx"
1887− regrAvgY = unsafeAggregate2 "regr_avgy"
1888− regrCount = unsafeAggregate2 "regr_count"
1889− regrIntercept = unsafeAggregate2 "regr_intercept"
1890− regrR2 = unsafeAggregate2 "regr_r2"
1891− regrSlope = unsafeAggregate2 "regr_slope"
1892− regrSxx = unsafeAggregate2 "regr_sxx"
1893− regrSxy = unsafeAggregate2 "regr_sxy"
1894− regrSyy = unsafeAggregate2 "regr_syy"
1895− stddev = unsafeAggregate1 "stddev"
1896− stddevPop = unsafeAggregate1 "stddev_pop"
1897− stddevSamp = unsafeAggregate1 "stddev_samp"
1898− variance = unsafeAggregate1 "variance"
1899− varPop = unsafeAggregate1 "var_pop"
1900− varSamp = unsafeAggregate1 "var_samp"
1902− (Expression outer grp commons schemas params from)
1903− (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1904− (WindowFunction outer grp commons schemas params from) where
1905− countStar = UnsafeWindowFunction "count(*)"
1906− count = unsafeWindowFunction1 "count"
1907− sum_ = unsafeWindowFunction1 "sum"
1908− arrayAgg = unsafeWindowFunction1 "array_agg"
1909− jsonAgg = unsafeWindowFunction1 "json_agg"
1910− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1911− bitAnd = unsafeWindowFunction1 "bit_and"
1912− bitOr = unsafeWindowFunction1 "bit_or"
1913− boolAnd = unsafeWindowFunction1 "bool_and"
1914− boolOr = unsafeWindowFunction1 "bool_or"
1915− every = unsafeWindowFunction1 "every"
1916− max_ = unsafeWindowFunction1 "max"
1917− min_ = unsafeWindowFunction1 "min"
1918− avg = unsafeWindowFunction1 "avg"
1919− corr = unsafeWindowFunction2 "corr"
1920− covarPop = unsafeWindowFunction2 "covar_pop"
1921− covarSamp = unsafeWindowFunction2 "covar_samp"
1922− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1923− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1924− regrCount = unsafeWindowFunction2 "regr_count"
1925− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1926− regrR2 = unsafeWindowFunction2 "regr_r2"
1927− regrSlope = unsafeWindowFunction2 "regr_slope"
1928− regrSxx = unsafeWindowFunction2 "regr_sxx"
1929− regrSxy = unsafeWindowFunction2 "regr_sxy"
1930− regrSyy = unsafeWindowFunction2 "regr_syy"
1931− stddev = unsafeWindowFunction1 "stddev"
1932− stddevPop = unsafeWindowFunction1 "stddev_pop"
1933− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1934− variance = unsafeWindowFunction1 "variance"
1935− varPop = unsafeWindowFunction1 "var_pop"
1936− varSamp = unsafeWindowFunction1 "var_samp"
1938−-- | escape hatch to define aggregate functions
1940− :: ByteString -- ^ aggregate function
1941− -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1942− -> Expression outer ('Grouped bys) commons schemas params from yty
1943−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1944− [fun, "(", renderSQL x, ")"]
1946−-- | escape hatch to define aggregate binary functions
1948− :: ByteString -- ^ aggregate function
1949− -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1950− -> Expression outer ('Grouped bys) commons schemas params from yty
1951−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1952− [fun, "(", renderSQL xx, ")"]
1954−-- | A type family that calculates `PGAvg` type of a `PGType`.
1955−type family PGAvg ty where
1956− PGAvg 'PGint2 = 'PGnumeric
1957− PGAvg 'PGint4 = 'PGnumeric
1958− PGAvg 'PGint8 = 'PGnumeric
1959− PGAvg 'PGnumeric = 'PGnumeric
1960− PGAvg 'PGfloat4 = 'PGfloat8
1961− PGAvg 'PGfloat8 = 'PGfloat8
1962− PGAvg 'PGinterval = 'PGinterval
1963− PGAvg pg = TypeError
1964− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1966−{-----------------------------------------
1968−-----------------------------------------}
1970−-- | `TypeExpression`s are used in `cast`s and
1971−-- `Squeal.PostgreSQL.Definition.createTable` commands.
1972−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1973− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1974− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1975−instance RenderSQL (TypeExpression schemas ty) where
1976− renderSQL = renderTypeExpression
1978−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1980− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1981− => QualifiedAlias sch td
1982− -> TypeExpression schemas (null ty)
1983−typedef = UnsafeTypeExpression . renderSQL
1985−-- | The composite type corresponding to a `Table` definition can be expressed
1988− :: (Has sch schemas schema, Has tab schema ('Table table))
1989− => QualifiedAlias sch tab
1990− -> TypeExpression schemas (null ('PGcomposite (TableToRow table)))
1991−typetable = UnsafeTypeExpression . renderSQL
1993−-- | The composite type corresponding to a `View` definition can be expressed
1996− :: (Has sch schemas schema, Has vw schema ('View view))
1997− => QualifiedAlias sch vw
1998− -> TypeExpression schemas (null ('PGcomposite view))
1999−typeview = UnsafeTypeExpression . renderSQL
2001−-- | logical Boolean (true/false)
2002−bool :: TypeExpression schemas (null 'PGbool)
2003−bool = UnsafeTypeExpression "bool"
2004−-- | signed two-byte integer
2005−int2, smallint :: TypeExpression schemas (null 'PGint2)
2006−int2 = UnsafeTypeExpression "int2"
2007−smallint = UnsafeTypeExpression "smallint"
2008−-- | signed four-byte integer
2009−int4, int, integer :: TypeExpression schemas (null 'PGint4)
2010−int4 = UnsafeTypeExpression "int4"
2011−int = UnsafeTypeExpression "int"
2012−integer = UnsafeTypeExpression "integer"
2013−-- | signed eight-byte integer
2014−int8, bigint :: TypeExpression schemas (null 'PGint8)
2015−int8 = UnsafeTypeExpression "int8"
2016−bigint = UnsafeTypeExpression "bigint"
2017−-- | arbitrary precision numeric type
2018−numeric :: TypeExpression schemas (null 'PGnumeric)
2019−numeric = UnsafeTypeExpression "numeric"
2020−-- | single precision floating-point number (4 bytes)
2021−float4, real :: TypeExpression schemas (null 'PGfloat4)
2022−float4 = UnsafeTypeExpression "float4"
2023−real = UnsafeTypeExpression "real"
2024−-- | double precision floating-point number (8 bytes)
2025−float8, doublePrecision :: TypeExpression schemas (null 'PGfloat8)
2026−float8 = UnsafeTypeExpression "float8"
2027−doublePrecision = UnsafeTypeExpression "double precision"
2028−-- | currency amount
2029−money :: TypeExpression schema (null 'PGmoney)
2030−money = UnsafeTypeExpression "money"
2031−-- | variable-length character string
2032−text :: TypeExpression schemas (null 'PGtext)
2033−text = UnsafeTypeExpression "text"
2034−-- | fixed-length character string
2036− :: forall n schemas null. (KnownNat n, 1 <= n)
2037− => TypeExpression schemas (null ('PGchar n))
2038−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
2039−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
2040−-- | variable-length character string
2041−varchar, characterVarying
2042− :: forall n schemas null. (KnownNat n, 1 <= n)
2043− => TypeExpression schemas (null ('PGvarchar n))
2044−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
2045−characterVarying = UnsafeTypeExpression $
2046− "character varying(" <> renderNat @n <> ")"
2047−-- | binary data ("byte array")
2048−bytea :: TypeExpression schemas (null 'PGbytea)
2049−bytea = UnsafeTypeExpression "bytea"
2050−-- | date and time (no time zone)
2051−timestamp :: TypeExpression schemas (null 'PGtimestamp)
2052−timestamp = UnsafeTypeExpression "timestamp"
2053−-- | date and time, including time zone
2054−timestampWithTimeZone :: TypeExpression schemas (null 'PGtimestamptz)
2055−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
2056−-- | calendar date (year, month, day)
2057−date :: TypeExpression schemas (null 'PGdate)
2058−date = UnsafeTypeExpression "date"
2059−-- | time of day (no time zone)
2060−time :: TypeExpression schemas (null 'PGtime)
2061−time = UnsafeTypeExpression "time"
2062−-- | time of day, including time zone
2063−timeWithTimeZone :: TypeExpression schemas (null 'PGtimetz)
2064−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
2066−interval :: TypeExpression schemas (null 'PGinterval)
2067−interval = UnsafeTypeExpression "interval"
2068−-- | universally unique identifier
2069−uuid :: TypeExpression schemas (null 'PGuuid)
2070−uuid = UnsafeTypeExpression "uuid"
2071−-- | IPv4 or IPv6 host address
2072−inet :: TypeExpression schemas (null 'PGinet)
2073−inet = UnsafeTypeExpression "inet"
2074−-- | textual JSON data
2075−json :: TypeExpression schemas (null 'PGjson)
2076−json = UnsafeTypeExpression "json"
2077−-- | binary JSON data, decomposed
2078−jsonb :: TypeExpression schemas (null 'PGjsonb)
2079−jsonb = UnsafeTypeExpression "jsonb"
2080−-- | variable length array
2082− :: TypeExpression schemas pg
2083− -> TypeExpression schemas (null ('PGvararray pg))
2084−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
2085−-- | fixed length array
2087−-- >>> renderSQL (fixarray @'[2] json)
2090− :: forall dims schemas null pg. SOP.All KnownNat dims
2091− => TypeExpression schemas pg
2092− -> TypeExpression schemas (null ('PGfixarray dims pg))
2093−fixarray ty = UnsafeTypeExpression $
2094− renderSQL ty <> renderDims @dims
2096− renderDims :: forall ns. SOP.All KnownNat ns => ByteString
2100− . ByteString.intercalate "]["
2102− $ hcmap (SOP.Proxy @KnownNat)
2103− (K . fromString . show . natVal)
2104− (hpure SOP.Proxy :: NP SOP.Proxy ns)
2105−tsvector :: TypeExpression schemas (null 'PGtsvector)
2106−tsvector = UnsafeTypeExpression "tsvector"
2107−tsquery :: TypeExpression schemas (null 'PGtsquery)
2108−tsquery = UnsafeTypeExpression "tsquery"
2110−-- | `pgtype` is a demoted version of a `PGType`
2111−class PGTyped schemas (ty :: NullityType) where
2112− pgtype :: TypeExpression schemas ty
2113−instance PGTyped schemas (null 'PGbool) where pgtype = bool
2114−instance PGTyped schemas (null 'PGint2) where pgtype = int2
2115−instance PGTyped schemas (null 'PGint4) where pgtype = int4
2116−instance PGTyped schemas (null 'PGint8) where pgtype = int8
2117−instance PGTyped schemas (null 'PGnumeric) where pgtype = numeric
2118−instance PGTyped schemas (null 'PGfloat4) where pgtype = float4
2119−instance PGTyped schemas (null 'PGfloat8) where pgtype = float8
2120−instance PGTyped schemas (null 'PGmoney) where pgtype = money
2121−instance PGTyped schemas (null 'PGtext) where pgtype = text
2122−instance (KnownNat n, 1 <= n)
2123− => PGTyped schemas (null ('PGchar n)) where pgtype = char @n
2124−instance (KnownNat n, 1 <= n)
2125− => PGTyped schemas (null ('PGvarchar n)) where pgtype = varchar @n
2126−instance PGTyped schemas (null 'PGbytea) where pgtype = bytea
2127−instance PGTyped schemas (null 'PGtimestamp) where pgtype = timestamp
2128−instance PGTyped schemas (null 'PGtimestamptz) where pgtype = timestampWithTimeZone
2129−instance PGTyped schemas (null 'PGdate) where pgtype = date
2130−instance PGTyped schemas (null 'PGtime) where pgtype = time
2131−instance PGTyped schemas (null 'PGtimetz) where pgtype = timeWithTimeZone
2132−instance PGTyped schemas (null 'PGinterval) where pgtype = interval
2133−instance PGTyped schemas (null 'PGuuid) where pgtype = uuid
2134−instance PGTyped schemas (null 'PGjson) where pgtype = json
2135−instance PGTyped schemas (null 'PGjsonb) where pgtype = jsonb
2136−instance PGTyped schemas ty
2137− => PGTyped schemas (null ('PGvararray ty)) where
2138− pgtype = vararray (pgtype @schemas @ty)
2139−instance (SOP.All KnownNat dims, PGTyped schemas ty)
2140− => PGTyped schemas (null ('PGfixarray dims ty)) where
2141− pgtype = fixarray @dims (pgtype @schemas @ty)
2142−instance PGTyped schemas (null 'PGtsvector) where pgtype = tsvector
2143−instance PGTyped schemas (null 'PGtsquery) where pgtype = tsquery
2145−{-----------------------------------------
2147−-----------------------------------------}
2149−-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2150−-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2151−-- set the sort direction of a `NotNull` result
2152−-- column to ascending or descending. Ascending order puts smaller values
2153−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2154−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2155−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2156−-- determine whether nulls appear before or after non-null values in the sort
2157−-- ordering of a `Null` result column.
2158−data SortExpression outer grp commons schemas params from where
2160− :: Expression outer grp commons schemas params from ('NotNull ty)
2161− -> SortExpression outer grp commons schemas params from
2163− :: Expression outer grp commons schemas params from ('NotNull ty)
2164− -> SortExpression outer grp commons schemas params from
2166− :: Expression outer grp commons schemas params from ('Null ty)
2167− -> SortExpression outer grp commons schemas params from
2169− :: Expression outer grp commons schemas params from ('Null ty)
2170− -> SortExpression outer grp commons schemas params from
2172− :: Expression outer grp commons schemas params from ('Null ty)
2173− -> SortExpression outer grp commons schemas params from
2175− :: Expression outer grp commons schemas params from ('Null ty)
2176− -> SortExpression outer grp commons schemas params from
2177−deriving instance Show (SortExpression outer grp commons schemas params from)
2180−The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2181−to be sorted according to the specified `SortExpression`(s).
2182−If two rows are equal according to the leftmost expression,
2183−they are compared according to the next expression and so on.
2184−If they are equal according to all specified expressions,
2185−they are returned in an implementation-dependent order.
2187−You can also control the order in which rows are processed by window functions
2188−using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2190−class OrderBy expr where
2192− :: [SortExpression outer grp commons schemas params from]
2193− -> expr outer grp commons schemas params from
2194− -> expr outer grp commons schemas params from
2196−-- | Render a `SortExpression`.
2197−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2199− Asc expression -> renderSQL expression <+> "ASC"
2200− Desc expression -> renderSQL expression <+> "DESC"
2201− AscNullsFirst expression -> renderSQL expression
2202− <+> "ASC NULLS FIRST"
2203− DescNullsFirst expression -> renderSQL expression
2204− <+> "DESC NULLS FIRST"
2205− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2206− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2208−-- | A `WindowDefinition` is a set of table rows that are somehow related
2209−-- to the current row
2210−data WindowDefinition outer grp commons schemas params from where
2213− => NP (Expression outer grp commons schemas params from) bys
2214− -> [SortExpression outer grp commons schemas params from]
2215− -> WindowDefinition outer grp commons schemas params from
2217−instance OrderBy WindowDefinition where
2218− orderBy sortsR (WindowDefinition parts sortsL)
2219− = WindowDefinition parts (sortsL ++ sortsR)
2221−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2222− renderSQL (WindowDefinition part ord) =
2223− renderPartitionByClause part <> renderOrderByClause ord
2225− renderPartitionByClause = \case
2227− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2228− renderOrderByClause = \case
2230− srts -> " ORDER" <+> "BY"
2231− <+> commaSeparated (renderSQL <$> srts)
2234−The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2235−or partitions, that share the same values of the `partitionBy` `Expression`(s).
2236−For each row, the window function is computed across the rows that fall into
2237−the same partition as the current row.
2241− => NP (Expression outer grp commons schemas params from) bys
2242− -> WindowDefinition outer grp commons schemas params from
2243−partitionBy bys = WindowDefinition bys []
2246−A window function performs a calculation across a set of table rows
2247−that are somehow related to the current row. This is comparable to the type
2248−of calculation that can be done with an aggregate function.
2249−However, window functions do not cause rows to become grouped into a single
2250−output row like non-window aggregate calls would.
2251−Instead, the rows retain their separate identities.
2252−Behind the scenes, the window function is able to access more than
2253−just the current row of the query result.
2255−newtype WindowFunction
2256− (outer :: FromType)
2258− (commons :: FromType)
2259− (schemas :: SchemasType)
2260− (params :: [NullityType])
2262− (ty :: NullityType)
2263− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2264− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2266−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2267− renderSQL = renderWindowFunction
2269−unsafeWindowFunction1
2271− -> Expression outer grp commons schemas params from ty0
2272− -> WindowFunction outer grp commons schemas params from ty1
2273−unsafeWindowFunction1 fun x
2274− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2276−unsafeWindowFunction2
2278− -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2279− -> WindowFunction outer grp commons schemas params from ty1
2280−unsafeWindowFunction2 fun (x :*: x')
2281− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2283−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2287−rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2288−rank = UnsafeWindowFunction "rank()"
2290−{- | number of the current row within its partition, counting from 1
2291−>>> printSQL rowNumber
2294−rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2295−rowNumber = UnsafeWindowFunction "row_number()"
2297−{- | rank of the current row without gaps; this function counts peer groups
2298−>>> printSQL denseRank
2301−denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2302−denseRank = UnsafeWindowFunction "dense_rank()"
2304−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2305−>>> printSQL percentRank
2308−percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2309−percentRank = UnsafeWindowFunction "percent_rank()"
2311−{- | cumulative distribution: (number of partition rows
2312−preceding or peer with current row) / total partition rows
2313−>>> printSQL cumeDist
2316−cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2317−cumeDist = UnsafeWindowFunction "cume_dist()"
2319−{- | integer ranging from 1 to the argument value,
2320−dividing the partition as equally as possible
2323− :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2325− -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2326−ntile = unsafeWindowFunction1 "ntile"
2328−{- | returns value evaluated at the row that is offset rows before the current
2329−row within the partition; if there is no such row, instead return default
2330−(which must be of the same type as value). Both offset and default are
2331−evaluated with respect to the current row.
2334− :: Expression outer grp commons schemas params from ty
2336− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2338− -> Expression outer grp commons schemas params from ty
2340− -> WindowFunction outer grp commons schemas params from ty
2341−lag value offset def = UnsafeWindowFunction $ "lag"
2343− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2345−{- | returns value evaluated at the row that is offset rows after the current
2346−row within the partition; if there is no such row, instead return default
2347−(which must be of the same type as value). Both offset and default are
2348−evaluated with respect to the current row.
2351− :: Expression outer grp commons schemas params from ty
2353− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2355− -> Expression outer grp commons schemas params from ty
2357− -> WindowFunction outer grp commons schemas params from ty
2358−lead value offset def = UnsafeWindowFunction $ "lag"
2360− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2362−{- | returns value evaluated at the row that is the
2363−first row of the window frame
2366− :: Expression outer grp commons schemas params from ty
2368− -> WindowFunction outer grp commons schemas params from ty
2369−firstValue = unsafeWindowFunction1 "first_value"
2371−{- | returns value evaluated at the row that is the
2372−last row of the window frame
2375− :: Expression outer grp commons schemas params from ty
2377− -> WindowFunction outer grp commons schemas params from ty
2378−lastValue = unsafeWindowFunction1 "last_value"
2380−{- | returns value evaluated at the row that is the nth
2381−row of the window frame (counting from 1); null if no such row
2384− :: Expression outer grp commons schemas params from (null ty)
2386− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2388− -> WindowFunction outer grp commons schemas params from ('Null ty)
2389−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2390− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])
2393−Create date from year, month and day fields
2395−>>> printSQL (makeDate (1984 :* 7 *: 3))
2396−make_date(1984, 7, 3)
2398−makeDate :: FunctionHet
2399− '[ null 'PGint4, null 'PGint4, null 'PGint4 ]
2401−makeDate = unsafeFunctionHet "make_date"
2404−Create time from hour, minute and seconds fields
2406−>>> printSQL (makeTime (8 :* 15 *: 23.5))
2407−make_time(8, 15, 23.5)
2409−makeTime :: FunctionHet
2410− '[ null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2412−makeTime = unsafeFunctionHet "make_time"
2415−Create timestamp from year, month, day, hour, minute and seconds fields
2417−>>> printSQL (makeTimestamp (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2418−make_timestamp(2013, 7, 15, 8, 15, 23.5)
2420−makeTimestamp :: FunctionHet
2421− '[ null 'PGint4, null 'PGint4, null 'PGint4
2422− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2423− ( null 'PGtimestamp )
2424−makeTimestamp = unsafeFunctionHet "make_timestamp"
2427−Create timestamp with time zone from
2428−year, month, day, hour, minute and seconds fields;
2429−the current time zone is used
2431−>>> printSQL (makeTimestamptz (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2432−make_timestamptz(2013, 7, 15, 8, 15, 23.5)
2434−makeTimestamptz :: FunctionHet
2435− '[ null 'PGint4, null 'PGint4, null 'PGint4
2436− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2437− ( null 'PGtimestamptz )
2438−makeTimestamptz = unsafeFunctionHet "make_timestamptz"
2441−Affine space operations on time types.
2443−class TimeOp time diff | time -> diff where
2445− >>> printSQL (makeDate (1984 :* 7 *: 3) !+ 365)
2446− (make_date(1984, 7, 3) + 365)
2448− (!+) :: Operator (null time) (null diff) (null time)
2449− (!+) = unsafeBinaryOp "+"
2451− >>> printSQL (365 +! makeDate (1984 :* 7 *: 3))
2452− (365 + make_date(1984, 7, 3))
2454− (+!) :: Operator (null diff) (null time) (null time)
2455− (+!) = unsafeBinaryOp "+"
2457− >>> printSQL (makeDate (1984 :* 7 *: 3) !- 365)
2458− (make_date(1984, 7, 3) - 365)
2460− (!-) :: Operator (null time) (null diff) (null time)
2461− (!-) = unsafeBinaryOp "-"
2463− >>> printSQL (makeDate (1984 :* 7 *: 3) !-! currentDate)
2464− (make_date(1984, 7, 3) - CURRENT_DATE)
2466− (!-!) :: Operator (null time) (null time) (null diff)
2467− (!-!) = unsafeBinaryOp "-"
2468−instance TimeOp 'PGtimestamp 'PGinterval
2469−instance TimeOp 'PGtimestamptz 'PGinterval
2470−instance TimeOp 'PGtime 'PGinterval
2471−instance TimeOp 'PGtimetz 'PGinterval
2472−instance TimeOp 'PGinterval 'PGinterval
2473−instance TimeOp 'PGdate 'PGint4