@@ -69,7 +69,6 @@ module Squeal.PostgreSQL.Query
69 , jsonbToRecordSet
69 , jsonbToRecordSet
70 -- * Table Expressions
70 -- * Table Expressions
71 , TableExpression (..)
71 , TableExpression (..)
72− , renderTableExpression
@@ -90,7 +89,6 @@ module Squeal.PostgreSQL.Query
90 , fullOuterJoin
89 , fullOuterJoin
91 -- * Grouping
90 -- * Grouping
94 , GroupByClause (..)
92 , GroupByClause (..)
95 , HavingClause (..)
93 , HavingClause (..)
96 -- * Sorting
94 -- * Sorting
@@ -329,9 +327,9 @@ union
329 -> Query db params columns
327 -> Query db params columns
330 -> Query db params columns
328 -> Query db params columns
331q1 `union` q2 = UnsafeQuery $
329q1 `union` q2 = UnsafeQuery $
332− parenthesized (renderQuery q1)
330+ parenthesized (renderSQL q1)
333 <+> "UNION"
331 <+> "UNION"
334− <+> parenthesized (renderQuery q2)
332+ <+> parenthesized (renderSQL q2)
336-- | The results of two queries can be combined using the set operation
334-- | The results of two queries can be combined using the set operation
337-- `unionAll`, the disjoint union. Duplicate rows are retained.
335-- `unionAll`, the disjoint union. Duplicate rows are retained.
@@ -340,9 +338,9 @@ unionAll
340 -> Query db params columns
338 -> Query db params columns
341 -> Query db params columns
339 -> Query db params columns
342q1 `unionAll` q2 = UnsafeQuery $
340q1 `unionAll` q2 = UnsafeQuery $
343− parenthesized (renderQuery q1)
341+ parenthesized (renderSQL q1)
344 <+> "UNION" <+> "ALL"
342 <+> "UNION" <+> "ALL"
345− <+> parenthesized (renderQuery q2)
343+ <+> parenthesized (renderSQL q2)
347-- | The results of two queries can be combined using the set operation
345-- | The results of two queries can be combined using the set operation
348-- `intersect`, the intersection. Duplicate rows are eliminated.
346-- `intersect`, the intersection. Duplicate rows are eliminated.
@@ -351,9 +349,9 @@ intersect
351 -> Query db params columns
349 -> Query db params columns
352 -> Query db params columns
350 -> Query db params columns
353q1 `intersect` q2 = UnsafeQuery $
351q1 `intersect` q2 = UnsafeQuery $
354− parenthesized (renderQuery q1)
352+ parenthesized (renderSQL q1)
355 <+> "INTERSECT"
353 <+> "INTERSECT"
356− <+> parenthesized (renderQuery q2)
354+ <+> parenthesized (renderSQL q2)
358-- | The results of two queries can be combined using the set operation
356-- | The results of two queries can be combined using the set operation
359-- `intersectAll`, the intersection. Duplicate rows are retained.
357-- `intersectAll`, the intersection. Duplicate rows are retained.
@@ -362,9 +360,9 @@ intersectAll
362 -> Query db params columns
360 -> Query db params columns
363 -> Query db params columns
361 -> Query db params columns
364q1 `intersectAll` q2 = UnsafeQuery $
362q1 `intersectAll` q2 = UnsafeQuery $
365− parenthesized (renderQuery q1)
363+ parenthesized (renderSQL q1)
366 <+> "INTERSECT" <+> "ALL"
364 <+> "INTERSECT" <+> "ALL"
367− <+> parenthesized (renderQuery q2)
365+ <+> parenthesized (renderSQL q2)
369-- | The results of two queries can be combined using the set operation
367-- | The results of two queries can be combined using the set operation
370-- `except`, the set difference. Duplicate rows are eliminated.
368-- `except`, the set difference. Duplicate rows are eliminated.
@@ -373,9 +371,9 @@ except
373 -> Query db params columns
371 -> Query db params columns
374 -> Query db params columns
372 -> Query db params columns
375q1 `except` q2 = UnsafeQuery $
373q1 `except` q2 = UnsafeQuery $
376− parenthesized (renderQuery q1)
374+ parenthesized (renderSQL q1)
377 <+> "EXCEPT"
375 <+> "EXCEPT"
378− <+> parenthesized (renderQuery q2)
376+ <+> parenthesized (renderSQL q2)
380-- | The results of two queries can be combined using the set operation
378-- | The results of two queries can be combined using the set operation
381-- `exceptAll`, the set difference. Duplicate rows are retained.
379-- `exceptAll`, the set difference. Duplicate rows are retained.
@@ -384,9 +382,9 @@ exceptAll
384 -> Query db params columns
382 -> Query db params columns
385 -> Query db params columns
383 -> Query db params columns
386q1 `exceptAll` q2 = UnsafeQuery $
384q1 `exceptAll` q2 = UnsafeQuery $
387− parenthesized (renderQuery q1)
385+ parenthesized (renderSQL q1)
388 <+> "EXCEPT" <+> "ALL"
386 <+> "EXCEPT" <+> "ALL"
389− <+> parenthesized (renderQuery q2)
387+ <+> parenthesized (renderSQL q2)
391{-----------------------------------------
389{-----------------------------------------
392SELECT queries
390SELECT queries
@@ -456,7 +454,7 @@ select
456select selection tabexpr = UnsafeQuery $
454select selection tabexpr = UnsafeQuery $
458 <+> renderSQL selection
456 <+> renderSQL selection
459− <+> renderTableExpression tabexpr
457+ <+> renderSQL tabexpr
462 :: (SListI row, row ~ (x ': xs))
460 :: (SListI row, row ~ (x ': xs))
@@ -477,7 +475,7 @@ selectDistinct
477selectDistinct selection tabexpr = UnsafeQuery $
475selectDistinct selection tabexpr = UnsafeQuery $
478 "SELECT DISTINCT"
476 "SELECT DISTINCT"
479 <+> renderSQL selection
477 <+> renderSQL selection
480− <+> renderTableExpression tabexpr
478+ <+> renderSQL tabexpr
482selectDistinct_
480selectDistinct_
483 :: (SListI columns, columns ~ (col ': cols))
481 :: (SListI columns, columns ~ (col ': cols))
@@ -511,11 +509,11 @@ values rw rws = UnsafeQuery $ "SELECT * FROM"
511 ( parenthesized
509 ( parenthesized
512 . renderCommaSeparated renderValuePart <$> rw:rws )
510 . renderCommaSeparated renderValuePart <$> rw:rws )
513 ) <+> "AS t"
511 ) <+> "AS t"
514− <+> parenthesized (renderCommaSeparated renderSQLPart rw)
512+ <+> parenthesized (renderCommaSeparated renderAliasPart rw)
516− renderSQLPart, renderValuePart
514+ renderAliasPart, renderValuePart
517 :: Aliased (Expression db params 'Ungrouped '[] ) ty -> ByteString
515 :: Aliased (Expression db params 'Ungrouped '[] ) ty -> ByteString
518− renderSQLPart (_ `As` name) = renderSQL name
516+ renderAliasPart (_ `As` name) = renderSQL name
519 renderValuePart (value `As` _) = renderSQL value
517 renderValuePart (value `As` _) = renderSQL value
521-- | `values_` computes a row value or set of row values
519-- | `values_` computes a row value or set of row values
@@ -585,34 +583,32 @@ data TableExpression
587-- | Render a `TableExpression`
585-- | Render a `TableExpression`
588−renderTableExpression
589− :: TableExpression db params grp from
586+instance RenderSQL (TableExpression db params grp from) where
590− -> ByteString
587+ renderSQL
591−renderTableExpression
592− (TableExpression frm' whs' grps' hvs' srts' lims' offs') = mconcat
588+ (TableExpression frm' whs' grps' hvs' srts' lims' offs') = mconcat
593− [ "FROM ", renderFromClause frm'
589+ [ "FROM ", renderSQL frm'
594− , renderWheres whs'
590+ , renderWheres whs'
595− , renderSQL grps'
591+ , renderSQL grps'
596− , renderSQL hvs'
592+ , renderSQL hvs'
597− , renderOrderByClause srts'
593+ , renderOrderByClause srts'
598− , renderLimits lims'
594+ , renderLimits lims'
599− , renderOffsets offs'
595+ , renderOffsets offs'
602− renderWheres = \case
598+ renderWheres = \case
603− [] -> ""
599+ [] -> ""
604− wh:[] -> " WHERE" <+> renderSQL wh
600+ wh:[] -> " WHERE" <+> renderSQL wh
605− wh:whs -> " WHERE" <+> renderSQL (foldr (.&&) wh whs)
601+ wh:whs -> " WHERE" <+> renderSQL (foldr (.&&) wh whs)
606− renderOrderByClause = \case
602+ renderOrderByClause = \case
607− [] -> ""
603+ [] -> ""
608− srts -> " ORDER BY"
604+ srts -> " ORDER BY"
609− <+> commaSeparated (renderSQL <$> srts)
605+ <+> commaSeparated (renderSQL <$> srts)
610− renderLimits = \case
606+ renderLimits = \case
611− [] -> ""
607+ [] -> ""
612− lims -> " LIMIT" <+> fromString (show (minimum lims))
608+ lims -> " LIMIT" <+> fromString (show (minimum lims))
613− renderOffsets = \case
609+ renderOffsets = \case
614− [] -> ""
610+ [] -> ""
615− offs -> " OFFSET" <+> fromString (show (sum offs))
611+ offs -> " OFFSET" <+> fromString (show (sum offs))
617-- | A `from` generates a `TableExpression` from a table reference that can be
613-- | A `from` generates a `TableExpression` from a table reference that can be
618-- a table name, or a derived table such as a subquery, a JOIN construct,
614-- a table name, or a derived table such as a subquery, a JOIN construct,
@@ -835,6 +831,8 @@ as a subquery, a @JOIN@ construct, or complex combinations of these.
835newtype FromClause db params from
831newtype FromClause db params from
836 = UnsafeFromClause { renderFromClause :: ByteString }
832 = UnsafeFromClause { renderFromClause :: ByteString }
837 deriving (GHC.Generic,Show,Eq,Ord,NFData)
833 deriving (GHC.Generic,Show,Eq,Ord,NFData)
834+instance RenderSQL (FromClause db params from) where
835+ renderSQL = renderFromClause
839-- | A real `table` is a table from the database.
837-- | A real `table` is a table from the database.
@@ -878,7 +876,7 @@ crossJoin
878 -- ^ left
876 -- ^ left
879 -> FromClause db params (Join left right)
877 -> FromClause db params (Join left right)
880crossJoin right left = UnsafeFromClause $
878crossJoin right left = UnsafeFromClause $
881− renderFromClause left <+> "CROSS JOIN" <+> renderFromClause right
879+ renderSQL left <+> "CROSS JOIN" <+> renderSQL right
883{- | @left & innerJoin right on@. The joined table is filtered by
881{- | @left & innerJoin right on@. The joined table is filtered by
884the @on@ condition.
882the @on@ condition.
@@ -892,7 +890,7 @@ innerJoin
892 -- ^ left
890 -- ^ left
893 -> FromClause db params (Join left right)
891 -> FromClause db params (Join left right)
894innerJoin right on left = UnsafeFromClause $
892innerJoin right on left = UnsafeFromClause $
895− renderFromClause left <+> "INNER JOIN" <+> renderFromClause right
893+ renderSQL left <+> "INNER JOIN" <+> renderSQL right
896 <+> "ON" <+> renderSQL on
894 <+> "ON" <+> renderSQL on
898{- | @left & leftOuterJoin right on@. First, an inner join is performed.
896{- | @left & leftOuterJoin right on@. First, an inner join is performed.
@@ -909,7 +907,7 @@ leftOuterJoin
909 -- ^ left
907 -- ^ left
910 -> FromClause db params (Join left (NullifyFrom right))
908 -> FromClause db params (Join left (NullifyFrom right))
911leftOuterJoin right on left = UnsafeFromClause $
909leftOuterJoin right on left = UnsafeFromClause $
912− renderFromClause left <+> "LEFT OUTER JOIN" <+> renderFromClause right
910+ renderSQL left <+> "LEFT OUTER JOIN" <+> renderSQL right
913 <+> "ON" <+> renderSQL on
911 <+> "ON" <+> renderSQL on
915{- | @left & rightOuterJoin right on@. First, an inner join is performed.
913{- | @left & rightOuterJoin right on@. First, an inner join is performed.
@@ -927,7 +925,7 @@ rightOuterJoin
927 -- ^ left
925 -- ^ left
928 -> FromClause db params (Join (NullifyFrom left) right)
926 -> FromClause db params (Join (NullifyFrom left) right)
929rightOuterJoin right on left = UnsafeFromClause $
927rightOuterJoin right on left = UnsafeFromClause $
930− renderFromClause left <+> "RIGHT OUTER JOIN" <+> renderFromClause right
928+ renderSQL left <+> "RIGHT OUTER JOIN" <+> renderSQL right
931 <+> "ON" <+> renderSQL on
929 <+> "ON" <+> renderSQL on
933{- | @left & fullOuterJoin right on@. First, an inner join is performed.
931{- | @left & fullOuterJoin right on@. First, an inner join is performed.
@@ -947,7 +945,7 @@ fullOuterJoin
947 -> FromClause db params
945 -> FromClause db params
948 (Join (NullifyFrom left) (NullifyFrom right))
946 (Join (NullifyFrom left) (NullifyFrom right))
949fullOuterJoin right on left = UnsafeFromClause $
947fullOuterJoin right on left = UnsafeFromClause $
950− renderFromClause left <+> "FULL OUTER JOIN" <+> renderFromClause right
948+ renderSQL left <+> "FULL OUTER JOIN" <+> renderSQL right
951 <+> "ON" <+> renderSQL on
949 <+> "ON" <+> renderSQL on
953{-----------------------------------------
951{-----------------------------------------
@@ -974,6 +972,10 @@ data By
974deriving instance Show (By from by)
972deriving instance Show (By from by)
975deriving instance Eq (By from by)
973deriving instance Eq (By from by)
976deriving instance Ord (By from by)
974deriving instance Ord (By from by)
975+instance RenderSQL (By from by) where
977+ By1 column -> renderSQL column
978+ By2 rel column -> renderSQL rel <> "." <> renderSQL column
978instance (HasUnique rel rels cols, Has col cols ty, by ~ '(rel, col))
980instance (HasUnique rel rels cols, Has col cols ty, by ~ '(rel, col))
979 => IsLabel col (By rels by) where fromLabel = By1 fromLabel
981 => IsLabel col (By rels by) where fromLabel = By1 fromLabel
@@ -985,12 +987,6 @@ instance (Has rel rels cols, Has col cols ty, bys ~ '[ '(rel, col)])
985 => IsQualified rel col (NP (By rels) bys) where
987 => IsQualified rel col (NP (By rels) bys) where
986 rel ! col = By2 rel col :* Nil
988 rel ! col = By2 rel col :* Nil
989−renderBy :: By from by -> ByteString
991− By1 column -> renderSQL column
992− By2 rel column -> renderSQL rel <> "." <> renderSQL column
994-- | A `GroupByClause` indicates the `Grouping` of a `TableExpression`.
990-- | A `GroupByClause` indicates the `Grouping` of a `TableExpression`.
995-- A `NoGroups` indicates `Ungrouped` while a `Group` indicates `Grouped`.
991-- A `NoGroups` indicates `Ungrouped` while a `Group` indicates `Grouped`.
996-- @NoGroups@ is distinguised from @Group Nil@ since no aggregation can be
992-- @NoGroups@ is distinguised from @Group Nil@ since no aggregation can be
@@ -1009,7 +1005,7 @@ instance RenderSQL (GroupByClause grp from) where
1009 renderSQL = \case
1005 renderSQL = \case
1010 NoGroups -> ""
1006 NoGroups -> ""
1011 Group Nil -> ""
1007 Group Nil -> ""
1012− Group bys -> " GROUP BY" <+> renderCommaSeparated renderBy bys
1008+ Group bys -> " GROUP BY" <+> renderCommaSeparated renderSQL bys
1014-- | A `HavingClause` is used to eliminate groups that are not of interest.
1010-- | A `HavingClause` is used to eliminate groups that are not of interest.
1015-- An `Ungrouped` `TableExpression` may only use `NoHaving` while a `Grouped`
1011-- An `Ungrouped` `TableExpression` may only use `NoHaving` while a `Grouped`
@@ -1083,7 +1079,7 @@ unsafeSubqueryExpression
1083 -> Query db params '[alias ::: ty]
1079 -> Query db params '[alias ::: ty]
1084 -> Expression db params grp from (nullity 'PGbool)
1080 -> Expression db params grp from (nullity 'PGbool)
1085unsafeSubqueryExpression op x q = UnsafeExpression $
1081unsafeSubqueryExpression op x q = UnsafeExpression $
1086− renderSQL x <+> op <+> parenthesized (renderQuery q)
1082+ renderSQL x <+> op <+> parenthesized (renderSQL q)
1088unsafeRowSubqueryExpression
1084unsafeRowSubqueryExpression
1089 :: SListI row
1085 :: SListI row
@@ -1092,7 +1088,7 @@ unsafeRowSubqueryExpression
1092 -> Query db params row
1088 -> Query db params row
1093 -> Expression db params grp from (nullity 'PGbool)
1089 -> Expression db params grp from (nullity 'PGbool)
1094unsafeRowSubqueryExpression op xs q = UnsafeExpression $
1090unsafeRowSubqueryExpression op xs q = UnsafeExpression $
1095− renderSQL (row xs) <+> op <+> parenthesized (renderQuery q)
1091+ renderSQL (row xs) <+> op <+> parenthesized (renderSQL q)
1097-- | The right-hand side is a sub`Query`, which must return exactly one column.
1093-- | The right-hand side is a sub`Query`, which must return exactly one column.
1098-- The left-hand expression is evaluated and compared to each row of the
1094-- The left-hand expression is evaluated and compared to each row of the
@@ -1404,5 +1400,5 @@ class With statement where
1404instance With Query where
1400instance With Query where
1405 with Done query = query
1401 with Done query = query
1406 with (cte :>> ctes) query = UnsafeQuery $
1402 with (cte :>> ctes) query = UnsafeQuery $
1407− "WITH" <+> renderCommonTableExpressions renderQuery cte ctes
1403+ "WITH" <+> renderCommonTableExpressions renderSQL cte ctes
1408− <+> renderQuery query
1404+ <+> renderSQL query