{-# LANGUAGE
ConstraintKinds
, DeriveGeneric
, FlexibleContexts
, FlexibleInstances
, GADTs
, GeneralizedNewtypeDeriving
, LambdaCase
, MultiParamTypeClasses
, OverloadedStrings
, StandaloneDeriving
, TypeFamilies
, TypeInType
, TypeOperators
, RankNTypes
, UndecidableInstances
#-}
module Squeal.PostgreSQL.Query
(
Query (UnsafeQuery, renderQuery)
, select
, selectDistinct
, selectStar
, selectDistinctStar
, selectDotStar
, selectDistinctDotStar
, values
, values_
, union
, unionAll
, intersect
, intersectAll
, except
, exceptAll
, With (with)
, CommonTableExpression (..)
, renderCommonTableExpression
, renderCommonTableExpressions
, jsonEach
, jsonbEach
, jsonEachAsText
, jsonbEachAsText
, jsonObjectKeys
, jsonbObjectKeys
, jsonPopulateRecord
, jsonbPopulateRecord
, jsonPopulateRecordSet
, jsonbPopulateRecordSet
, jsonToRecord
, jsonbToRecord
, jsonToRecordSet
, jsonbToRecordSet
, TableExpression (..)
, renderTableExpression
, from
, where_
, groupBy
, having
, orderBy
, limit
, offset
, FromClause (..)
, table
, subquery
, view
, crossJoin
, innerJoin
, leftOuterJoin
, rightOuterJoin
, fullOuterJoin
, By (By1, By2)
, renderBy
, GroupByClause (NoGroups, Group)
, renderGroupByClause
, HavingClause (NoHaving, Having)
, renderHavingClause
, SortExpression (..)
, renderSortExpression
, in_
, rowIn
, eqAll
, rowEqAll
, eqAny
, rowEqAny
, neqAll
, rowNeqAll
, neqAny
, rowNeqAny
, allLt
, rowLtAll
, ltAny
, rowLtAny
, lteAll
, rowLteAll
, lteAny
, rowLteAny
, gtAll
, rowGtAll
, gtAny
, rowGtAny
, gteAll
, rowGteAll
, gteAny
, rowGteAny
) where
import Control.DeepSeq
import Data.ByteString (ByteString)
import Data.String
import Data.Word
import Generics.SOP hiding (from)
import GHC.TypeLits
import qualified GHC.Generics as GHC
import Squeal.PostgreSQL.Expression
import Squeal.PostgreSQL.Render
import Squeal.PostgreSQL.Schema
newtype Query
(schema :: SchemaType)
(params :: [NullityType])
(columns :: RowType)
= UnsafeQuery { renderQuery :: ByteString }
deriving (GHC.Generic,Show,Eq,Ord,NFData)
instance RenderSQL (Query schema params columns) where renderSQL = renderQuery
union
:: Query schema params columns
-> Query schema params columns
-> Query schema params columns
q1 `union` q2 = UnsafeQuery $
parenthesized (renderQuery q1)
<+> "UNION"
<+> parenthesized (renderQuery q2)
unionAll
:: Query schema params columns
-> Query schema params columns
-> Query schema params columns
q1 `unionAll` q2 = UnsafeQuery $
parenthesized (renderQuery q1)
<+> "UNION" <+> "ALL"
<+> parenthesized (renderQuery q2)
intersect
:: Query schema params columns
-> Query schema params columns
-> Query schema params columns
q1 `intersect` q2 = UnsafeQuery $
parenthesized (renderQuery q1)
<+> "INTERSECT"
<+> parenthesized (renderQuery q2)
intersectAll
:: Query schema params columns
-> Query schema params columns
-> Query schema params columns
q1 `intersectAll` q2 = UnsafeQuery $
parenthesized (renderQuery q1)
<+> "INTERSECT" <+> "ALL"
<+> parenthesized (renderQuery q2)
except
:: Query schema params columns
-> Query schema params columns
-> Query schema params columns
q1 `except` q2 = UnsafeQuery $
parenthesized (renderQuery q1)
<+> "EXCEPT"
<+> parenthesized (renderQuery q2)
exceptAll
:: Query schema params columns
-> Query schema params columns
-> Query schema params columns
q1 `exceptAll` q2 = UnsafeQuery $
parenthesized (renderQuery q1)
<+> "EXCEPT" <+> "ALL"
<+> parenthesized (renderQuery q2)
select
:: SListI columns
=> NP (Aliased (Expression schema from grouping params)) (column ': columns)
-> TableExpression schema params from grouping
-> Query schema params (column ': columns)
select list rels = UnsafeQuery $
"SELECT"
<+> renderCommaSeparated (renderAliasedAs renderExpression) list
<+> renderTableExpression rels
selectDistinct
:: SListI columns
=> NP (Aliased (Expression schema from 'Ungrouped params)) (column ': columns)
-> TableExpression schema params from 'Ungrouped
-> Query schema params (column ': columns)
selectDistinct list rels = UnsafeQuery $
"SELECT DISTINCT"
<+> renderCommaSeparated (renderAliasedAs renderExpression) list
<+> renderTableExpression rels
selectStar
:: HasUnique table from columns
=> TableExpression schema params from 'Ungrouped
-> Query schema params columns
selectStar rels = UnsafeQuery $ "SELECT" <+> "*" <+> renderTableExpression rels
selectDistinctStar
:: HasUnique table from columns
=> TableExpression schema params from 'Ungrouped
-> Query schema params columns
selectDistinctStar rels = UnsafeQuery $
"SELECT DISTINCT" <+> "*" <+> renderTableExpression rels
selectDotStar
:: Has table from columns
=> Alias table
-> TableExpression schema params from 'Ungrouped
-> Query schema params columns
selectDotStar rel tab = UnsafeQuery $
"SELECT" <+> renderAlias rel <> ".*" <+> renderTableExpression tab
selectDistinctDotStar
:: Has table from columns
=> Alias table
-> TableExpression schema params from 'Ungrouped
-> Query schema params columns
selectDistinctDotStar rel tab = UnsafeQuery $
"SELECT DISTINCT" <+> renderAlias rel <> ".*"
<+> renderTableExpression tab
values
:: SListI cols
=> NP (Aliased (Expression schema '[] 'Ungrouped params)) cols
-> [NP (Aliased (Expression schema '[] 'Ungrouped params)) cols]
-> Query schema params cols
values rw rws = UnsafeQuery $ "SELECT * FROM"
<+> parenthesized (
"VALUES"
<+> commaSeparated
( parenthesized
. renderCommaSeparated renderValuePart <$> rw:rws )
) <+> "AS t"
<+> parenthesized (renderCommaSeparated renderAliasPart rw)
where
renderAliasPart, renderValuePart
:: Aliased (Expression schema '[] 'Ungrouped params) ty -> ByteString
renderAliasPart (_ `As` name) = renderAlias name
renderValuePart (value `As` _) = renderExpression value
values_
:: SListI cols
=> NP (Aliased (Expression schema '[] 'Ungrouped params)) cols
-> Query schema params cols
values_ rw = values rw []
data TableExpression
(schema :: SchemaType)
(params :: [NullityType])
(from :: FromType)
(grouping :: Grouping)
= TableExpression
{ fromClause :: FromClause schema params from
, whereClause :: [Condition schema from 'Ungrouped params]
, groupByClause :: GroupByClause from grouping
, havingClause :: HavingClause schema from grouping params
, orderByClause :: [SortExpression schema from grouping params]
, limitClause :: [Word64]
, offsetClause :: [Word64]
}
renderTableExpression
:: TableExpression schema params from grouping
-> ByteString
renderTableExpression
(TableExpression frm' whs' grps' hvs' srts' lims' offs') = mconcat
[ "FROM ", renderFromClause frm'
, renderWheres whs'
, renderGroupByClause grps'
, renderHavingClause hvs'
, renderOrderByClause srts'
, renderLimits lims'
, renderOffsets offs'
]
where
renderWheres = \case
[] -> ""
wh:[] -> " WHERE" <+> renderExpression wh
wh:whs -> " WHERE" <+> renderExpression (foldr (.&&) wh whs)
renderOrderByClause = \case
[] -> ""
srts -> " ORDER BY"
<+> commaSeparated (renderSortExpression <$> srts)
renderLimits = \case
[] -> ""
lims -> " LIMIT" <+> fromString (show (minimum lims))
renderOffsets = \case
[] -> ""
offs -> " OFFSET" <+> fromString (show (sum offs))
from
:: FromClause schema params from
-> TableExpression schema params from 'Ungrouped
from rels = TableExpression rels [] NoGroups NoHaving [] [] []
where_
:: Condition schema from 'Ungrouped params
-> TableExpression schema params from grouping
-> TableExpression schema params from grouping
where_ wh rels = rels {whereClause = wh : whereClause rels}
groupBy
:: SListI bys
=> NP (By from) bys
-> TableExpression schema params from 'Ungrouped
-> TableExpression schema params from ('Grouped bys)
groupBy bys rels = TableExpression
{ fromClause = fromClause rels
, whereClause = whereClause rels
, groupByClause = Group bys
, havingClause = Having []
, orderByClause = []
, limitClause = limitClause rels
, offsetClause = offsetClause rels
}
having
:: Condition schema from ('Grouped bys) params
-> TableExpression schema params from ('Grouped bys)
-> TableExpression schema params from ('Grouped bys)
having hv rels = rels
{ havingClause = case havingClause rels of Having hvs -> Having (hv:hvs) }
orderBy
:: [SortExpression schema from grouping params]
-> TableExpression schema params from grouping
-> TableExpression schema params from grouping
orderBy srts rels = rels {orderByClause = orderByClause rels ++ srts}
limit
:: Word64
-> TableExpression schema params from grouping
-> TableExpression schema params from grouping
limit lim rels = rels {limitClause = lim : limitClause rels}
offset
:: Word64
-> TableExpression schema params from grouping
-> TableExpression schema params from grouping
offset off rels = rels {offsetClause = off : offsetClause rels}
unsafeSetOfFunction
:: ByteString
-> Expression schema '[] 'Ungrouped params ty
-> Query schema params row
unsafeSetOfFunction fun expr = UnsafeQuery $
"SELECT * FROM " <> fun <> "(" <> renderExpression expr <> ")"
jsonEach
:: Expression schema '[] 'Ungrouped params (nullity 'PGjson)
-> Query schema params
'["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGjson]
jsonEach = unsafeSetOfFunction "json_each"
jsonbEach
:: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
-> Query schema params
'["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGjsonb]
jsonbEach = unsafeSetOfFunction "jsonb_each"
jsonEachAsText
:: Expression schema '[] 'Ungrouped params (nullity 'PGjson)
-> Query schema params
'["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGtext]
jsonEachAsText = unsafeSetOfFunction "json_each_text"
jsonbEachAsText
:: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
-> Query schema params
'["key" ::: 'NotNull 'PGtext, "value" ::: 'NotNull 'PGtext]
jsonbEachAsText = unsafeSetOfFunction "jsonb_each_text"
jsonObjectKeys
:: Expression schema '[] 'Ungrouped params (nullity 'PGjson)
-> Query schema params '["json_object_keys" ::: 'NotNull 'PGtext]
jsonObjectKeys = unsafeSetOfFunction "json_object_keys"
jsonbObjectKeys
:: Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
-> Query schema params '["jsonb_object_keys" ::: 'NotNull 'PGtext]
jsonbObjectKeys = unsafeSetOfFunction "jsonb_object_keys"
unsafePopulateFunction
:: ByteString
-> TypeExpression schema (nullity ('PGcomposite row))
-> Expression schema '[] 'Ungrouped params ty
-> Query schema params row
unsafePopulateFunction fun ty expr = UnsafeQuery $
"SELECT * FROM " <> fun <> "("
<> "null::" <> renderTypeExpression ty <> ", "
<> renderExpression expr <> ")"
jsonPopulateRecord
:: TypeExpression schema (nullity ('PGcomposite row))
-> Expression schema '[] 'Ungrouped params (nullity 'PGjson)
-> Query schema params row
jsonPopulateRecord = unsafePopulateFunction "json_populate_record"
jsonbPopulateRecord
:: TypeExpression schema (nullity ('PGcomposite row))
-> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
-> Query schema params row
jsonbPopulateRecord = unsafePopulateFunction "jsonb_populate_record"
jsonPopulateRecordSet
:: TypeExpression schema (nullity ('PGcomposite row))
-> Expression schema '[] 'Ungrouped params (nullity 'PGjson)
-> Query schema params row
jsonPopulateRecordSet = unsafePopulateFunction "json_populate_record_set"
jsonbPopulateRecordSet
:: TypeExpression schema (nullity ('PGcomposite row))
-> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
-> Query schema params row
jsonbPopulateRecordSet = unsafePopulateFunction "jsonb_populate_record_set"
unsafeRecordFunction
:: (SListI record, json `In` PGJsonType)
=> ByteString
-> Expression schema '[] 'Ungrouped params (nullity json)
-> NP (Aliased (TypeExpression schema)) record
-> Query schema params record
unsafeRecordFunction fun expr types = UnsafeQuery $
"SELECT * FROM " <> fun <> "("
<> renderExpression expr <> ")"
<+> "AS" <+> "x" <> parenthesized (renderCommaSeparated renderTy types)
where
renderTy :: Aliased (TypeExpression schema) ty -> ByteString
renderTy (ty `As` alias) =
renderAlias alias <+> renderTypeExpression ty
jsonToRecord
:: SListI record
=> Expression schema '[] 'Ungrouped params (nullity 'PGjson)
-> NP (Aliased (TypeExpression schema)) record
-> Query schema params record
jsonToRecord = unsafeRecordFunction "json_to_record"
jsonbToRecord
:: SListI record
=> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
-> NP (Aliased (TypeExpression schema)) record
-> Query schema params record
jsonbToRecord = unsafeRecordFunction "jsonb_to_record"
jsonToRecordSet
:: SListI record
=> Expression schema '[] 'Ungrouped params (nullity 'PGjson)
-> NP (Aliased (TypeExpression schema)) record
-> Query schema params record
jsonToRecordSet = unsafeRecordFunction "json_to_record_set"
jsonbToRecordSet
:: SListI record
=> Expression schema '[] 'Ungrouped params (nullity 'PGjsonb)
-> NP (Aliased (TypeExpression schema)) record
-> Query schema params record
jsonbToRecordSet = unsafeRecordFunction "jsonb_to_record_set"
newtype FromClause schema params from
= UnsafeFromClause { renderFromClause :: ByteString }
deriving (GHC.Generic,Show,Eq,Ord,NFData)
table
:: Has tab schema ('Table table)
=> Aliased Alias (alias ::: tab)
-> FromClause schema params '[alias ::: TableToRow table]
table (tab `As` alias) = UnsafeFromClause $
renderAlias tab <+> "AS" <+> renderAlias alias
subquery
:: Aliased (Query schema params) rel
-> FromClause schema params '[rel]
subquery = UnsafeFromClause . renderAliasedAs (parenthesized . renderQuery)
view
:: Has view schema ('View row)
=> Aliased Alias (alias ::: view)
-> FromClause schema params '[alias ::: row]
view (vw `As` alias) = UnsafeFromClause $
renderAlias vw <+> "AS" <+> renderAlias alias
crossJoin
:: FromClause schema params right
-> FromClause schema params left
-> FromClause schema params (Join left right)
crossJoin right left = UnsafeFromClause $
renderFromClause left <+> "CROSS JOIN" <+> renderFromClause right
innerJoin
:: FromClause schema params right
-> Condition schema (Join left right) 'Ungrouped params
-> FromClause schema params left
-> FromClause schema params (Join left right)
innerJoin right on left = UnsafeFromClause $
renderFromClause left <+> "INNER JOIN" <+> renderFromClause right
<+> "ON" <+> renderExpression on
leftOuterJoin
:: FromClause schema params right
-> Condition schema (Join left right) 'Ungrouped params
-> FromClause schema params left
-> FromClause schema params (Join left (NullifyFrom right))
leftOuterJoin right on left = UnsafeFromClause $
renderFromClause left <+> "LEFT OUTER JOIN" <+> renderFromClause right
<+> "ON" <+> renderExpression on
rightOuterJoin
:: FromClause schema params right
-> Condition schema (Join left right) 'Ungrouped params
-> FromClause schema params left
-> FromClause schema params (Join (NullifyFrom left) right)
rightOuterJoin right on left = UnsafeFromClause $
renderFromClause left <+> "RIGHT OUTER JOIN" <+> renderFromClause right
<+> "ON" <+> renderExpression on
fullOuterJoin
:: FromClause schema params right
-> Condition schema (Join left right) 'Ungrouped params
-> FromClause schema params left
-> FromClause schema params
(Join (NullifyFrom left) (NullifyFrom right))
fullOuterJoin right on left = UnsafeFromClause $
renderFromClause left <+> "FULL OUTER JOIN" <+> renderFromClause right
<+> "ON" <+> renderExpression on
data By
(from :: FromType)
(by :: (Symbol,Symbol)) where
By1
:: (HasUnique table from columns, Has column columns ty)
=> Alias column
-> By from '(table, column)
By2
:: (Has table from columns, Has column columns ty)
=> Alias table
-> Alias column
-> By from '(table, column)
deriving instance Show (By from by)
deriving instance Eq (By from by)
deriving instance Ord (By from by)
instance (HasUnique rel rels cols, Has col cols ty, by ~ '(rel, col))
=> IsLabel col (By rels by) where fromLabel = By1 fromLabel
instance (HasUnique rel rels cols, Has col cols ty, bys ~ '[ '(rel, col)])
=> IsLabel col (NP (By rels) bys) where fromLabel = By1 fromLabel :* Nil
instance (Has rel rels cols, Has col cols ty, by ~ '(rel, col))
=> IsQualified rel col (By rels by) where (!) = By2
instance (Has rel rels cols, Has col cols ty, bys ~ '[ '(rel, col)])
=> IsQualified rel col (NP (By rels) bys) where
rel ! col = By2 rel col :* Nil
renderBy :: By from by -> ByteString
renderBy = \case
By1 column -> renderAlias column
By2 rel column -> renderAlias rel <> "." <> renderAlias column
data GroupByClause from grouping where
NoGroups :: GroupByClause from 'Ungrouped
Group
:: SListI bys
=> NP (By from) bys
-> GroupByClause from ('Grouped bys)
renderGroupByClause :: GroupByClause from grouping -> ByteString
renderGroupByClause = \case
NoGroups -> ""
Group Nil -> ""
Group bys -> " GROUP BY" <+> renderCommaSeparated renderBy bys
data HavingClause schema from grouping params where
NoHaving :: HavingClause schema from 'Ungrouped params
Having
:: [Condition schema from ('Grouped bys) params]
-> HavingClause schema from ('Grouped bys) params
deriving instance Show (HavingClause schema from grouping params)
deriving instance Eq (HavingClause schema from grouping params)
deriving instance Ord (HavingClause schema from grouping params)
renderHavingClause :: HavingClause schema from grouping params -> ByteString
renderHavingClause = \case
NoHaving -> ""
Having [] -> ""
Having conditions ->
" HAVING" <+> commaSeparated (renderExpression <$> conditions)
data SortExpression schema from grouping params where
Asc
:: Expression schema from grouping params ('NotNull ty)
-> SortExpression schema from grouping params
Desc
:: Expression schema from grouping params ('NotNull ty)
-> SortExpression schema from grouping params
AscNullsFirst
:: Expression schema from grouping params ('Null ty)
-> SortExpression schema from grouping params
AscNullsLast
:: Expression schema from grouping params ('Null ty)
-> SortExpression schema from grouping params
DescNullsFirst
:: Expression schema from grouping params ('Null ty)
-> SortExpression schema from grouping params
DescNullsLast
:: Expression schema from grouping params ('Null ty)
-> SortExpression schema from grouping params
deriving instance Show (SortExpression schema from grouping params)
renderSortExpression :: SortExpression schema from grouping params -> ByteString
renderSortExpression = \case
Asc expression -> renderExpression expression <+> "ASC"
Desc expression -> renderExpression expression <+> "DESC"
AscNullsFirst expression -> renderExpression expression
<+> "ASC NULLS FIRST"
DescNullsFirst expression -> renderExpression expression
<+> "DESC NULLS FIRST"
AscNullsLast expression -> renderExpression expression <+> "ASC NULLS LAST"
DescNullsLast expression -> renderExpression expression <+> "DESC NULLS LAST"
unsafeSubqueryExpression
:: ByteString
-> Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
unsafeSubqueryExpression op x q = UnsafeExpression $
renderExpression x <+> op <+> parenthesized (renderQuery q)
unsafeRowSubqueryExpression
:: SListI row
=> ByteString
-> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
unsafeRowSubqueryExpression op xs q = UnsafeExpression $
renderExpression (row xs) <+> op <+> parenthesized (renderQuery q)
in_
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
in_ = unsafeSubqueryExpression "IN"
rowIn
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowIn = unsafeRowSubqueryExpression "IN"
eqAll
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
eqAll = unsafeSubqueryExpression "= ALL"
rowEqAll
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowEqAll = unsafeRowSubqueryExpression "= ALL"
eqAny
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
eqAny = unsafeSubqueryExpression "= ANY"
rowEqAny
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowEqAny = unsafeRowSubqueryExpression "= ANY"
neqAll
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
neqAll = unsafeSubqueryExpression "<> ALL"
rowNeqAll
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowNeqAll = unsafeRowSubqueryExpression "<> ALL"
neqAny
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
neqAny = unsafeSubqueryExpression "<> ANY"
rowNeqAny
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowNeqAny = unsafeRowSubqueryExpression "<> ANY"
allLt
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
allLt = unsafeSubqueryExpression "ALL <"
rowLtAll
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowLtAll = unsafeRowSubqueryExpression "ALL <"
ltAny
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
ltAny = unsafeSubqueryExpression "ANY <"
rowLtAny
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowLtAny = unsafeRowSubqueryExpression "ANY <"
lteAll
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
lteAll = unsafeSubqueryExpression "<= ALL"
rowLteAll
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowLteAll = unsafeRowSubqueryExpression "<= ALL"
lteAny
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
lteAny = unsafeSubqueryExpression "<= ANY"
rowLteAny
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowLteAny = unsafeRowSubqueryExpression "<= ANY"
gtAll
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
gtAll = unsafeSubqueryExpression "> ALL"
rowGtAll
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowGtAll = unsafeRowSubqueryExpression "> ALL"
gtAny
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
gtAny = unsafeSubqueryExpression "> ANY"
rowGtAny
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowGtAny = unsafeRowSubqueryExpression "> ANY"
gteAll
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
gteAll = unsafeSubqueryExpression ">= ALL"
rowGteAll
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowGteAll = unsafeRowSubqueryExpression ">= ALL"
gteAny
:: Expression schema from grp params ty
-> Query schema params '[alias ::: ty]
-> Expression schema from grp params (nullity 'PGbool)
gteAny = unsafeSubqueryExpression ">= ANY"
rowGteAny
:: SListI row
=> NP (Aliased (Expression schema from grp params)) row
-> Query schema params row
-> Expression schema from grp params (nullity 'PGbool)
rowGteAny = unsafeRowSubqueryExpression ">= ANY"
data CommonTableExpression statement
(params :: [NullityType])
(schema0 :: SchemaType)
(schema1 :: SchemaType) where
CommonTableExpression
:: Aliased (statement schema params) (alias ::: cte)
-> CommonTableExpression
statement params schema (alias ::: 'View cte ': schema)
instance (KnownSymbol alias, schema1 ~ (alias ::: 'View cte ': schema))
=> Aliasable alias
(statement schema params cte)
(CommonTableExpression statement params schema schema1) where
statement `as` alias = CommonTableExpression (statement `as` alias)
instance (KnownSymbol alias, schema1 ~ (alias ::: 'View cte ': schema))
=> Aliasable alias (statement schema params cte)
(AlignedList (CommonTableExpression statement params) schema schema1) where
statement `as` alias = single (statement `as` alias)
renderCommonTableExpression
:: (forall sch ps row. statement ps sch row -> ByteString)
-> CommonTableExpression statement params schema0 schema1 -> ByteString
renderCommonTableExpression renderStatement
(CommonTableExpression (statement `As` alias)) =
renderAlias alias <+> "AS" <+> parenthesized (renderStatement statement)
renderCommonTableExpressions
:: (forall sch ps row. statement ps sch row -> ByteString)
-> CommonTableExpression statement params schema0 schema1
-> AlignedList (CommonTableExpression statement params) schema1 schema2
-> ByteString
renderCommonTableExpressions renderStatement cte ctes =
renderCommonTableExpression renderStatement cte <> case ctes of
Done -> ""
cte' :>> ctes' -> "," <+>
renderCommonTableExpressions renderStatement cte' ctes'
class With statement where
with
:: AlignedList (CommonTableExpression statement params) schema0 schema1
-> statement schema1 params row
-> statement schema0 params row
instance With Query where
with Done query = query
with (cte :>> ctes) query = UnsafeQuery $
"WITH" <+> renderCommonTableExpressions renderQuery cte ctes
<+> renderQuery query