7 , GeneralizedNewtypeDeriving
10 , MultiParamTypeClasses
17 , UndecidableInstances
20module Squeal.PostgreSQL.Query
22 Query (UnsafeQuery, renderQuery)
35 , selectDistinctDotStar
39 -- * Table Expressions
40 , TableExpression (..)
41 , renderTableExpression
52 , GroupByClause (NoGroups, Group)
54 , HavingClause (NoHaving, Having)
56 , GroupedBy (getGroup1, getGroup2)
59 , renderSortExpression
63import Data.ByteString (ByteString)
67import Generics.SOP hiding (from)
70import qualified GHC.Generics as GHC
72import Squeal.PostgreSQL.Expression
73import Squeal.PostgreSQL.Prettyprint
74import Squeal.PostgreSQL.Schema
77 (schema :: TablesType)
78 (params :: [ColumnType])
79 (columns :: ColumnsType)
80 = UnsafeQuery { renderQuery :: ByteString }
81 deriving (GHC.Generic,Show,Eq,Ord,NFData)
83union, unionAll, intersect, intersectAll, except, exceptAll
84 :: Query schema params columns
85 -> Query schema params columns
86 -> Query schema params columns
87q1 `union` q2 = UnsafeQuery $
88 parenthesized (renderQuery q1)
90 <+> parenthesized (renderQuery q2)
91q1 `unionAll` q2 = UnsafeQuery $
92 parenthesized (renderQuery q1)
94 <+> parenthesized (renderQuery q2)
95q1 `intersect` q2 = UnsafeQuery $
96 parenthesized (renderQuery q1)
98 <+> parenthesized (renderQuery q2)
99q1 `intersectAll` q2 = UnsafeQuery $
100 parenthesized (renderQuery q1)
101 <+> "INTERSECT" <+> "ALL"
102 <+> parenthesized (renderQuery q2)
103q1 `except` q2 = UnsafeQuery $
104 parenthesized (renderQuery q1)
106 <+> parenthesized (renderQuery q2)
107q1 `exceptAll` q2 = UnsafeQuery $
108 parenthesized (renderQuery q1)
109 <+> "EXCEPT" <+> "ALL"
110 <+> parenthesized (renderQuery q2)
112{-----------------------------------------
114-----------------------------------------}
118 => NP (Aliased (Expression tables grouping params)) (column ': columns)
119 -> TableExpression schema params tables grouping
120 -> Query schema params (column ': columns)
121select list tabs = UnsafeQuery $
123 <+> renderCommaSeparated (renderAliased renderExpression) list
124 <+> renderTableExpression tabs
128 => NP (Aliased (Expression tables 'Ungrouped params)) (column ': columns)
129 -> TableExpression schema params tables 'Ungrouped
130 -> Query schema params (column ': columns)
131selectDistinct list tabs = UnsafeQuery $
133 <+> renderCommaSeparated (renderAliased renderExpression) list
134 <+> renderTableExpression tabs
136selectStar, selectDistinctStar
137 :: HasUnique table tables columns
138 => TableExpression schema params tables 'Ungrouped
139 -> Query schema params columns
140selectStar tabs = UnsafeQuery $ "SELECT" <+> "*" <+> renderTableExpression tabs
141selectDistinctStar tabs = UnsafeQuery $
142 "SELECT DISTINCT" <+> "*" <+> renderTableExpression tabs
144selectDotStar, selectDistinctDotStar
145 :: HasTable table tables columns
147 -> TableExpression schema params tables 'Ungrouped
148 -> Query schema params columns
149selectDotStar table tables = UnsafeQuery $
150 "SELECT" <+> renderAlias table <> ".*" <+> renderTableExpression tables
151selectDistinctDotStar table tables = UnsafeQuery $
152 "SELECT DISTINCT" <+> renderAlias table <> ".*"
153 <+> renderTableExpression tables
155{-----------------------------------------
157-----------------------------------------}
159data FromClause schema params tables where
161 :: Aliased (Table schema) table
162 -> FromClause schema params '[table]
164 :: Aliased (Query schema params) table
165 -> FromClause schema params '[table]
167 :: FromClause schema params right
168 -> FromClause schema params left
169 -> FromClause schema params (Join left right)
171 :: FromClause schema params right
172 -> Condition (Join left right) 'Ungrouped params
173 -> FromClause schema params left
174 -> FromClause schema params (Join left right)
176 :: FromClause schema params right
177 -> Condition (Join left right) 'Ungrouped params
178 -> FromClause schema params left
179 -> FromClause schema params (Join left (NullifyTables right))
181 :: FromClause schema params right
182 -> Condition (Join left right) 'Ungrouped params
183 -> FromClause schema params left
184 -> FromClause schema params (Join (NullifyTables left) right)
186 :: FromClause schema params right
187 -> Condition (Join left right) 'Ungrouped params
188 -> FromClause schema params left
189 -> FromClause schema params
190 (Join (NullifyTables left) (NullifyTables right))
192renderFromClause :: FromClause schema params tables -> ByteString
193renderFromClause = \case
194 Table table -> renderAliased renderTable table
195 Subquery selection -> renderAliased (parenthesized . renderQuery) selection
196 CrossJoin right left ->
197 renderFromClause left <+> "CROSS JOIN" <+> renderFromClause right
198 InnerJoin right on left -> renderJoin "INNER JOIN" right on left
199 LeftOuterJoin right on left -> renderJoin "LEFT OUTER JOIN" right on left
200 RightOuterJoin right on left -> renderJoin "RIGHT OUTER JOIN" right on left
201 FullOuterJoin right on left -> renderJoin "FULL OUTER JOIN" right on left
203 renderJoin op right on left =
204 renderFromClause left <+> op <+> renderFromClause right
205 <+> "ON" <+> renderExpression on
207{-----------------------------------------
209-----------------------------------------}
212 (schema :: TablesType)
213 (params :: [ColumnType])
214 (tables :: TablesType)
215 (grouping :: Grouping)
217 { fromClause :: FromClause schema params tables
218 , whereClause :: [Condition tables 'Ungrouped params]
219 , groupByClause :: GroupByClause tables grouping
220 , havingClause :: HavingClause tables grouping params
221 , orderByClause :: [SortExpression tables grouping params]
222 , limitClause :: [Word64]
223 , offsetClause :: [Word64]
227 :: TableExpression schema params tables grouping
230 (TableExpression tables whs' grps' hvs' srts' lims' offs') = mconcat
231 [ "FROM ", renderFromClause tables
233 , renderGroupByClause grps'
234 , renderHavingClause hvs'
237 , renderOffsets offs'
242 wh:[] -> " WHERE" <+> renderExpression wh
243 wh:whs -> " WHERE" <+> renderExpression (foldr (.&&) wh whs)
247 <+> commaSeparated (renderSortExpression <$> srts)
250 lims -> " LIMIT" <+> fromString (show (minimum lims))
251 renderOffsets = \case
253 offs -> " OFFSET" <+> fromString (show (sum offs))
256 :: FromClause schema params tables
257 -> TableExpression schema params tables 'Ungrouped
258from tables = TableExpression tables [] NoGroups NoHaving [] [] []
261 :: Condition tables 'Ungrouped params
262 -> TableExpression schema params tables grouping
263 -> TableExpression schema params tables grouping
264where_ wh tables = tables {whereClause = wh : whereClause tables}
268 => NP (By tables) bys
269 -> TableExpression schema params tables 'Ungrouped
270 -> TableExpression schema params tables ('Grouped bys)
271group bys tables = TableExpression
272 { fromClause = fromClause tables
273 , whereClause = whereClause tables
274 , groupByClause = Group bys
275 , havingClause = Having []
277 , limitClause = limitClause tables
278 , offsetClause = offsetClause tables
282 :: Condition tables ('Grouped bys) params
283 -> TableExpression schema params tables ('Grouped bys)
284 -> TableExpression schema params tables ('Grouped bys)
285having hv tables = tables
286 { havingClause = case havingClause tables of Having hvs -> Having (hv:hvs) }
289 :: [SortExpression tables grouping params]
290 -> TableExpression schema params tables grouping
291 -> TableExpression schema params tables grouping
292orderBy srts tables = tables {orderByClause = orderByClause tables ++ srts}
296 -> TableExpression schema params tables grouping
297 -> TableExpression schema params tables grouping
298limit lim tables = tables {limitClause = lim : limitClause tables}
302 -> TableExpression schema params tables grouping
303 -> TableExpression schema params tables grouping
304offset off tables = tables {offsetClause = off : offsetClause tables}
306{-----------------------------------------
308-----------------------------------------}
311 (tables :: TablesType)
312 (by :: (Symbol,Symbol)) where
314 :: (HasUnique table tables columns, HasColumn column columns ty)
316 -> By tables '(table, column)
318 :: (HasTable table tables columns, HasColumn column columns ty)
319 => (Alias table, Alias column)
320 -> By tables '(table, column)
321deriving instance Show (By tables by)
322deriving instance Eq (By tables by)
323deriving instance Ord (By tables by)
325renderBy :: By tables tabcolty -> ByteString
327 By column -> renderAlias column
328 By2 (table, column) -> renderAlias table <> "." <> renderAlias column
330data GroupByClause tables grouping where
331 NoGroups :: GroupByClause tables 'Ungrouped
334 => NP (By tables) bys
335 -> GroupByClause tables ('Grouped bys)
337renderGroupByClause :: GroupByClause tables grouping -> ByteString
338renderGroupByClause = \case
341 Group bys -> " GROUP BY" <+> renderCommaSeparated renderBy bys
343data HavingClause tables grouping params where
344 NoHaving :: HavingClause tables 'Ungrouped params
346 :: [Condition tables ('Grouped bys) params]
347 -> HavingClause tables ('Grouped bys) params
348deriving instance Show (HavingClause tables grouping params)
349deriving instance Eq (HavingClause tables grouping params)
350deriving instance Ord (HavingClause tables grouping params)
352renderHavingClause :: HavingClause tables grouping params -> ByteString
353renderHavingClause = \case
357 " HAVING" <+> commaSeparated (renderExpression <$> conditions)
359{-----------------------------------------
361-----------------------------------------}
363data SortExpression tables grouping params where
365 :: Expression tables grouping params ('Required ('NotNull ty))
366 -> SortExpression tables grouping params
368 :: Expression tables grouping params ('Required ('NotNull ty))
369 -> SortExpression tables grouping params
371 :: Expression tables grouping params ('Required ('Null ty))
372 -> SortExpression tables grouping params
374 :: Expression tables grouping params ('Required ('Null ty))
375 -> SortExpression tables grouping params
377 :: Expression tables grouping params ('Required ('Null ty))
378 -> SortExpression tables grouping params
380 :: Expression tables grouping params ('Required ('Null ty))
381 -> SortExpression tables grouping params
382deriving instance Show (SortExpression tables grouping params)
384renderSortExpression :: SortExpression tables grouping params -> ByteString
385renderSortExpression = \case
386 Asc expression -> renderExpression expression <+> "ASC"
387 Desc expression -> renderExpression expression <+> "DESC"
388 AscNullsFirst expression -> renderExpression expression
389 <+> "ASC NULLS FIRST"
390 DescNullsFirst expression -> renderExpression expression
391 <+> "DESC NULLS FIRST"
392 AscNullsLast expression -> renderExpression expression <+> "ASC NULLS LAST"
393 DescNullsLast expression -> renderExpression expression <+> "DESC NULLS LAST"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list