packages feed

opaleye 0.10.1.1 → 0.10.2.0

raw patch · 37 files changed

+251/−154 lines, 37 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Opaleye.Internal.HaskellDB.PrimQuery: data Aggr
- Opaleye.Internal.HaskellDB.PrimQuery: data OrderExpr
- Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Read.Read Opaleye.Internal.HaskellDB.PrimQuery.Aggr
- Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Read.Read Opaleye.Internal.HaskellDB.PrimQuery.OrderExpr
- Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Show.Show Opaleye.Internal.HaskellDB.PrimQuery.Aggr
- Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Show.Show Opaleye.Internal.HaskellDB.PrimQuery.OrderExpr
+ Opaleye.Field: unsafeCast :: String -> Field_ n a -> Field_ n b
+ Opaleye.Internal.Aggregate: makeAggrExplicit :: Unpackspec a a' -> AggrOp -> Aggregator a (Field_ n b)
+ Opaleye.Internal.Aggregate: withinGroup :: Order a -> Aggregator a b -> Aggregator a b
+ Opaleye.Internal.HaskellDB.PrimQuery: Aggregate :: Aggr' a -> Aggregate' a
+ Opaleye.Internal.HaskellDB.PrimQuery: [aggrExprs] :: Aggr' a -> ![a]
+ Opaleye.Internal.HaskellDB.PrimQuery: [aggrGroup] :: Aggr' a -> ![OrderExpr' a]
+ Opaleye.Internal.HaskellDB.PrimQuery: data Aggr' a
+ Opaleye.Internal.HaskellDB.PrimQuery: data Aggregate' a
+ Opaleye.Internal.HaskellDB.PrimQuery: data OrderExpr' a
+ Opaleye.Internal.HaskellDB.PrimQuery: instance Data.Foldable.Foldable Opaleye.Internal.HaskellDB.PrimQuery.Aggr'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance Data.Foldable.Foldable Opaleye.Internal.HaskellDB.PrimQuery.Aggregate'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance Data.Foldable.Foldable Opaleye.Internal.HaskellDB.PrimQuery.OrderExpr'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance Data.Traversable.Traversable Opaleye.Internal.HaskellDB.PrimQuery.Aggr'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance Data.Traversable.Traversable Opaleye.Internal.HaskellDB.PrimQuery.Aggregate'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance Data.Traversable.Traversable Opaleye.Internal.HaskellDB.PrimQuery.OrderExpr'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Base.Functor Opaleye.Internal.HaskellDB.PrimQuery.Aggr'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Base.Functor Opaleye.Internal.HaskellDB.PrimQuery.Aggregate'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Base.Functor Opaleye.Internal.HaskellDB.PrimQuery.OrderExpr'
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Read.Read a => GHC.Read.Read (Opaleye.Internal.HaskellDB.PrimQuery.Aggr' a)
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Read.Read a => GHC.Read.Read (Opaleye.Internal.HaskellDB.PrimQuery.Aggregate' a)
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Read.Read a => GHC.Read.Read (Opaleye.Internal.HaskellDB.PrimQuery.OrderExpr' a)
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Show.Show a => GHC.Show.Show (Opaleye.Internal.HaskellDB.PrimQuery.Aggr' a)
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Show.Show a => GHC.Show.Show (Opaleye.Internal.HaskellDB.PrimQuery.Aggregate' a)
+ Opaleye.Internal.HaskellDB.PrimQuery: instance GHC.Show.Show a => GHC.Show.Show (Opaleye.Internal.HaskellDB.PrimQuery.OrderExpr' a)
+ Opaleye.Internal.HaskellDB.PrimQuery: type Aggregate = Aggregate' PrimExpr
+ Opaleye.Internal.HaskellDB.PrimQuery: type OrderExpr = OrderExpr' PrimExpr
+ Opaleye.Internal.HaskellDB.Sql.Default: showAggrOpFunction :: AggrOp -> String
+ Opaleye.Internal.MaybeFields: isJustAnd :: MaybeFields a -> (a -> Field SqlBool) -> Field SqlBool
+ Opaleye.Internal.PrimQuery: Materialized :: Materialized
+ Opaleye.Internal.PrimQuery: NotMaterialized :: Materialized
+ Opaleye.Internal.PrimQuery: data Materialized
+ Opaleye.Internal.PrimQuery: instance GHC.Show.Show Opaleye.Internal.PrimQuery.Materialized
+ Opaleye.Internal.Print: ppMaterialized :: Materialized -> Doc
+ Opaleye.Internal.Sql: Materialized :: Materialized
+ Opaleye.Internal.Sql: NotMaterialized :: Materialized
+ Opaleye.Internal.Sql: [wMaterialized] :: With -> Maybe Materialized
+ Opaleye.Internal.Sql: data Materialized
+ Opaleye.Internal.Sql: instance GHC.Show.Show Opaleye.Internal.Sql.Materialized
+ Opaleye.MaybeFields: isJustAnd :: MaybeFields a -> (a -> Field SqlBool) -> Field SqlBool
+ Opaleye.Operators: CenturyPrecision :: TimestampPrecision
+ Opaleye.Operators: DayPrecision :: TimestampPrecision
+ Opaleye.Operators: DecadePrecision :: TimestampPrecision
+ Opaleye.Operators: HourPrecision :: TimestampPrecision
+ Opaleye.Operators: MicrosecondsPrecision :: TimestampPrecision
+ Opaleye.Operators: MillenniumPrecision :: TimestampPrecision
+ Opaleye.Operators: MillisecondsPrecision :: TimestampPrecision
+ Opaleye.Operators: MinutePrecision :: TimestampPrecision
+ Opaleye.Operators: MonthPrecision :: TimestampPrecision
+ Opaleye.Operators: QuarterPrecision :: TimestampPrecision
+ Opaleye.Operators: SecondPrecision :: TimestampPrecision
+ Opaleye.Operators: WeekPrecision :: TimestampPrecision
+ Opaleye.Operators: YearPrecision :: TimestampPrecision
+ Opaleye.Operators: data TimestampPrecision
+ Opaleye.Operators: dateTruncTimestamp :: TimestampPrecision -> Field SqlTimestamp -> Field SqlTimestamp
+ Opaleye.Operators: dateTruncTimestamptz :: TimestampPrecision -> Field SqlTimestamptz -> Field SqlTimestamptz
+ Opaleye.Operators: instance GHC.Show.Show Opaleye.Operators.TimestampPrecision
+ Opaleye.With: withMaterialized :: Default Unpackspec a a => Select a -> (Select a -> Select b) -> Select b
+ Opaleye.With: withMaterializedExplicit :: Unpackspec a a -> Select a -> (Select a -> Select b) -> Select b
- Opaleye.Internal.Aggregate: Aggregator :: PackMap (Aggr, PrimExpr) PrimExpr a b -> Aggregator a b
+ Opaleye.Internal.Aggregate: Aggregator :: PackMap Aggregate PrimExpr a b -> Aggregator a b
- Opaleye.Internal.Aggregate: extractAggregateFields :: Tag -> (m, PrimExpr) -> PM [((Symbol, (m, Symbol)), (Symbol, PrimExpr))] PrimExpr
+ Opaleye.Internal.Aggregate: extractAggregateFields :: Traversable t => Tag -> t PrimExpr -> PM [((Symbol, t Symbol), Bindings PrimExpr)] PrimExpr
- Opaleye.Internal.Aggregate: runAggregator :: Applicative f => Aggregator a b -> ((Aggr, PrimExpr) -> f PrimExpr) -> a -> f b
+ Opaleye.Internal.Aggregate: runAggregator :: Applicative f => Aggregator a b -> (Aggregate -> f PrimExpr) -> a -> f b
- Opaleye.Internal.HaskellDB.PrimQuery: Aggr :: !AggrOp -> ![OrderExpr] -> !AggrDistinct -> !Maybe PrimExpr -> Aggr
+ Opaleye.Internal.HaskellDB.PrimQuery: Aggr :: !AggrOp -> ![a] -> ![OrderExpr' a] -> !AggrDistinct -> ![OrderExpr' a] -> !Maybe PrimExpr -> Aggr' a
- Opaleye.Internal.HaskellDB.PrimQuery: AggrExpr :: AggrDistinct -> AggrOp -> PrimExpr -> [OrderExpr] -> Maybe PrimExpr -> PrimExpr
+ Opaleye.Internal.HaskellDB.PrimQuery: AggrExpr :: Aggr' PrimExpr -> PrimExpr
- Opaleye.Internal.HaskellDB.PrimQuery: AggrStringAggr :: PrimExpr -> AggrOp
+ Opaleye.Internal.HaskellDB.PrimQuery: AggrStringAggr :: AggrOp
- Opaleye.Internal.HaskellDB.PrimQuery: GroupBy :: Aggr
+ Opaleye.Internal.HaskellDB.PrimQuery: GroupBy :: a -> Aggregate' a
- Opaleye.Internal.HaskellDB.PrimQuery: OrderExpr :: OrderOp -> PrimExpr -> OrderExpr
+ Opaleye.Internal.HaskellDB.PrimQuery: OrderExpr :: OrderOp -> a -> OrderExpr' a
- Opaleye.Internal.HaskellDB.PrimQuery: WndwAggregate :: AggrOp -> PrimExpr -> WndwOp
+ Opaleye.Internal.HaskellDB.PrimQuery: WndwAggregate :: AggrOp -> [PrimExpr] -> WndwOp
- Opaleye.Internal.HaskellDB.PrimQuery: [aggrDistinct] :: Aggr -> !AggrDistinct
+ Opaleye.Internal.HaskellDB.PrimQuery: [aggrDistinct] :: Aggr' a -> !AggrDistinct
- Opaleye.Internal.HaskellDB.PrimQuery: [aggrFilter] :: Aggr -> !Maybe PrimExpr
+ Opaleye.Internal.HaskellDB.PrimQuery: [aggrFilter] :: Aggr' a -> !Maybe PrimExpr
- Opaleye.Internal.HaskellDB.PrimQuery: [aggrOp] :: Aggr -> !AggrOp
+ Opaleye.Internal.HaskellDB.PrimQuery: [aggrOp] :: Aggr' a -> !AggrOp
- Opaleye.Internal.HaskellDB.PrimQuery: [aggrOrder] :: Aggr -> ![OrderExpr]
+ Opaleye.Internal.HaskellDB.PrimQuery: [aggrOrder] :: Aggr' a -> ![OrderExpr' a]
- Opaleye.Internal.HaskellDB.Sql: AggrFunSqlExpr :: String -> [SqlExpr] -> [(SqlExpr, SqlOrder)] -> SqlDistinct -> Maybe SqlExpr -> SqlExpr
+ Opaleye.Internal.HaskellDB.Sql: AggrFunSqlExpr :: String -> [SqlExpr] -> [(SqlExpr, SqlOrder)] -> SqlDistinct -> [(SqlExpr, SqlOrder)] -> Maybe SqlExpr -> SqlExpr
- Opaleye.Internal.HaskellDB.Sql.Default: showAggrOp :: SqlGenerator -> AggrOp -> PrimExpr -> (String, [SqlExpr])
+ Opaleye.Internal.HaskellDB.Sql.Default: showAggrOp :: SqlGenerator -> AggrOp -> [PrimExpr] -> (String, [SqlExpr])
- Opaleye.Internal.PrimQuery: Aggregate :: Bindings (Aggr, Symbol) -> PrimQuery' a -> PrimQuery' a
+ Opaleye.Internal.PrimQuery: Aggregate :: Bindings (Aggregate' Symbol) -> PrimQuery' a -> PrimQuery' a
- Opaleye.Internal.PrimQuery: PrimQueryFold :: p' -> (a -> p') -> (TableIdentifier -> Bindings PrimExpr -> p') -> (NonEmpty (Lateral, p) -> [PrimExpr] -> p') -> (Bindings (Aggr, Symbol) -> p -> p') -> (Bindings (WndwOp, Partition) -> p -> p') -> (Maybe (NonEmpty PrimExpr) -> [OrderExpr] -> p -> p') -> (LimitOp -> p -> p') -> (JoinType -> PrimExpr -> (Lateral, p) -> (Lateral, p) -> p') -> (SemijoinType -> p -> p -> p') -> (Symbol -> p -> p') -> ([Symbol] -> NonEmpty [PrimExpr] -> p') -> (BinOp -> (p, p) -> p') -> (String -> p -> p') -> (PrimExpr -> [Symbol] -> p') -> (Bool -> Bindings PrimExpr -> p -> p') -> (p -> p') -> (Recursive -> Symbol -> [Symbol] -> p -> p -> p') -> PrimQueryFoldP a p p'
+ Opaleye.Internal.PrimQuery: PrimQueryFold :: p' -> (a -> p') -> (TableIdentifier -> Bindings PrimExpr -> p') -> (NonEmpty (Lateral, p) -> [PrimExpr] -> p') -> (Bindings (Aggregate' Symbol) -> p -> p') -> (Bindings (WndwOp, Partition) -> p -> p') -> (Maybe (NonEmpty PrimExpr) -> [OrderExpr] -> p -> p') -> (LimitOp -> p -> p') -> (JoinType -> PrimExpr -> (Lateral, p) -> (Lateral, p) -> p') -> (SemijoinType -> p -> p -> p') -> (Symbol -> p -> p') -> ([Symbol] -> NonEmpty [PrimExpr] -> p') -> (BinOp -> (p, p) -> p') -> (String -> p -> p') -> (PrimExpr -> [Symbol] -> p') -> (Bool -> Bindings PrimExpr -> p -> p') -> (p -> p') -> (Recursive -> Maybe Materialized -> Symbol -> [Symbol] -> p -> p -> p') -> PrimQueryFoldP a p p'
- Opaleye.Internal.PrimQuery: With :: Recursive -> Symbol -> [Symbol] -> PrimQuery' a -> PrimQuery' a -> PrimQuery' a
+ Opaleye.Internal.PrimQuery: With :: Recursive -> Maybe Materialized -> Symbol -> [Symbol] -> PrimQuery' a -> PrimQuery' a -> PrimQuery' a
- Opaleye.Internal.PrimQuery: [aggregate] :: PrimQueryFoldP a p p' -> Bindings (Aggr, Symbol) -> p -> p'
+ Opaleye.Internal.PrimQuery: [aggregate] :: PrimQueryFoldP a p p' -> Bindings (Aggregate' Symbol) -> p -> p'
- Opaleye.Internal.PrimQuery: [with] :: PrimQueryFoldP a p p' -> Recursive -> Symbol -> [Symbol] -> p -> p -> p'
+ Opaleye.Internal.PrimQuery: [with] :: PrimQueryFoldP a p p' -> Recursive -> Maybe Materialized -> Symbol -> [Symbol] -> p -> p -> p'
- Opaleye.Internal.Sql: With :: SqlTable -> [SqlColumn] -> Recursive -> Select -> Select -> With
+ Opaleye.Internal.Sql: With :: SqlTable -> [SqlColumn] -> Recursive -> Maybe Materialized -> Select -> Select -> With
- Opaleye.Internal.Sql: aggrExpr :: Aggr -> PrimExpr -> PrimExpr
+ Opaleye.Internal.Sql: aggrExpr :: Aggregate -> PrimExpr
- Opaleye.Internal.Sql: aggregate :: Bindings (Aggr, Symbol) -> Select -> Select
+ Opaleye.Internal.Sql: aggregate :: Bindings (Aggregate' Symbol) -> Select -> Select
- Opaleye.Internal.Sql: with :: Recursive -> Symbol -> [Symbol] -> Select -> Select -> Select
+ Opaleye.Internal.Sql: with :: Recursive -> Maybe Materialized -> Symbol -> [Symbol] -> Select -> Select -> Select

Files

CHANGELOG.md view
@@ -1,3 +1,12 @@+## 0.10.2.0++* Added `isJustAnd`++* Add `withMaterialized` (thanks to Shane O'Brien)++* Added 'dateTruncTimestamp` and `dateTruncTimestamptz` (thanks to+  @njaremko)+ ## 0.10.1.1  * Fix bugs in `WITH`.  See
Doc/Tutorial/TutorialBasic.lhs view
@@ -171,8 +171,7 @@ Projection gives us our first example of using "do notation" to write Opaleye queries. -Here we run the `personSelect` passing in () to signify "zero-arguments".  We pattern match on the results and return only the+Here we run the `personSelect`, pattern match on the results and return only the fields we are interested in.  > nameAge :: Select (Field SqlText, Field SqlInt4)@@ -644,9 +643,7 @@ Outer join ========== -Opaleye supports left joins.  (Full outer joins and right joins are-left to be added as a simple starter project for a new Opaleye-contributor!)+Opaleye supports left joins.  Because left joins can change non-nullable fields into nullable fields we have to make sure the type of the output supports
Doc/Tutorial/TutorialBasicMonomorphic.lhs view
@@ -7,7 +7,7 @@ > import           Prelude hiding (sum) > > import           Opaleye (Field, FieldNullable,->                          Table, table, selectTable,+>                          Table, table, tableWithSchema, selectTable, >                          tableField, >                          Select, (.==), >                          aggregate, groupBy,@@ -69,9 +69,9 @@  > personTable' :: Table (Field SqlText, Field SqlInt4, Field SqlText) >                       (Field SqlText, Field SqlInt4, Field SqlText)-> personTable' = table "personTable" (p3 ( tableField "name"->                                        , tableField "age"->                                        , tableField "address" ))+> personTable' = tableWithSchema "myschema" "personTable" (p3 ( tableField "name"+>                                                             , tableField "age"+>                                                             , tableField "address" ))  By default, the table `"personTable"` is looked up in PostgreSQL's default `"public"` schema. If we wanted to specify a different schema we
README.md view
@@ -1,4 +1,4 @@-# Brief introduction to Opaleye [![Hackage version](https://img.shields.io/hackage/v/opaleye.svg?label=Hackage)](https://hackage.haskell.org/package/opaleye) [![Build status](https://img.shields.io/github/workflow/status/tomjaguarpaw/haskell-opaleye/ci/master.svg)](https://github.com/tomjaguarpaw/haskell-opaleye/actions)+# Brief introduction to Opaleye [![Hackage version](https://img.shields.io/hackage/v/opaleye.svg?label=Hackage)](https://hackage.haskell.org/package/opaleye)[![Stackage version](https://www.stackage.org/package/opaleye/badge/nightly?label=Stackage)](https://www.stackage.org/package/opaleye)[![Build status](https://img.shields.io/github/actions/workflow/status/tomjaguarpaw/haskell-opaleye/ci.yml?branch=master)](https://github.com/tomjaguarpaw/haskell-opaleye/actions)  Opaleye is a Haskell library that provides an SQL-generating embedded domain specific language for targeting Postgres.  You need Opaleye if
Test/Opaleye/Test/Arbitrary.hs view
@@ -16,7 +16,7 @@ import qualified Opaleye.Exists as OE import qualified Opaleye.Join as OJ -import           Control.Applicative (pure, (<$>), (<*>), liftA2)+import           Control.Applicative (liftA2) import qualified Control.Arrow as Arrow import           Control.Arrow ((<<<)) import           Control.Category ((.), id)
Test/Opaleye/Test/Fields.hs view
@@ -18,7 +18,6 @@ import qualified Opaleye.Internal.Values as OV  import           Control.Arrow ((>>>))-import           Control.Applicative (pure) import qualified Data.Profunctor.Product.Default as D import qualified Data.Profunctor as P import qualified Data.Profunctor.Product as PP
Test/QuickCheck.hs view
@@ -20,7 +20,6 @@ import qualified Opaleye.Exists as OE  import qualified Database.PostgreSQL.Simple as PGS-import           Control.Applicative (Applicative, pure, (<$>), (<*>)) import qualified Control.Arrow as Arrow import           Control.Arrow ((<<<)) import           Control.Category (Category, (.), id)
Test/Test.hs view
@@ -6,7 +6,7 @@ module Main where  import qualified Configuration.Dotenv             as Dotenv-import           Control.Applicative              ((<$>), (<*>), (<|>))+import           Control.Applicative              ((<|>)) import qualified Control.Applicative              as A import           Control.Arrow                    ((&&&), (***), (<<<), (>>>)) import qualified Control.Arrow                    as Arr@@ -15,7 +15,6 @@ import qualified Data.Function                    as F import           Data.Int (Int32) import qualified Data.List                        as L-import           Data.Monoid                      ((<>)) import qualified Data.Ord                         as Ord import qualified Data.Profunctor                  as P import qualified Data.Profunctor.Product          as PP
opaleye.cabal view
@@ -1,6 +1,6 @@ name:            opaleye copyright:       Copyright (c) 2014-2018 Purely Agile Limited; 2019-2023 Tom Ellis-version:         0.10.1.1+version:         0.10.2.0 synopsis:        An SQL-generating DSL targeting PostgreSQL description:     An SQL-generating DSL targeting PostgreSQL.  Allows                  Postgres queries to be written within Haskell in a@@ -27,7 +27,7 @@   hs-source-dirs: src   build-depends:       aeson               >= 0.6     && < 2.3-    , base                >= 4.9     && < 4.19+    , base                >= 4.9     && < 4.20     , base16-bytestring   >= 0.1.1.6 && < 1.1     , case-insensitive    >= 1.2     && < 1.3     , bytestring          >= 0.10    && < 0.12@@ -38,7 +38,7 @@     , profunctors         >= 4.0     && < 5.7     , scientific          >= 0.3     && < 0.4     , semigroups          >= 0.13    && < 0.21-    , text                >= 0.11    && < 2.1+    , text                >= 0.11    && < 2.2     , transformers        >= 0.3     && < 0.7     , time-compat         >= 1.9.5   && < 1.12     , time-locale-compat  >= 0.1     && < 0.2
src/Opaleye/Aggregate.hs view
@@ -35,19 +35,18 @@        , countRows        ) where -import           Control.Applicative (pure) import           Data.Profunctor     (lmap) import qualified Data.Profunctor as P  import qualified Opaleye.Internal.Aggregate as A import           Opaleye.Internal.Aggregate (Aggregator, orderAggregate)-import qualified Opaleye.Internal.Column as IC import           Opaleye.Internal.MaybeFields (MaybeFields (MaybeFields)) import qualified Opaleye.Internal.QueryArr as Q import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ import qualified Opaleye.Internal.Operators as O import qualified Opaleye.Internal.PackMap as PM import qualified Opaleye.Internal.Tag as Tag+import qualified Opaleye.Internal.Unpackspec as U  import qualified Opaleye.Field     as F import qualified Opaleye.Order     as Ord@@ -106,11 +105,11 @@ -- | Aggregate only distinct values distinctAggregator :: Aggregator a b -> Aggregator a b distinctAggregator (A.Aggregator (PM.PackMap pm)) =-  A.Aggregator (PM.PackMap (\f c -> pm (f . P.first' setDistinct) c))+  A.Aggregator (PM.PackMap (\f c -> pm (f . setDistinct) c))   where-    setDistinct HPQ.GroupBy = HPQ.GroupBy-    setDistinct aggr =-      aggr+    setDistinct (HPQ.GroupBy expr) = HPQ.GroupBy expr+    setDistinct (HPQ.Aggregate aggr) =+      HPQ.Aggregate aggr         { HPQ.aggrDistinct = HPQ.AggrDistinct         } @@ -195,7 +194,10 @@  stringAgg :: F.Field T.SqlText           -> Aggregator (F.Field T.SqlText) (F.Field T.SqlText)-stringAgg = A.makeAggr' . Just . HPQ.AggrStringAggr . IC.unColumn+stringAgg delimiter =+  A.makeAggrExplicit+    (U.unpackspecField <* lmap (const delimiter) U.unpackspecField)+    HPQ.AggrStringAggr  -- | Count the number of rows in a query.  This is different from -- 'aggregate' 'count' because it always returns exactly one row, even
src/Opaleye/Field.hs view
@@ -20,7 +20,8 @@   Field,   FieldNullable,   Nullability(..),-  -- * Coercing fields+  -- * Casting fields+  C.unsafeCast,   unsafeCoerceField,   -- * Working with @NULL@   -- | Instead of working with @NULL@ you are recommended to use
src/Opaleye/FunctionalJoin.hs view
@@ -10,9 +10,6 @@   fullJoinF,   ) where -import           Control.Applicative             ((<$>), (<*>))-import           Control.Arrow                   ((<<<))- import qualified Data.Profunctor.Product.Default as D import qualified Data.Profunctor.Product         as PP 
src/Opaleye/Internal/Aggregate.hs view
@@ -1,7 +1,9 @@ {-# LANGUAGE TupleSections #-} module Opaleye.Internal.Aggregate where -import           Control.Applicative (Applicative, liftA2, pure, (<*>))+import           Control.Applicative (liftA2)+import           Data.Foldable (toList)+import           Data.Traversable (for)  import qualified Data.Profunctor as P import qualified Data.Profunctor.Product as PP@@ -12,6 +14,7 @@ import qualified Opaleye.Internal.PackMap as PM import qualified Opaleye.Internal.PrimQuery as PQ import qualified Opaleye.Internal.Tag as T+import qualified Opaleye.Internal.Unpackspec as U import qualified Opaleye.SqlTypes as T  import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ@@ -30,19 +33,28 @@ takes a list of @a@ and returns a single value of type @b@. -} newtype Aggregator a b =-  Aggregator (PM.PackMap (HPQ.Aggr, HPQ.PrimExpr) HPQ.PrimExpr a b)+  Aggregator (PM.PackMap HPQ.Aggregate HPQ.PrimExpr a b)  makeAggr' :: Maybe HPQ.AggrOp -> Aggregator (C.Field_ n a) (C.Field_ n' b) makeAggr' mAggrOp = P.dimap C.unColumn C.Column $ Aggregator (PM.PackMap-  (\f e -> f (aggr, e)))+  (\f e -> f (aggr e)))   where     aggr = case mAggrOp of       Nothing -> HPQ.GroupBy-      Just op -> HPQ.Aggr op [] HPQ.AggrAll Nothing+      Just op -> \e -> HPQ.Aggregate (HPQ.Aggr op [e] [] HPQ.AggrAll [] Nothing)  makeAggr :: HPQ.AggrOp -> Aggregator (C.Field_ n a) (C.Field_ n' b) makeAggr = makeAggr' . Just +makeAggrExplicit :: U.Unpackspec a a' -> HPQ.AggrOp -> Aggregator a (C.Field_ n b)+makeAggrExplicit unpackspec op =+  C.Column <$> Aggregator (PM.PackMap (\f e -> f (aggr e)))+  where+    aggr a = HPQ.Aggregate (HPQ.Aggr op exprs [] HPQ.AggrAll [] Nothing)+      where+        exprs = U.collectPEs unpackspec a++ -- | Order the values within each aggregation in `Aggregator` using -- the given ordering. This is only relevant for aggregations that -- depend on the order they get their elements, like@@ -81,18 +93,18 @@  orderAggregate :: O.Order a -> Aggregator a b -> Aggregator a b orderAggregate o (Aggregator (PM.PackMap pm)) = Aggregator (PM.PackMap-  (\f c -> pm (f . P.first' (setOrder (O.orderExprs c o))) c))+  (\f c -> pm (f . setOrder (O.orderExprs c o)) c))   where-    setOrder _ HPQ.GroupBy = HPQ.GroupBy-    setOrder order aggr =-      aggr+    setOrder _ (HPQ.GroupBy e) = HPQ.GroupBy e+    setOrder order (HPQ.Aggregate aggr) =+      HPQ.Aggregate aggr         { HPQ.aggrOrder = order         }  runAggregator   :: Applicative f   => Aggregator a b-  -> ((HPQ.Aggr, HPQ.PrimExpr) -> f HPQ.PrimExpr)+  -> (HPQ.Aggregate -> f HPQ.PrimExpr)   -> a -> f b runAggregator (Aggregator a) = PM.traversePM a @@ -127,25 +139,32 @@           PM.run (runAggregator agg (extractAggregateFields t0) c0)          projPEs = map fst projPEs_inners-        inners  = map snd projPEs_inners+        inners  = concatMap snd projPEs_inners          primQ' = PQ.Aggregate projPEs (PQ.Rebind True inners primQ)  extractAggregateFields-  :: T.Tag-  -> (m, HPQ.PrimExpr)+  :: Traversable t+  => T.Tag+  -> (t HPQ.PrimExpr)   -> PM.PM [((HPQ.Symbol,-              (m, HPQ.Symbol)),-              (HPQ.Symbol, HPQ.PrimExpr))]+              t HPQ.Symbol),+              PQ.Bindings HPQ.PrimExpr)]            HPQ.PrimExpr-extractAggregateFields tag (m, pe) = do+extractAggregateFields tag agg = do   i <- PM.new    let souter = HPQ.Symbol ("result" ++ i) tag-      sinner = HPQ.Symbol ("inner" ++ i) tag -  PM.write ((souter, (m, sinner)), (sinner, pe))+  bindings <- for agg $ \pe -> do+    j <- PM.new+    let sinner = HPQ.Symbol ("inner" ++ j) tag+    pure (sinner, pe) +  let agg' = fmap fst bindings++  PM.write ((souter, agg'), toList bindings)+   pure (HPQ.AttrExpr souter)  unsafeMax :: Aggregator (C.Field a) (C.Field a)@@ -169,12 +188,12 @@ filterWhereInternal maybeField predicate aggregator =   case liftA2 maybeField true aggregator of     Aggregator (PM.PackMap pm) ->-      Aggregator (PM.PackMap (\f c -> pm (f . P.first' (setFilter c)) c))+      Aggregator (PM.PackMap (\f c -> pm (f . setFilter c) c))   where     true = P.lmap (const (T.sqlBool True)) (makeAggr HPQ.AggrBoolAnd)-    setFilter _ HPQ.GroupBy = HPQ.GroupBy-    setFilter row aggr =-      aggr+    setFilter _ (HPQ.GroupBy e) = HPQ.GroupBy e+    setFilter row (HPQ.Aggregate aggr) =+      HPQ.Aggregate aggr         { HPQ.aggrFilter = aggrFilter'         }       where@@ -182,6 +201,16 @@         aggrFilter' = Just $ case HPQ.aggrFilter aggr of           Nothing -> cond'           Just cond -> HPQ.BinExpr HPQ.OpAnd cond cond'++withinGroup :: O.Order a -> Aggregator a b -> Aggregator a b+withinGroup o (Aggregator (PM.PackMap pm)) = Aggregator (PM.PackMap+  (\f c -> pm (f . setOrder (O.orderExprs c o)) c))+  where+    setOrder _ (HPQ.GroupBy e) = HPQ.GroupBy e+    setOrder order (HPQ.Aggregate aggr) =+      HPQ.Aggregate aggr+        { HPQ.aggrGroup = order+        }  -- { Boilerplate instances 
src/Opaleye/Internal/Binary.hs view
@@ -17,7 +17,6 @@ import qualified Data.Profunctor.Product as PP import           Data.Profunctor.Product.Default (Default, def) -import           Control.Applicative (Applicative, pure, (<*>)) import           Control.Arrow ((***))  extractBinaryFields :: T.Tag -> (HPQ.PrimExpr, HPQ.PrimExpr)
src/Opaleye/Internal/Constant.hs view
@@ -25,9 +25,6 @@ import qualified Data.Profunctor.Product.Default as D import qualified Data.Profunctor                 as P -import           Control.Applicative (Applicative, pure, (<*>))-import           Data.Functor                    ((<$>))- import qualified Database.PostgreSQL.Simple.Range as R import           Database.PostgreSQL.Simple.Newtypes ( Aeson, getAeson ) 
src/Opaleye/Internal/Distinct.hs view
@@ -10,8 +10,6 @@ import           Opaleye.Field (Field_) import           Opaleye.Aggregate (Aggregator, groupBy, aggregate) -import           Control.Applicative (Applicative, pure, (<*>))- import qualified Data.Profunctor as P import qualified Data.Profunctor.Product as PP import           Data.Profunctor.Product.Default (Default, def)
src/Opaleye/Internal/HaskellDB/PrimQuery.hs view
@@ -2,6 +2,8 @@ --                HWT Group (c) 2003, haskelldb-users@lists.sourceforge.net -- License     :  BSD-style +{-# LANGUAGE DeriveTraversable #-}+ module Opaleye.Internal.HaskellDB.PrimQuery where  import qualified Opaleye.Internal.Tag as T@@ -22,7 +24,7 @@                 | CompositeExpr     PrimExpr Attribute -- ^ Composite Type Query                 | BinExpr   BinOp PrimExpr PrimExpr                 | UnExpr    UnOp PrimExpr-                | AggrExpr  AggrDistinct AggrOp PrimExpr [OrderExpr] (Maybe PrimExpr)+                | AggrExpr  (Aggr' PrimExpr)                 | WndwExpr  WndwOp Partition                 | ConstExpr Literal                 | CaseExpr [(PrimExpr,PrimExpr)] PrimExpr@@ -80,26 +82,33 @@ data AggrOp     = AggrCount | AggrSum | AggrAvg | AggrMin | AggrMax                 | AggrStdDev | AggrStdDevP | AggrVar | AggrVarP                 | AggrBoolOr | AggrBoolAnd | AggrArr | JsonArr-                | AggrStringAggr PrimExpr+                | AggrStringAggr                 | AggrOther String                 deriving (Show,Read)  data AggrDistinct = AggrDistinct | AggrAll                   deriving (Eq,Show,Read) -data Aggr-  = GroupBy-  | Aggr-      { aggrOp :: !AggrOp-      , aggrOrder :: ![OrderExpr]-      , aggrDistinct :: !AggrDistinct-      , aggrFilter :: !(Maybe PrimExpr)-      }-  deriving (Show, Read)+type Aggregate = Aggregate' PrimExpr -data OrderExpr = OrderExpr OrderOp PrimExpr-               deriving (Show,Read)+data Aggregate' a = GroupBy a | Aggregate (Aggr' a)+  deriving (Functor, Foldable, Traversable, Show, Read) +data Aggr' a = Aggr+  { aggrOp :: !AggrOp+  , aggrExprs :: ![a]+  , aggrOrder :: ![OrderExpr' a]+  , aggrDistinct :: !AggrDistinct+  , aggrGroup :: ![OrderExpr' a]+  , aggrFilter :: !(Maybe PrimExpr)+  }+  deriving (Functor, Foldable, Traversable, Show, Read)++type OrderExpr = OrderExpr' PrimExpr++data OrderExpr' a = OrderExpr OrderOp a+  deriving (Functor, Foldable, Traversable, Show, Read)+ data OrderNulls = NullsFirst | NullsLast                 deriving (Show,Read) @@ -125,7 +134,7 @@   | WndwFirstValue PrimExpr   | WndwLastValue PrimExpr   | WndwNthValue PrimExpr PrimExpr-  | WndwAggregate AggrOp PrimExpr+  | WndwAggregate AggrOp [PrimExpr]   deriving (Show,Read)  data Partition = Partition
src/Opaleye/Internal/HaskellDB/Sql.hs view
@@ -52,7 +52,7 @@              | PrefixSqlExpr  String SqlExpr              | PostfixSqlExpr String SqlExpr              | FunSqlExpr     String [SqlExpr]-             | AggrFunSqlExpr String [SqlExpr] [(SqlExpr, SqlOrder)] SqlDistinct (Maybe SqlExpr) -- ^ Aggregate functions separate from normal functions.+             | AggrFunSqlExpr String [SqlExpr] [(SqlExpr, SqlOrder)] SqlDistinct [(SqlExpr, SqlOrder)] (Maybe SqlExpr) -- ^ Aggregate functions separate from normal functions.              | WndwFunSqlExpr String [SqlExpr] SqlPartition              | ConstSqlExpr   String              | CaseSqlExpr    (NEL.NonEmpty (SqlExpr,SqlExpr)) SqlExpr
src/Opaleye/Internal/HaskellDB/Sql/Default.hs view
@@ -2,9 +2,9 @@ --                HWT Group (c) 2003, haskelldb-users@lists.sourceforge.net -- License     :  BSD-style -module Opaleye.Internal.HaskellDB.Sql.Default  where+{-# LANGUAGE LambdaCase #-} -import Control.Applicative ((<$>))+module Opaleye.Internal.HaskellDB.Sql.Default  where  import Opaleye.Internal.HaskellDB.PrimQuery import qualified Opaleye.Internal.HaskellDB.PrimQuery as PQ@@ -130,21 +130,16 @@                                 UnOpFun     -> FunSqlExpr op' [e']                                 UnOpPrefix  -> PrefixSqlExpr op' (ParensSqlExpr e')                                 UnOpPostfix -> PostfixSqlExpr op' (ParensSqlExpr e')-      -- TODO: The current arrangement whereby the delimiter parameter-      -- of string_agg is in the AggrStringAggr constructor, but the-      -- parameter being aggregated is not, seems unsatisfactory-      -- because it leads to a non-uniformity of treatment, as seen-      -- below.  Perhaps we should have just `AggrExpr AggrOp` and-      -- always put the `PrimExpr` in the `AggrOp`.-      AggrExpr distinct op e ord mfilter ->+      AggrExpr (Aggr op e ord distinct group mfilter) ->         let           (op', e') = showAggrOp gen op e           ord' = toSqlOrder gen <$> ord           distinct' = case distinct of             AggrDistinct -> SqlDistinct             AggrAll      -> SqlNotDistinct+          group' = toSqlOrder gen <$> group           mfilter' = sqlExpr gen <$> mfilter-         in AggrFunSqlExpr op' e' ord' distinct' mfilter'+         in AggrFunSqlExpr op' e' ord' distinct' group' mfilter'       WndwExpr op window  -> let (op', e') = showWndwOp gen op                                  window' = toSqlPartition gen window                               in WndwFunSqlExpr op' e' window'@@ -223,23 +218,27 @@ sqlUnOp  (UnOpOther s) = (s, UnOpFun)  -showAggrOp :: SqlGenerator -> AggrOp -> PrimExpr -> (String, [SqlExpr])-showAggrOp gen op arg = case op of-  AggrCount -> ("COUNT", [sqlExpr gen arg])-  AggrSum -> ("SUM", [sqlExpr gen arg])-  AggrAvg -> ("AVG", [sqlExpr gen arg])-  AggrMin -> ("MIN", [sqlExpr gen arg])-  AggrMax -> ("MAX", [sqlExpr gen arg])-  AggrStdDev -> ("StdDev", [sqlExpr gen arg])-  AggrStdDevP -> ("StdDevP", [sqlExpr gen arg])-  AggrVar -> ("Var", [sqlExpr gen arg])-  AggrVarP -> ("VarP", [sqlExpr gen arg])-  AggrBoolAnd -> ("BOOL_AND", [sqlExpr gen arg])-  AggrBoolOr -> ("BOOL_OR", [sqlExpr gen arg])-  AggrArr -> ("ARRAY_AGG", [sqlExpr gen arg])-  JsonArr -> ("JSON_AGG", [sqlExpr gen arg])-  AggrStringAggr sep -> ("STRING_AGG", [sqlExpr gen arg, sqlExpr gen sep])-  AggrOther s -> (s, [sqlExpr gen arg])+showAggrOp :: SqlGenerator -> AggrOp -> [PrimExpr] -> (String, [SqlExpr])+showAggrOp gen op args = (showAggrOpFunction op, map (sqlExpr gen) args)+++showAggrOpFunction :: AggrOp -> String+showAggrOpFunction = \case+  AggrCount -> "COUNT"+  AggrSum -> "SUM"+  AggrAvg -> "AVG"+  AggrMin -> "MIN"+  AggrMax -> "MAX"+  AggrStdDev -> "StdDev"+  AggrStdDevP -> "StdDevP"+  AggrVar -> "Var"+  AggrVarP -> "VarP"+  AggrBoolAnd -> "BOOL_AND"+  AggrBoolOr -> "BOOL_OR"+  AggrArr -> "ARRAY_AGG"+  JsonArr -> "JSON_AGG"+  AggrStringAggr -> "STRING_AGG"+  AggrOther s -> s   showWndwOp :: SqlGenerator -> WndwOp -> (String, [SqlExpr])
src/Opaleye/Internal/HaskellDB/Sql/Print.hs view
@@ -192,9 +192,16 @@       DefaultSqlExpr         -> text "DEFAULT"       ArraySqlExpr es        -> text "ARRAY" <> brackets (commaH ppSqlExpr es)       RangeSqlExpr t s e     -> ppRange t s e-      AggrFunSqlExpr f es ord distinct mfilter -> text f <> parens (ppSqlDistinct distinct <+> commaH ppSqlExpr es <+> ppOrderBy ord) <+> case mfilter of-        Nothing -> mempty-        Just e -> text "FILTER" <+> parens (text "WHERE" <+> ppSqlExpr e)+      AggrFunSqlExpr f es ord distinct group mfilter ->+        text f <> args <+> within <+> filter+        where+          args = parens (ppSqlDistinct distinct <+> commaH ppSqlExpr es <+> ppOrderBy ord)+          within = case group of+            [] -> empty+            _ -> text "WITHIN GROUP" <+> parens (ppOrderBy group)+          filter = case mfilter of+            Nothing -> mempty+            Just e -> text "FILTER" <+> parens (text "WHERE" <+> ppSqlExpr e)       WndwFunSqlExpr f es window -> ppWindowExpr f es window       CaseSqlExpr cs el   -> text "CASE" <+> vcat (toList (fmap ppWhen cs))                              <+> text "ELSE" <+> ppSqlExpr el <+> text "END"
src/Opaleye/Internal/JSONBuildObjectFields.hs view
@@ -9,7 +9,6 @@ import Opaleye.Field (Field) import Opaleye.Internal.HaskellDB.PrimQuery (Literal (StringLit), PrimExpr (ConstExpr, FunExpr)) import Opaleye.Internal.PGTypesExternal (SqlJson)-import Data.Semigroup  -- | Combine @JSONBuildObjectFields@ using @('<>')@ newtype JSONBuildObjectFields
src/Opaleye/Internal/MaybeFields.hs view
@@ -142,6 +142,14 @@    where a `implies` b = Opaleye.Internal.Operators.not a .|| b +isJustAnd ::+  MaybeFields a ->+  (a -> Opaleye.Field.Field SqlBool) ->+  Opaleye.Field.Field SqlBool+isJustAnd ma cond = matchMaybe ma $ \case+  Nothing -> Opaleye.SqlTypes.sqlBool False+  Just a -> cond a+ optional :: SelectArr i a -> SelectArr i (MaybeFields a) optional = Opaleye.Internal.Lateral.laterally (optionalInternal (MaybeFields . isNotNull))   where isNotNull = Opaleye.Internal.Operators.not . Opaleye.Field.isNull
src/Opaleye/Internal/Optimize.hs view
@@ -8,9 +8,8 @@ import           Opaleye.Internal.Helpers   ((.:))  import qualified Data.List.NonEmpty as NEL-import           Data.Semigroup ((<>)) -import           Control.Applicative ((<$>), (<*>), liftA2, pure)+import           Control.Applicative (liftA2) import           Control.Arrow (first)  optimize :: PQ.PrimQuery' a -> PQ.PrimQuery' a@@ -73,7 +72,7 @@   , PQ.relExpr   = return .: PQ.RelExpr   , PQ.rebind    = \b -> fmap . PQ.Rebind b   , PQ.forUpdate = fmap PQ.ForUpdate-  , PQ.with      = \recursive name cols -> liftA2 (PQ.With recursive name cols)+  , PQ.with      = \recursive materialized name cols -> liftA2 (PQ.With recursive materialized name cols)   }   where -- If only the first argument is Just, do n1 on it         -- If only the second argument is Just, do n2 on it
src/Opaleye/Internal/PackMap.hs view
@@ -7,7 +7,7 @@  import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ -import           Control.Applicative (Applicative, pure, (<*>), liftA2)+import           Control.Applicative (liftA2) import           Control.Arrow (first, second) import qualified Control.Monad.Trans.State as State import           Data.Profunctor (Profunctor, dimap, rmap)
src/Opaleye/Internal/PrimQuery.hs view
@@ -5,7 +5,6 @@ import           Prelude hiding (product)  import qualified Data.List.NonEmpty as NEL-import           Data.Semigroup (Semigroup, (<>)) import qualified Opaleye.Internal.HaskellDB.Sql as HSql import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ import           Opaleye.Internal.HaskellDB.PrimQuery (Symbol)@@ -50,6 +49,9 @@ data Recursive = NonRecursive | Recursive   deriving Show +data Materialized = Materialized | NotMaterialized+  deriving Show+ aLeftJoin :: HPQ.PrimExpr -> PrimQuery -> PrimQueryArr aLeftJoin cond primQuery' = PrimQueryArr $ \lat primQueryL ->   Join LeftJoin cond (NonLateral, primQueryL) (lat, primQuery')@@ -131,7 +133,7 @@                   | Product   (NEL.NonEmpty (Lateral, PrimQuery' a)) [HPQ.PrimExpr]                   -- | The subqueries to take the product of and the                   --   restrictions to apply-                  | Aggregate (Bindings (HPQ.Aggr, HPQ.Symbol))+                  | Aggregate (Bindings (HPQ.Aggregate' HPQ.Symbol))                               (PrimQuery' a)                   | Window (Bindings (HPQ.WndwOp, HPQ.Partition)) (PrimQuery' a)                   -- | Represents both @DISTINCT ON@ and @ORDER BY@@@ -163,7 +165,7 @@                   -- ForUpdate in the future                   --                   -- https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE-                  | With Recursive Symbol [Symbol] (PrimQuery' a) (PrimQuery' a)+                  | With Recursive (Maybe Materialized) Symbol [Symbol] (PrimQuery' a) (PrimQuery' a)                  deriving Show  type PrimQuery = PrimQuery' ()@@ -176,7 +178,7 @@   , empty             :: a -> p'   , baseTable         :: TableIdentifier -> Bindings HPQ.PrimExpr -> p'   , product           :: NEL.NonEmpty (Lateral, p) -> [HPQ.PrimExpr] -> p'-  , aggregate         :: Bindings (HPQ.Aggr, HPQ.Symbol)+  , aggregate         :: Bindings (HPQ.Aggregate' HPQ.Symbol)                       -> p                       -> p'   , window            :: Bindings (HPQ.WndwOp, HPQ.Partition) -> p -> p'@@ -201,7 +203,7 @@     -- ^ A relation-valued expression   , rebind            :: Bool -> Bindings HPQ.PrimExpr -> p -> p'   , forUpdate         :: p -> p'-  , with              :: Recursive -> Symbol -> [Symbol] -> p -> p -> p'+  , with              :: Recursive -> Maybe Materialized -> Symbol -> [Symbol] -> p -> p -> p'   }  @@ -249,7 +251,7 @@   , relExpr = \pe bs -> g (relExpr f pe bs)   , rebind = \s bs p -> g (rebind f s bs (self p))   , forUpdate = \p -> g (forUpdate f (self p))-  , with = \r s ss p1 p2 -> g (with f r s ss (self p1) (self p2))+  , with = \r m s ss p1 p2 -> g (with f r m s ss (self p1) (self p2))   }  applyPrimQueryFoldF ::@@ -272,7 +274,7 @@   Exists s q -> exists f s q   Rebind star pes q -> rebind f star pes q   ForUpdate q -> forUpdate f q-  With recursive name cols a b -> with f recursive name cols a b+  With recursive materialized name cols a b -> with f recursive materialized name cols a b  primQueryFoldF ::   PrimQueryFoldP a p p' -> (PrimQuery' a -> p) -> PrimQuery' a -> p'
src/Opaleye/Internal/Print.hs view
@@ -126,12 +126,17 @@ ppRecursive Sql.Recursive = text "RECURSIVE" ppRecursive Sql.NonRecursive = mempty +ppMaterialized :: Sql.Materialized -> Doc+ppMaterialized Sql.Materialized = text "MATERIALIZED"+ppMaterialized Sql.NotMaterialized = text "NOT MATERIALIZED"+ ppWith :: With -> Doc ppWith w   =  text "WITH" <+> ppRecursive (Sql.wRecursive w)   <+> HPrint.ppTable (Sql.wTable w)   <+> parens (HPrint.commaV unColumn (Sql.wCols w))   <+> text "AS"+  <+> foldMap ppMaterialized (Sql.wMaterialized w)   $$ parens (ppSql (Sql.wWith w))   $$ ppSql (Sql.wSelect w)   where unColumn (HSql.SqlColumn col) = text col
src/Opaleye/Internal/QueryArr.hs view
@@ -18,11 +18,9 @@ import           Control.Arrow ((&&&), (***), arr, returnA) import qualified Control.Category as C import           Control.Category ((<<<), id)-import           Control.Applicative (Applicative, pure, (<*>)) import           Control.Monad.Trans.State.Strict (State, evalState, runState, state) import qualified Data.Profunctor as P import qualified Data.Profunctor.Product as PP-import           Data.Semigroup ((<>))  -- | A parametrised 'Select'.  A @SelectArr a b@ accepts an argument -- of type @a@.
src/Opaleye/Internal/RunQuery.hs view
@@ -7,7 +7,7 @@ module Opaleye.Internal.RunQuery where  import           Control.Applicative-  (Applicative, pure, (<$>), (*>), (<*>), liftA2)+  (liftA2)  import qualified Database.PostgreSQL.Simple as PGS import qualified Database.PostgreSQL.Simple.Cursor  as PGSC (Cursor)
src/Opaleye/Internal/RunQueryExternal.hs view
@@ -10,7 +10,6 @@                          IRQ.FromField,                  ) where -import           Control.Applicative (pure, (<$>)) import qualified Database.PostgreSQL.Simple as PGS import qualified Database.PostgreSQL.Simple.Cursor  as PGSC 
src/Opaleye/Internal/Sql.hs view
@@ -83,12 +83,14 @@ data Lateral = Lateral | NonLateral deriving Show data LockStrength = Update deriving Show data Recursive = NonRecursive | Recursive deriving Show+data Materialized = Materialized | NotMaterialized deriving Show data With = With {-  wTable     :: HSql.SqlTable, -- The name of the result, i.e. WITH <name> AS-  wCols      :: [HSql.SqlColumn],-  wRecursive :: Recursive,-  wWith      :: Select,-  wSelect    :: Select+  wTable        :: HSql.SqlTable, -- The name of the result, i.e. WITH <name> AS+  wCols         :: [HSql.SqlColumn],+  wRecursive    :: Recursive,+  wMaterialized :: Maybe Materialized,+  wWith         :: Select,+  wSelect       :: Select } deriving Show  @@ -158,13 +160,13 @@           PQ.Lateral    -> Lateral           PQ.NonLateral -> NonLateral -aggregate :: PQ.Bindings (HPQ.Aggr, HPQ.Symbol)+aggregate :: PQ.Bindings (HPQ.Aggregate' HPQ.Symbol)           -> Select           -> Select aggregate aggrs' s =   SelectFrom $ newSelect { attrs = SelectAttrs (ensureColumns (map attr aggrs))                          , tables = oneTable s-                         , groupBy = (Just . groupBy') aggrs }+                         , groupBy = Just (groupBy' aggrs) }   where --- Although in the presence of an aggregation function,         --- grouping by an empty list is equivalent to omitting group         --- by, the equivalence does not hold in the absence of an@@ -188,19 +190,21 @@         handleEmpty :: [HSql.SqlExpr] -> NEL.NonEmpty HSql.SqlExpr         handleEmpty = ensureColumnsGen SP.deliteral -        aggrs = (map . Arr.second . Arr.second) HPQ.AttrExpr aggrs'+        aggrs :: [(Symbol, HPQ.Aggregate)]+        aggrs = (map . Arr.second . fmap) HPQ.AttrExpr aggrs' -        groupBy' :: [(symbol, (HPQ.Aggr, HPQ.PrimExpr))]+        groupBy' :: [(symbol, HPQ.Aggregate)]                  -> NEL.NonEmpty HSql.SqlExpr         groupBy' aggs = handleEmpty $ do-          (_, (HPQ.GroupBy, e)) <- aggs+          (_, HPQ.GroupBy e) <- aggs           pure $ sqlExpr e-        attr = sqlBinding . Arr.second (uncurry aggrExpr) -aggrExpr :: HPQ.Aggr -> HPQ.PrimExpr -> HPQ.PrimExpr+        attr = sqlBinding . Arr.second aggrExpr++aggrExpr :: HPQ.Aggregate -> HPQ.PrimExpr aggrExpr = \case-  HPQ.GroupBy -> id-  HPQ.Aggr op ord distinct filter -> \e -> HPQ.AggrExpr distinct op e ord filter+  HPQ.GroupBy e -> e+  HPQ.Aggregate aggr -> HPQ.AggrExpr aggr  window :: PQ.Bindings (HPQ.WndwOp, HPQ.Partition) -> Select -> Select window wndws' s = SelectFrom $ newSelect@@ -264,8 +268,8 @@   bSelect2 = select2   } -with :: PQ.Recursive -> Symbol -> [Symbol] -> Select -> Select -> Select-with recursive name cols wWith wSelect =+with :: PQ.Recursive -> Maybe PQ.Materialized -> Symbol -> [Symbol] -> Select -> Select -> Select+with recursive materialized name cols wWith wSelect =   SelectFrom     newSelect       { attrs = Star@@ -276,6 +280,10 @@    wRecursive = case recursive of      PQ.NonRecursive -> NonRecursive      PQ.Recursive -> Recursive+   wMaterialized = case materialized of+     Nothing -> Nothing+     Just PQ.Materialized -> Just Materialized+     Just PQ.NotMaterialized -> Just NotMaterialized    wCols = map (HSql.SqlColumn . sqlSymbol) cols  
src/Opaleye/Internal/Table.hs view
@@ -18,9 +18,7 @@ import           Data.Profunctor.Product (ProductProfunctor) import qualified Data.Profunctor.Product as PP import qualified Data.List.NonEmpty as NEL-import           Data.Monoid (Monoid, mempty, mappend)-import           Data.Semigroup (Semigroup, (<>))-import           Control.Applicative (Applicative, pure, (<*>), liftA2)+import           Control.Applicative (liftA2) import qualified Control.Arrow as Arr  -- | Define a table as follows, where \"id\", \"color\", \"location\",
src/Opaleye/Internal/Unpackspec.hs view
@@ -8,7 +8,6 @@ import qualified Opaleye.Internal.Column as IC import qualified Opaleye.Field as F -import           Control.Applicative (Applicative, pure, (<*>)) import           Data.Profunctor (Profunctor, dimap) import           Data.Profunctor.Product (ProductProfunctor) import qualified Data.Profunctor.Product as PP
src/Opaleye/Internal/Values.hs view
@@ -8,7 +8,6 @@ import           Opaleye.Internal.Column (Field_(Column)) import qualified Opaleye.Internal.Column as C import qualified Opaleye.Column as OC-import qualified Opaleye.Internal.Unpackspec as U import qualified Opaleye.Internal.Tag as T import qualified Opaleye.Internal.Operators as O import qualified Opaleye.Internal.PrimQuery as PQ@@ -25,9 +24,8 @@ import           Data.Profunctor.Product (ProductProfunctor) import qualified Data.Profunctor.Product as PP import           Data.Profunctor.Product.Default (Default, def)-import           Data.Semigroup (Semigroup, (<>)) -import           Control.Applicative (Applicative, pure, (<*>), liftA2)+import           Control.Applicative (liftA2)  nonEmptyValues :: Rowspec columns columns'                -> NEL.NonEmpty columns
src/Opaleye/Internal/Window.hs view
@@ -7,11 +7,11 @@ -- Perhaps the answer should be "Window"?  This is also attested by -- the WINDOW declaration in a SELECT. +{-# LANGUAGE LambdaCase #-}+ module Opaleye.Internal.Window where -import           Control.Applicative (Applicative, pure, (<*>), liftA2) import           Data.Profunctor (lmap, Profunctor, dimap)-import           Data.Semigroup (Semigroup, (<>))  import qualified Opaleye.Internal.Aggregate as A import qualified Opaleye.Internal.PackMap as PM@@ -127,11 +127,10 @@ -- argument to 'over'). aggregatorWindowFunction :: A.Aggregator a b -> (a' -> a) -> WindowFunction a' b aggregatorWindowFunction agg g = WindowFunction $ PM.PackMap $ \f a ->-  pm (\(mop, expr) -> case mop of-         HPQ.GroupBy -> pure expr-         HPQ.Aggr op _ _ _ -> f (HPQ.WndwAggregate op expr)) a+  pm (\case+         HPQ.GroupBy expr -> pure expr+         HPQ.Aggregate (HPQ.Aggr op e _ _ _ _) -> f (HPQ.WndwAggregate op e)) a   where A.Aggregator (PM.PackMap pm) = lmap g agg-  -- | 'over' applies a 'WindowFunction' on a particular 'Window'.  For -- example,
src/Opaleye/MaybeFields.hs view
@@ -19,6 +19,7 @@   fromMaybeFields,   maybeFields,   maybeFieldsToNullable,+  isJustAnd,   -- * Creating a 'Select' which returns 'MaybeFields'   Opaleye.Join.optional,   Opaleye.MaybeFields.traverseMaybeFields,
src/Opaleye/Operators.hs view
@@ -104,6 +104,9 @@   , IntervalNum   , addInterval   , minusInterval+  , TimestampPrecision(..)+  , dateTruncTimestamp+  , dateTruncTimestamptz   -- * Deprecated   ) @@ -137,6 +140,9 @@  import qualified Data.Profunctor.Product.Default as D +import qualified Data.Text as Text+import qualified Data.Text.Encoding as TE+ {-| Keep only the rows of a query satisfying a given condition, using an SQL @WHERE@ clause.  It is equivalent to the Haskell function @@ -492,3 +498,28 @@ -- | Current date and time (start of current transaction) now :: F.Field T.SqlTimestamptz now = Column $ HPQ.FunExpr "now" []++data TimestampPrecision =+  MicrosecondsPrecision+  | MillisecondsPrecision+  | SecondPrecision+  | MinutePrecision+  | HourPrecision+  | DayPrecision+  | WeekPrecision+  | MonthPrecision+  | QuarterPrecision+  | YearPrecision+  | DecadePrecision+  | CenturyPrecision+  | MillenniumPrecision+  deriving Show++precisionToExpr :: TimestampPrecision -> HPQ.PrimExpr+precisionToExpr p = HPQ.ConstExpr . HPQ.ByteStringLit . TE.encodeUtf8 . Text.toLower . Text.dropEnd 9 . Text.pack $ show p++dateTruncTimestamp :: TimestampPrecision -> F.Field T.SqlTimestamp -> F.Field T.SqlTimestamp+dateTruncTimestamp p (Column e) = Column $ HPQ.FunExpr "date_trunc" [(precisionToExpr p), e]++dateTruncTimestamptz :: TimestampPrecision -> F.Field T.SqlTimestamptz -> F.Field T.SqlTimestamptz+dateTruncTimestamptz p (Column e) = Column $ HPQ.FunExpr "date_trunc" [(precisionToExpr p), e]
src/Opaleye/With.hs view
@@ -2,11 +2,13 @@  module Opaleye.With   ( with,+    withMaterialized,     withRecursive,     withRecursiveDistinct,      -- * Explicit versions     withExplicit,+    withMaterializedExplicit,     withRecursiveExplicit,     withRecursiveDistinctExplicit,   )@@ -30,6 +32,9 @@ with :: Default Unpackspec a a => Select a -> (Select a -> Select b) -> Select b with = withExplicit def +withMaterialized :: Default Unpackspec a a => Select a -> (Select a -> Select b) -> Select b+withMaterialized = withMaterializedExplicit def+ -- | Denotionally, @withRecursive s f@ is the smallest set of rows @r@ such -- that --@@ -65,16 +70,22 @@  withExplicit :: Unpackspec a a -> Select a -> (Select a -> Select b) -> Select b withExplicit unpackspec rhsSelect bodySelect = productQueryArr $ do-  withG unpackspec PQ.NonRecursive (\_ -> rebind rhsSelect) bodySelect+  withG unpackspec PQ.NonRecursive Nothing (\_ -> rebind rhsSelect) bodySelect   where     rebind = (>>> rebindExplicitPrefixNoStar "rebind" unpackspec) +withMaterializedExplicit :: Unpackspec a a -> Select a -> (Select a -> Select b) -> Select b+withMaterializedExplicit unpackspec rhsSelect bodySelect = productQueryArr $ do+  withG unpackspec PQ.NonRecursive (Just PQ.Materialized) (\_ -> rebind rhsSelect) bodySelect+  where+    rebind = (>>> rebindExplicitPrefixNoStar "rebind" unpackspec)+ withRecursiveExplicit :: Binaryspec a a -> Select a -> (a -> Select a) -> Select a withRecursiveExplicit binaryspec base recursive = productQueryArr $ do   let bodySelect selectCte = selectCte   let rhsSelect selectCte = unionAllExplicit binaryspec base (selectCte >>= recursive) -  withG unpackspec PQ.Recursive rhsSelect bodySelect+  withG unpackspec PQ.Recursive Nothing rhsSelect bodySelect   where     unpackspec = binaryspecToUnpackspec binaryspec @@ -83,17 +94,18 @@   let bodySelect selectCte = selectCte   let rhsSelect selectCte = unionExplicit binaryspec base (selectCte >>= recursive) -  withG unpackspec PQ.Recursive rhsSelect bodySelect+  withG unpackspec PQ.Recursive Nothing rhsSelect bodySelect   where     unpackspec = binaryspecToUnpackspec binaryspec  withG ::   Unpackspec a a ->   PQ.Recursive ->+  Maybe PQ.Materialized ->   (Select a -> Select a) ->   (Select a -> Select b) ->   State Tag.Tag (b, PQ.PrimQuery)-withG unpackspec recursive rhsSelect bodySelect = do+withG unpackspec recursive materialized rhsSelect bodySelect = do   (selectCte, withCte) <- freshCte unpackspec    let rhsSelect' = rhsSelect selectCte@@ -102,14 +114,14 @@   (_, rhsQ) <- runSimpleSelect rhsSelect'   bodyQ <- runSimpleSelect bodySelect' -  pure (withCte recursive rhsQ bodyQ)+  pure (withCte recursive materialized rhsQ bodyQ)  freshCte ::   Unpackspec a a ->   State     Tag.Tag     ( Select a,-      PQ.Recursive -> PQ.PrimQuery -> (b, PQ.PrimQuery) -> (b, PQ.PrimQuery)+      PQ.Recursive -> Maybe PQ.Materialized -> PQ.PrimQuery -> (b, PQ.PrimQuery) -> (b, PQ.PrimQuery)     ) freshCte unpackspec = do   cteName <- HPQ.Symbol "cte" <$> Tag.fresh@@ -131,8 +143,8 @@    pure     ( selectCte,-      \recursive withQ (withedCols, withedQ) ->-        (withedCols, PQ.With recursive cteName (map fst cteBindings) withQ withedQ)+      \recursive materialized withQ (withedCols, withedQ) ->+        (withedCols, PQ.With recursive materialized cteName (map fst cteBindings) withQ withedQ)     )  binaryspecToUnpackspec :: Binaryspec a a -> Unpackspec a a