@@ -71,6 +71,8 @@ import Control.Monad.Free.Church
7171import Control.Monad.State.Strict (evalState )
7272import Control.Monad.Writer (runWriterT )
7373
74+ import Data.List.NonEmpty (nonEmpty )
75+ import qualified Data.List.NonEmpty as NonEmpty
7476import Data.Kind (Type )
7577import Data.Proxy (Proxy (.. ))
7678import qualified Data.Text as T
@@ -289,18 +291,21 @@ lateral_ using mkSubquery = do
289291--
290292-- @beam-core@ offers 'selectWith' to produce a top-level 'SqlSelect'
291293-- but these cannot be turned into 'Q' objects for use within joins.
292- --
293- -- The 'pgSelectWith' function is more flexible and indeed
294- -- 'selectWith' for @beam-postgres@ is equivalent to se
294+ -- The 'pgSelectWith' function is more flexible.
295295pgSelectWith :: forall db s res
296296 . Projectible Postgres res
297297 => With Postgres db (Q Postgres db s res ) -> Q Postgres db s res
298298pgSelectWith (CTE. With mkQ) =
299- let (q, (recursiveness, ctes )) = evalState (runWriterT mkQ) 0
299+ let (q, (recursiveness, mctes )) = evalState (runWriterT mkQ) 0
300300 fromSyntax tblPfx =
301- case recursiveness of
302- CTE. Nonrecursive -> withSyntax ctes (buildSqlQuery tblPfx q)
303- CTE. Recursive -> withRecursiveSyntax ctes (buildSqlQuery tblPfx q)
301+ case (recursiveness, nonEmpty mctes) of
302+ (CTE. Nonrecursive , Just ctes) -> withSyntax (NonEmpty. toList ctes) (buildSqlQuery tblPfx q)
303+ (CTE. Recursive , Just ctes) -> withRecursiveSyntax (NonEmpty. toList ctes) (buildSqlQuery tblPfx q)
304+ -- If there are no subqueries, we don't want to generate
305+ -- an empty 'WITH' statement, which would be malformed.
306+ --
307+ -- see: https://github.com/haskell-beam/beam/issues/760
308+ (_, Nothing ) -> buildSqlQuery tblPfx q
304309 in Q (liftF (QAll (\ tblPfx tName ->
305310 let (_, names) = mkFieldNames @ Postgres @ res (qualifiedField tName)
306311 in fromTable (PgTableSourceSyntax $
@@ -309,7 +314,7 @@ pgSelectWith (CTE.With mkQ) =
309314 (\ tName ->
310315 let (projection, _) = mkFieldNames @ Postgres @ res (qualifiedField tName)
311316 in projection)
312- (\ _ -> Nothing )
317+ (const Nothing )
313318 snd ))
314319
315320-- | By default, Postgres will throw an error when a conflict is detected. This
0 commit comments