diff --git a/src/Database/Esqueleto/Experimental.hs b/src/Database/Esqueleto/Experimental.hs index a96d1d5..e9ddd9f 100644 --- a/src/Database/Esqueleto/Experimental.hs +++ b/src/Database/Esqueleto/Experimental.hs @@ -53,8 +53,6 @@ module Database.Esqueleto.Experimental , with , withRecursive - , agg - -- ** Internals , From(..) , ToMaybe(..) diff --git a/src/Database/Esqueleto/Experimental/Aggregates.hs b/src/Database/Esqueleto/Experimental/Aggregates.hs index 0968d4c..315908c 100644 --- a/src/Database/Esqueleto/Experimental/Aggregates.hs +++ b/src/Database/Esqueleto/Experimental/Aggregates.hs @@ -16,11 +16,13 @@ module Database.Esqueleto.Experimental.Aggregates import Control.Monad.IO.Class import qualified Control.Monad.Trans.Writer as W import Data.Coerce (Coercible, coerce) +import Data.Proxy import Database.Esqueleto.Internal.Internal ( GroupByClause(..) , SideData(..) , SqlExpr(..) , SqlQuery(..) + , SqlQueryHaving(..) , SqlSelect(..) , ToSomeValues(..) , noMeta @@ -53,8 +55,16 @@ instance SqlExprEntity SqlExpr where (^.) = (I.^.) (?.) = (I.?.) -newtype SqlAggregate a = SqlAggregate { agg :: SqlExpr a } +newtype SqlAggregate a = SqlAggregate { unsafeSqlAggregate :: SqlExpr a } deriving via SqlExpr instance SqlExprEntity SqlAggregate +instance forall a. PersistField a => SqlSelect (SqlAggregate a) a where + sqlSelectCols info (SqlAggregate e) = sqlSelectCols info e + sqlSelectColCount = const 1 + sqlSelectProcessRow _ = sqlSelectProcessRow (Proxy :: Proxy (SqlExpr a)) +instance SqlQueryHaving (SqlAggregate Bool) where + having expr = Q $ W.tell mempty { sdHavingClause = I.Where (coerce expr) } +instance SqlQueryHaving (SqlAggregate (Maybe Bool)) where + having expr = Q $ W.tell mempty { sdHavingClause = I.Where (coerce expr) } test :: (PersistEntity ent, PersistField a, PersistField b, PersistField c) => SqlExpr (Maybe (Entity ent)) diff --git a/src/Database/Esqueleto/Experimental/WindowFunctions.hs b/src/Database/Esqueleto/Experimental/WindowFunctions.hs index 5f5b99f..2b6c441 100644 --- a/src/Database/Esqueleto/Experimental/WindowFunctions.hs +++ b/src/Database/Esqueleto/Experimental/WindowFunctions.hs @@ -62,7 +62,7 @@ example = <> orderBy_ [asc (val @Int64 10)] ) -data NeedsWindow a +example2 = countRows_ @Int64 `over_` () lag :: SqlExpr (Value a) -> WindowExpr a lag v = lag_ v Nothing Nothing @@ -254,7 +254,7 @@ currentRow :: FrameRange currentRow = FrameRangeCurrentRow class Over expr where - over_ :: RenderWindow window => expr a -> window -> SqlExpr (WindowedValue a) + over_ :: RenderWindow window => expr a -> window -> SqlAggregate (WindowedValue a) data WindowedValue a = WindowedValue { unWindowedValue :: a } instance PersistField a => SqlSelect (SqlExpr (WindowedValue a)) (WindowedValue a) where @@ -266,7 +266,7 @@ instance PersistField a => SqlSelect (SqlExpr (WindowedValue a)) (WindowedValue newtype WindowExpr a = WindowExpr { unsafeWindowExpr :: SqlExpr a } instance Over WindowExpr where - (WindowExpr (ERaw _ f)) `over_` window = ERaw noMeta $ \p info -> + (WindowExpr (ERaw _ f)) `over_` window = SqlAggregate $ ERaw noMeta $ \p info -> let (b, v) = f Never info (w, vw) = renderWindow info window in (parensM p $ b <> " OVER " <> parens w , v <> vw) diff --git a/src/Database/Esqueleto/Internal/Internal.hs b/src/Database/Esqueleto/Internal/Internal.hs index dbb61f3..98bb376 100644 --- a/src/Database/Esqueleto/Internal/Internal.hs +++ b/src/Database/Esqueleto/Internal/Internal.hs @@ -377,11 +377,16 @@ distinctOnOrderBy exprs act = rand :: SqlExpr OrderBy rand = ERaw noMeta $ \_ _ -> ("RANDOM()", []) --- | @HAVING@. --- --- @since 1.2.2 -having :: SqlExpr Bool -> SqlQuery () -having expr = Q $ W.tell mempty { sdHavingClause = Where expr } +class SqlQueryHaving expr where + -- | @HAVING@. + -- + -- @since 1.2.2 + having :: expr -> SqlQuery () + +instance SqlQueryHaving (SqlExpr Bool) where + having expr = Q $ W.tell mempty { sdHavingClause = Where expr } +instance SqlQueryHaving (SqlExpr (Maybe Bool)) where + having expr = Q $ W.tell mempty { sdHavingClause = Where (coerce expr) } -- | Add a locking clause to the query. Please read -- 'LockingKind' documentation and your RDBMS manual.