Skip to content

Commit

Permalink
Export materialize (#260)
Browse files Browse the repository at this point in the history
The main reason I wasn't happy with this before is that there was nothing stopping you from writing `materialize query pure`. This returned query would produce invalid SQL if you actually tried to use it, because it would attempt to reference a common table expression outside the scope of the `WITH` statement.

The "solution" here is just to throw a `rebind` around the result such that `materialize` incurs an extra `Table Expr b` constraint, which means that you can't return `Query (Query a)` because `Query a` can't satisfy a `Table Expr` constraint.
  • Loading branch information
shane-circuithub committed Jul 15, 2023
1 parent 9f372dc commit cdf0c76
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/Rel8.hs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ module Rel8
, without
, withoutBy

-- ** @WITH@
, materialize

-- ** @WITH RECURSIVE@
, loop

Expand Down
7 changes: 4 additions & 3 deletions src/Rel8/Query/Materialize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ import Rel8.Table.Opaleye ( unpackspec )
-- 'materialize' to use the newer @WITH foo AS MATERIALIZED bar@ syntax
-- introduced in PostgreSQL 12 in the future. Currently Rel8 does not use
-- @AS MATERIALIZED@ to support earlier PostgreSQL versions.
materialize :: Table Expr a => Query a -> (Query a -> Query b) -> Query b
materialize :: (Table Expr a, Table Expr b)
=> Query a -> (Query a -> Query b) -> Query b
materialize query f =
fromOpaleye $
(>>= rebind "with") . fromOpaleye $
withExplicit unpackspec
(toOpaleye query')
(toOpaleye . f . fromOpaleye)
where
query' = query >>= rebind "with"
query' = query >>= rebind "materialize"
2 changes: 1 addition & 1 deletion src/Rel8/Tabulate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ difference a b = a <* absent b


-- | 'Q.materialize' for 'Tabulation's.
materialize :: (Table Expr k, Table Expr a)
materialize :: (Table Expr k, Table Expr a, Table Expr b)
=> Tabulation k a -> (Tabulation k a -> Query b) -> Query b
materialize tabulation f = case peek tabulation of
Tabulation query -> do
Expand Down

0 comments on commit cdf0c76

Please sign in to comment.