@@ -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,389 +34,213 @@ module Squeal.PostgreSQL.Expression
35 ( -- * Expression
34 ( -- * Expression
36 Expression (..)
35 Expression (..)
38 , Operator
45 , Operator
39− , (:-->)
46+ , OperatorDB
40− , HasParameter (parameter)
59 , unsafeBinaryOp
47 , unsafeBinaryOp
60− , unsafeUnaryOpL
48+ , binaryOp
61− , unsafeUnaryOpR
49+ , FunctionVar
62− , unsafeFunction
50+ , unsafeFunctionVar
63− , unsafeFunctionHet
51+ , type (--->)
64− , atan2_
52+ , FunctionNDB
65− , cast
53+ , unsafeFunctionN
66− , quot_
54+ , functionN
67− , rem_
55+ , PGSubset (..)
68− , trunc
56+ , PGIntersect (..)
92− , notBetweenSymmetric
119− -- *** Json and Jsonb operators
124− -- *** Jsonb operators
150− , jsonExtractPathAsText
151− , jsonbExtractPathAsText
170− , websearchToTSquery
185− -- * Window Functions
186− , WindowDefinition (..)
188− , WindowFunction (..)
201− , SortExpression (..)
204− , TypeExpression (..)
230− , timestampWithTimeZone
243 -- * Re-export
57 -- * Re-export
249import Control.Category
63import Control.Category
250import Control.DeepSeq
64import Control.DeepSeq
251import Data.ByteString (ByteString)
65import Data.ByteString (ByteString)
252−import Data.ByteString.Lazy (toStrict)
253import Data.Function ((&))
66import Data.Function ((&))
255import Data.Semigroup hiding (All)
67import Data.Semigroup hiding (All)
256−import qualified Data.Aeson as JSON
257import Data.String
68import Data.String
259import Generics.SOP hiding (All, from)
69import Generics.SOP hiding (All, from)
260import GHC.OverloadedLabels
70import GHC.OverloadedLabels
261import GHC.TypeLits
71import GHC.TypeLits
262import Numeric
72import Numeric
263import Prelude hiding (id, (.))
73import Prelude hiding (id, (.))
265−import qualified Data.ByteString as ByteString
266import qualified GHC.Generics as GHC
75import qualified GHC.Generics as GHC
267−import qualified Generics.SOP as SOP
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
269import Squeal.PostgreSQL.Render
79import Squeal.PostgreSQL.Render
270import Squeal.PostgreSQL.Schema
80import Squeal.PostgreSQL.Schema
83+-- >>> import Squeal.PostgreSQL
272{-----------------------------------------
85{-----------------------------------------
273column expressions
86column expressions
274-----------------------------------------}
87-----------------------------------------}
276{- | `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
277−such as in the target list of the `Squeal.PostgreSQL.Query.select` command,
91+`Squeal.PostgreSQL.Query.select` command,
278as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
92as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
279`Squeal.PostgreSQL.Manipulation.update`,
93`Squeal.PostgreSQL.Manipulation.update`,
280−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
282The expression syntax allows the calculation of
96The expression syntax allows the calculation of
283values from primitive expression using arithmetic, logical,
97values from primitive expression using arithmetic, logical,
284and 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`.
286newtype Expression
114newtype Expression
287 (outer :: FromType)
115 (outer :: FromType)
289 (commons :: FromType)
116 (commons :: FromType)
290 (schemas :: SchemasType)
118 (schemas :: SchemasType)
291 (params :: [NullityType])
119 (params :: [NullityType])
292 (from :: FromType)
120 (from :: FromType)
293 (ty :: NullityType)
121 (ty :: NullityType)
294 = UnsafeExpression { renderExpression :: ByteString }
122 = UnsafeExpression { renderExpression :: ByteString }
295 deriving (GHC.Generic,Show,Eq,Ord,NFData)
123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
296−instance RenderSQL (Expression outer grp commons schemas params from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
297 renderSQL = renderExpression
125 renderSQL = renderExpression
299-- | An `Expr` is a closed `Expression`.
127-- | An `Expr` is a closed `Expression`.
300−-- It is a F`RankNType` but don't be scared.
128+-- It is a F@RankNType@ but don't be scared.
301-- Think of it as an expression which sees no
129-- Think of it as an expression which sees no
302-- namespaces, so you can't use parameters
130-- namespaces, so you can't use parameters
303-- or alias references. It can be used as
131-- or alias references. It can be used as
304-- a simple piece of more complex `Expression`s.
132-- a simple piece of more complex `Expression`s.
305type Expr x
133type Expr x
306− = forall outer grp commons schemas params from
134+ = forall outer commons grp schemas params from
307− . Expression outer grp commons schemas params from x
135+ . Expression outer commons grp schemas params from x
308 -- ^ cannot reference aliases
136 -- ^ cannot reference aliases
310−-- | A `RankNType` for binary operators.
138+-- | A @RankNType@ for binary operators.
311type Operator x1 x2 y
139type Operator x1 x2 y
140+ = forall outer commons grp schemas params from
312− = forall outer grp commons schemas params from
141+ . Expression outer commons grp schemas params from x1
143+ -> Expression outer commons grp schemas params from x2
145+ -> Expression outer commons grp schemas params from y
148+type OperatorDB schemas x1 x2 y
149+ = forall outer commons grp params from
313− . Expression outer grp commons schemas params from x1
150+ . Expression outer commons grp schemas params from x1
314 -- ^ left input
151 -- ^ left input
315− -> Expression outer grp commons schemas params from x2
152+ -> Expression outer commons grp schemas params from x2
316 -- ^ right input
153 -- ^ right input
317− -> Expression outer grp commons schemas params from y
154+ -> Expression outer commons grp schemas params from y
318 -- ^ output
155 -- ^ output
320−-- | A `RankNType` for functions with a single argument.
157+-- | A @RankNType@ for functions with a single argument.
321-- These could be either function calls or unary operators.
158-- These could be either function calls or unary operators.
322-- This is a subtype of the usual Haskell function type `Prelude.->`,
159-- This is a subtype of the usual Haskell function type `Prelude.->`,
323-- indeed a subcategory as it is closed under the usual
160-- indeed a subcategory as it is closed under the usual
324-- `Prelude..` and `Prelude.id`.
161-- `Prelude..` and `Prelude.id`.
325−type (:-->) x y
162+type (-->) x y
326− = forall outer grp commons schemas params from
163+ = forall outer commons grp schemas params from
327− . Expression outer grp commons schemas params from x
164+ . Expression outer commons grp schemas params from x
328 -- ^ input
165 -- ^ input
329− -> Expression outer grp commons schemas params from y
166+ -> Expression outer commons grp schemas params from y
330 -- ^ output
167 -- ^ output
332−type FunctionHet xs y
169+type FunctionDB schemas x y
333− = forall outer grp commons schemas params from
170+ = forall outer commons grp params from
334− . NP (Expression outer grp commons schemas params from) xs
171+ . Expression outer commons grp schemas params from x
335− -- ^ inputs
172+ -- ^ input
336− -> Expression outer grp commons schemas params from y
173+ -> Expression outer commons grp schemas params from y
337 -- ^ output
174 -- ^ output
339−type FunctionHom x0 x1 y
176+{- | A @RankNType@ for functions with a fixed-length list of heterogeneous arguments.
177+Use the `*:` operator to end your argument lists, like so.
179+>>> printSQL (unsafeFunctionN "fun" (true :* false :* localTime *: true))
180+fun(TRUE, FALSE, LOCALTIME, TRUE)
340− = forall outer grp commons schemas params from
183+ = forall outer commons grp schemas params from
341− . [Expression outer grp commons schemas params from x0]
184+ . NP (Expression outer commons grp schemas params from) xs
342 -- ^ inputs
185 -- ^ inputs
343− -> Expression outer grp commons schemas params from x1
186+ -> Expression outer commons grp schemas params from y
344− -- ^ must have at least 1 input
345− -> Expression outer grp commons schemas params from y
346 -- ^ output
187 -- ^ output
348−unsafeFunctionHom :: ByteString -> FunctionHom x0 x1 y
189+type FunctionNDB schemas xs y
349−unsafeFunctionHom fun xs x = UnsafeExpression $ fun <> parenthesized
190+ = forall outer commons grp params from
350− (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
191+ . NP (Expression outer commons grp schemas params from) xs
193+ -> Expression outer commons grp schemas params from y
352−{- | A `HasParameter` constraint is used to indicate a value that is
196+{- | A @RankNType@ for functions with a variable-length list of
353−supplied externally to a SQL statement.
197+homogeneous arguments and at least 1 more argument.
354−`Squeal.PostgreSQL.PQ.manipulateParams`,
355−`Squeal.PostgreSQL.PQ.queryParams` and
356−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
357−separately from the SQL command string, in which case `param`s are used to
358−refer to the out-of-line data values.
360−class KnownNat n => HasParameter
199+type FunctionVar x0 x1 y
361− (n :: Nat)
200+ = forall outer commons grp schemas params from
362− (params :: [NullityType])
364− | n params -> ty where
365− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
367− -- >>> let expr = parameter @1 int4 :: Expression outer grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
201+ . [Expression outer commons grp schemas params from x0]
368− -- >>> printSQL expr
202+ -- ^ inputs
371− :: TypeExpression schemas ty
372− -> Expression outer grp commons schemas params from ty
203+ -> Expression outer commons grp schemas params from x1
373− parameter ty = UnsafeExpression $ parenthesized $
204+ -- ^ must have at least 1 input
374− "$" <> renderNat @n <+> "::"
205+ -> Expression outer commons grp schemas params from y
375− <+> renderSQL ty
206+ -- ^ output
376−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
377−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
378− => HasParameter n (ty' : params) ty
380−-- | `param` takes a `Nat` using type application and for basic types,
208+{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
381−-- infers a `TypeExpression`.
209+greatest(TRUE, NULL, FALSE)
383−-- >>> let expr = param @1 :: Expression outer grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
211+unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
384−-- >>> printSQL expr
212+unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
385−-- ($1 :: int4)
213+ (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
387− :: forall n outer commons schemas params from grp ty
388− . (PGTyped schemas ty, HasParameter n params ty)
389− => Expression outer grp commons schemas params from ty -- ^ param
390−param = parameter @n (pgtype @schemas)
392instance (HasUnique tab (Join outer from) row, Has col row ty)
215instance (HasUnique tab (Join outer from) row, Has col row ty)
393− => IsLabel col (Expression outer 'Ungrouped commons schemas params from ty) where
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
394 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
395instance (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])
396− => 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
397 fromLabel = fromLabel @col :* Nil
220 fromLabel = fromLabel @col :* Nil
398instance (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))
399 => IsLabel col
222 => IsLabel col
400− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
401 fromLabel = fromLabel @col `As` Alias
224 fromLabel = fromLabel @col `As` Alias
402instance (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])
403 => IsLabel col
226 => IsLabel col
404− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
405 fromLabel = fromLabel @col :* Nil
228 fromLabel = fromLabel @col :* Nil
407instance (Has tab (Join outer from) row, Has col row ty)
230instance (Has tab (Join outer from) row, Has col row ty)
408− => 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
409 tab ! col = UnsafeExpression $
232 tab ! col = UnsafeExpression $
410 renderSQL tab <> "." <> renderSQL col
233 renderSQL tab <> "." <> renderSQL col
411instance (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])
412− => 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
413 tab ! col = tab ! col :* Nil
236 tab ! col = tab ! col :* Nil
414instance (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))
415 => IsQualified tab col
238 => IsQualified tab col
416− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
417 tab ! col = tab ! col `As` col
240 tab ! col = tab ! col `As` col
418instance (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])
419 => IsQualified tab col
242 => IsQualified tab col
420− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
421 tab ! col = tab ! col :* Nil
244 tab ! col = tab ! col :* Nil
@@ -425,7 +248,7 @@ instance
425 , Has col row ty
248 , Has col row ty
426 , GroupedBy tab col bys
249 , GroupedBy tab col bys
427 ) => IsLabel col
250 ) => IsLabel col
428− (Expression outer ('Grouped bys) commons schemas params from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
429 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
431 ( HasUnique tab (Join outer from) row
254 ( HasUnique tab (Join outer from) row
@@ -433,7 +256,7 @@ instance
433 , GroupedBy tab col bys
256 , GroupedBy tab col bys
434 , tys ~ '[ty]
257 , tys ~ '[ty]
435 ) => IsLabel col
258 ) => IsLabel col
436− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
437 fromLabel = fromLabel @col :* Nil
260 fromLabel = fromLabel @col :* Nil
439 ( HasUnique tab (Join outer from) row
262 ( HasUnique tab (Join outer from) row
@@ -441,7 +264,7 @@ instance
441 , GroupedBy tab col bys
264 , GroupedBy tab col bys
442 , column ~ (col ::: ty)
265 , column ~ (col ::: ty)
443 ) => IsLabel col
266 ) => IsLabel col
444− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
445 fromLabel = fromLabel @col `As` Alias
268 fromLabel = fromLabel @col `As` Alias
447 ( HasUnique tab (Join outer from) row
270 ( HasUnique tab (Join outer from) row
@@ -449,7 +272,7 @@ instance
449 , GroupedBy tab col bys
272 , GroupedBy tab col bys
450 , columns ~ '[col ::: ty]
273 , columns ~ '[col ::: ty]
451 ) => IsLabel col
274 ) => IsLabel col
452− (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
453 fromLabel = fromLabel @col :* Nil
276 fromLabel = fromLabel @col :* Nil
@@ -457,7 +280,7 @@ instance
457 , Has col row ty
280 , Has col row ty
458 , GroupedBy tab col bys
281 , GroupedBy tab col bys
459 ) => IsQualified tab col
282 ) => IsQualified tab col
460− (Expression outer ('Grouped bys) commons schemas params from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
461 tab ! col = UnsafeExpression $
284 tab ! col = UnsafeExpression $
462 renderSQL tab <> "." <> renderSQL col
285 renderSQL tab <> "." <> renderSQL col
@@ -466,7 +289,7 @@ instance
466 , GroupedBy tab col bys
289 , GroupedBy tab col bys
467 , tys ~ '[ty]
290 , tys ~ '[ty]
468 ) => IsQualified tab col
291 ) => IsQualified tab col
469− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
470 tab ! col = tab ! col :* Nil
293 tab ! col = tab ! col :* Nil
472 ( Has tab (Join outer from) row
295 ( Has tab (Join outer from) row
@@ -474,7 +297,7 @@ instance
474 , GroupedBy tab col bys
297 , GroupedBy tab col bys
475 , column ~ (col ::: ty)
298 , column ~ (col ::: ty)
476 ) => IsQualified tab col
299 ) => IsQualified tab col
477− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
478 tab ! col = tab ! col `As` col
301 tab ! col = tab ! col `As` col
480 ( Has tab (Join outer from) row
303 ( Has tab (Join outer from) row
@@ -482,196 +305,78 @@ instance
482 , GroupedBy tab col bys
305 , GroupedBy tab col bys
483 , columns ~ '[col ::: ty]
306 , columns ~ '[col ::: ty]
484 ) => IsQualified tab col
307 ) => IsQualified tab col
485− (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
486 tab ! col = tab ! col :* Nil
309 tab ! col = tab ! col :* Nil
488−-- | analagous to `Nothing`
490−-- >>> printSQL null_
492−null_ :: Expr ('Null ty)
493−null_ = UnsafeExpression "NULL"
495−-- | analagous to `Just`
497−-- >>> printSQL $ notNull true
499−notNull :: 'NotNull ty :--> 'Null ty
500−notNull = UnsafeExpression . renderSQL
502−-- | return the leftmost value which is not NULL
504−-- >>> printSQL $ coalesce [null_, true] false
505−-- COALESCE(NULL, TRUE, FALSE)
506−coalesce :: FunctionHom ('Null ty) ('NotNull ty) ('NotNull ty)
507−coalesce nullxs notNullx = UnsafeExpression $
508− "COALESCE" <> parenthesized (commaSeparated
509− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
511−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
513−-- >>> printSQL $ fromNull true null_
514−-- COALESCE(NULL, TRUE)
516− :: Expression outer grp commons schemas params from ('NotNull ty)
517− -- ^ what to convert @NULL@ to
518− -> Expression outer grp commons schemas params from ('Null ty)
519− -> Expression outer grp commons schemas params from ('NotNull ty)
520−fromNull notNullx nullx = coalesce [nullx] notNullx
522−-- | >>> printSQL $ null_ & isNull
524−isNull :: 'Null ty :--> null 'PGbool
525−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
527−-- | >>> printSQL $ null_ & isNotNull
529−isNotNull :: 'Null ty :--> null 'PGbool
530−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
532−-- | analagous to `maybe` using @IS NULL@
534−-- >>> printSQL $ matchNull true not_ null_
535−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
537− :: Expression outer grp commons schemas params from (nullty)
538− -- ^ what to convert @NULL@ to
539− -> ( Expression outer grp commons schemas params from ('NotNull ty)
540− -> Expression outer grp commons schemas params from (nullty) )
541− -- ^ function to perform when @NULL@ is absent
542− -> Expression outer grp commons schemas params from ('Null ty)
543− -> Expression outer grp commons schemas params from (nullty)
544−matchNull y f x = ifThenElse (isNull x) y
545− (f (UnsafeExpression (renderSQL x)))
547−{-| right inverse to `fromNull`, if its arguments are equal then
548−`nullIf` gives @NULL@.
550−>>> :set -XTypeApplications -XDataKinds
551−>>> let expr = nullIf (false *: param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
553−NULLIF(FALSE, ($1 :: bool))
555−nullIf :: FunctionHet '[ 'NotNull ty, 'NotNull ty] ('Null ty)
556−nullIf = unsafeFunctionHet "NULLIF"
558−-- | >>> printSQL $ array [null_, false, true]
559−-- ARRAY[NULL, FALSE, TRUE]
561− :: [Expression outer grp commons schemas params from ty]
563− -> Expression outer grp commons schemas params from (null ('PGvararray ty))
564−array xs = UnsafeExpression $
565− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
567−-- | >>> printSQL $ cardinality (array [null_, false, true])
568−-- cardinality(ARRAY[NULL, FALSE, TRUE])
569−cardinality :: null ('PGvararray ty) :--> null 'PGint8
570−cardinality = unsafeFunction "cardinality"
572−-- | >>> printSQL $ array [null_, false, true] & index 2
573−-- (ARRAY[NULL, FALSE, TRUE])[2]
575− :: Word64 -- ^ index
576− -> null ('PGvararray ty) :--> NullifyType ty
577−index n expr = UnsafeExpression $
578− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
580instance (KnownSymbol label, label `In` labels) => IsPGlabel label
311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
581− (Expression outer grp commons schemas params from (null ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
582 label = UnsafeExpression $ renderSQL (PGlabel @label)
313 label = UnsafeExpression $ renderSQL (PGlabel @label)
584−-- | A row constructor is an expression that builds a row value
585−-- (also called a composite value) using values for its member fields.
588−-- type Complex = 'PGcomposite
589−-- '[ "real" ::: 'NotNull 'PGfloat8
590−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
593−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
598− => NP (Aliased (Expression outer grp commons schemas params from)) row
599− -- ^ zero or more expressions for the row field values
600− -> Expression outer grp commons schemas params from (null ('PGcomposite row))
601−row exprs = UnsafeExpression $ "ROW" <> parenthesized
602− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
605−-- type Complex = 'PGcomposite
606−-- '[ "real" ::: 'NotNull 'PGfloat8
607−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
608−-- type Schema = '["complex" ::: 'Typedef Complex]
611−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
612−-- >>> printSQL $ i & field #complex #imaginary
613−-- (ROW(0, 1)::"complex")."imaginary"
615− :: ( Has sch schemas schema
616− , Has tydef schema ('Typedef ('PGcomposite row))
618− => QualifiedAlias sch tydef -- ^ row type
619− -> Alias field -- ^ field name
620− -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
621− -> Expression outer grp commons schemas params from ty
622−field td fld expr = UnsafeExpression $
623− parenthesized (renderSQL expr <> "::" <> renderSQL td)
624− <> "." <> renderSQL fld
627− (Expression outer grp commons schemas params from (null ('PGvararray ty))) where
628− (<>) = unsafeBinaryOp "||"
631− (Expression outer grp commons schemas params from (null ('PGvararray ty))) where
635−-- | >>> let expr = greatest [param @1] currentTimestamp :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
637−-- GREATEST(($1 :: timestamp with time zone), CURRENT_TIMESTAMP)
638−greatest :: FunctionHom ty ty ty
639−greatest = unsafeFunctionHom "GREATEST"
641−-- | >>> printSQL $ least [null_] currentTimestamp
642−-- LEAST(NULL, CURRENT_TIMESTAMP)
643−least :: FunctionHom ty ty ty
644−least = unsafeFunctionHom "LEAST"
646-- | >>> printSQL $ unsafeBinaryOp "OR" true false
315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
647-- (TRUE OR FALSE)
316-- (TRUE OR FALSE)
648−unsafeBinaryOp :: ByteString {- ^ operator -} -> Operator ty0 ty1 ty2
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
649unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
650 renderSQL x <+> op <+> renderSQL y
319 renderSQL x <+> op <+> renderSQL y
652−-- | >>> printSQL $ unsafeUnaryOpL "NOT" true
321+binaryOp
653−-- (NOT TRUE)
322+ :: forall op sch schemas schema x y z.
654−unsafeUnaryOpL :: ByteString {- ^ operator -} -> x :--> y
323+ ( Has sch schemas schema
655−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
657−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
658−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
660-- | >>> printSQL $ unsafeFunction "f" true
352-- | >>> printSQL $ unsafeFunction "f" true
661-- f(TRUE)
353-- f(TRUE)
662−unsafeFunction :: ByteString {- ^ function -} -> x :--> y
354+unsafeFunction :: ByteString -> x --> y
663unsafeFunction fun x = UnsafeExpression $
355unsafeFunction fun x = UnsafeExpression $
664 fun <> parenthesized (renderSQL x)
356 fun <> parenthesized (renderSQL x)
666−unsafeFunctionHet
358+function
667− :: SListI xs
359+ :: (Has sch schemas schema, Has fun schema ('Function ('[x] :=> 'Returns y)))
668− => ByteString {- ^ function -}
360+ => QualifiedAlias sch fun
669− -> 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
670−unsafeFunctionHet fun xs = UnsafeExpression $
367+unsafeFunctionN fun xs = UnsafeExpression $
671 fun <> parenthesized (renderCommaSeparated renderSQL xs)
368 fun <> parenthesized (renderCommaSeparated renderSQL xs)
371+ :: ( Has sch schemas schema
372+ , Has fun schema ('Function (xs :=> 'Returns y))
374+ => QualifiedAlias sch fun
375+ -> FunctionNDB schemas xs y
376+functionN = unsafeFunctionN . renderSQL
673instance ty `In` PGNum
378instance ty `In` PGNum
674− => Num (Expression outer grp commons schemas params from (null ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
675 (+) = unsafeBinaryOp "+"
380 (+) = unsafeBinaryOp "+"
676 (-) = unsafeBinaryOp "-"
381 (-) = unsafeBinaryOp "-"
677 (*) = unsafeBinaryOp "*"
382 (*) = unsafeBinaryOp "*"
@@ -683,7 +388,7 @@ instance ty `In` PGNum
685instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
686− (Expression outer grp commons schemas params from (null ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
687 (/) = unsafeBinaryOp "/"
392 (/) = unsafeBinaryOp "/"
688 fromRational
393 fromRational
689 = UnsafeExpression
394 = UnsafeExpression
@@ -693,7 +398,7 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
693 . fromRat @Double
398 . fromRat @Double
695instance (ty `In` PGNum, ty `In` PGFloating) => Floating
400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
696− (Expression outer grp commons schemas params from (null ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
697 pi = UnsafeExpression "pi()"
402 pi = UnsafeExpression "pi()"
698 exp = unsafeFunction "exp"
403 exp = unsafeFunction "exp"
699 log = unsafeFunction "ln"
404 log = unsafeFunction "ln"
@@ -714,1748 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
714 acosh x = log (x + sqrt (x*x - 1))
419 acosh x = log (x + sqrt (x*x - 1))
715 atanh x = log ((1 + x) / (1 - x)) / 2
420 atanh x = log ((1 + x) / (1 - x)) / 2
717−-- | >>> :{
422+-- | Contained by operators
718−-- let
423+class PGSubset ty where
719−-- expression :: Expr (null 'PGfloat4)
424+ (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
720−-- expression = atan2_ (pi *: 2)
425+ (@>) = unsafeBinaryOp "@>"
721−-- in printSQL expression
426+ (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
722−-- :}
427+ (<@) = unsafeBinaryOp "<@"
723−-- atan2(pi(), 2)
428+instance PGSubset 'PGjsonb
724−atan2_
429+instance PGSubset 'PGtsquery
725− :: float `In` PGFloating
430+instance PGSubset ('PGvararray ty)
726− => FunctionHet '[ null float, null float] (null float)
431+instance PGSubset ('PGrange ty)
727−atan2_ = unsafeFunctionHet "atan2"
729−-- When a `cast` is applied to an `Expression` of a known type, it
730−-- represents a run-time type conversion. The cast will succeed only if a
731−-- suitable type conversion operation has been defined.
733−-- | >>> printSQL $ true & cast int4
736− :: TypeExpression schemas ty1
737− -- ^ type to cast as
738− -> Expression outer grp commons schemas params from ty0
739− -- ^ value to convert
740− -> Expression outer grp commons schemas params from ty1
741−cast ty x = UnsafeExpression $ parenthesized $
742− renderSQL x <+> "::" <+> renderSQL ty
744−-- | integer division, truncates the result
748−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
749−-- expression = 5 `quot_` 2
750−-- in printSQL expression
754− :: int `In` PGIntegral
755− => Operator (null int) (null int) (null int)
756−quot_ = unsafeBinaryOp "/"
758−-- | remainder upon integer division
762−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
763−-- expression = 5 `rem_` 2
764−-- in printSQL expression
768− :: int `In` PGIntegral
769− => Operator (null int) (null int) (null int)
770−rem_ = unsafeBinaryOp "%"
774−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
775−-- expression = trunc pi
776−-- in printSQL expression
779−trunc :: frac `In` PGFloating => null frac :--> null frac
780−trunc = unsafeFunction "trunc"
784−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
785−-- expression = round_ pi
786−-- in printSQL expression
789−round_ :: frac `In` PGFloating => null frac :--> null frac
790−round_ = unsafeFunction "round"
794−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
795−-- expression = ceiling_ pi
796−-- in printSQL expression
799−ceiling_ :: frac `In` PGFloating => null frac :--> null frac
800−ceiling_ = unsafeFunction "ceiling"
802−-- | A `Condition` is an `Expression`, which can evaluate
803−-- to `true`, `false` or `null_`. This is because SQL uses
804−-- a three valued logic.
805−type Condition outer grp commons schemas params from =
806− Expression outer grp commons schemas params from ('Null 'PGbool)
808−-- | >>> printSQL true
810−true :: Expr (null 'PGbool)
811−true = UnsafeExpression "TRUE"
813−-- | >>> printSQL false
815−false :: Expr (null 'PGbool)
816−false = UnsafeExpression "FALSE"
818−-- | >>> printSQL $ not_ true
820−not_ :: null 'PGbool :--> null 'PGbool
821−not_ = unsafeUnaryOpL "NOT"
823−-- | >>> printSQL $ true .&& false
825−(.&&) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
827−(.&&) = unsafeBinaryOp "AND"
829−-- | >>> printSQL $ true .|| false
831−(.||) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
833−(.||) = unsafeBinaryOp "OR"
837−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
838−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
839−-- in printSQL expression
841−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
843− :: [ ( Condition outer grp commons schemas params from
844− , Expression outer grp commons schemas params from ty
846− -- ^ whens and thens
847− -> Expression outer grp commons schemas params from ty
849− -> Expression outer grp commons schemas params from ty
850−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
854− [ " WHEN ", renderSQL when_
855− , " THEN ", renderSQL then_
857− | (when_,then_) <- whenThens
859− , " ELSE ", renderSQL else_
865−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
866−-- expression = ifThenElse true 1 0
867−-- in printSQL expression
869−-- CASE WHEN TRUE THEN 1 ELSE 0 END
871− :: Condition outer grp commons schemas params from
872− -> Expression outer grp commons schemas params from ty -- ^ then
873− -> Expression outer grp commons schemas params from ty -- ^ else
874− -> Expression outer grp commons schemas params from ty
875−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
877−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
878−-- will produce @NULL@s if one of their arguments is @NULL@.
880−-- >>> printSQL $ true .== null_
882−(.==) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
883−(.==) = unsafeBinaryOp "="
886−-- | >>> printSQL $ true ./= null_
888−(./=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
889−(./=) = unsafeBinaryOp "<>"
892−-- | >>> printSQL $ true .>= null_
894−(.>=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
895−(.>=) = unsafeBinaryOp ">="
898−-- | >>> printSQL $ true .< null_
900−(.<) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
901−(.<) = unsafeBinaryOp "<"
904−-- | >>> printSQL $ true .<= null_
906−(.<=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
907−(.<=) = unsafeBinaryOp "<="
910−-- | >>> printSQL $ true .> null_
912−(.>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
913−(.>) = unsafeBinaryOp ">"
916−{- | >>> printSQL $ true `between` (null_, false)
917−TRUE BETWEEN NULL AND FALSE
920− :: Expression outer grp commons schemas params from (null ty)
921− -> ( Expression outer grp commons schemas params from (null ty)
922− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
923− -> Condition outer grp commons schemas params from
924−between a (x,y) = UnsafeExpression $ renderSQL a <+> "BETWEEN"
925− <+> renderSQL x <+> "AND" <+> renderSQL y
927−{- | >>> printSQL $ true `notBetween` (null_, false)
928−TRUE NOT BETWEEN NULL AND FALSE
931− :: Expression outer grp commons schemas params from (null ty)
932− -> ( Expression outer grp commons schemas params from (null ty)
933− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
934− -> Condition outer grp commons schemas params from
935−notBetween a (x,y) = UnsafeExpression $ renderSQL a <+> "NOT BETWEEN"
936− <+> renderSQL x <+> "AND" <+> renderSQL y
938−{- | between, after sorting the comparison values
940−>>> printSQL $ true `betweenSymmetric` (null_, false)
941−TRUE BETWEEN SYMMETRIC NULL AND FALSE
944− :: Expression outer grp commons schemas params from (null ty)
945− -> ( Expression outer grp commons schemas params from (null ty)
946− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
947− -> Condition outer grp commons schemas params from
948−betweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
949− <+> "BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
951−{- | not between, after sorting the comparison values
953−>>> printSQL $ true `notBetweenSymmetric` (null_, false)
954−TRUE NOT BETWEEN SYMMETRIC NULL AND FALSE
957− :: Expression outer grp commons schemas params from (null ty)
958− -> ( Expression outer grp commons schemas params from (null ty)
959− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
960− -> Condition outer grp commons schemas params from
961−notBetweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
962− <+> "NOT BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
964−{- | not equal, treating null like an ordinary value
966−>>> printSQL $ true `isDistinctFrom` null_
967−(TRUE IS DISTINCT FROM NULL)
969−isDistinctFrom :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
970−isDistinctFrom = unsafeBinaryOp "IS DISTINCT FROM"
972−{- | equal, treating null like an ordinary value
974−>>> printSQL $ true `isNotDistinctFrom` null_
975−(TRUE IS NOT DISTINCT FROM NULL)
977−isNotDistinctFrom :: Operator (null0 ty) (null1 ty) ('NotNull 'PGbool)
978−isNotDistinctFrom = unsafeBinaryOp "IS NOT DISTINCT FROM"
982−>>> printSQL $ true & isTrue
985−isTrue :: null0 'PGbool :--> null1 'PGbool
986−isTrue = unsafeUnaryOpR "IS TRUE"
988−{- | is false or unknown
990−>>> printSQL $ true & isNotTrue
993−isNotTrue :: null0 'PGbool :--> null1 'PGbool
994−isNotTrue = unsafeUnaryOpR "IS NOT TRUE"
998−>>> printSQL $ true & isFalse
1001−isFalse :: null0 'PGbool :--> null1 'PGbool
1002−isFalse = unsafeUnaryOpR "IS FALSE"
1004−{- | is true or unknown
1006−>>> printSQL $ true & isNotFalse
1009−isNotFalse :: null0 'PGbool :--> null1 'PGbool
1010−isNotFalse = unsafeUnaryOpR "IS NOT FALSE"
1014−>>> printSQL $ true & isUnknown
1017−isUnknown :: null0 'PGbool :--> null1 'PGbool
1018−isUnknown = unsafeUnaryOpR "IS UNKNOWN"
1020−{- | is true or false
1022−>>> printSQL $ true & isNotUnknown
1023−(TRUE IS NOT UNKNOWN)
1025−isNotUnknown :: null0 'PGbool :--> null1 'PGbool
1026−isNotUnknown = unsafeUnaryOpR "IS NOT UNKNOWN"
1028−-- | >>> printSQL currentDate
1030−currentDate :: Expr (null 'PGdate)
1031−currentDate = UnsafeExpression "CURRENT_DATE"
1033−-- | >>> printSQL currentTime
1035−currentTime :: Expr (null 'PGtimetz)
1036−currentTime = UnsafeExpression "CURRENT_TIME"
1038−-- | >>> printSQL currentTimestamp
1039−-- CURRENT_TIMESTAMP
1040−currentTimestamp :: Expr (null 'PGtimestamptz)
1041−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
1043−-- | >>> printSQL localTime
1045−localTime :: Expr (null 'PGtime)
1046−localTime = UnsafeExpression "LOCALTIME"
1048−-- | >>> printSQL localTimestamp
1050−localTimestamp :: Expr (null 'PGtimestamp)
1051−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
1053−{-----------------------------------------
1055−-----------------------------------------}
1057−escape :: Char -> String
433+class PGIntersect ty where
1058−escape = \case
434+ (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
1059− '\NUL' -> "\\0"
435+ (@&&) = unsafeBinaryOp "&&"
1060− '\'' -> "''"
436+instance PGIntersect ('PGvararray ty)
1061− '"' -> "\\\""
437+instance PGIntersect ('PGrange ty)
1069instance IsString
439instance IsString
1070− (Expression outer grp commons schemas params from (null 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1071 fromString str = UnsafeExpression $
441 fromString str = UnsafeExpression $
1072 "E\'" <> fromString (escape =<< str) <> "\'"
442 "E\'" <> fromString (escape =<< str) <> "\'"
1073instance IsString
443instance IsString
1074− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1075− fromString str = cast tsvector . UnsafeExpression $
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
1076 "E\'" <> fromString (escape =<< str) <> "\'"
446 "E\'" <> fromString (escape =<< str) <> "\'"
1077instance IsString
447instance IsString
1078− (Expression outer grp commons schemas params from (null 'PGtsquery)) where
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
1079− fromString str = cast tsquery . UnsafeExpression $
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
1080 "E\'" <> fromString (escape =<< str) <> "\'"
450 "E\'" <> fromString (escape =<< str) <> "\'"
1082instance Semigroup
452instance Semigroup
1083− (Expression outer grp commons schemas params from (null 'PGtext)) where
453+ (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
1084 (<>) = unsafeBinaryOp "||"
454 (<>) = unsafeBinaryOp "||"
1085instance 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 "||"
1086− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
462+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1087 (<>) = unsafeBinaryOp "||"
463 (<>) = unsafeBinaryOp "||"
1089instance Monoid
465instance Monoid
1090− (Expression outer grp commons schemas params from (null 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1091 mempty = fromString ""
467 mempty = fromString ""
1092 mappend = (<>)
468 mappend = (<>)
1093instance Monoid
469instance Monoid
1094− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1095 mempty = fromString ""
471 mempty = fromString ""
1096 mappend = (<>)
472 mappend = (<>)
1098−-- | >>> printSQL $ lower "ARRRGGG"
1099−-- lower(E'ARRRGGG')
1100−lower :: null 'PGtext :--> null 'PGtext
1101−lower = unsafeFunction "lower"
1103−-- | >>> printSQL $ upper "eeee"
1105−upper :: null 'PGtext :--> null 'PGtext
1106−upper = unsafeFunction "upper"
1108−-- | >>> printSQL $ charLength "four"
1109−-- char_length(E'four')
1110−charLength :: null 'PGtext :--> null 'PGint4
1111−charLength = unsafeFunction "char_length"
1113−-- | The `like` expression returns true if the @string@ matches
1114−-- the supplied @pattern@. If @pattern@ does not contain percent signs
1115−-- or underscores, then the pattern only represents the string itself;
1116−-- in that case `like` acts like the equals operator. An underscore (_)
1117−-- in pattern stands for (matches) any single character; a percent sign (%)
1118−-- matches any sequence of zero or more characters.
1120−-- >>> printSQL $ "abc" `like` "a%"
1121−-- (E'abc' LIKE E'a%')
1122−like :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1123−like = unsafeBinaryOp "LIKE"
1125−-- | The key word ILIKE can be used instead of LIKE to make the
1126−-- match case-insensitive according to the active locale.
1128−-- >>> printSQL $ "abc" `ilike` "a%"
1129−-- (E'abc' ILIKE E'a%')
1130−ilike :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1131−ilike = unsafeBinaryOp "ILIKE"
1133−{-----------------------------------------
1134− -- json and jsonb support
1136−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1137−comments lifted directly from this page.
1139−Table 9.44: json and jsonb operators
1140−-----------------------------------------}
1142−-- | Get JSON value (object field or array element) at a key.
1144− :: (json `In` PGJsonType, key `In` PGJsonKey)
1145− => Operator (null json) (null key) ('Null json)
1147−(.->) = unsafeBinaryOp "->"
1149−-- | Get JSON value (object field or array element) at a key, as text.
1151− :: (json `In` PGJsonType, key `In` PGJsonKey)
1152− => Operator (null json) (null key) ('Null 'PGtext)
1154−(.->>) = unsafeBinaryOp "->>"
1156−-- | Get JSON value at a specified path.
1158− :: json `In` PGJsonType
1159− => Operator (null json) (null ('PGvararray ('NotNull 'PGtext))) ('Null json)
1161−(.#>) = unsafeBinaryOp "#>"
1163−-- | Get JSON value at a specified path as text.
1165− :: json `In` PGJsonType
1166− => Operator (null json) (null ('PGvararray ('NotNull 'PGtext))) ('Null 'PGtext)
1168−(.#>>) = unsafeBinaryOp "#>>"
1170−-- Additional jsonb operators
1172−class PGSubset container where
1173− (@>) :: Operator (null0 container) (null1 container) ('Null 'PGbool)
1174− (@>) = unsafeBinaryOp "@>"
1175− (<@) :: Operator (null0 container) (null1 container) ('Null 'PGbool)
1176− (<@) = unsafeBinaryOp "<@"
1177−instance PGSubset 'PGjsonb
1178−instance PGSubset 'PGtsquery
1179−instance PGSubset ('PGvararray ty)
1181−-- | Does the string exist as a top-level key within the JSON value?
1182−(.?) :: Operator (null 'PGjsonb) (null 'PGtext) ('Null 'PGbool)
1184−(.?) = unsafeBinaryOp "?"
1186−-- | Do any of these array strings exist as top-level keys?
1189− (null ('PGvararray ('NotNull 'PGtext)))
1192−(.?|) = unsafeBinaryOp "?|"
1194−-- | Do all of these array strings exist as top-level keys?
1197− (null ('PGvararray ('NotNull 'PGtext)))
1200−(.?&) = unsafeBinaryOp "?&"
1202−-- | Concatenate two jsonb values into a new jsonb value.
1204− (Expression outer grp commons schemas params from (null 'PGjsonb)) where
1205− (<>) = unsafeBinaryOp "||"
1207−-- | Delete a key or keys from a JSON object, or remove an array element.
1209−-- If the right operand is..
1211−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1212−-- are matched based on their key value.
1214−-- @ text[] @: Delete multiple key/value pairs or string elements
1215−-- from left operand. Key/value pairs are matched based on their key value.
1217−-- @ integer @: Delete the array element with specified index (Negative integers
1218−-- count from the end). Throws an error if top level container is not an array.
1220− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1221− => Operator (null 'PGjsonb) (null key) (null 'PGjsonb)
1223−(.-.) = unsafeBinaryOp "-"
1225−-- | Delete the field or element with specified path (for JSON arrays, negative
1226−-- integers count from the end)
1227−(#-.) :: Operator (null 'PGjsonb) (null ('PGvararray ('NotNull 'PGtext))) (null 'PGjsonb)
1229−(#-.) = unsafeBinaryOp "#-"
1231−{-----------------------------------------
1232−Table 9.45: JSON creation functions
1233−-----------------------------------------}
1235−-- | Literal binary JSON
1236−jsonbLit :: JSON.ToJSON x => x -> Expr (null 'PGjsonb)
1237−jsonbLit = cast jsonb . UnsafeExpression
1238− . singleQuotedUtf8 . toStrict . JSON.encode
1241−jsonLit :: JSON.ToJSON x => x -> Expr (null 'PGjson)
1242−jsonLit = cast json . UnsafeExpression
1243− . singleQuotedUtf8 . toStrict . JSON.encode
1245−-- | Returns the value as json. Arrays and composites are converted
1246−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1247−-- type to json, the cast function will be used to perform the conversion;
1248−-- otherwise, a scalar value is produced. For any scalar type other than a
1249−-- number, a Boolean, or a null value, the text representation will be used, in
1250−-- such a fashion that it is a valid json value.
1251−toJson :: null ty :--> null 'PGjson
1252−toJson = unsafeFunction "to_json"
1254−-- | Returns the value as jsonb. Arrays and composites are converted
1255−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1256−-- type to json, the cast function will be used to perform the conversion;
1257−-- otherwise, a scalar value is produced. For any scalar type other than a
1258−-- number, a Boolean, or a null value, the text representation will be used, in
1259−-- such a fashion that it is a valid jsonb value.
1260−toJsonb :: null ty :--> null 'PGjsonb
1261−toJsonb = unsafeFunction "to_jsonb"
1263−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1264−-- becomes a JSON array of arrays.
1265−arrayToJson :: null ('PGvararray ty) :--> null 'PGjson
1266−arrayToJson = unsafeFunction "array_to_json"
1268−-- | Returns the row as a JSON object.
1269−rowToJson :: null ('PGcomposite ty) :--> null 'PGjson
1270−rowToJson = unsafeFunction "row_to_json"
1272−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1274−jsonBuildArray :: SListI tuple => FunctionHet tuple (null 'PGjson)
1275−jsonBuildArray = unsafeFunctionHet "json_build_array"
1277−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1278−-- variadic argument list.
1279−jsonbBuildArray :: SListI tuple => FunctionHet tuple (null 'PGjsonb)
1280−jsonbBuildArray = unsafeFunctionHet "jsonb_build_array"
1282−class PGBuildObject tys where
1283−instance PGBuildObject '[]
1284−instance (PGBuildObject tys, key `In` PGJsonKey)
1285− => PGBuildObject ('NotNull key ': value ': tys)
1287−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1288−-- argument list. The elements of the argument list must alternate between text
1291− :: (SListI elems, PGBuildObject elems)
1292− => FunctionHet elems (null 'PGjson)
1293−jsonBuildObject = unsafeFunctionHet "json_build_object"
1295−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1296−-- variadic argument list. The elements of the argument list must alternate
1297−-- between keys and values.
1299− :: (SListI elems, PGBuildObject elems)
1300− => FunctionHet elems (null 'PGjsonb)
1301−jsonbBuildObject = unsafeFunctionHet "jsonb_build_object"
1303−-- | Builds a JSON object out of a text array.
1304−-- The array must have two dimensions
1305−-- such that each inner array has exactly two elements,
1306−-- which are taken as a key/value pair.
1308− :: null ('PGfixarray '[n,2] ('NotNull 'PGtext))
1310−jsonObject = unsafeFunction "json_object"
1312−-- | Builds a binary JSON object out of a text array.
1313−-- The array must have two dimensions
1314−-- such that each inner array has exactly two elements,
1315−-- which are taken as a key/value pair.
1317− :: null ('PGfixarray '[n,2] ('NotNull 'PGtext))
1319−jsonbObject = unsafeFunction "jsonb_object"
1321−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1322−-- keys and one for values, that are zipped pairwise to create a JSON object.
1323−jsonZipObject :: FunctionHet
1324− '[ null ('PGvararray ('NotNull 'PGtext))
1325− , null ('PGvararray ('NotNull 'PGtext)) ]
1327−jsonZipObject = unsafeFunctionHet "json_object"
1329−-- | This is an alternate form of 'jsonbObject' that takes two arrays; one for
1330−-- keys and one for values, that are zipped pairwise to create a binary JSON
1332−jsonbZipObject :: FunctionHet
1333− '[ null ('PGvararray ('NotNull 'PGtext))
1334− , null ('PGvararray ('NotNull 'PGtext)) ]
1336−jsonbZipObject = unsafeFunctionHet "jsonb_object"
1338−{-----------------------------------------
1339−Table 9.46: JSON processing functions
1340−-----------------------------------------}
1342−-- | Returns the number of elements in the outermost JSON array.
1343−jsonArrayLength :: null 'PGjson :--> null 'PGint4
1344−jsonArrayLength = unsafeFunction "json_array_length"
1346−-- | Returns the number of elements in the outermost binary JSON array.
1347−jsonbArrayLength :: null 'PGjsonb :--> null 'PGint4
1348−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1350−-- | Returns JSON value pointed to by the given path (equivalent to #>
1354− => Expression outer grp commons schemas params from (null 'PGjson)
1355− -> NP (Expression outer grp commons schemas params from) elems
1356− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1357−jsonExtractPath x xs =
1358− unsafeFunctionHet "json_extract_path" (x :* xs)
1360−-- | Returns JSON value pointed to by the given path (equivalent to #>
1364− => Expression outer grp commons schemas params from (null 'PGjsonb)
1365− -> NP (Expression outer grp commons schemas params from) elems
1366− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1367−jsonbExtractPath x xs =
1368− unsafeFunctionHet "jsonb_extract_path" (x :* xs)
1370−-- | Returns JSON value pointed to by the given path (equivalent to #>
1371−-- operator), as text.
1372−jsonExtractPathAsText
1374− => Expression outer grp commons schemas params from (null 'PGjson)
1375− -> NP (Expression outer grp commons schemas params from) elems
1376− -> Expression outer grp commons schemas params from (null 'PGjson)
1377−jsonExtractPathAsText x xs =
1378− unsafeFunctionHet "json_extract_path_text" (x :* xs)
1380−-- | Returns JSON value pointed to by the given path (equivalent to #>
1381−-- operator), as text.
1382−jsonbExtractPathAsText
1384− => Expression outer grp commons schemas params from (null 'PGjsonb)
1385− -> NP (Expression outer grp commons schemas params from) elems
1386− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1387−jsonbExtractPathAsText x xs =
1388− unsafeFunctionHet "jsonb_extract_path_text" (x :* xs)
1390−-- | Returns the type of the outermost JSON value as a text string. Possible
1391−-- types are object, array, string, number, boolean, and null.
1392−jsonTypeof :: null 'PGjson :--> null 'PGtext
1393−jsonTypeof = unsafeFunction "json_typeof"
1395−-- | Returns the type of the outermost binary JSON value as a text string.
1396−-- Possible types are object, array, string, number, boolean, and null.
1397−jsonbTypeof :: null 'PGjsonb :--> null 'PGtext
1398−jsonbTypeof = unsafeFunction "jsonb_typeof"
1400−-- | Returns its argument with all object fields that have null values omitted.
1401−-- Other null values are untouched.
1402−jsonStripNulls :: null 'PGjson :--> null 'PGjson
1403−jsonStripNulls = unsafeFunction "json_strip_nulls"
1405−-- | Returns its argument with all object fields that have null values omitted.
1406−-- Other null values are untouched.
1407−jsonbStripNulls :: null 'PGjsonb :--> null 'PGjsonb
1408−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1410−-- | @ jsonbSet target path new_value create_missing @
1412−-- Returns target with the section designated by path replaced by new_value,
1413−-- or with new_value added if create_missing is true ( default is true) and the
1414−-- item designated by path does not exist. As with the path orientated
1415−-- operators, negative integers that appear in path count from the end of JSON
1418− :: Expression outer grp commons schemas params from (null 'PGjsonb)
1419− -> Expression outer grp commons schemas params from (null ('PGvararray ('NotNull 'PGtext)))
1420− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1421− -> Maybe (Expression outer grp commons schemas params from (null 'PGbool))
1422− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1423−jsonbSet tgt path val createMissing = case createMissing of
1424− Just m -> unsafeFunctionHet "jsonb_set" (tgt :* path :* val :* m :* Nil)
1425− Nothing -> unsafeFunctionHet "jsonb_set" (tgt :* path :* val :* Nil)
1427−-- | @ jsonbInsert target path new_value insert_after @
1429−-- Returns target with new_value inserted. If target section designated by
1430−-- path is in a JSONB array, new_value will be inserted before target or after
1431−-- if insert_after is true (default is false). If target section designated by
1432−-- path is in JSONB object, new_value will be inserted only if target does not
1433−-- exist. As with the path orientated operators, negative integers that appear
1434−-- in path count from the end of JSON arrays.
1436− :: Expression outer grp commons schemas params from (null 'PGjsonb)
1437− -> Expression outer grp commons schemas params from (null ('PGvararray ('NotNull 'PGtext)))
1438− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1439− -> Maybe (Expression outer grp commons schemas params from (null 'PGbool))
1440− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1441−jsonbInsert tgt path val insertAfter = case insertAfter of
1442− Just i -> unsafeFunctionHet "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1443− Nothing -> unsafeFunctionHet "jsonb_insert" (tgt :* path :* val :* Nil)
1445−-- | Returns its argument as indented JSON text.
1446−jsonbPretty :: null 'PGjsonb :--> null 'PGtext
1447−jsonbPretty = unsafeFunction "jsonb_pretty"
1449−(@@) :: Operator (null 'PGtsvector) (null 'PGtsquery) ('Null 'PGbool)
1450−(@@) = unsafeBinaryOp "@@"
1452−(.&) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1453−(.&) = unsafeBinaryOp "&&"
1455−(.|) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1456−(.|) = unsafeBinaryOp "||"
1458−(.!) :: null 'PGtsquery :--> null 'PGtsquery
1459−(.!) = unsafeUnaryOpL "!!"
1461−(<->) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1462−(<->) = unsafeBinaryOp "<->"
1465− :: null ('PGvararray ('NotNull 'PGtext))
1466− :--> null 'PGtsvector
1467−arrayToTSvector = unsafeFunction "array_to_tsvector"
1469−tsvectorLength :: null 'PGtsvector :--> null 'PGint4
1470−tsvectorLength = unsafeFunction "length"
1472−numnode :: null 'PGtsquery :--> null 'PGint4
1473−numnode = unsafeFunction "numnode"
1475−plainToTSquery :: null 'PGtext :--> null 'PGtsquery
1476−plainToTSquery = unsafeFunction "plainto_tsquery"
1478−phraseToTSquery :: null 'PGtext :--> null 'PGtsquery
1479−phraseToTSquery = unsafeFunction "phraseto_tsquery"
1481−websearchToTSquery :: null 'PGtext :--> null 'PGtsquery
1482−websearchToTSquery = unsafeFunction "websearch_to_tsquery"
1484−queryTree :: null 'PGtsquery :--> null 'PGtext
1485−queryTree = unsafeFunction "query_tree"
1487−toTSquery :: null 'PGtext :--> null 'PGtsquery
1488−toTSquery = unsafeFunction "to_tsquery"
1491− :: ty `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1492− => null ty :--> null 'PGtsquery
1493−toTSvector = unsafeFunction "to_tsvector"
1496− :: FunctionHet '[null 'PGtsvector, null ('PGchar 1)] (null 'PGtsvector)
1497−setWeight = unsafeFunctionHet "set_weight"
1499−litChar :: Char -> Expr (null ('PGchar 1))
1500−litChar chr = UnsafeExpression $
1501− "E\'" <> fromString (escape =<< [chr]) <> "\'"
1503−strip :: null 'PGtsvector :--> null 'PGtsvector
1504−strip = unsafeFunction "strip"
1506−jsonToTSvector :: FunctionHet '[null 'PGjson, null 'PGjson] (null 'PGtsvector)
1507−jsonToTSvector = unsafeFunctionHet "json_to_tsvector"
1509−jsonbToTSvector :: FunctionHet '[null 'PGjsonb, null 'PGjsonb] (null 'PGtsvector)
1510−jsonbToTSvector = unsafeFunctionHet "jsonb_to_tsvector"
1512−tsDelete :: FunctionHet
1513− '[null 'PGtsvector, null ('PGvararray ('NotNull 'PGtext))]
1515−tsDelete = unsafeFunctionHet "ts_delete"
1517−tsFilter :: FunctionHet
1518− '[null 'PGtsvector, null ('PGvararray ('NotNull ('PGchar 1)))]
1520−tsFilter = unsafeFunctionHet "ts_filter"
1523− :: document `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1524− => FunctionHet '[null document, null 'PGtsquery] (null 'PGtext)
1525−tsHeadline = unsafeFunctionHet "ts_headline"
1526−{-----------------------------------------
1528−-----------------------------------------}
1531− = forall outer bys commons schemas params from
1532− . Distinction (Expression outer 'Ungrouped commons schemas params from) x
1534− -> Expression outer ('Grouped bys) commons schemas params from y
1538− = forall outer bys commons schemas params from
1539− . Distinction (NP (Expression outer 'Ungrouped commons schemas params from)) xs
1541− -> Expression outer ('Grouped bys) commons schemas params from y
1544−unsafeAggregateHet :: SOP.SListI xs => ByteString -> AggrHet xs y
1545−unsafeAggregateHet fun xs = UnsafeExpression $ mconcat
1546− [fun, "(", renderSQL xs, ")"]
1549−`Aggregate` functions compute a single result from a set of input values.
1550−`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1551−as `WindowFunction`s.
1553−class Aggregate expr1 exprHet aggr
1554− | aggr -> expr1, aggr -> exprHet where
1556− -- | A special aggregation that does not require an input
1560− -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1561− -- expression = countStar
1562− -- in printSQL expression
1565− countStar :: aggr ('NotNull 'PGint8)
1569− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null ty]] ('NotNull 'PGint8)
1570− -- expression = count (All #col)
1571− -- in printSQL expression
1573− -- count(ALL "col")
1577− -> aggr ('NotNull 'PGint8)
1581− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('NotNull 'PGnumeric)
1582− -- expression = sum_ (Distinct #col)
1583− -- in printSQL expression
1585− -- sum(DISTINCT "col")
1589− -> aggr ('NotNull ty)
1591− -- | input values, including nulls, concatenated into an array
1594− -> aggr ('Null ('PGvararray ty))
1596− -- | aggregates values as a JSON array
1599− -> aggr ('Null 'PGjson)
1601− -- | aggregates values as a JSON array
1604− -> aggr ('Null 'PGjsonb)
1607− the bitwise AND of all non-null input values, or null if none
1610− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1611− expression = bitAnd (Distinct #col)
1612− in printSQL expression
1614− bit_and(DISTINCT "col")
1617− :: int `In` PGIntegral
1618− => expr1 (null int)
1619− -- ^ what to aggregate
1620− -> aggr ('Null int)
1623− the bitwise OR of all non-null input values, or null if none
1627− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1628− expression = bitOr (All #col)
1629− in printSQL expression
1634− :: int `In` PGIntegral
1635− => expr1 (null int)
1636− -- ^ what to aggregate
1637− -> aggr ('Null int)
1640− true if all input values are true, otherwise false
1644− winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1645− winFun = boolAnd #col
1651− :: expr1 (null 'PGbool)
1652− -- ^ what to aggregate
1653− -> aggr ('Null 'PGbool)
1656− true if at least one input value is true, otherwise false
1660− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1661− expression = boolOr (All #col)
1662− in printSQL expression
1667− :: expr1 (null 'PGbool)
1668− -- ^ what to aggregate
1669− -> aggr ('Null 'PGbool)
1672− equivalent to `boolAnd`
1676− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1677− expression = every (Distinct #col)
1678− in printSQL expression
1680− every(DISTINCT "col")
1683− :: expr1 (null 'PGbool)
1684− -- ^ what to aggregate
1685− -> aggr ('Null 'PGbool)
1687− {- |maximum value of expression across all input values-}
1690− -- ^ what to maximize
1693− -- | minimum value of expression across all input values
1696− -- ^ what to minimize
1699− -- | the average (arithmetic mean) of all input values
1702− -- ^ what to average
1703− -> aggr ('Null (PGAvg ty))
1705− {- | correlation coefficient
1708− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1709− expression = corr (All (#y *: #x))
1710− in printSQL expression
1715− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1716− -> aggr ('Null 'PGfloat8)
1718− {- | population covariance
1721− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1722− expression = covarPop (All (#y *: #x))
1723− in printSQL expression
1725− covar_pop(ALL "y", "x")
1728− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1729− -> aggr ('Null 'PGfloat8)
1731− {- | sample covariance
1734− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1735− winFun = covarSamp (#y *: #x)
1738− covar_samp("y", "x")
1741− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1742− -> aggr ('Null 'PGfloat8)
1744− {- | average of the independent variable (sum(X)/N)
1747− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1748− expression = regrAvgX (All (#y *: #x))
1749− in printSQL expression
1751− regr_avgx(ALL "y", "x")
1754− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1755− -> aggr ('Null 'PGfloat8)
1757− {- | average of the dependent variable (sum(Y)/N)
1760− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1761− winFun = regrAvgY (#y *: #x)
1764− regr_avgy("y", "x")
1767− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1768− -> aggr ('Null 'PGfloat8)
1770− {- | number of input rows in which both expressions are nonnull
1773− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGint8)
1774− winFun = regrCount (#y *: #x)
1777− regr_count("y", "x")
1780− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1781− -> aggr ('Null 'PGint8)
1783− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1786− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1787− expression = regrIntercept (All (#y *: #x))
1788− in printSQL expression
1790− regr_intercept(ALL "y", "x")
1793− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1794− -> aggr ('Null 'PGfloat8)
1796− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1798− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1799− -> aggr ('Null 'PGfloat8)
1801− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1802− -- determined by the (X, Y) pairs
1804− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1805− -> aggr ('Null 'PGfloat8)
1807− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1808− -- (“sum of squares” of the independent variable)
1810− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1811− -> aggr ('Null 'PGfloat8)
1813− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1814− -- (“sum of products” of independent times dependent variable)
1816− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1817− -> aggr ('Null 'PGfloat8)
1819− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1820− -- (“sum of squares” of the dependent variable)
1822− :: exprHet '[null 'PGfloat8, null 'PGfloat8]
1823− -> aggr ('Null 'PGfloat8)
1825− -- | historical alias for `stddevSamp`
1828− -> aggr ('Null (PGAvg ty))
1830− -- | population standard deviation of the input values
1833− -> aggr ('Null (PGAvg ty))
1835− -- | sample standard deviation of the input values
1838− -> aggr ('Null (PGAvg ty))
1840− -- | historical alias for `varSamp`
1843− -> aggr ('Null (PGAvg ty))
1845− -- | population variance of the input values
1846− -- (square of the population standard deviation)
1849− -> aggr ('Null (PGAvg ty))
1851− -- | sample variance of the input values
1852− -- (square of the sample standard deviation)
1855− -> aggr ('Null (PGAvg ty))
1858−`Distinction`s are used for the input of `Aggregate` `Expression`s.
1859−`All` invokes the aggregate once for each input row.
1860−`Distinct` invokes the aggregate once for each distinct value of the expression
1861−(or distinct set of values, for multiple expressions) found in the input
1863−data Distinction (expr :: kind -> Type) (ty :: kind)
1865− | Distinct (expr ty)
1866− deriving (GHC.Generic,Show,Eq,Ord)
1867−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1868−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1870− All x -> "ALL" <+> renderSQL x
1871− Distinct x -> "DISTINCT" <+> renderSQL x
1872−instance SOP.SListI tys => RenderSQL
1873− (Distinction (NP (Expression outer grp commons schemas params from)) tys) where
1875− All xs -> "ALL" <+> renderCommaSeparated renderSQL xs
1876− Distinct xs -> "DISTINCT" <+> renderCommaSeparated renderSQL xs
1879− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1880− (Distinction (NP (Expression outer 'Ungrouped commons schemas params from)))
1881− (Expression outer ('Grouped bys) commons schemas params from) where
1882− countStar = UnsafeExpression "count(*)"
1883− count = unsafeAggregate1 "count"
1884− sum_ = unsafeAggregate1 "sum"
1885− arrayAgg = unsafeAggregate1 "array_agg"
1886− jsonAgg = unsafeAggregate1 "json_agg"
1887− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1888− bitAnd = unsafeAggregate1 "bit_and"
1889− bitOr = unsafeAggregate1 "bit_or"
1890− boolAnd = unsafeAggregate1 "bool_and"
1891− boolOr = unsafeAggregate1 "bool_or"
1892− every = unsafeAggregate1 "every"
1893− max_ = unsafeAggregate1 "max"
1894− min_ = unsafeAggregate1 "min"
1895− avg = unsafeAggregate1 "avg"
1896− corr = unsafeAggregateHet "corr"
1897− covarPop = unsafeAggregateHet "covar_pop"
1898− covarSamp = unsafeAggregateHet "covar_samp"
1899− regrAvgX = unsafeAggregateHet "regr_avgx"
1900− regrAvgY = unsafeAggregateHet "regr_avgy"
1901− regrCount = unsafeAggregateHet "regr_count"
1902− regrIntercept = unsafeAggregateHet "regr_intercept"
1903− regrR2 = unsafeAggregateHet "regr_r2"
1904− regrSlope = unsafeAggregateHet "regr_slope"
1905− regrSxx = unsafeAggregateHet "regr_sxx"
1906− regrSxy = unsafeAggregateHet "regr_sxy"
1907− regrSyy = unsafeAggregateHet "regr_syy"
1908− stddev = unsafeAggregate1 "stddev"
1909− stddevPop = unsafeAggregate1 "stddev_pop"
1910− stddevSamp = unsafeAggregate1 "stddev_samp"
1911− variance = unsafeAggregate1 "variance"
1912− varPop = unsafeAggregate1 "var_pop"
1913− varSamp = unsafeAggregate1 "var_samp"
1915− (Expression outer grp commons schemas params from)
1916− (NP (Expression outer grp commons schemas params from))
1917− (WindowFunction outer grp commons schemas params from) where
1918− countStar = UnsafeWindowFunction "count(*)"
1919− count = unsafeWindowFunction1 "count"
1920− sum_ = unsafeWindowFunction1 "sum"
1921− arrayAgg = unsafeWindowFunction1 "array_agg"
1922− jsonAgg = unsafeWindowFunction1 "json_agg"
1923− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1924− bitAnd = unsafeWindowFunction1 "bit_and"
1925− bitOr = unsafeWindowFunction1 "bit_or"
1926− boolAnd = unsafeWindowFunction1 "bool_and"
1927− boolOr = unsafeWindowFunction1 "bool_or"
1928− every = unsafeWindowFunction1 "every"
1929− max_ = unsafeWindowFunction1 "max"
1930− min_ = unsafeWindowFunction1 "min"
1931− avg = unsafeWindowFunction1 "avg"
1932− corr = unsafeWindowFunctionHet "corr"
1933− covarPop = unsafeWindowFunctionHet "covar_pop"
1934− covarSamp = unsafeWindowFunctionHet "covar_samp"
1935− regrAvgX = unsafeWindowFunctionHet "regr_avgx"
1936− regrAvgY = unsafeWindowFunctionHet "regr_avgy"
1937− regrCount = unsafeWindowFunctionHet "regr_count"
1938− regrIntercept = unsafeWindowFunctionHet "regr_intercept"
1939− regrR2 = unsafeWindowFunctionHet "regr_r2"
1940− regrSlope = unsafeWindowFunctionHet "regr_slope"
1941− regrSxx = unsafeWindowFunctionHet "regr_sxx"
1942− regrSxy = unsafeWindowFunctionHet "regr_sxy"
1943− regrSyy = unsafeWindowFunctionHet "regr_syy"
1944− stddev = unsafeWindowFunction1 "stddev"
1945− stddevPop = unsafeWindowFunction1 "stddev_pop"
1946− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1947− variance = unsafeWindowFunction1 "variance"
1948− varPop = unsafeWindowFunction1 "var_pop"
1949− varSamp = unsafeWindowFunction1 "var_samp"
1951−-- | escape hatch to define aggregate functions
1953− :: ByteString -- ^ aggregate function
1955−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1956− [fun, "(", renderSQL x, ")"]
1958−-- | A type family that calculates `PGAvg` type of a `PGType`.
1959−type family PGAvg ty where
1960− PGAvg 'PGint2 = 'PGnumeric
1961− PGAvg 'PGint4 = 'PGnumeric
1962− PGAvg 'PGint8 = 'PGnumeric
1963− PGAvg 'PGnumeric = 'PGnumeric
1964− PGAvg 'PGfloat4 = 'PGfloat8
1965− PGAvg 'PGfloat8 = 'PGfloat8
1966− PGAvg 'PGinterval = 'PGinterval
1967− PGAvg pg = TypeError
1968− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1970−{-----------------------------------------
1972−-----------------------------------------}
1974−-- | `TypeExpression`s are used in `cast`s and
1975−-- `Squeal.PostgreSQL.Definition.createTable` commands.
1976−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1977− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1978− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1979−instance RenderSQL (TypeExpression schemas ty) where
1980− renderSQL = renderTypeExpression
1982−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1984− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1985− => QualifiedAlias sch td
1986− -> TypeExpression schemas (null ty)
1987−typedef = UnsafeTypeExpression . renderSQL
1989−-- | The composite type corresponding to a `Table` definition can be expressed
1992− :: (Has sch schemas schema, Has tab schema ('Table table))
1993− => QualifiedAlias sch tab
1994− -> TypeExpression schemas (null ('PGcomposite (TableToRow table)))
1995−typetable = UnsafeTypeExpression . renderSQL
1997−-- | The composite type corresponding to a `View` definition can be expressed
2000− :: (Has sch schemas schema, Has vw schema ('View view))
2001− => QualifiedAlias sch vw
2002− -> TypeExpression schemas (null ('PGcomposite view))
2003−typeview = UnsafeTypeExpression . renderSQL
2005−-- | logical Boolean (true/false)
2006−bool :: TypeExpression schemas (null 'PGbool)
2007−bool = UnsafeTypeExpression "bool"
2008−-- | signed two-byte integer
2009−int2, smallint :: TypeExpression schemas (null 'PGint2)
2010−int2 = UnsafeTypeExpression "int2"
2011−smallint = UnsafeTypeExpression "smallint"
2012−-- | signed four-byte integer
2013−int4, int, integer :: TypeExpression schemas (null 'PGint4)
2014−int4 = UnsafeTypeExpression "int4"
2015−int = UnsafeTypeExpression "int"
2016−integer = UnsafeTypeExpression "integer"
2017−-- | signed eight-byte integer
2018−int8, bigint :: TypeExpression schemas (null 'PGint8)
2019−int8 = UnsafeTypeExpression "int8"
2020−bigint = UnsafeTypeExpression "bigint"
2021−-- | arbitrary precision numeric type
2022−numeric :: TypeExpression schemas (null 'PGnumeric)
2023−numeric = UnsafeTypeExpression "numeric"
2024−-- | single precision floating-point number (4 bytes)
2025−float4, real :: TypeExpression schemas (null 'PGfloat4)
2026−float4 = UnsafeTypeExpression "float4"
2027−real = UnsafeTypeExpression "real"
2028−-- | double precision floating-point number (8 bytes)
2029−float8, doublePrecision :: TypeExpression schemas (null 'PGfloat8)
2030−float8 = UnsafeTypeExpression "float8"
2031−doublePrecision = UnsafeTypeExpression "double precision"
2032−-- | currency amount
2033−money :: TypeExpression schema (null 'PGmoney)
2034−money = UnsafeTypeExpression "money"
2035−-- | variable-length character string
2036−text :: TypeExpression schemas (null 'PGtext)
2037−text = UnsafeTypeExpression "text"
2038−-- | fixed-length character string
2040− :: forall n schemas null. (KnownNat n, 1 <= n)
2041− => TypeExpression schemas (null ('PGchar n))
2042−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
2043−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
2044−-- | variable-length character string
2045−varchar, characterVarying
2046− :: forall n schemas null. (KnownNat n, 1 <= n)
2047− => TypeExpression schemas (null ('PGvarchar n))
2048−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
2049−characterVarying = UnsafeTypeExpression $
2050− "character varying(" <> renderNat @n <> ")"
2051−-- | binary data ("byte array")
2052−bytea :: TypeExpression schemas (null 'PGbytea)
2053−bytea = UnsafeTypeExpression "bytea"
2054−-- | date and time (no time zone)
2055−timestamp :: TypeExpression schemas (null 'PGtimestamp)
2056−timestamp = UnsafeTypeExpression "timestamp"
2057−-- | date and time, including time zone
2058−timestampWithTimeZone :: TypeExpression schemas (null 'PGtimestamptz)
2059−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
2060−-- | calendar date (year, month, day)
2061−date :: TypeExpression schemas (null 'PGdate)
2062−date = UnsafeTypeExpression "date"
2063−-- | time of day (no time zone)
2064−time :: TypeExpression schemas (null 'PGtime)
2065−time = UnsafeTypeExpression "time"
2066−-- | time of day, including time zone
2067−timeWithTimeZone :: TypeExpression schemas (null 'PGtimetz)
2068−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
2070−interval :: TypeExpression schemas (null 'PGinterval)
2071−interval = UnsafeTypeExpression "interval"
2072−-- | universally unique identifier
2073−uuid :: TypeExpression schemas (null 'PGuuid)
2074−uuid = UnsafeTypeExpression "uuid"
2075−-- | IPv4 or IPv6 host address
2076−inet :: TypeExpression schemas (null 'PGinet)
2077−inet = UnsafeTypeExpression "inet"
2078−-- | textual JSON data
2079−json :: TypeExpression schemas (null 'PGjson)
2080−json = UnsafeTypeExpression "json"
2081−-- | binary JSON data, decomposed
2082−jsonb :: TypeExpression schemas (null 'PGjsonb)
2083−jsonb = UnsafeTypeExpression "jsonb"
2084−-- | variable length array
2086− :: TypeExpression schemas pg
2087− -> TypeExpression schemas (null ('PGvararray pg))
2088−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
2089−-- | fixed length array
2091−-- >>> renderSQL (fixarray @'[2] json)
2094− :: forall dims schemas null pg. SOP.All KnownNat dims
2095− => TypeExpression schemas pg
2096− -> TypeExpression schemas (null ('PGfixarray dims pg))
2097−fixarray ty = UnsafeTypeExpression $
2098− renderSQL ty <> renderDims @dims
2100− renderDims :: forall ns. SOP.All KnownNat ns => ByteString
2104− . ByteString.intercalate "]["
2106− $ hcmap (SOP.Proxy @KnownNat)
2107− (K . fromString . show . natVal)
2108− (hpure SOP.Proxy :: NP SOP.Proxy ns)
2109−tsvector :: TypeExpression schemas (null 'PGtsvector)
2110−tsvector = UnsafeTypeExpression "tsvector"
2111−tsquery :: TypeExpression schemas (null 'PGtsquery)
2112−tsquery = UnsafeTypeExpression "tsquery"
2114−-- | `pgtype` is a demoted version of a `PGType`
2115−class PGTyped schemas (ty :: NullityType) where
2116− pgtype :: TypeExpression schemas ty
2117−instance PGTyped schemas (null 'PGbool) where pgtype = bool
2118−instance PGTyped schemas (null 'PGint2) where pgtype = int2
2119−instance PGTyped schemas (null 'PGint4) where pgtype = int4
2120−instance PGTyped schemas (null 'PGint8) where pgtype = int8
2121−instance PGTyped schemas (null 'PGnumeric) where pgtype = numeric
2122−instance PGTyped schemas (null 'PGfloat4) where pgtype = float4
2123−instance PGTyped schemas (null 'PGfloat8) where pgtype = float8
2124−instance PGTyped schemas (null 'PGmoney) where pgtype = money
2125−instance PGTyped schemas (null 'PGtext) where pgtype = text
2126−instance (KnownNat n, 1 <= n)
2127− => PGTyped schemas (null ('PGchar n)) where pgtype = char @n
2128−instance (KnownNat n, 1 <= n)
2129− => PGTyped schemas (null ('PGvarchar n)) where pgtype = varchar @n
2130−instance PGTyped schemas (null 'PGbytea) where pgtype = bytea
2131−instance PGTyped schemas (null 'PGtimestamp) where pgtype = timestamp
2132−instance PGTyped schemas (null 'PGtimestamptz) where pgtype = timestampWithTimeZone
2133−instance PGTyped schemas (null 'PGdate) where pgtype = date
2134−instance PGTyped schemas (null 'PGtime) where pgtype = time
2135−instance PGTyped schemas (null 'PGtimetz) where pgtype = timeWithTimeZone
2136−instance PGTyped schemas (null 'PGinterval) where pgtype = interval
2137−instance PGTyped schemas (null 'PGuuid) where pgtype = uuid
2138−instance PGTyped schemas (null 'PGjson) where pgtype = json
2139−instance PGTyped schemas (null 'PGjsonb) where pgtype = jsonb
2140−instance PGTyped schemas ty
2141− => PGTyped schemas (null ('PGvararray ty)) where
2142− pgtype = vararray (pgtype @schemas @ty)
2143−instance (SOP.All KnownNat dims, PGTyped schemas ty)
2144− => PGTyped schemas (null ('PGfixarray dims ty)) where
2145− pgtype = fixarray @dims (pgtype @schemas @ty)
2146−instance PGTyped schemas (null 'PGtsvector) where pgtype = tsvector
2147−instance PGTyped schemas (null 'PGtsquery) where pgtype = tsquery
2149−{-----------------------------------------
2151−-----------------------------------------}
2153−-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2154−-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2155−-- set the sort direction of a `NotNull` result
2156−-- column to ascending or descending. Ascending order puts smaller values
2157−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2158−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2159−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2160−-- determine whether nulls appear before or after non-null values in the sort
2161−-- ordering of a `Null` result column.
2162−data SortExpression outer grp commons schemas params from where
2164− :: Expression outer grp commons schemas params from ('NotNull ty)
2165− -> SortExpression outer grp commons schemas params from
2167− :: Expression outer grp commons schemas params from ('NotNull ty)
2168− -> SortExpression outer grp commons schemas params from
2170− :: Expression outer grp commons schemas params from ('Null ty)
2171− -> SortExpression outer grp commons schemas params from
2173− :: Expression outer grp commons schemas params from ('Null ty)
2174− -> SortExpression outer grp commons schemas params from
2176− :: Expression outer grp commons schemas params from ('Null ty)
2177− -> SortExpression outer grp commons schemas params from
2179− :: Expression outer grp commons schemas params from ('Null ty)
2180− -> SortExpression outer grp commons schemas params from
2181−deriving instance Show (SortExpression outer grp commons schemas params from)
2184−The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2185−to be sorted according to the specified `SortExpression`(s).
2186−If two rows are equal according to the leftmost expression,
2187−they are compared according to the next expression and so on.
2188−If they are equal according to all specified expressions,
2189−they are returned in an implementation-dependent order.
2191−You can also control the order in which rows are processed by window functions
2192−using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2194−class OrderBy expr where
2196− :: [SortExpression outer grp commons schemas params from]
2197− -> expr outer grp commons schemas params from
2198− -> expr outer grp commons schemas params from
2200−-- | Render a `SortExpression`.
2201−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2203− Asc expression -> renderSQL expression <+> "ASC"
2204− Desc expression -> renderSQL expression <+> "DESC"
2205− AscNullsFirst expression -> renderSQL expression
2206− <+> "ASC NULLS FIRST"
2207− DescNullsFirst expression -> renderSQL expression
2208− <+> "DESC NULLS FIRST"
2209− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2210− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2212−-- | A `WindowDefinition` is a set of table rows that are somehow related
2213−-- to the current row
2214−data WindowDefinition outer grp commons schemas params from where
2217− => NP (Expression outer grp commons schemas params from) bys
2218− -> [SortExpression outer grp commons schemas params from]
2219− -> WindowDefinition outer grp commons schemas params from
2221−instance OrderBy WindowDefinition where
2222− orderBy sortsR (WindowDefinition parts sortsL)
2223− = WindowDefinition parts (sortsL ++ sortsR)
2225−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2226− renderSQL (WindowDefinition part ord) =
2227− renderPartitionByClause part <> renderOrderByClause ord
2229− renderPartitionByClause = \case
2231− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2232− renderOrderByClause = \case
2234− srts -> " ORDER" <+> "BY"
2235− <+> commaSeparated (renderSQL <$> srts)
2238−The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2239−or partitions, that share the same values of the `partitionBy` `Expression`(s).
2240−For each row, the window function is computed across the rows that fall into
2241−the same partition as the current row.
2245− => NP (Expression outer grp commons schemas params from) bys
2246− -> WindowDefinition outer grp commons schemas params from
2247−partitionBy bys = WindowDefinition bys []
2250−A window function performs a calculation across a set of table rows
2251−that are somehow related to the current row. This is comparable to the type
2252−of calculation that can be done with an aggregate function.
2253−However, window functions do not cause rows to become grouped into a single
2254−output row like non-window aggregate calls would.
2255−Instead, the rows retain their separate identities.
2256−Behind the scenes, the window function is able to access more than
2257−just the current row of the query result.
2259−newtype WindowFunction
2260− (outer :: FromType)
2262− (commons :: FromType)
2263− (schemas :: SchemasType)
2264− (params :: [NullityType])
2266− (ty :: NullityType)
2267− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2268− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2270−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2271− renderSQL = renderWindowFunction
2274− = forall outer grp commons schemas params from
2275− . WindowFunction outer grp commons schemas params from x
2276− -- ^ cannot reference aliases
2279− = forall outer grp commons schemas params from
2280− . Expression outer grp commons schemas params from x
2282− -> WindowFunction outer grp commons schemas params from y
2286− = forall outer grp commons schemas params from
2287− . NP (Expression outer grp commons schemas params from) xs
2289− -> WindowFunction outer grp commons schemas params from y
2292−unsafeWindowFunction1 :: ByteString -> WinFun1 x y
2293−unsafeWindowFunction1 fun x
2294− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2296−unsafeWindowFunctionHet :: SOP.SListI xs => ByteString -> WinFunHet xs y
2297−unsafeWindowFunctionHet fun xs = UnsafeWindowFunction $ fun <>
2298− parenthesized (renderCommaSeparated renderSQL xs)
2300−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2304−rank :: WinFun0 ('NotNull 'PGint8)
2305−rank = UnsafeWindowFunction "rank()"
2307−{- | number of the current row within its partition, counting from 1
2308−>>> printSQL rowNumber
2311−rowNumber :: WinFun0 ('NotNull 'PGint8)
2312−rowNumber = UnsafeWindowFunction "row_number()"
2314−{- | rank of the current row without gaps; this function counts peer groups
2315−>>> printSQL denseRank
2318−denseRank :: WinFun0 ('NotNull 'PGint8)
2319−denseRank = UnsafeWindowFunction "dense_rank()"
2321−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2322−>>> printSQL percentRank
2325−percentRank :: WinFun0 ('NotNull 'PGfloat8)
2326−percentRank = UnsafeWindowFunction "percent_rank()"
2328−{- | cumulative distribution: (number of partition rows
2329−preceding or peer with current row) / total partition rows
2330−>>> printSQL cumeDist
2333−cumeDist :: WinFun0 ('NotNull 'PGfloat8)
2334−cumeDist = UnsafeWindowFunction "cume_dist()"
2336−{- | integer ranging from 1 to the argument value,
2337−dividing the partition as equally as possible
2339−ntile :: WinFun1 ('NotNull 'PGint4) ('NotNull 'PGint4)
2340−ntile = unsafeWindowFunction1 "ntile"
2342−{- | returns value evaluated at the row that is offset rows before the current
2343−row within the partition; if there is no such row, instead return default
2344−(which must be of the same type as value). Both offset and default are
2345−evaluated with respect to the current row.
2347−lag :: WinFunHet '[ty, 'NotNull 'PGint4, ty] ty
2348−lag = unsafeWindowFunctionHet "lag"
2350−{- | returns value evaluated at the row that is offset rows after the current
2351−row within the partition; if there is no such row, instead return default
2352−(which must be of the same type as value). Both offset and default are
2353−evaluated with respect to the current row.
2355−lead :: WinFunHet '[ty, 'NotNull 'PGint4, ty] ty
2356−lead = unsafeWindowFunctionHet "lag"
2358−{- | returns value evaluated at the row that is the
2359−first row of the window frame
2361−firstValue :: WinFun1 ty ty
2362−firstValue = unsafeWindowFunction1 "first_value"
2364−{- | returns value evaluated at the row that is the
2365−last row of the window frame
2367−lastValue :: WinFun1 ty ty
2368−lastValue = unsafeWindowFunction1 "last_value"
2370−{- | returns value evaluated at the row that is the nth
2371−row of the window frame (counting from 1); null if no such row
2373−nthValue :: WinFunHet '[null ty, 'NotNull 'PGint4] ('Null ty)
2374−nthValue = unsafeWindowFunctionHet "nth_value"
2377−Create date from year, month and day fields
2379−>>> printSQL (makeDate (1984 :* 7 *: 3))
2380−make_date(1984, 7, 3)
2382−makeDate :: FunctionHet
2383− '[ null 'PGint4, null 'PGint4, null 'PGint4 ]
2385−makeDate = unsafeFunctionHet "make_date"
2388−Create time from hour, minute and seconds fields
2390−>>> printSQL (makeTime (8 :* 15 *: 23.5))
2391−make_time(8, 15, 23.5)
2393−makeTime :: FunctionHet
2394− '[ null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2396−makeTime = unsafeFunctionHet "make_time"
2399−Create timestamp from year, month, day, hour, minute and seconds fields
2401−>>> printSQL (makeTimestamp (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2402−make_timestamp(2013, 7, 15, 8, 15, 23.5)
2404−makeTimestamp :: FunctionHet
2405− '[ null 'PGint4, null 'PGint4, null 'PGint4
2406− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2407− ( null 'PGtimestamp )
2408−makeTimestamp = unsafeFunctionHet "make_timestamp"
2411−Create timestamp with time zone from
2412−year, month, day, hour, minute and seconds fields;
2413−the current time zone is used
2415−>>> printSQL (makeTimestamptz (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2416−make_timestamptz(2013, 7, 15, 8, 15, 23.5)
2418−makeTimestamptz :: FunctionHet
2419− '[ null 'PGint4, null 'PGint4, null 'PGint4
2420− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2421− ( null 'PGtimestamptz )
2422−makeTimestamptz = unsafeFunctionHet "make_timestamptz"
2425−Affine space operations on time types.
2427−class TimeOp time diff | time -> diff where
2429− >>> printSQL (makeDate (1984 :* 7 *: 3) !+ 365)
2430− (make_date(1984, 7, 3) + 365)
2432− (!+) :: Operator (null time) (null diff) (null time)
2433− (!+) = unsafeBinaryOp "+"
2435− >>> printSQL (365 +! makeDate (1984 :* 7 *: 3))
2436− (365 + make_date(1984, 7, 3))
2438− (+!) :: Operator (null diff) (null time) (null time)
2439− (+!) = unsafeBinaryOp "+"
2441− >>> printSQL (makeDate (1984 :* 7 *: 3) !- 365)
2442− (make_date(1984, 7, 3) - 365)
2444− (!-) :: Operator (null time) (null diff) (null time)
2445− (!-) = unsafeBinaryOp "-"
2447− >>> printSQL (makeDate (1984 :* 7 *: 3) !-! currentDate)
2448− (make_date(1984, 7, 3) - CURRENT_DATE)
2450− (!-!) :: Operator (null time) (null time) (null diff)
2451− (!-!) = unsafeBinaryOp "-"
2452−instance TimeOp 'PGtimestamp 'PGinterval
2453−instance TimeOp 'PGtimestamptz 'PGinterval
2454−instance TimeOp 'PGtime 'PGinterval
2455−instance TimeOp 'PGtimetz 'PGinterval
2456−instance TimeOp 'PGinterval 'PGinterval
2457−instance TimeOp 'PGdate 'PGint4