Skip to content

Commit

Permalink
Switch to WITH _ AS MATERIALIZED (_) for materialize (#284)
Browse files Browse the repository at this point in the history
  • Loading branch information
shane-circuithub authored Jan 9, 2024
1 parent b5789a6 commit 2cbf663
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 13 deletions.
2 changes: 1 addition & 1 deletion changelog.d/20230707_183519_ollie_scriv.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
### Added

- `Rel8.materialize` and `Rel8.Tabulate.materialize`, which add a materialization/optimisation fence to `SELECT` statements by binding a query to a `WITH` subquery. Note that Rel8 doesn't currently add `MATERIALIZE` to this, but may in the future. ([#180](https://github.com/circuithub/rel8/pull/180))
- `Rel8.materialize` and `Rel8.Tabulate.materialize`, which add a materialization/optimisation fence to `SELECT` statements by binding a query to a `WITH` subquery. Note that explicitly materialized common table expressions are only supported in PostgreSQL 12 an higher.
2 changes: 1 addition & 1 deletion rel8.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ library
, data-textual
, hasql ^>= 1.6.1.2
, network-ip
, opaleye ^>= 0.10.1.0
, opaleye ^>= 0.10.2.0
, pretty
, profunctors
, product-profunctors
Expand Down
20 changes: 9 additions & 11 deletions src/Rel8/Query/Materialize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

module Rel8.Query.Materialize
( materialize
) where
)
where

-- base
import Prelude

-- opaleye
import Opaleye.With ( withExplicit )
import Opaleye.With ( withMaterializedExplicit )

-- rel8
import Rel8.Expr ( Expr )
Expand All @@ -26,19 +27,16 @@ import Rel8.Table.Opaleye ( unpackspec )
-- you're doing this can sometimes help to nudge it in a particular direction.
--
-- 'materialize' is currently implemented in terms of Postgres'
-- [@WITH](https://www.postgresql.org/docs/current/queries-with.html) syntax.
-- Note that on newer versions of PostgreSQL starting with version 12, @WITH@
-- doesn't always automatically materialize if the results of the query aren't
-- used more than once. We reserve the right to change the implementation of
-- '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.
-- [@WITH](https://www.postgresql.org/docs/current/queries-with.html) syntax,
-- specifically the @WITH _ AS MATERIALIZED (_)@ form introduced in PostgreSQL
-- 12. This means that 'materialize' can only be used with PostgreSQL 12 or
-- newer.
materialize :: (Table Expr a, Table Expr b)
=> Query a -> (Query a -> Query b) -> Query b
materialize query f =
(>>= rebind "with") . fromOpaleye $
withExplicit unpackspec
withMaterializedExplicit unpackspec
(toOpaleye query')
(toOpaleye . f . fromOpaleye)
where
query' = query >>= rebind "materialize"
query' = query

0 comments on commit 2cbf663

Please sign in to comment.