@@ -1,1212 +0,0 @@
1−{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
2−{-# LANGUAGE
3− DataKinds
4− , FlexibleContexts
5− , FlexibleInstances
6− , FunctionalDependencies
7− , GADTs
8− , LambdaCase
9− , MagicHash
10− , OverloadedStrings
11− , PolyKinds
12− , RankNTypes
13− , ScopedTypeVariables
14− , TypeApplications
15− , TypeFamilies
16− , TypeOperators
17− , UndecidableInstances
18−#-}
19−
20−module Squeel.PostgreSQL.Statement where
21−
22−import Control.Category
23−import Data.ByteString (ByteString)
24−import Data.Foldable
25−import Data.Maybe
26−import Data.Monoid
27−import Data.Ratio
28−import Data.String
29−import Data.Word
30−import Generics.SOP
31−import GHC.Exts
32−import GHC.OverloadedLabels
33−import GHC.TypeLits
34−import Prelude hiding (RealFrac(..), id, (.))
35−
36−import qualified Data.ByteString as ByteString
37−
38−import Squeel.PostgreSQL.Schema
39−
40−{-----------------------------------------
41−column expressions
42−-----------------------------------------}
43−
44−newtype Expression
45− (params :: [ColumnType])
46− (tables :: [(Symbol,[(Symbol,ColumnType)])])
47− (grouping :: Grouping)
48− (ty :: ColumnType)
49− = UnsafeExpression { renderExpression :: ByteString }
50− deriving (Show,Eq)
51−
52−class (PGTyped (BaseType ty), KnownNat n)
53− => HasParameter (n :: Nat) params ty | n params -> ty where
54− param :: proxy n -> Expression params tables grouping ty
55− param _ = UnsafeExpression $ parenthesized $
56− "$" <> paramNum <+> "::" <+> renderTypeExpression (pgtype @(BaseType ty))
57− where
58− paramNum = fromString $ show $ natVal (Proxy @n)
59−instance {-# OVERLAPPING #-} PGTyped (BaseType ty1)
60− => HasParameter 1 (ty1:tys) ty1
61−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
62− => HasParameter n (ty' : params) ty
63−
64−class KnownSymbol column => HasColumn column columns ty
65− | column columns -> ty where
66− getColumn
67− :: Proxy# column
68− -> Expression params '[table ::: columns] 'Ungrouped ty
69− getColumn column = UnsafeExpression $ renderSymbol column
70−instance {-# OVERLAPPING #-} KnownSymbol column
71− => HasColumn column ((column ::: optionality ty) ': tys) ('Required ty)
72−instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
73− => HasColumn column (ty' ': table) ty
74−
75−instance (HasColumn column columns ty, tables ~ '[table ::: columns])
76− => IsLabel column (Expression params tables 'Ungrouped ty) where
77− fromLabel = getColumn
78−
79−instance (HasTable table tables columns, HasColumn column columns ty)
80− => IsTableColumn table column (Expression params tables 'Ungrouped ty) where
81− table &. column = UnsafeExpression $
82− renderAlias table <> "." <> renderAlias column
83−
84−def :: Expression params '[] grouping ('Optional (nullity ty))
85−def = UnsafeExpression "DEFAULT"
86−
87−unDef
88− :: Expression params '[] grouping ('Required (nullity ty))
89− -> Expression params '[] grouping ('Optional (nullity ty))
90−unDef = UnsafeExpression . renderExpression
91−
92−null :: Expression params tables grouping (optionality ('Null ty))
93−null = UnsafeExpression "NULL"
94−
95−unNull
96− :: Expression params tables grouping (optionality ('NotNull ty))
97− -> Expression params tables grouping (optionality ('Null ty))
98−unNull = UnsafeExpression . renderExpression
99−
100−coalesce
101− :: [Expression params tables grouping ('Required ('Null x))]
102− -> Expression params tables grouping ('Required ('NotNull x))
103− -> Expression params tables grouping ('Required ('NotNull x))
104−coalesce nulls isn'tNull = UnsafeExpression $
105− "COALESCE" <> parenthesized (commaSeparated
106− ((renderExpression <$> nulls) <> [renderExpression isn'tNull]))
107−
108−unsafeBinaryOp
109− :: ByteString
110− -> Expression params tables grouping ty0
111− -> Expression params tables grouping ty1
112− -> Expression params tables grouping ty2
113−unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
114− renderExpression x <+> op <+> renderExpression y
115−
116−unsafeUnaryOp
117− :: ByteString
118− -> Expression params tables grouping ty0
119− -> Expression params tables grouping ty1
120−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
121− op <+> renderExpression x
122−
123−unsafeFunction
124− :: ByteString
125− -> Expression params tables grouping xty
126− -> Expression params tables grouping yty
127−unsafeFunction fun x = UnsafeExpression $
128− fun <> parenthesized (renderExpression x)
129−
130−instance PGNum ty
131− => Num (Expression params tables grouping ('Required (nullity ty))) where
132− (+) = unsafeBinaryOp "+"
133− (-) = unsafeBinaryOp "-"
134− (*) = unsafeBinaryOp "*"
135− abs = unsafeFunction "abs"
136− signum = unsafeFunction "sign"
137− fromInteger
138− = UnsafeExpression
139− . (<> if decimal (Proxy :: Proxy ty) then "." else "")
140− . fromString
141− . show
142−
143−instance PGFractional ty => Fractional
144− (Expression params tables grouping ('Required (nullity ty))) where
145− (/) = unsafeBinaryOp "/"
146− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
147−
148−instance (PGFloating ty, PGCast 'PGNumeric ty, PGTyped ty) => Floating
149− (Expression params tables grouping ('Required (nullity ty))) where
150− pi = UnsafeExpression "pi()"
151− exp = unsafeFunction "exp"
152− log = unsafeFunction "ln"
153− sqrt = unsafeFunction "sqrt"
154− b ** x = UnsafeExpression $
155− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
156− logBase b y = cast pgtype $ logBaseNumeric b y
157− where
158− logBaseNumeric
159− :: Expression params tables grouping ('Required (nullity ty))
160− -> Expression params tables grouping ('Required (nullity ty))
161− -> Expression params tables grouping ('Required (nullity 'PGNumeric))
162− logBaseNumeric b' y' = UnsafeExpression $ mconcat
163− [ "log("
164− , renderExpression b' <> "::numeric"
165− , ", "
166− , renderExpression y' <> "::numeric"
167− , ")"
168− ]
169− sin = unsafeFunction "sin"
170− cos = unsafeFunction "cos"
171− tan = unsafeFunction "tan"
172− asin = unsafeFunction "asin"
173− acos = unsafeFunction "acos"
174− atan = unsafeFunction "atan"
175− sinh x = (exp x - exp (-x)) / 2
176− cosh x = (exp x + exp (-x)) / 2
177− tanh x = sinh x / cosh x
178− asinh x = log (x + sqrt (x*x + 1))
179− acosh x = log (x + sqrt (x*x - 1))
180− atanh x = log ((1 + x) / (1 - x)) / 2
181−
182−atan2
183− :: PGFloating float
184− => Expression params tables grouping ('Required (nullity float))
185− -> Expression params tables grouping ('Required (nullity float))
186− -> Expression params tables grouping ('Required (nullity float))
187−atan2 y x = UnsafeExpression $
188− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
189−
190−class PGCast (ty0 :: PGType) (ty1 :: PGType) where
191− cast
192− :: TypeExpression ('Required ('Null ty1))
193− -> Expression params tables grouping ('Required (nullity ty0))
194− -> Expression params tables grouping ('Required (nullity ty1))
195− cast ty x = UnsafeExpression $
196− "(" <> renderExpression x <> "::" <> renderTypeExpression ty <> ")"
197−instance PGCast 'PGInt2 'PGInt2
198−instance PGCast 'PGInt2 'PGInt4
199−instance PGCast 'PGInt2 'PGInt8
200−instance PGCast 'PGInt4 'PGInt2
201−instance PGCast 'PGInt4 'PGInt4
202−instance PGCast 'PGInt4 'PGInt8
203−instance PGCast 'PGInt8 'PGInt2
204−instance PGCast 'PGInt8 'PGInt4
205−instance PGCast 'PGInt8 'PGInt8
206−instance PGCast 'PGInt8 'PGFloat4
207−instance PGCast 'PGInt8 'PGFloat8
208−instance PGCast 'PGInt8 'PGNumeric
209−
210−div
211− :: (PGNum ty, PGTyped ty, PGCast 'PGInt8 ty, PGCast ty 'PGInt8)
212− => Expression params tables grouping ('Required (nullity ty))
213− -> Expression params tables grouping ('Required (nullity ty))
214− -> Expression params tables grouping ('Required (nullity ty))
215−div = unsafeBinaryOp "/"
216−
217−mod
218− :: (PGNum ty, PGTyped ty, PGCast 'PGInt8 ty, PGCast ty 'PGInt8)
219− => Expression params tables grouping ('Required (nullity ty))
220− -> Expression params tables grouping ('Required (nullity ty))
221− -> Expression params tables grouping ('Required (nullity ty))
222−mod = unsafeBinaryOp "%"
223−
224−truncate
225− :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
226− => Expression params tables grouping ('Required (nullity frac))
227− -> Expression params tables grouping ('Required (nullity int))
228−truncate = cast pgtype . truncate'
229− where
230− truncate'
231− :: Expression params tables grouping ('Required (nullity frac))
232− -> Expression params tables grouping ('Required (nullity 'PGInt4))
233− truncate' = unsafeFunction "trunc"
234−
235−round
236− :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
237− => Expression params tables grouping ('Required (nullity frac))
238− -> Expression params tables grouping ('Required (nullity int))
239−round = cast pgtype . round'
240− where
241− round'
242− :: Expression params tables grouping ('Required (nullity frac))
243− -> Expression params tables grouping ('Required (nullity 'PGInt4))
244− round' = unsafeFunction "round"
245−
246−ceiling
247− :: (PGFractional frac, PGCast 'PGInt4 int, PGTyped int)
248− => Expression params tables grouping ('Required (nullity frac))
249− -> Expression params tables grouping ('Required (nullity int))
250−ceiling = cast pgtype . ceiling'
251− where
252− ceiling'
253− :: Expression params tables grouping ('Required (nullity frac))
254− -> Expression params tables grouping ('Required (nullity 'PGInt4))
255− ceiling' = unsafeFunction "ceiling"
256−
257−instance IsString
258− (Expression params tables grouping ('Required (nullity 'PGText))) where
259− fromString str = UnsafeExpression $
260− "E\'" <> fromString (escape =<< str) <> "\'"
261− where
262− escape = \case
263− '\NUL' -> "\\0"
264− '\'' -> "''"
265− '"' -> "\\\""
266− '\b' -> "\\b"
267− '\n' -> "\\n"
268− '\r' -> "\\r"
269− '\t' -> "\\t"
270− '\\' -> "\\\\"
271− c -> [c]
272−
273−type Condition params tables grouping =
274− Expression params tables grouping ('Required ('NotNull 'PGBool))
275−
276−true :: Condition params tables grouping
277−true = UnsafeExpression "TRUE"
278−
279−false :: Condition params tables grouping
280−false = UnsafeExpression "FALSE"
281−
282−not_
283− :: Condition params tables grouping
284− -> Condition params tables grouping
285−not_ = unsafeUnaryOp "NOT"
286−
287−(&&*)
288− :: Condition params tables grouping
289− -> Condition params tables grouping
290− -> Condition params tables grouping
291−(&&*) = unsafeBinaryOp "AND"
292−
293−(||*)
294− :: Condition params tables grouping
295− -> Condition params tables grouping
296− -> Condition params tables grouping
297−(||*) = unsafeBinaryOp "OR"
298−
299−caseWhenThenElse
300− :: [(Condition params tables grouping, Expression params tables grouping ty)]
301− -> Expression params tables grouping ty
302− -> Expression params tables grouping ty
303−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
304− [ "CASE"
305− , mconcat
306− [ mconcat
307− [ " WHEN ", renderExpression when_
308− , " THEN ", renderExpression then_
309− ]
310− | (when_,then_) <- whenThens
311− ]
312− , " ELSE ", renderExpression else_
313− , " END"
314− ]
315−
316−ifThenElse
317− :: Condition params tables grouping
318− -> Expression params tables grouping ty
319− -> Expression params tables grouping ty
320− -> Expression params tables grouping ty
321−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
322−
323−(==*)
324− :: Expression params tables grouping ('Required (nullity ty))
325− -> Expression params tables grouping ('Required (nullity ty))
326− -> Expression params tables grouping ('Required (nullity 'PGBool))
327−(==*) = unsafeBinaryOp "="
328−
329−(/=*)
330− :: Expression params tables grouping ('Required (nullity ty))
331− -> Expression params tables grouping ('Required (nullity ty))
332− -> Expression params tables grouping ('Required (nullity 'PGBool))
333−(/=*) = unsafeBinaryOp "<>"
334−
335−(>=*)
336− :: Expression params tables grouping ('Required (nullity ty))
337− -> Expression params tables grouping ('Required (nullity ty))
338− -> Expression params tables grouping ('Required (nullity 'PGBool))
339−(>=*) = unsafeBinaryOp ">="
340−
341−(<*)
342− :: Expression params tables grouping ('Required (nullity ty))
343− -> Expression params tables grouping ('Required (nullity ty))
344− -> Expression params tables grouping ('Required (nullity 'PGBool))
345−(<*) = unsafeBinaryOp "<"
346−
347−(<=*)
348− :: Expression params tables grouping ('Required (nullity ty))
349− -> Expression params tables grouping ('Required (nullity ty))
350− -> Expression params tables grouping ('Required (nullity 'PGBool))
351−(<=*) = unsafeBinaryOp "<="
352−
353−(>*)
354− :: Expression params tables grouping ('Required (nullity ty))
355− -> Expression params tables grouping ('Required (nullity ty))
356− -> Expression params tables grouping ('Required (nullity 'PGBool))
357−(>*) = unsafeBinaryOp ">"
358−
359−data SortExpression params tables grouping where
360− Asc
361− :: Expression params tables grouping ty
362− -> SortExpression params tables grouping
363− Desc
364− :: Expression params tables grouping ty
365− -> SortExpression params tables grouping
366−
367−renderSortExpression :: SortExpression params tables grouping -> ByteString
368−renderSortExpression = \case
369− Asc expression -> renderExpression expression <+> "ASC"
370− Desc expression -> renderExpression expression <+> "DESC"
371−
372−{-----------------------------------------
373−aggregation
374−-----------------------------------------}
375−
376−data By
377− (tables :: [(Symbol,[(Symbol,ColumnType)])])
378− (tabcol :: (Symbol,Symbol)) where
379− By
380− :: (tables ~ '[table ::: columns], HasColumn column columns ty)
381− => Alias column
382− -> By tables '(table, column)
383− By2
384− :: (HasTable table tables columns, HasColumn column columns ty)
385− => (Alias table, Alias column)
386− -> By tables '(table, column)
387−
388−renderBy :: By tables tabcolty -> ByteString
389−renderBy = \case
390− By column -> renderAlias column
391− By2 (table, column) -> renderAlias table <> "." <> renderAlias column
392−
393−data GroupByClause tables grouping where
394− NoGroups :: GroupByClause tables 'Ungrouped
395− Group
396− :: SListI bys
397− => NP (By tables) bys
398− -> GroupByClause tables ('Grouped bys)
399−
400−renderGroupByClause :: GroupByClause tables grouping -> ByteString
401−renderGroupByClause = \case
402− NoGroups -> ""
403− Group Nil -> ""
404− Group bys -> " GROUP BY" <+> renderCommaSeparated renderBy bys
405−
406−data HavingClause params tables grouping where
407− NoHaving :: HavingClause params tables 'Ungrouped
408− Having
409− :: [Condition params tables ('Grouped bys)]
410− -> HavingClause params tables ('Grouped bys)
411−
412−renderHavingClause :: HavingClause params tables grouping -> ByteString
413−renderHavingClause = \case
414− NoHaving -> ""
415− Having [] -> ""
416− Having conditions ->
417− " HAVING" <+> commaSeparated (renderExpression <$> conditions)
418−
419−class (KnownSymbol table, KnownSymbol column)
420− => GroupedBy table column bys where
421− getGroup1
422− :: (tables ~ '[table ::: columns], HasColumn column columns ty)
423− => Proxy# column
424− -> Expression params tables ('Grouped bys) ty
425− getGroup1 column = UnsafeExpression $ fromString (symbolVal' column)
426− getGroup2
427− :: (HasTable table tables columns, HasColumn column columns ty)
428− => Alias table
429− -> Alias column
430− -> Expression params tables ('Grouped bys) ty
431− getGroup2 table column = UnsafeExpression $
432− renderAlias table <> "." <> renderAlias column
433−instance {-# OVERLAPPING #-} (KnownSymbol table, KnownSymbol column)
434− => GroupedBy table column ('(table,column) ': bys)
435−instance {-# OVERLAPPABLE #-}
436− ( KnownSymbol table
437− , KnownSymbol column
438− , GroupedBy table column bys
439− ) => GroupedBy table column (tabcol ': bys)
440−
441−instance
442− ( tables ~ '[table ::: columns]
443− , HasColumn column columns ty
444− , GroupedBy table column bys
445− ) => IsLabel column
446− (Expression params tables ('Grouped bys) ty) where fromLabel = getGroup1
447−
448−instance
449− ( HasTable table tables columns
450− , HasColumn column columns ty
451− , GroupedBy table column bys
452− ) => IsTableColumn table column
453− (Expression params tables ('Grouped bys) ty) where (&.) = getGroup2
454−
455−unsafeAggregate
456− :: ByteString
457− -> Expression params tables 'Ungrouped xty
458− -> Expression params tables ('Grouped bys) yty
459−unsafeAggregate fun x = UnsafeExpression $ mconcat
460− [fun, "(", renderExpression x, ")"]
461−
462−sum_
463− :: PGNum ty
464− => Expression params tables 'Ungrouped ('Required (nullity ty))
465− -> Expression params tables ('Grouped bys) ('Required (nullity ty))
466−sum_ = unsafeAggregate "sum"
467−
468−{-----------------------------------------
469−tables
470−-----------------------------------------}
471−
472−newtype Table
473− (schema :: [(Symbol,[(Symbol,ColumnType)])])
474− (columns :: [(Symbol,ColumnType)])
475− = UnsafeTable { renderTable :: ByteString }
476− deriving (Show,Eq)
477−
478−class KnownSymbol table => HasTable table tables columns
479− | table tables -> columns where
480− getTable :: Proxy# table -> Table tables columns
481− getTable table = UnsafeTable $ fromString $ symbolVal' table
482−instance {-# OVERLAPPING #-} KnownSymbol table
483− => HasTable table ((table ::: columns) ': tables) columns
484−instance {-# OVERLAPPABLE #-}
485− (KnownSymbol table, HasTable table schema columns)
486− => HasTable table (table' ': schema) columns
487−
488−instance HasTable table schema columns
489− => IsLabel table (Table schema columns) where
490− fromLabel = getTable
491−
492−data TableReference params schema tables where
493− Table
494− :: Aliased (Table schema) table
495− -> TableReference params schema '[table]
496− Subquery
497− :: Aliased (Query schema params) table
498− -> TableReference params schema '[table]
499− CrossJoin
500− :: TableReference params schema right
501− -> TableReference params schema left
502− -> TableReference params schema (Join left right)
503− InnerJoin
504− :: TableReference params schema right
505− -> Condition params (Join left right) 'Ungrouped
506− -> TableReference params schema left
507− -> TableReference params schema (Join left right)
508− LeftOuterJoin
509− :: TableReference params schema right
510− -> Condition params (Join left right) 'Ungrouped
511− -> TableReference params schema left
512− -> TableReference params schema (Join left (NullifyTables right))
513− RightOuterJoin
514− :: TableReference params schema right
515− -> Condition params (Join left right) 'Ungrouped
516− -> TableReference params schema left
517− -> TableReference params schema (Join (NullifyTables left) right)
518− FullOuterJoin
519− :: TableReference params schema right
520− -> Condition params (Join left right) 'Ungrouped
521− -> TableReference params schema left
522− -> TableReference params schema
523− (Join (NullifyTables left) (NullifyTables right))
524−
525−renderTableReference :: TableReference params schema tables -> ByteString
526−renderTableReference = \case
527− Table table -> renderAliased renderTable table
528− Subquery selection -> renderAliased renderQuery selection
529− CrossJoin right left ->
530− renderTableReference left <+> "CROSS JOIN" <+> renderTableReference right
531− InnerJoin right on left -> renderJoin "INNER JOIN" right on left
532− LeftOuterJoin right on left -> renderJoin "LEFT OUTER JOIN" right on left
533− RightOuterJoin right on left -> renderJoin "RIGHT OUTER JOIN" right on left
534− FullOuterJoin right on left -> renderJoin "FULL OUTER JOIN" right on left
535− where
536− renderJoin op right on left =
537− renderTableReference left <+> op <+> renderTableReference right
538− <+> "ON" <+> renderExpression on
539−
540−data TableExpression
541− (params :: [ColumnType])
542− (schema :: [(Symbol,[(Symbol,ColumnType)])])
543− (tables :: [(Symbol,[(Symbol,ColumnType)])])
544− (grouping :: Grouping)
545− = TableExpression
546− { fromClause :: TableReference params schema tables
547− , whereClause :: [Condition params tables 'Ungrouped]
548− , groupByClause :: GroupByClause tables grouping
549− , havingClause :: HavingClause params tables grouping
550− , orderByClause :: [SortExpression params tables grouping]
551− , limitClause :: [Word64]
552− , offsetClause :: [Word64]
553− }
554−
555−renderTableExpression
556− :: TableExpression params schema tables grouping
557− -> ByteString
558−renderTableExpression
559− (TableExpression tables whs' grps' hvs' srts' lims' offs') = mconcat
560− [ "FROM ", renderTableReference tables
561− , renderWheres whs'
562− , renderGroupByClause grps'
563− , renderHavingClause hvs'
564− , renderSorts srts'
565− , renderLimits lims'
566− , renderOffsets offs'
567− ]
568− where
569− renderWheres = \case
570− [] -> ""
571− wh:[] -> " WHERE" <+> renderExpression wh
572− wh:whs -> " WHERE" <+> renderExpression (foldr (&&*) wh whs)
573− renderSorts = \case
574− [] -> ""
575− srts -> " SORT BY"
576− <+> commaSeparated (renderSortExpression <$> srts)
577− renderLimits = \case
578− [] -> ""
579− lims -> " LIMIT" <+> fromString (show (minimum lims))
580− renderOffsets = \case
581− [] -> ""
582− offs -> " OFFSET" <+> fromString (show (sum offs))
583−
584−from
585− :: TableReference params schema tables
586− -> TableExpression params schema tables 'Ungrouped
587−from tables = TableExpression tables [] NoGroups NoHaving [] [] []
588−
589−where_
590− :: Condition params tables 'Ungrouped
591− -> TableExpression params schema tables grouping
592− -> TableExpression params schema tables grouping
593−where_ wh tables = tables {whereClause = wh : whereClause tables}
594−
595−group
596− :: SListI bys
597− => NP (By tables) bys
598− -> TableExpression params schema tables 'Ungrouped
599− -> TableExpression params schema tables ('Grouped bys)
600−group bys tables = TableExpression
601− { fromClause = fromClause tables
602− , whereClause = whereClause tables
603− , groupByClause = Group bys
604− , havingClause = Having []
605− , orderByClause = []
606− , limitClause = limitClause tables
607− , offsetClause = offsetClause tables
608− }
609−
610−having
611− :: Condition params tables ('Grouped bys)
612− -> TableExpression params schema tables ('Grouped bys)
613− -> TableExpression params schema tables ('Grouped bys)
614−having hv tables = tables
615− { havingClause = case havingClause tables of Having hvs -> Having (hv:hvs) }
616−
617−orderBy
618− :: [SortExpression params tables grouping]
619− -> TableExpression params schema tables grouping
620− -> TableExpression params schema tables grouping
621−orderBy srts tables = tables {orderByClause = orderByClause tables ++ srts}
622−
623−limit
624− :: Word64
625− -> TableExpression params schema tables grouping
626− -> TableExpression params schema tables grouping
627−limit lim tables = tables {limitClause = lim : limitClause tables}
628−
629−offset
630− :: Word64
631− -> TableExpression params schema tables grouping
632− -> TableExpression params schema tables grouping
633−offset off tables = tables {offsetClause = off : offsetClause tables}
634−
635−{-----------------------------------------
636−type expressions
637−-----------------------------------------}
638−
639−newtype TypeExpression (ty :: ColumnType)
640− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
641− deriving (Show,Eq)
642−
643−bool :: TypeExpression ('Required ('Null 'PGBool))
644−bool = UnsafeTypeExpression "bool"
645−int2 :: TypeExpression ('Required ('Null 'PGInt2))
646−int2 = UnsafeTypeExpression "int2"
647−smallint :: TypeExpression ('Required ('Null 'PGInt2))
648−smallint = UnsafeTypeExpression "smallint"
649−int4 :: TypeExpression ('Required ('Null 'PGInt4))
650−int4 = UnsafeTypeExpression "int4"
651−int :: TypeExpression ('Required ('Null 'PGInt4))
652−int = UnsafeTypeExpression "int"
653−integer :: TypeExpression ('Required ('Null 'PGInt4))
654−integer = UnsafeTypeExpression "integer"
655−int8 :: TypeExpression ('Required ('Null 'PGInt8))
656−int8 = UnsafeTypeExpression "int8"
657−bigint :: TypeExpression ('Required ('Null 'PGInt8))
658−bigint = UnsafeTypeExpression "bigint"
659−numeric :: TypeExpression ('Required ('Null 'PGNumeric))
660−numeric = UnsafeTypeExpression "numeric"
661−float4 :: TypeExpression ('Required ('Null 'PGFloat4))
662−float4 = UnsafeTypeExpression "float4"
663−real :: TypeExpression ('Required ('Null 'PGFloat4))
664−real = UnsafeTypeExpression "real"
665−float8 :: TypeExpression ('Required ('Null 'PGFloat8))
666−float8 = UnsafeTypeExpression "float8"
667−doublePrecision :: TypeExpression ('Required ('Null 'PGFloat8))
668−doublePrecision = UnsafeTypeExpression "double precision"
669−serial2 :: TypeExpression ('Optional ('NotNull 'PGInt2))
670−serial2 = UnsafeTypeExpression "serial2"
671−smallserial :: TypeExpression ('Optional ('NotNull 'PGInt2))
672−smallserial = UnsafeTypeExpression "smallserial"
673−serial4 :: TypeExpression ('Optional ('NotNull 'PGInt4))
674−serial4 = UnsafeTypeExpression "serial4"
675−serial :: TypeExpression ('Optional ('NotNull 'PGInt4))
676−serial = UnsafeTypeExpression "serial"
677−serial8 :: TypeExpression ('Optional ('NotNull 'PGInt8))
678−serial8 = UnsafeTypeExpression "serial8"
679−bigserial :: TypeExpression ('Optional ('NotNull 'PGInt8))
680−bigserial = UnsafeTypeExpression "bigserial"
681−money :: TypeExpression ('Required ('Null 'PGMoney))
682−money = UnsafeTypeExpression "money"
683−text :: TypeExpression ('Required ('Null 'PGText))
684−text = UnsafeTypeExpression "text"
685−char
686− :: KnownNat n
687− => proxy n
688− -> TypeExpression ('Required ('Null ('PGChar n)))
689−char (_ :: proxy n) = UnsafeTypeExpression $
690− "char(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
691−character
692− :: KnownNat n
693− => proxy n
694− -> TypeExpression ('Required ('Null ('PGChar n)))
695−character (_ :: proxy n) = UnsafeTypeExpression $
696− "character(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
697−varchar
698− :: KnownNat n
699− => proxy n
700− -> TypeExpression ('Required ('Null ('PGVarChar n)))
701−varchar (_ :: proxy n) = UnsafeTypeExpression $
702− "varchar(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
703−characterVarying
704− :: KnownNat n
705− => proxy n
706− -> TypeExpression ('Required ('Null ('PGVarChar n)))
707−characterVarying (_ :: proxy n) = UnsafeTypeExpression $
708− "character varying(" <> fromString (show (natVal' (proxy# :: Proxy# n))) <> ")"
709−bytea :: TypeExpression ('Required ('Null ('PGBytea)))
710−bytea = UnsafeTypeExpression "bytea"
711−timestamp :: TypeExpression ('Required ('Null ('PGTimestamp)))
712−timestamp = UnsafeTypeExpression "timestamp"
713−timestampWithTimeZone :: TypeExpression ('Required ('Null ('PGTimestampTZ)))
714−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
715−date :: TypeExpression ('Required ('Null ('PGDate)))
716−date = UnsafeTypeExpression "date"
717−time :: TypeExpression ('Required ('Null ('PGTime)))
718−time = UnsafeTypeExpression "time"
719−timeWithTimeZone :: TypeExpression ('Required ('Null ('PGTimeTZ)))
720−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
721−interval :: TypeExpression ('Required ('Null ('PGInterval)))
722−interval = UnsafeTypeExpression "interval"
723−uuid :: TypeExpression ('Required ('Null ('PGUuid)))
724−uuid = UnsafeTypeExpression "uuid"
725−json :: TypeExpression ('Required ('Null ('PGJson)))
726−json = UnsafeTypeExpression "json"
727−jsonb :: TypeExpression ('Required ('Null ('PGJsonb)))
728−jsonb = UnsafeTypeExpression "jsonb"
729−
730−notNull
731− :: TypeExpression (optionality ('Null ty))
732− -> TypeExpression (optionality ('NotNull ty))
733−notNull ty = UnsafeTypeExpression $ renderTypeExpression ty <+> "NOT NULL"
734−default_
735− :: Expression '[] '[] 'Ungrouped ('Required ty)
736− -> TypeExpression ('Required ty)
737− -> TypeExpression ('Optional ty)
738−default_ x ty = UnsafeTypeExpression $
739− renderTypeExpression ty <+> "DEFAULT" <+> renderExpression x
740−
741−class PGTyped (ty :: PGType) where
742− pgtype :: TypeExpression ('Required ('Null ty))
743−instance PGTyped 'PGBool where pgtype = bool
744−instance PGTyped 'PGInt2 where pgtype = int2
745−instance PGTyped 'PGInt4 where pgtype = int4
746−instance PGTyped 'PGInt8 where pgtype = int8
747−instance PGTyped 'PGNumeric where pgtype = numeric
748−instance PGTyped 'PGFloat4 where pgtype = float4
749−instance PGTyped 'PGFloat8 where pgtype = float8
750−instance PGTyped 'PGMoney where pgtype = money
751−instance PGTyped 'PGText where pgtype = text
752−instance KnownNat n => PGTyped ('PGChar n) where pgtype = char (Proxy @n)
753−instance KnownNat n => PGTyped ('PGVarChar n) where pgtype = varchar (Proxy @n)
754−instance PGTyped 'PGBytea where pgtype = bytea
755−instance PGTyped 'PGTimestamp where pgtype = timestamp
756−instance PGTyped 'PGTimestampTZ where pgtype = timestampWithTimeZone
757−instance PGTyped 'PGDate where pgtype = date
758−instance PGTyped 'PGTime where pgtype = time
759−instance PGTyped 'PGTimeTZ where pgtype = timeWithTimeZone
760−instance PGTyped 'PGInterval where pgtype = interval
761−instance PGTyped 'PGUuid where pgtype = uuid
762−instance PGTyped 'PGJson where pgtype = json
763−instance PGTyped 'PGJsonb where pgtype = jsonb
764−
765−{-----------------------------------------
766−statements
767−-----------------------------------------}
768−
769−newtype Definition
770− (schema0 :: [(Symbol,[(Symbol,ColumnType)])])
771− (schema1 :: [(Symbol,[(Symbol,ColumnType)])])
772− = UnsafeDefinition { renderDefinition :: ByteString }
773−
774−instance Category Definition where
775− id = UnsafeDefinition ";"
776− ddl1 . ddl0 = UnsafeDefinition $
777− renderDefinition ddl0 <+> renderDefinition ddl1
778−
779−newtype Manipulation
780− (schema :: [(Symbol,[(Symbol,ColumnType)])])
781− (params :: [ColumnType])
782− (columns :: [(Symbol,ColumnType)])
783− = UnsafeManipulation { renderManipulation :: ByteString }
784−
785−newtype Query
786− (schema :: [(Symbol,[(Symbol,ColumnType)])])
787− (params :: [ColumnType])
788− (columns :: [(Symbol,ColumnType)])
789− = UnsafeQuery { renderQuery :: ByteString }
790−
791−query
792− :: Query schema params columns
793− -> Manipulation schema params columns
794−query q = UnsafeManipulation $ renderQuery q <> ";"
795−
796−union, unionAll, intersect, intersectAll, except, exceptAll
797− :: Query schema params columns
798− -> Query schema params columns
799− -> Query schema params columns
800−q1 `union` q2 = UnsafeQuery $
801− parenthesized (renderQuery q1)
802− <+> "UNION"
803− <+> parenthesized (renderQuery q2)
804−q1 `unionAll` q2 = UnsafeQuery $
805− parenthesized (renderQuery q1)
806− <+> "UNION" <+> "ALL"
807− <+> parenthesized (renderQuery q2)
808−q1 `intersect` q2 = UnsafeQuery $
809− parenthesized (renderQuery q1)
810− <+> "INTERSECT"
811− <+> parenthesized (renderQuery q2)
812−q1 `intersectAll` q2 = UnsafeQuery $
813− parenthesized (renderQuery q1)
814− <+> "INTERSECT" <+> "ALL"
815− <+> parenthesized (renderQuery q2)
816−q1 `except` q2 = UnsafeQuery $
817− parenthesized (renderQuery q1)
818− <+> "EXCEPT"
819− <+> parenthesized (renderQuery q2)
820−q1 `exceptAll` q2 = UnsafeQuery $
821− parenthesized (renderQuery q1)
822− <+> "EXCEPT" <+> "ALL"
823− <+> parenthesized (renderQuery q2)
824−
825−{-----------------------------------------
826−SELECT statements
827−-----------------------------------------}
828−
829−select
830− :: SListI columns
831− => NP (Aliased (Expression params tables grouping)) columns
832− -> TableExpression params schema tables grouping
833− -> Query schema params columns
834−select list tabs = UnsafeQuery $
835− "SELECT"
836− <+> renderCommaSeparated (renderAliased renderExpression) list
837− <+> renderTableExpression tabs
838−
839−selectStar
840− :: (tables ~ '[table ::: columns])
841− => TableExpression params schema tables 'Ungrouped
842− -> Query schema params columns
843−selectStar tabs = UnsafeQuery $ "SELECT" <+> "*" <+> renderTableExpression tabs
844−
845−selectDotStar
846− :: HasTable table tables columns
847− => Alias table
848− -> TableExpression params schema tables 'Ungrouped
849− -> Query schema params columns
850−selectDotStar table tables = UnsafeQuery $
851− "SELECT" <+> renderAlias table <> ".*" <+> renderTableExpression tables
852−
853−selectRow
854− :: SListI columns
855− => NP (Aliased (Expression params '[] 'Ungrouped)) columns
856− -> Query schema params columns
857−selectRow row = UnsafeQuery $
858− "SELECT" <+> renderCommaSeparated (renderAliased renderExpression) row
859−
860−{-----------------------------------------
861−CREATE statements
862−-----------------------------------------}
863−
864−createTable
865− :: (KnownSymbol table, SListI columns)
866− => Alias table
867− -> NP (Aliased TypeExpression) columns
868− -> [TableConstraint schema columns]
869− -> Definition schema (Create table columns schema)
870−createTable table columns constraints = UnsafeDefinition $
871− "CREATE TABLE" <+> renderAlias table
872− <+> parenthesized
873− ( renderCommaSeparated renderColumnDef columns
874− <> renderConstraints constraints )
875− <> ";"
876− where
877− renderColumnDef :: Aliased TypeExpression x -> ByteString
878− renderColumnDef (ty `As` column) =
879− renderAlias column <+> renderTypeExpression ty
880− renderConstraints :: [TableConstraint schema columns] -> ByteString
881− renderConstraints = \case
882− [] -> ""
883− _ -> ", " <> commaSeparated (renderTableConstraint <$> constraints)
884−
885−data TableConstraint
886− (schema :: [(Symbol,[(Symbol,ColumnType)])])
887− (columns :: [(Symbol,ColumnType)])
888− = UnsafeTableConstraint { renderTableConstraint :: ByteString }
889−
890−check
891− :: Condition '[] '[table ::: columns] 'Ungrouped
892− -> TableConstraint schema columns
893−check condition = UnsafeTableConstraint $
894− "CHECK" <+> parenthesized (renderExpression condition)
895−
896−data Column
897− (columns :: [(Symbol,ColumnType)])
898− (columnty :: (Symbol,ColumnType))
899− where
900− Column
901− :: HasColumn column columns ty
902− => Alias column
903− -> Column columns (column ::: ty)
904−
905−renderColumn :: Column columns columnty -> ByteString
906−renderColumn (Column column) = renderAlias column
907−
908−unique
909− :: SListI subcolumns
910− => NP (Column columns) subcolumns
911− -> TableConstraint schema columns
912−unique columns = UnsafeTableConstraint $
913− "UNIQUE" <+> parenthesized (renderCommaSeparated renderColumn columns)
914−
915−primaryKey
916− :: (SListI subcolumns, NotNullTypes subcolumns)
917− => NP (Column columns) subcolumns
918− -> TableConstraint schema columns
919−primaryKey columns = UnsafeTableConstraint $
920− "PRIMARY KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
921−
922−type family SameTypes columns0 columns1 :: Constraint where
923− SameTypes '[] '[] = ()
924− SameTypes ((column0 ::: ty0) ': columns0) ((column1 ::: ty1) ': columns1)
925− = (ty0 ~ ty1, SameTypes columns0 columns1)
926−
927−type family NotNullTypes columns :: Constraint where
928− NotNullTypes '[] = ()
929− NotNullTypes ((column ::: (optionality ('NotNull ty))) ': columns)
930− = NotNullTypes columns
931−
932−foreignKey
933− :: ( HasTable reftable schema refcolumns
934− , SameTypes subcolumns refsubcolumns
935− , NotNullTypes subcolumns
936− , SListI subcolumns
937− , SListI refsubcolumns)
938− => NP (Column columns) subcolumns
939− -> Alias reftable
940− -> NP (Column refcolumns) refsubcolumns
941− -> TableConstraint schema columns
942−foreignKey columns reftable refcolumns = UnsafeTableConstraint $
943− "FOREIGN KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
944− <+> "REFERENCES" <+> renderAlias reftable
945− <+> parenthesized (renderCommaSeparated renderColumn refcolumns)
946−
947−{-----------------------------------------
948−DROP statements
949−-----------------------------------------}
950−
951−dropTable
952− :: KnownSymbol table
953− => Alias table
954− -> Definition schema (Drop table schema)
955−dropTable table = UnsafeDefinition $ "DROP TABLE" <+> renderAlias table <> ";"
956−
957−{-----------------------------------------
958−ALTER statements
959−-----------------------------------------}
960−
961−alterTable
962− :: HasTable table schema columns0
963− => Alias table
964− -> AlterTable columns0 columns1
965− -> Definition schema (Alter table schema columns1)
966−alterTable table alteration = UnsafeDefinition $
967− "ALTER TABLE"
968− <+> renderAlias table
969− <+> renderAlterTable alteration
970− <> ";"
971−
972−alterTableRename
973− :: (KnownSymbol table0, KnownSymbol table1)
974− => Alias table0
975− -> Alias table1
976− -> Definition schema (Rename table0 table1 schema)
977−alterTableRename table0 table1 = UnsafeDefinition $
978− "ALTER TABLE" <+> renderAlias table0
979− <+> "RENAME TO" <+> renderAlias table1 <> ";"
980−
981−data AlterTable
982− (columns0 :: [(Symbol, ColumnType)])
983− (columns1 :: [(Symbol, ColumnType)]) =
984− UnsafeAlterTable {renderAlterTable :: ByteString}
985−
986−addColumnDefault
987− :: KnownSymbol column
988− => Alias column
989− -> TypeExpression ('Optional ty)
990− -> AlterTable columns (Create column ('Optional ty) columns)
991−addColumnDefault column ty = UnsafeAlterTable $
992− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
993−
994−addColumnNull
995− :: KnownSymbol column
996− => Alias column
997− -> TypeExpression ('Required ('Null ty))
998− -> AlterTable columns ((column ::: 'Required ('Null ty)) ': columns)
999−addColumnNull column ty = UnsafeAlterTable $
1000− "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
1001−
1002−dropColumn
1003− :: KnownSymbol column
1004− => Alias column
1005− -> AlterTable columns (Drop column columns)
1006−dropColumn column = UnsafeAlterTable $
1007− "DROP COLUMN" <+> renderAlias column
1008−
1009−renameColumn
1010− :: (KnownSymbol column0, KnownSymbol column1)
1011− => Alias column0
1012− -> Alias column1
1013− -> AlterTable columns (Rename column0 column1 columns)
1014−renameColumn column0 column1 = UnsafeAlterTable $
1015− "RENAME COLUMN" <+> renderAlias column0 <+> "TO" <+> renderAlias column1
1016−
1017−alterColumn
1018− :: (KnownSymbol column, HasColumn column columns ty0)
1019− => Alias column
1020− -> AlterColumn ty0 ty1
1021− -> AlterTable columns (Alter column columns ty1)
1022−alterColumn column alteration = UnsafeAlterTable $
1023− "ALTER COLUMN" <+> renderAlias column <+> renderAlterColumn alteration
1024−
1025−data AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
1026− UnsafeAlterColumn {renderAlterColumn :: ByteString}
1027−
1028−setDefault
1029− :: Expression '[] '[] 'Ungrouped ('Required ty)
1030− -> AlterColumn ('Required ty) ('Optional ty)
1031−setDefault expression = UnsafeAlterColumn $
1032− "SET DEFAULT" <+> renderExpression expression
1033−
1034−dropDefault :: AlterColumn ('Optional ty) ('Required ty)
1035−dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
1036−
1037−setNotNull
1038− :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
1039−setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
1040−
1041−dropNotNull
1042− :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
1043−dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
1044−
1045−alterType
1046− :: PGCast ty0 ty1
1047− => TypeExpression (optionality (nullity ty1))
1048− -> AlterColumn (optionality (nullity ty0)) (optionality (nullity ty1))
1049−alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty
1050−
1051−{-----------------------------------------
1052−INSERT statements
1053−-----------------------------------------}
1054−
1055−insertInto
1056− :: (SListI columns, SListI results, HasTable table schema columns)
1057− => Alias table
1058− -> ValuesClause schema params columns
1059− -> ConflictClause params columns
1060− -> ReturningClause params columns results
1061− -> Manipulation schema params results
1062−insertInto table insert conflict returning = UnsafeManipulation $
1063− "INSERT" <+> "INTO" <+> renderAlias table
1064− <+> renderValuesClause insert
1065− <> renderConflictClause conflict
1066− <> renderReturningClause returning
1067−
1068−data ValuesClause
1069− (schema :: [(Symbol,[(Symbol,ColumnType)])])
1070− (params :: [ColumnType])
1071− (columns :: [(Symbol,ColumnType)])
1072− = Values
1073− (NP (Aliased (Expression params '[] 'Ungrouped)) columns)
1074− [NP (Aliased (Expression params '[] 'Ungrouped)) columns]
1075− | ValuesQuery (Query schema params columns)
1076−
1077−renderValuesClause
1078− :: SListI columns
1079− => ValuesClause schema params columns
1080− -> ByteString
1081−renderValuesClause = \case
1082− Values row rows ->
1083− parenthesized (renderCommaSeparated renderAliasPart row)
1084− <+> "VALUES"
1085− <+> commaSeparated
1086− (parenthesized . renderCommaSeparated renderValuePart <$> row:rows)
1087− where
1088− renderAliasPart, renderValuePart
1089− :: Aliased (Expression params '[] 'Ungrouped) ty -> ByteString
1090− renderAliasPart (_ `As` name) = renderAlias name
1091− renderValuePart (value `As` _) = renderExpression value
1092− ValuesQuery q -> renderQuery q
1093−
1094−data ReturningClause
1095− (params :: [ColumnType])
1096− (columns :: [(Symbol,ColumnType)])
1097− (results :: [(Symbol,ColumnType)])
1098− where
1099− ReturningNil :: ReturningClause params columns '[]
1100− ReturningStar :: ReturningClause params columns columns
1101− Returning
1102− :: NP (Aliased (Expression params '[table ::: columns] 'Ungrouped)) results
1103− -> ReturningClause params columns results
1104−
1105−renderReturningClause
1106− :: SListI results
1107− => ReturningClause params columns results
1108− -> ByteString
1109−renderReturningClause = \case
1110− ReturningNil -> ";"
1111− ReturningStar -> " RETURNING *;"
1112− Returning results -> " RETURNING"
1113− <+> renderCommaSeparated (renderAliased renderExpression) results <> ";"
1114−
1115−data ConflictClause params columns where
1116− Conflict :: ConflictClause params columns
1117− OnConflictDoNothing :: ConflictClause params columns
1118− OnConflictDoUpdate
1119− :: NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1120− -> Condition params '[table ::: columns] 'Ungrouped
1121− -> ConflictClause params columns
1122−
1123−renderConflictClause
1124− :: SListI columns
1125− => ConflictClause params columns
1126− -> ByteString
1127−renderConflictClause = \case
1128− Conflict -> ""
1129− OnConflictDoNothing -> " ON CONFLICT DO NOTHING"
1130− OnConflictDoUpdate updates wh
1131− -> " ON CONFLICT DO UPDATE SET"
1132− <+> renderCommaSeparatedMaybe renderUpdateExpression updates
1133− <+> "WHERE" <+> renderExpression wh
1134−
1135−{-----------------------------------------
1136−UPDATE statements
1137−-----------------------------------------}
1138−
1139−data UpdateExpression params table ty
1140− = Same
1141− | Set (Expression params table 'Ungrouped ty)
1142−
1143−renderUpdateExpression
1144− :: Aliased (UpdateExpression params '[table ::: columns]) column
1145− -> Maybe ByteString
1146−renderUpdateExpression = \case
1147− Same `As` _ -> Nothing
1148− Set expression `As` column -> Just $
1149− renderAlias column <+> "=" <+> renderExpression expression
1150−
1151−update
1152− :: (HasTable table schema columns, SListI columns, SListI results)
1153− => Alias table
1154− -> NP (Aliased (UpdateExpression params '[table ::: columns])) columns
1155− -> Condition params '[table ::: columns] 'Ungrouped
1156− -> ReturningClause params columns results
1157− -> Manipulation schema params results
1158−update table columns wh returning = UnsafeManipulation $
1159− "UPDATE"
1160− <+> renderAlias table
1161− <+> "SET"
1162− <+> renderCommaSeparatedMaybe renderUpdateExpression columns
1163− <+> "WHERE" <+> renderExpression wh
1164− <> renderReturningClause returning
1165−
1166−{-----------------------------------------
1167−DELETE statements
1168−-----------------------------------------}
1169−
1170−deleteFrom
1171− :: HasTable table schema columns
1172− => Alias table
1173− -> Condition params '[table ::: columns] 'Ungrouped
1174− -> Manipulation schema params '[]
1175−deleteFrom table wh = UnsafeManipulation $
1176− "DELETE FROM" <+> renderAlias table
1177− <+> "WHERE" <+> renderExpression wh <> ";"
1178−
1179−{-----------------------------------------
1180−render helper functions
1181−-----------------------------------------}
1182−
1183−parenthesized :: ByteString -> ByteString
1184−parenthesized str = "(" <> str <> ")"
1185−
1186−(<+>) :: ByteString -> ByteString -> ByteString
1187−str1 <+> str2 = str1 <> " " <> str2
1188−
1189−commaSeparated :: [ByteString] -> ByteString
1190−commaSeparated = ByteString.intercalate ", "
1191−
1192−renderCommaSeparated
1193− :: SListI xs
1194− => (forall x. expression x -> ByteString)
1195− -> NP expression xs -> ByteString
1196−renderCommaSeparated render
1197− = commaSeparated
1198− . hcollapse
1199− . hmap (K . render)
1200−
1201−renderCommaSeparatedMaybe
1202− :: SListI xs
1203− => (forall x. expression x -> Maybe ByteString)
1204− -> NP expression xs -> ByteString
1205−renderCommaSeparatedMaybe render
1206− = commaSeparated
1207− . catMaybes
1208− . hcollapse
1209− . hmap (K . render)
1210−
1211−renderSymbol :: KnownSymbol str => Proxy# str -> ByteString
1212−renderSymbol p = fromString $ symbolVal' p