diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,24 @@
-## 0.6.7006.1
+## 0.7.0.0
 
-* Add `sumInt4` and `sumInt8` `Aggregator`s, which don't crash at run
-  time (`sum` currently does on those types).
+* Many renamings have taken place to help make Opaleye easier to
+  understand.  The old versions have been deprecated.
 
-* Add inferrable `FromFields` instance for `SqlNumeric` to
-  `Scientific`.
+* All previously deprecated functions have been removed.
+
+Old | New
+-----|-------
+Query | Select
+QueryArr | SelectArr
+PG*Type*  | Sql*Type*
+PG*Class* | Sql*Class*
+Constant | ToFields
+QueryRunner | FromFields
+QueryRunnerColumn | FromField
+QueryRunnerColumnDefault | DefaultFromField
+TableProperties | TableFields
+optional | optionalTableField
+required | requiredTableField
+readOnly | readOnlyTableField
 
 ## 0.6.7006.0
 
diff --git a/Test/Opaleye/Test/Arbitrary.hs b/Test/Opaleye/Test/Arbitrary.hs
--- a/Test/Opaleye/Test/Arbitrary.hs
+++ b/Test/Opaleye/Test/Arbitrary.hs
@@ -54,7 +54,8 @@
 twoIntTable :: String
             -> O.Table (O.Field O.SqlInt4, O.Field O.SqlInt4)
                        (O.Field O.SqlInt4, O.Field O.SqlInt4)
-twoIntTable n = O.Table n (PP.p2 (O.required "column1", O.required "column2"))
+twoIntTable n = O.Table n (PP.p2 (O.requiredTableField "column1",
+                                  O.requiredTableField "column2"))
 
 table1 :: O.Table (O.Field O.SqlInt4, O.Field O.SqlInt4)
                   (O.Field O.SqlInt4, O.Field O.SqlInt4)
diff --git a/Test/Test.hs b/Test/Test.hs
--- a/Test/Test.hs
+++ b/Test/Test.hs
@@ -85,10 +85,13 @@
 
 -}
 
+required :: String -> O.TableFields (O.Column a) (O.Column a)
+required = O.requiredTableField
+
 twoIntTable :: String
             -> O.Table (Field O.SqlInt4, Field O.SqlInt4)
                        (Field O.SqlInt4, Field O.SqlInt4)
-twoIntTable n = O.Table n (PP.p2 (O.required "column1", O.required "column2"))
+twoIntTable n = O.Table n (PP.p2 (required "column1", required "column2"))
 
 table1 :: O.Table (Field O.SqlInt4, Field O.SqlInt4)
                   (Field O.SqlInt4, Field O.SqlInt4)
@@ -115,29 +118,29 @@
 table5 :: O.Table (Maybe (Field O.SqlInt4), Maybe (Field  O.SqlInt4))
                   (Field O.SqlInt4, Field O.SqlInt4)
 table5 = O.TableWithSchema "public" "table5"
-  (PP.p2 (O.optional "column1", O.optional "column2"))
+  (PP.p2 (O.optionalTableField "column1", O.optionalTableField "column2"))
 
 table6 :: O.Table (Field O.SqlText, Field O.SqlText)
                   (Field O.SqlText, Field O.SqlText)
-table6 = O.Table "table6" (PP.p2 (O.required "column1", O.required "column2"))
+table6 = O.Table "table6" (PP.p2 (required "column1", required "column2"))
 
 table7 :: O.Table (Field O.SqlText, Field O.SqlText)
                   (Field O.SqlText, Field O.SqlText)
-table7 = O.Table "table7" (PP.p2 (O.required "column1", O.required "column2"))
+table7 = O.Table "table7" (PP.p2 (required "column1", required "column2"))
 
 table8 :: O.Table (Field O.SqlJson) (Field O.SqlJson)
-table8 = O.Table "table8" (O.required "column1")
+table8 = O.Table "table8" (required "column1")
 
 table9 :: O.Table (Field O.SqlJsonb) (Field O.SqlJsonb)
-table9 = O.Table "table9" (O.required "column1")
+table9 = O.Table "table9" (required "column1")
 
 table10 :: O.Table (Field O.SqlInt4) (Field O.SqlInt4)
-table10 = O.Table "table10" (O.required "column1")
+table10 = O.Table "table10" (required "column1")
 
 tableKeywordColNames :: O.Table (Field O.SqlInt4, Field O.SqlInt4)
                                 (Field O.SqlInt4, Field O.SqlInt4)
 tableKeywordColNames = O.Table "keywordtable"
-  (PP.p2 (O.required "column", O.required "where"))
+  (PP.p2 (required "column", required "where"))
 
 table1Q :: Select (Field O.SqlInt4, Field O.SqlInt4)
 table1Q = O.selectTable table1
diff --git a/opaleye.cabal b/opaleye.cabal
--- a/opaleye.cabal
+++ b/opaleye.cabal
@@ -1,6 +1,6 @@
 name:            opaleye
 copyright:       Copyright (c) 2014-2018 Purely Agile Limited; 2019-2020 Tom Ellis
-version:         0.6.7006.1
+version:         0.7.0.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
@@ -75,6 +75,7 @@
                    Opaleye.Values,
                    Opaleye.Internal.Aggregate,
                    Opaleye.Internal.Binary,
+                   Opaleye.Internal.Constant,
                    Opaleye.Internal.Column,
                    Opaleye.Internal.Distinct,
                    Opaleye.Internal.Locking,
@@ -83,6 +84,7 @@
                    Opaleye.Internal.Join,
                    Opaleye.Internal.Label,
                    Opaleye.Internal.Lateral,
+                   Opaleye.Internal.Map,
                    Opaleye.Internal.Manipulation,
                    Opaleye.Internal.MaybeFields,
                    Opaleye.Internal.Order,
@@ -90,10 +92,12 @@
                    Opaleye.Internal.Optimize,
                    Opaleye.Internal.PackMap,
                    Opaleye.Internal.PGTypes,
+                   Opaleye.Internal.PGTypesExternal,
                    Opaleye.Internal.PrimQuery,
                    Opaleye.Internal.Print,
                    Opaleye.Internal.QueryArr,
                    Opaleye.Internal.RunQuery,
+                   Opaleye.Internal.RunQueryExternal,
                    Opaleye.Internal.Sql,
                    Opaleye.Internal.Table,
                    Opaleye.Internal.TableMaker,
diff --git a/src/Opaleye.hs b/src/Opaleye.hs
--- a/src/Opaleye.hs
+++ b/src/Opaleye.hs
@@ -17,7 +17,7 @@
                , module Opaleye.Aggregate
                , module Opaleye.Binary
                , module Opaleye.Column
-               , module Opaleye.Constant
+               , module Opaleye.Internal.Constant
                , module Opaleye.Distinct
                , module Opaleye.Field
                , module Opaleye.FunctionalJoin
@@ -28,7 +28,7 @@
                , module Opaleye.MaybeFields
                , module Opaleye.Operators
                , module Opaleye.Order
-               , module Opaleye.PGTypes
+               , module Opaleye.Internal.PGTypesExternal
                , module Opaleye.QueryArr
                , module Opaleye.RunQuery
                , module Opaleye.RunSelect
@@ -44,7 +44,8 @@
 import Opaleye.Aggregate
 import Opaleye.Binary
 import Opaleye.Column
-import Opaleye.Constant
+import Opaleye.Internal.Constant
+  hiding (toFields)
 import Opaleye.Distinct
 import Opaleye.Field
   hiding (null,
@@ -63,7 +64,7 @@
   hiding (optional)
 import Opaleye.Operators
 import Opaleye.Order
-import Opaleye.PGTypes
+import Opaleye.Internal.PGTypesExternal
 import Opaleye.QueryArr
 import Opaleye.RunQuery
 import Opaleye.RunSelect
diff --git a/src/Opaleye/Adaptors.hs b/src/Opaleye/Adaptors.hs
--- a/src/Opaleye/Adaptors.hs
+++ b/src/Opaleye/Adaptors.hs
@@ -62,6 +62,7 @@
     -- * Updater
     Updater,
     -- * Valuesspec
+    Valuesspec,
     ValuesspecSafe,
     valuesspecField,
     valuesspecMaybeFields,
diff --git a/src/Opaleye/Aggregate.hs b/src/Opaleye/Aggregate.hs
--- a/src/Opaleye/Aggregate.hs
+++ b/src/Opaleye/Aggregate.hs
@@ -1,4 +1,3 @@
-{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
 -- | Perform aggregation on 'S.Select's.  To aggregate a 'S.Select' you
 -- should construct an 'Aggregator' encoding how you want the
 -- aggregation to proceed, then call 'aggregate' on it.  The
@@ -10,10 +9,14 @@
        (
        -- * Aggregation
          aggregate
+       , aggregateOrdered
+       , distinctAggregator
        , Aggregator
        -- * Basic 'Aggregator's
        , groupBy
        , Opaleye.Aggregate.sum
+       , sumInt4
+       , sumInt8
        , count
        , countStar
        , avg
@@ -25,8 +28,6 @@
        , stringAgg
        -- * Counting rows
        , countRows
-       -- * Entire module
-       , module Opaleye.Aggregate
        ) where
 
 import           Control.Applicative (pure)
diff --git a/src/Opaleye/Binary.hs b/src/Opaleye/Binary.hs
--- a/src/Opaleye/Binary.hs
+++ b/src/Opaleye/Binary.hs
@@ -34,7 +34,23 @@
 
 {-# LANGUAGE MultiParamTypeClasses, FlexibleContexts #-}
 
-module Opaleye.Binary where
+module Opaleye.Binary (-- * Binary operations
+                       unionAll,
+                       union,
+                       intersectAll,
+                       intersect,
+                       exceptAll,
+                       except,
+                       -- * Explicit versions
+                       unionAllExplicit,
+                       unionExplicit,
+                       intersectAllExplicit,
+                       intersectExplicit,
+                       exceptAllExplicit,
+                       exceptExplicit,
+                       -- * Adaptors
+                       binaryspecField,
+                      ) where
 
 import qualified Opaleye.Internal.Binary as B
 import qualified Opaleye.Internal.Column
@@ -43,8 +59,6 @@
 
 import           Data.Profunctor.Product.Default (Default, def)
 
--- * Binary operations
-
 unionAll :: Default B.Binaryspec fields fields =>
             S.Select fields -> S.Select fields -> S.Select fields
 unionAll = unionAllExplicit def
@@ -75,8 +89,6 @@
          S.Select fields -> S.Select fields -> S.Select fields
 except = exceptExplicit def
 
--- * Explicit versions
-
 unionAllExplicit :: B.Binaryspec fields fields'
                  -> S.Select fields -> S.Select fields -> S.Select fields'
 unionAllExplicit = B.sameTypeBinOpHelper PQ.UnionAll
@@ -100,8 +112,6 @@
 exceptExplicit :: B.Binaryspec fields fields'
               -> S.Select fields -> S.Select fields -> S.Select fields'
 exceptExplicit = B.sameTypeBinOpHelper PQ.Except
-
--- * Adaptors
 
 binaryspecField :: (B.Binaryspec
                         (Opaleye.Internal.Column.Column a)
diff --git a/src/Opaleye/Column.hs b/src/Opaleye/Column.hs
--- a/src/Opaleye/Column.hs
+++ b/src/Opaleye/Column.hs
@@ -1,5 +1,5 @@
 {-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
--- | Do not use.  Will be deprecated in version 0.7.  Use
+-- | Do not use.  Will be deprecated in version 0.8.  Use
 -- "Opaleye.Field" instead.
 --
 -- Functions for working directly with 'Column's.
@@ -7,7 +7,7 @@
 -- Please note that numeric 'Column' types are instances of 'Num', so
 -- you can use '*', '/', '+', '-' on them.
 --
--- 'Column' will be renamed to 'Opaleye.Field.Field_' in version 0.7,
+-- 'Column' will be renamed to 'Opaleye.Field.Field_' in version 0.8,
 -- so you might want to use the latter as much as you can.
 
 module Opaleye.Column (-- * 'Column'
@@ -31,7 +31,7 @@
                                           unsafeCast, unsafeCompositeField)
 import qualified Opaleye.Internal.Column as C
 import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
-import qualified Opaleye.PGTypes as T
+import qualified Opaleye.Internal.PGTypesExternal as T
 import           Prelude hiding (null)
 
 -- | A NULL of any type
diff --git a/src/Opaleye/Constant.hs b/src/Opaleye/Constant.hs
--- a/src/Opaleye/Constant.hs
+++ b/src/Opaleye/Constant.hs
@@ -1,196 +1,4 @@
--- | Do not use.  Use "Opaleye.ToFields" instead.  Will be deprecated
--- in version 0.7.
-
-{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-}
-
-module Opaleye.Constant where
-
-import           Opaleye.Column                  (Column)
-import qualified Opaleye.Column                  as C
-import qualified Opaleye.SqlTypes                 as T
-
-import qualified Data.Aeson                      as Ae
-import qualified Data.CaseInsensitive            as CI
-import qualified Data.Int                        as Int
-import qualified Data.Text                       as ST
-import qualified Data.Text.Lazy                  as LT
-import qualified Data.ByteString                 as SBS
-import qualified Data.ByteString.Lazy            as LBS
-import qualified Data.Scientific                 as Sci
-import qualified Data.Time                       as Time
-import qualified Data.UUID                       as UUID
-
-import qualified Data.Profunctor.Product         as PP
-import           Data.Profunctor.Product         (empty, (***!), (+++!))
-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
-
--- | 'toFields' provides a convenient typeclass wrapper around the
--- 'Opaleye.Field.Field_' creation functions in "Opaleye.SqlTypes".  Besides
--- convenience it doesn't provide any additional functionality.
---
--- It can be used with functions like 'Opaleye.Manipulation.runInsert'
--- to insert custom Haskell types into the database.
--- The following is an example of a function for inserting custom types.
---
--- @
---   customInsert
---      :: ( 'D.Default' 'ToFields' haskells fields )
---      => Connection
---      -> 'Opaleye.Table' fields fields'
---      -> haskells
---      -> IO Int64
---   customInsert conn table haskells = 'Opaleye.Manipulation.runInsert' conn table $ 'toFields' haskells
--- @
---
--- In order to use this function with your custom types, you need to define an
--- instance of 'D.Default' 'ToFields' for your custom types.
-toFields :: D.Default ToFields haskells fields
-         => haskells -> fields
-toFields = constantExplicit D.def
-
--- | Do not use.  Use 'toFields' instead.  Will be deprecated in version 0.7.
-constant :: D.Default ToFields haskells fields
-         => haskells -> fields
-constant = constantExplicit D.def
-
--- | Do not use the name @Constant@.  Use 'ToFields' instead.  Will be
--- deprecated in version 0.7.
-newtype Constant haskells fields =
-  Constant { constantExplicit :: haskells -> fields }
-
-type ToFields = Constant
-
-instance D.Default ToFields haskell (Column sql)
-         => D.Default ToFields (Maybe haskell) (Column (C.Nullable sql)) where
-  def = Constant (C.maybeToNullable . fmap f)
-    where Constant f = D.def
-
-instance D.Default ToFields (Column a) (Column a) where
-  def = Constant id
-
-instance D.Default ToFields String (Column T.SqlText) where
-  def = Constant T.sqlString
-
-instance D.Default ToFields LBS.ByteString (Column T.SqlBytea) where
-  def = Constant T.sqlLazyByteString
-
-instance D.Default ToFields SBS.ByteString (Column T.SqlBytea) where
-  def = Constant T.sqlStrictByteString
-
-instance D.Default ToFields ST.Text (Column T.SqlText) where
-  def = Constant T.sqlStrictText
-
-instance D.Default ToFields LT.Text (Column T.SqlText) where
-  def = Constant T.sqlLazyText
-
-instance D.Default ToFields Sci.Scientific (Column T.SqlNumeric) where
-  def = Constant T.sqlNumeric
-
-instance D.Default ToFields Int (Column T.SqlInt4) where
-  def = Constant T.sqlInt4
-
-instance D.Default ToFields Int.Int32 (Column T.SqlInt4) where
-  def = Constant $ T.sqlInt4 . fromIntegral
-
-instance D.Default ToFields Int.Int64 (Column T.SqlInt8) where
-  def = Constant T.sqlInt8
-
-instance D.Default ToFields Double (Column T.SqlFloat8) where
-  def = Constant T.sqlDouble
-
-instance D.Default ToFields Bool (Column T.SqlBool) where
-  def = Constant T.sqlBool
-
-instance D.Default ToFields UUID.UUID (Column T.SqlUuid) where
-  def = Constant T.sqlUUID
-
-instance D.Default ToFields Time.Day (Column T.SqlDate) where
-  def = Constant T.sqlDay
-
-instance D.Default ToFields Time.UTCTime (Column T.SqlTimestamptz) where
-  def = Constant T.sqlUTCTime
-
-instance D.Default ToFields Time.LocalTime (Column T.SqlTimestamp) where
-  def = Constant T.sqlLocalTime
-
-instance D.Default ToFields Time.ZonedTime (Column T.SqlTimestamptz) where
-  def = Constant T.sqlZonedTime
-
-instance D.Default ToFields Time.TimeOfDay (Column T.SqlTime) where
-  def = Constant T.sqlTimeOfDay
-
-instance D.Default ToFields (CI.CI ST.Text) (Column T.SqlCitext) where
-  def = Constant T.sqlCiStrictText
-
-instance D.Default ToFields (CI.CI LT.Text) (Column T.SqlCitext) where
-  def = Constant T.sqlCiLazyText
-
-instance D.Default ToFields SBS.ByteString (Column T.SqlJson) where
-  def = Constant T.sqlStrictJSON
-
-instance D.Default ToFields LBS.ByteString (Column T.SqlJson) where
-  def = Constant T.sqlLazyJSON
-
-instance D.Default ToFields Ae.Value (Column T.SqlJson) where
-  def = Constant T.sqlValueJSON
-
-instance D.Default ToFields SBS.ByteString (Column T.SqlJsonb) where
-  def = Constant T.sqlStrictJSONB
-
-instance D.Default ToFields LBS.ByteString (Column T.SqlJsonb) where
-  def = Constant T.sqlLazyJSONB
-
-instance D.Default ToFields Ae.Value (Column T.SqlJsonb) where
-  def = Constant T.sqlValueJSONB
-
-instance D.Default ToFields haskell (Column sql) => D.Default ToFields (Maybe haskell) (Maybe (Column sql)) where
-  def = Constant (constant <$>)
-
-instance (D.Default ToFields a (Column b), T.IsSqlType b)
-         => D.Default ToFields [a] (Column (T.SqlArray b)) where
-  def = Constant (T.sqlArray (constantExplicit D.def))
-
-instance D.Default ToFields (R.PGRange Int.Int) (Column (T.SqlRange T.SqlInt4)) where
-  def = Constant $ \(R.PGRange a b) -> T.sqlRange T.sqlInt4 a b
-
-instance D.Default ToFields (R.PGRange Int.Int64) (Column (T.SqlRange T.SqlInt8)) where
-  def = Constant $ \(R.PGRange a b) -> T.sqlRange T.sqlInt8 a b
-
-instance D.Default ToFields (R.PGRange Sci.Scientific) (Column (T.SqlRange T.SqlNumeric)) where
-  def = Constant $ \(R.PGRange a b) -> T.sqlRange T.sqlNumeric a b
-
-instance D.Default ToFields (R.PGRange Time.LocalTime) (Column (T.SqlRange T.SqlTimestamp)) where
-  def = Constant $ \(R.PGRange a b) -> T.sqlRange T.sqlLocalTime a b
-
-instance D.Default ToFields (R.PGRange Time.UTCTime) (Column (T.SqlRange T.SqlTimestamptz)) where
-  def = Constant $ \(R.PGRange a b) -> T.sqlRange T.sqlUTCTime a b
-
-instance D.Default ToFields (R.PGRange Time.Day) (Column (T.SqlRange T.SqlDate)) where
-  def = Constant $ \(R.PGRange a b) -> T.sqlRange T.sqlDay a b
-
--- { Boilerplate instances
-
-instance Functor (Constant a) where
-  fmap f (Constant g) = Constant (fmap f g)
-
-instance Applicative (Constant a) where
-  pure = Constant . pure
-  Constant f <*> Constant x = Constant (f <*> x)
-
-instance P.Profunctor Constant where
-  dimap f g (Constant h) = Constant (P.dimap f g h)
-
-instance PP.ProductProfunctor Constant where
-  empty = Constant empty
-  Constant f ***! Constant g = Constant (f ***! g)
-
-instance PP.SumProfunctor Constant where
-  Constant f +++! Constant g = Constant (f +++! g)
+module Opaleye.Constant {-# DEPRECATED "Use \"Opaleye.ToFields\" instead.  Will be removed in version 0.8." #-}
+  (module Opaleye.Internal.Constant) where
 
--- }
+import Opaleye.Internal.Constant
diff --git a/src/Opaleye/Distinct.hs b/src/Opaleye/Distinct.hs
--- a/src/Opaleye/Distinct.hs
+++ b/src/Opaleye/Distinct.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE FlexibleContexts #-}
 
-module Opaleye.Distinct (module Opaleye.Distinct, Distinctspec,
+module Opaleye.Distinct (distinct,
+                         Distinctspec,
                          -- * Explicit versions
                          distinctExplicit,
                          -- * Adaptors
diff --git a/src/Opaleye/Field.hs b/src/Opaleye/Field.hs
--- a/src/Opaleye/Field.hs
+++ b/src/Opaleye/Field.hs
@@ -1,17 +1,38 @@
 -- | Functions for working directly with 'Field_'s.
 --
 -- Please note that numeric 'Field_' types are instances of 'Num', so
--- you can use '*', '/', '+', '-' on them.
+-- you can use '*', '/', '+', '-' on them.  To create 'Field_'s, see
+-- "Opaleye.ToFields" and "Opaleye.SqlTypes".
+--
+-- 'Field_' used to be called 'C.Column' and for technical reasons
+-- there are still a few uses of the old name around.  If you see
+-- @'C.Column' SqlType@ then you can understand it as @'Field'
+-- SqlType@, and if you see @'C.Column' ('C.Nullable' SqlType)@ then
+-- you can understand it as @'FieldNullable' SqlType@.
+--
+-- 'C.Column' will be fully deprecated in version 0.8.
 
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE DataKinds #-}
 
-module Opaleye.Field where
+module Opaleye.Field (
+  Field_,
+  Nullability(..),
+  FieldNullable,
+  Field,
+  Opaleye.Field.null,
+  isNull,
+  matchNullable,
+  fromNullable,
+  toNullable,
+  maybeToNullable,
+  unsafeCoerceField
+  ) where
 
 import qualified Opaleye.Column   as C
-import qualified Opaleye.PGTypes  as T
+import qualified Opaleye.Internal.PGTypesExternal  as T
 
--- | The name @Column@ will be replaced by @Field@ in version 0.7.
+-- | The name @Column@ will be replaced by @Field@ in version 0.8.
 -- The @Field_@, @Field@ and @FieldNullable@ types exist to help
 -- smooth the transition.  We recommend that you use @Field_@, @Field@
 -- or @FieldNullable@ instead of @Column@ everywhere that it is
diff --git a/src/Opaleye/FunctionalJoin.hs b/src/Opaleye/FunctionalJoin.hs
--- a/src/Opaleye/FunctionalJoin.hs
+++ b/src/Opaleye/FunctionalJoin.hs
@@ -5,7 +5,12 @@
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 
-module Opaleye.FunctionalJoin where
+module Opaleye.FunctionalJoin (
+  joinF,
+  leftJoinF,
+  rightJoinF,
+  fullJoinF,
+  ) where
 
 import           Control.Applicative             ((<$>), (<*>))
 import           Control.Arrow                   ((<<<))
diff --git a/src/Opaleye/Internal/Column.hs b/src/Opaleye/Internal/Column.hs
--- a/src/Opaleye/Internal/Column.hs
+++ b/src/Opaleye/Internal/Column.hs
@@ -7,22 +7,19 @@
 import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
 
 -- | A column of a @Query@, of type @pgType@.  For example 'Column'
--- @PGInt4@ is an @int4@ column and a 'Column' @PGText@ is a @text@
+-- @SqlInt4@ is an @int4@ column and a 'Column' @SqlText@ is a @text@
 -- column.
 --
--- Do not use the 'Show' instance of 'Column'.  It is considered
--- deprecated and will be removed in version 0.7.
---
--- The name @Column@ will be replaced by @Field@ in version 0.7.
+-- The name @Column@ will be replaced by @Field@ in version 0.8.
 -- There already exists a @Field@ type family to help smooth the
 -- transition.  We recommend that you use @Field_@, @Field@ or
 -- @FieldNullable@ instead of @Column@ everywhere that it is
 -- sufficient.
-newtype Column pgType = Column HPQ.PrimExpr deriving Show
+newtype Column pgType = Column HPQ.PrimExpr
 
 -- | Only used within a 'Column', to indicate that it can be @NULL@.
--- For example, a 'Column' ('Nullable' @PGText@) can be @NULL@ but a
--- 'Column' @PGText@ cannot.
+-- For example, a 'Column' ('Nullable' @SqlText@) can be @NULL@ but a
+-- 'Column' @SqlText@ cannot.
 data Nullable a = Nullable
 
 unColumn :: Column a -> HPQ.PrimExpr
@@ -53,7 +50,7 @@
 unOp :: HPQ.UnOp -> Column a -> Column b
 unOp op (Column e) = Column (HPQ.UnExpr op e)
 
--- For import order reasons we can't make the return type PGBool
+-- For import order reasons we can't make the return type SqlBool
 unsafeCase_ :: [(Column pgBool, Column a)] -> Column a -> Column a
 unsafeCase_ alts (Column otherwise_) = Column (HPQ.CaseExpr (unColumns alts) otherwise_)
   where unColumns = map (\(Column e, Column e') -> (e, e'))
@@ -67,13 +64,13 @@
 unsafeEq :: Column a -> Column a -> Column pgBool
 unsafeEq = binOp (HPQ.:==)
 
-class PGNum a where
+class SqlNum a where
   pgFromInteger :: Integer -> Column a
   pgFromInteger = sqlFromInteger
 
   sqlFromInteger :: Integer -> Column a
 
-type SqlNum = PGNum
+type PGNum = SqlNum
 
 instance SqlNum a => Num (Column a) where
   fromInteger = pgFromInteger
@@ -88,30 +85,30 @@
   -- numeric or a double
   signum c = unsafeCase_ [(c `unsafeGt` 0, 1), (c `unsafeEq` 0, 0)] (-1)
 
-class PGFractional a where
+class SqlFractional a where
   pgFromRational :: Rational -> Column a
   pgFromRational = sqlFromRational
 
   sqlFromRational :: Rational -> Column a
 
-type SqlFractional = PGFractional
+type PGFractional = SqlFractional
 
 instance (SqlNum a, SqlFractional a) => Fractional (Column a) where
   fromRational = sqlFromRational
   (/) = binOp (HPQ.:/)
 
 -- | A dummy typeclass whose instances support integral operations.
-class PGIntegral a
+class SqlIntegral a
 
-type SqlIntegral = PGIntegral
+type PGIntegral = SqlIntegral
 
-class PGString a where
+class SqlString a where
     pgFromString :: String -> Column a
     pgFromString = sqlFromString
 
     sqlFromString :: String -> Column a
 
-type SqlString = PGString
+type PGString = SqlString
 
 instance SqlString a => IsString (Column a) where
   fromString = sqlFromString
diff --git a/src/Opaleye/Internal/Constant.hs b/src/Opaleye/Internal/Constant.hs
new file mode 100644
--- /dev/null
+++ b/src/Opaleye/Internal/Constant.hs
@@ -0,0 +1,175 @@
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-}
+
+module Opaleye.Internal.Constant where
+
+import           Opaleye.Column                  (Column)
+import qualified Opaleye.Column                  as C
+import qualified Opaleye.SqlTypes                 as T
+
+import qualified Data.Aeson                      as Ae
+import qualified Data.CaseInsensitive            as CI
+import qualified Data.Int                        as Int
+import qualified Data.Text                       as ST
+import qualified Data.Text.Lazy                  as LT
+import qualified Data.ByteString                 as SBS
+import qualified Data.ByteString.Lazy            as LBS
+import qualified Data.Scientific                 as Sci
+import qualified Data.Time                       as Time
+import qualified Data.UUID                       as UUID
+
+import qualified Data.Profunctor.Product         as PP
+import           Data.Profunctor.Product         (empty, (***!), (+++!))
+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
+
+toFields :: D.Default ToFields haskells fields
+         => haskells -> fields
+toFields = constantExplicit D.def
+
+{-# DEPRECATED constant "Use 'toFields' instead.  Will be removed in version 0.8." #-}
+constant :: D.Default ToFields haskells fields
+         => haskells -> fields
+constant = constantExplicit D.def
+
+newtype ToFields haskells fields =
+  ToFields { constantExplicit :: haskells -> fields }
+
+{-# DEPRECATED Constant "Use 'ToFields' instead.  Will be removed in version 0.8." #-}
+type Constant = ToFields
+
+instance D.Default ToFields haskell (Column sql)
+         => D.Default ToFields (Maybe haskell) (Column (C.Nullable sql)) where
+  def = ToFields (C.maybeToNullable . fmap f)
+    where ToFields f = D.def
+
+toToFields :: (haskells -> fields) -> ToFields haskells fields
+toToFields = ToFields
+
+instance D.Default ToFields (Column a) (Column a) where
+  def = toToFields id
+
+instance D.Default ToFields String (Column T.SqlText) where
+  def = toToFields T.sqlString
+
+instance D.Default ToFields LBS.ByteString (Column T.SqlBytea) where
+  def = toToFields T.sqlLazyByteString
+
+instance D.Default ToFields SBS.ByteString (Column T.SqlBytea) where
+  def = toToFields T.sqlStrictByteString
+
+instance D.Default ToFields ST.Text (Column T.SqlText) where
+  def = toToFields T.sqlStrictText
+
+instance D.Default ToFields LT.Text (Column T.SqlText) where
+  def = toToFields T.sqlLazyText
+
+instance D.Default ToFields Sci.Scientific (Column T.SqlNumeric) where
+  def = toToFields T.sqlNumeric
+
+instance D.Default ToFields Int (Column T.SqlInt4) where
+  def = toToFields T.sqlInt4
+
+instance D.Default ToFields Int.Int32 (Column T.SqlInt4) where
+  def = toToFields $ T.sqlInt4 . fromIntegral
+
+instance D.Default ToFields Int.Int64 (Column T.SqlInt8) where
+  def = toToFields T.sqlInt8
+
+instance D.Default ToFields Double (Column T.SqlFloat8) where
+  def = toToFields T.sqlDouble
+
+instance D.Default ToFields Bool (Column T.SqlBool) where
+  def = toToFields T.sqlBool
+
+instance D.Default ToFields UUID.UUID (Column T.SqlUuid) where
+  def = toToFields T.sqlUUID
+
+instance D.Default ToFields Time.Day (Column T.SqlDate) where
+  def = toToFields T.sqlDay
+
+instance D.Default ToFields Time.UTCTime (Column T.SqlTimestamptz) where
+  def = toToFields T.sqlUTCTime
+
+instance D.Default ToFields Time.LocalTime (Column T.SqlTimestamp) where
+  def = toToFields T.sqlLocalTime
+
+instance D.Default ToFields Time.ZonedTime (Column T.SqlTimestamptz) where
+  def = toToFields T.sqlZonedTime
+
+instance D.Default ToFields Time.TimeOfDay (Column T.SqlTime) where
+  def = toToFields T.sqlTimeOfDay
+
+instance D.Default ToFields (CI.CI ST.Text) (Column T.SqlCitext) where
+  def = toToFields T.sqlCiStrictText
+
+instance D.Default ToFields (CI.CI LT.Text) (Column T.SqlCitext) where
+  def = toToFields T.sqlCiLazyText
+
+instance D.Default ToFields SBS.ByteString (Column T.SqlJson) where
+  def = toToFields T.sqlStrictJSON
+
+instance D.Default ToFields LBS.ByteString (Column T.SqlJson) where
+  def = toToFields T.sqlLazyJSON
+
+instance D.Default ToFields Ae.Value (Column T.SqlJson) where
+  def = toToFields T.sqlValueJSON
+
+instance D.Default ToFields SBS.ByteString (Column T.SqlJsonb) where
+  def = toToFields T.sqlStrictJSONB
+
+instance D.Default ToFields LBS.ByteString (Column T.SqlJsonb) where
+  def = toToFields T.sqlLazyJSONB
+
+instance D.Default ToFields Ae.Value (Column T.SqlJsonb) where
+  def = toToFields T.sqlValueJSONB
+
+instance D.Default ToFields haskell (Column sql) => D.Default ToFields (Maybe haskell) (Maybe (Column sql)) where
+  def = toToFields (constant <$>)
+
+instance (D.Default ToFields a (Column b), T.IsSqlType b)
+         => D.Default ToFields [a] (Column (T.SqlArray b)) where
+  def = toToFields (T.sqlArray (constantExplicit D.def))
+
+instance D.Default ToFields (R.PGRange Int.Int) (Column (T.SqlRange T.SqlInt4)) where
+  def = toToFields $ \(R.PGRange a b) -> T.sqlRange T.sqlInt4 a b
+
+instance D.Default ToFields (R.PGRange Int.Int64) (Column (T.SqlRange T.SqlInt8)) where
+  def = toToFields $ \(R.PGRange a b) -> T.sqlRange T.sqlInt8 a b
+
+instance D.Default ToFields (R.PGRange Sci.Scientific) (Column (T.SqlRange T.SqlNumeric)) where
+  def = toToFields $ \(R.PGRange a b) -> T.sqlRange T.sqlNumeric a b
+
+instance D.Default ToFields (R.PGRange Time.LocalTime) (Column (T.SqlRange T.SqlTimestamp)) where
+  def = toToFields $ \(R.PGRange a b) -> T.sqlRange T.sqlLocalTime a b
+
+instance D.Default ToFields (R.PGRange Time.UTCTime) (Column (T.SqlRange T.SqlTimestamptz)) where
+  def = toToFields $ \(R.PGRange a b) -> T.sqlRange T.sqlUTCTime a b
+
+instance D.Default ToFields (R.PGRange Time.Day) (Column (T.SqlRange T.SqlDate)) where
+  def = toToFields $ \(R.PGRange a b) -> T.sqlRange T.sqlDay a b
+
+-- { Boilerplate instances
+
+instance Functor (ToFields a) where
+  fmap f (ToFields g) = ToFields (fmap f g)
+
+instance Applicative (ToFields a) where
+  pure = ToFields . pure
+  ToFields f <*> ToFields x = ToFields (f <*> x)
+
+instance P.Profunctor ToFields where
+  dimap f g (ToFields h) = ToFields (P.dimap f g h)
+
+instance PP.ProductProfunctor ToFields where
+  empty = ToFields empty
+  ToFields f ***! ToFields g = ToFields (f ***! g)
+
+instance PP.SumProfunctor ToFields where
+  ToFields f +++! ToFields g = ToFields (f +++! g)
+
+-- }
diff --git a/src/Opaleye/Internal/Inferrable.hs b/src/Opaleye/Internal/Inferrable.hs
--- a/src/Opaleye/Internal/Inferrable.hs
+++ b/src/Opaleye/Internal/Inferrable.hs
@@ -10,7 +10,7 @@
 import           Opaleye.Internal.RunQuery (FromField, FromFields)
 import qualified Opaleye.Internal.RunQuery as RQ
 import qualified Opaleye.SqlTypes as T
-import           Opaleye.Constant (ToFields)
+import           Opaleye.Internal.Constant (ToFields)
 
 import qualified Data.ByteString as SBS
 import qualified Data.ByteString.Lazy as LBS
@@ -27,6 +27,9 @@
 import qualified Database.PostgreSQL.Simple.Range as R
 import           GHC.Int (Int32, Int64)
 
+-- | Despite its name, 'Inferrable' doesn't provide any inferability
+-- improvements itself, it's just a conveniently-named newtype wrapper
+-- to hang instances with better inferrability off of.
 newtype Inferrable p a b = Inferrable { runInferrable :: p a b }
 
 -- FromFields
diff --git a/src/Opaleye/Internal/Join.hs b/src/Opaleye/Internal/Join.hs
--- a/src/Opaleye/Internal/Join.hs
+++ b/src/Opaleye/Internal/Join.hs
@@ -12,11 +12,11 @@
 import qualified Opaleye.Internal.QueryArr as Q
 import qualified Opaleye.Internal.Operators as Op
 import qualified Opaleye.Internal.PrimQuery as PQ
-import qualified Opaleye.PGTypes as T
+import qualified Opaleye.Internal.PGTypesExternal as T
 import qualified Opaleye.SqlTypes as T
 import qualified Opaleye.Column as C
 import           Opaleye.Field   (Field)
-import qualified Opaleye.Map     as Map
+import qualified Opaleye.Internal.Map as Map
 import           Opaleye.Internal.MaybeFields (MaybeFields(MaybeFields),
                                                mfPresent, mfFields)
 import qualified Opaleye.Select  as S
@@ -109,7 +109,7 @@
       in MaybeFields { mfPresent = present
                      , mfFields  = rest
                      }) $
-  leftJoinAExplicit (PP.p2 (U.unpackspecColumn, uA))
+  leftJoinAExplicit (PP.p2 (U.unpackspecField, uA))
                     (Opaleye.Internal.Join.NullMaker id)
                     (fmap (\x -> (T.sqlBool True, x)) q)
 
@@ -149,7 +149,7 @@
 
 --
 
--- | Do not use.  Nulled will be deprecated in 0.7.
+{-# DEPRECATED Nulled "Will be removed in version 0.8" #-}
 data Nulled
 
 type instance TF.IMap Nulled TF.OT     = TF.NullsT
diff --git a/src/Opaleye/Internal/Manipulation.hs b/src/Opaleye/Internal/Manipulation.hs
--- a/src/Opaleye/Internal/Manipulation.hs
+++ b/src/Opaleye/Internal/Manipulation.hs
@@ -12,11 +12,11 @@
 import qualified Opaleye.Internal.HaskellDB.Sql.Default  as SD
 import qualified Opaleye.Internal.HaskellDB.Sql.Generate as SG
 import qualified Opaleye.Internal.HaskellDB.Sql.Print    as HPrint
-import           Opaleye.Internal.Helpers        ((.:.), (.::.), (.::))
+import           Opaleye.Internal.Helpers        ((.:), (.:.), (.::.), (.::))
 import qualified Opaleye.Internal.PrimQuery      as PQ
 import qualified Opaleye.Internal.Print          as Print
 import qualified Opaleye.Internal.RunQuery       as IRQ
-import qualified Opaleye.RunQuery                as RQ
+import qualified Opaleye.RunSelect               as RS
 import qualified Opaleye.Internal.Sql            as Sql
 import qualified Opaleye.Internal.Table          as TI
 import qualified Opaleye.Internal.Unpackspec     as U
@@ -38,7 +38,7 @@
   Count
     :: Returning a Int64
   ReturningExplicit
-    :: RQ.QueryRunner b c -> (a -> b) -> Returning a [c]
+    :: RS.FromFields b c -> (a -> b) -> Returning a [c]
 
 arrangeInsertMany :: T.Table columns a
                   -> NEL.NonEmpty columns
@@ -82,7 +82,7 @@
   show . HPrint.ppInsert .:. arrangeInsertMany
 
 runInsertManyReturningExplicit
-  :: RQ.QueryRunner columnsReturned haskells
+  :: RS.FromFields columnsReturned haskells
   -> PGS.Connection
   -> T.Table columnsW columnsR
   -> [columnsW]
@@ -151,7 +151,7 @@
   show . Print.ppDeleteReturning .:: arrangeDeleteReturning
 
 
-runDeleteReturning :: (D.Default RQ.QueryRunner columnsReturned haskells)
+runDeleteReturning :: (D.Default RS.FromFields columnsReturned haskells)
                    => PGS.Connection
                    -- ^
                    -> T.Table a columnsR
@@ -166,7 +166,7 @@
                    -- ^ Returned rows which have been deleted
 runDeleteReturning = runDeleteReturningExplicit D.def
 
-runDeleteReturningExplicit :: RQ.QueryRunner columnsReturned haskells
+runDeleteReturningExplicit :: RS.FromFields columnsReturned haskells
                            -> PGS.Connection
                            -> T.Table a columnsR
                            -> (columnsR -> Column SqlBool)
@@ -184,3 +184,101 @@
   SG.sqlDelete SD.defaultSqlGenerator (PQ.tiToSqlTable (TI.tableIdentifier t)) [condExpr]
   where Column condExpr = cond tableCols
         TI.View tableCols = TI.tableColumnsView (TI.tableColumns t)
+
+runInsert :: PGS.Connection -> T.Table fields fields' -> fields -> IO Int64
+runInsert conn = PGS.execute_ conn . fromString .: arrangeInsertSql
+
+runInsertReturning :: (D.Default RS.FromFields fieldsReturned haskells)
+                   => PGS.Connection
+                   -> T.Table fieldsW fieldsR
+                   -> fieldsW
+                   -> (fieldsR -> fieldsReturned)
+                   -> IO [haskells]
+runInsertReturning = runInsertReturningExplicit D.def
+
+runInsertReturningExplicit :: RS.FromFields columnsReturned haskells
+                           -> PGS.Connection
+                           -> T.Table columnsW columnsR
+                           -> columnsW
+                           -> (columnsR -> columnsReturned)
+                           -> IO [haskells]
+runInsertReturningExplicit qr conn t =
+  runInsertManyReturningExplicitI qr conn t . return
+
+runInsertManyReturningExplicitI :: RS.FromFields columnsReturned haskells
+                                -> PGS.Connection
+                                -> T.Table columnsW columnsR
+                                -> [columnsW]
+                                -> (columnsR -> columnsReturned)
+                                -> IO [haskells]
+runInsertManyReturningExplicitI qr conn t columns f =
+  runInsertManyReturningExplicit qr conn t columns f Nothing
+
+arrangeInsert :: T.Table columns a -> columns -> HSql.SqlInsert
+arrangeInsert t c = arrangeInsertManyI t (return c)
+
+arrangeInsertSql :: T.Table columns a -> columns -> String
+arrangeInsertSql = show . HPrint.ppInsert .: arrangeInsert
+
+arrangeInsertManyI :: T.Table columns a -> NEL.NonEmpty columns -> HSql.SqlInsert
+arrangeInsertManyI t columns = arrangeInsertMany t columns Nothing
+
+arrangeInsertManySqlI :: T.Table columns a -> NEL.NonEmpty columns -> String
+arrangeInsertManySqlI t c  = arrangeInsertManySql t c Nothing
+
+arrangeUpdate :: T.Table columnsW columnsR
+              -> (columnsR -> columnsW) -> (columnsR -> Column SqlBool)
+              -> HSql.SqlUpdate
+arrangeUpdate t update cond =
+  SG.sqlUpdate SD.defaultSqlGenerator
+               (PQ.tiToSqlTable (TI.tableIdentifier t))
+               [condExpr] (update' tableCols)
+  where TI.TableFields writer (TI.View tableCols) = TI.tableColumns t
+        update' = map (\(x, y) -> (y, x)) . TI.runWriter writer . update
+        Column condExpr = cond tableCols
+
+arrangeUpdateSql :: T.Table columnsW columnsR
+              -> (columnsR -> columnsW) -> (columnsR -> Column SqlBool)
+              -> String
+arrangeUpdateSql = show . HPrint.ppUpdate .:. arrangeUpdate
+
+arrangeDeleteSql :: T.Table a columnsR -> (columnsR -> Column SqlBool) -> String
+arrangeDeleteSql = show . HPrint.ppDelete .: arrangeDelete
+
+arrangeInsertManyReturningI :: U.Unpackspec columnsReturned ignored
+                            -> T.Table columnsW columnsR
+                            -> NEL.NonEmpty columnsW
+                            -> (columnsR -> columnsReturned)
+                            -> Sql.Returning HSql.SqlInsert
+arrangeInsertManyReturningI unpackspec t columns returningf =
+  arrangeInsertManyReturning unpackspec t columns returningf Nothing
+
+arrangeInsertManyReturningSqlI :: U.Unpackspec columnsReturned ignored
+                               -> T.Table columnsW columnsR
+                               -> NEL.NonEmpty columnsW
+                               -> (columnsR -> columnsReturned)
+                               -> String
+arrangeInsertManyReturningSqlI u t c r =
+  arrangeInsertManyReturningSql u t c r Nothing
+
+arrangeUpdateReturning :: U.Unpackspec columnsReturned ignored
+                       -> T.Table columnsW columnsR
+                       -> (columnsR -> columnsW)
+                       -> (columnsR -> Column SqlBool)
+                       -> (columnsR -> columnsReturned)
+                       -> Sql.Returning HSql.SqlUpdate
+arrangeUpdateReturning unpackspec t updatef cond returningf =
+  Sql.Returning update returningSEs
+  where update = arrangeUpdate t updatef cond
+        TI.View columnsR = TI.tableColumnsView (TI.tableColumns t)
+        returningPEs = U.collectPEs unpackspec (returningf columnsR)
+        returningSEs = Sql.ensureColumnsGen id (map Sql.sqlExpr returningPEs)
+
+arrangeUpdateReturningSql :: U.Unpackspec columnsReturned ignored
+                          -> T.Table columnsW columnsR
+                          -> (columnsR -> columnsW)
+                          -> (columnsR -> Column SqlBool)
+                          -> (columnsR -> columnsReturned)
+                          -> String
+arrangeUpdateReturningSql =
+  show . Print.ppUpdateReturning .::. arrangeUpdateReturning
diff --git a/src/Opaleye/Internal/Map.hs b/src/Opaleye/Internal/Map.hs
new file mode 100644
--- /dev/null
+++ b/src/Opaleye/Internal/Map.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module Opaleye.Internal.Map where
+
+type family Map f x
+
+type instance Map f (a1, a2)
+  = (Map f a1, Map f a2)
+type instance Map f (a1, a2, a3)
+  = (Map f a1, Map f a2, Map f a3)
+type instance Map f (a1, a2, a3, a4)
+  = (Map f a1, Map f a2, Map f a3, Map f a4)
+type instance Map f (a1, a2, a3, a4, a5)
+  = (Map f a1, Map f a2, Map f a3, Map f a4, Map f a5)
+type instance Map f (a1, a2, a3, a4, a5, a6)
+  = (Map f a1, Map f a2, Map f a3, Map f a4, Map f a5, Map f a6)
+type instance Map f (a1, a2, a3, a4, a5, a6, a7)
+  = (Map f a1, Map f a2, Map f a3, Map f a4, Map f a5, Map f a6,
+     Map f a7)
+type instance Map f (a1, a2, a3, a4, a5, a6, a7, a8)
+  = (Map f a1, Map f a2, Map f a3, Map f a4, Map f a5, Map f a6,
+     Map f a7, Map f a8)
diff --git a/src/Opaleye/Internal/MaybeFields.hs b/src/Opaleye/Internal/MaybeFields.hs
--- a/src/Opaleye/Internal/MaybeFields.hs
+++ b/src/Opaleye/Internal/MaybeFields.hs
@@ -139,7 +139,7 @@
         present = isNotNull (IC.unsafeCoerceColumn t')
 
         (t', bindings) =
-          PM.run (U.runUnpackspec U.unpackspecColumn (PM.extractAttr "maybe" tag') t)
+          PM.run (U.runUnpackspec U.unpackspecField (PM.extractAttr "maybe" tag') t)
         join = PQ.Join PQ.LeftJoin true [] bindings left right
     true = HPQ.ConstExpr (HPQ.BoolLit True)
     isNotNull = Opaleye.Internal.Operators.not . Opaleye.Field.isNull
@@ -172,7 +172,7 @@
 fromFieldsMaybeFields :: RQ.FromFields fields haskells
                       -> RQ.FromFields (MaybeFields fields) (Maybe haskells)
 fromFieldsMaybeFields (RQ.QueryRunner u p c) = RQ.QueryRunner u' p' c'
-  where u' = () <$ productProfunctorMaybeFields U.unpackspecColumn u
+  where u' = () <$ productProfunctorMaybeFields U.unpackspecField u
 
         p' = \mf -> do
           hIsPresent <- PGSR.field
@@ -204,8 +204,8 @@
                       -> U.Unpackspec (MaybeFields a) (MaybeFields b)
 unpackspecMaybeFields = productProfunctorMaybeFields U.unpackspecField
 
-valuesspecMaybeFields :: V.ValuesspecSafe a b
-                      -> V.ValuesspecSafe (MaybeFields a) (MaybeFields b)
+valuesspecMaybeFields :: V.Valuesspec a b
+                      -> V.Valuesspec (MaybeFields a) (MaybeFields b)
 valuesspecMaybeFields = productProfunctorMaybeFields V.valuesspecField
 
 toFieldsMaybeFields :: V.Nullspec a b
@@ -289,16 +289,16 @@
                   MaybeFields b (Left l)  -> Left  (MaybeFields b l)
                   MaybeFields b (Right r) -> Right (MaybeFields b r))
 
-instance PP.Default RQ.QueryRunner fields haskells
-  => PP.Default RQ.QueryRunner (MaybeFields fields) (Maybe haskells) where
+instance PP.Default RQ.FromFields fields haskells
+  => PP.Default RQ.FromFields (MaybeFields fields) (Maybe haskells) where
   def = fromFieldsMaybeFields PP.def
 
 instance PP.Default U.Unpackspec a b
   => PP.Default U.Unpackspec (MaybeFields a) (MaybeFields b) where
   def = unpackspecMaybeFields PP.def
 
-instance PP.Default V.ValuesspecSafe a b
-  => PP.Default V.ValuesspecSafe (MaybeFields a) (MaybeFields b) where
+instance PP.Default V.Valuesspec a b
+  => PP.Default V.Valuesspec (MaybeFields a) (MaybeFields b) where
   def = valuesspecMaybeFields PP.def
 
 instance (PP.Default Constant.ToFields a b, PP.Default V.Nullspec a b)
diff --git a/src/Opaleye/Internal/Operators.hs b/src/Opaleye/Internal/Operators.hs
--- a/src/Opaleye/Internal/Operators.hs
+++ b/src/Opaleye/Internal/Operators.hs
@@ -13,8 +13,7 @@
 import qualified Opaleye.Internal.TableMaker as TM
 import qualified Opaleye.Internal.Tag as Tag
 import qualified Opaleye.Internal.Unpackspec as U
-import qualified Opaleye.PGTypes as T
-import qualified Opaleye.SqlTypes as T
+import qualified Opaleye.Internal.PGTypesExternal as T
 import qualified Opaleye.Field as F
 import qualified Opaleye.Select as S
 
@@ -81,7 +80,7 @@
     }
 
 relExprColumn :: RelExprMaker String (Column a)
-relExprColumn = RelExprMaker TM.tableColumn U.unpackspecColumn
+relExprColumn = RelExprMaker TM.tableColumn U.unpackspecField
 
 instance D.Default RelExprMaker String (Column a) where
   def = relExprColumn
diff --git a/src/Opaleye/Internal/PGTypes.hs b/src/Opaleye/Internal/PGTypes.hs
--- a/src/Opaleye/Internal/PGTypes.hs
+++ b/src/Opaleye/Internal/PGTypes.hs
@@ -33,17 +33,10 @@
 lazyDecodeUtf8 :: LByteString.ByteString -> String
 lazyDecodeUtf8 = LText.unpack . LTextEncoding.decodeUtf8
 
-{-# DEPRECATED showPGType
-    "Use 'showSqlType' instead. 'showPGType' will be removed \
-    \in version 0.7." #-}
 class IsSqlType sqlType where
-  showPGType :: proxy sqlType -> String
-  showPGType  = showSqlType
-
   showSqlType :: proxy sqlType -> String
-  showSqlType = showPGType
 
-  {-# MINIMAL showPGType | showSqlType #-}
+  {-# MINIMAL showSqlType #-}
 
 instance IsSqlType a => IsSqlType (C.Nullable a) where
   showSqlType _ = showSqlType (Proxy :: Proxy a)
diff --git a/src/Opaleye/Internal/PGTypesExternal.hs b/src/Opaleye/Internal/PGTypesExternal.hs
new file mode 100644
--- /dev/null
+++ b/src/Opaleye/Internal/PGTypesExternal.hs
@@ -0,0 +1,265 @@
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+
+module Opaleye.Internal.PGTypesExternal
+  (module Opaleye.Internal.PGTypesExternal, IsSqlType(..)) where
+
+import           Opaleye.Internal.Column (Column)
+import qualified Opaleye.Internal.Column as C
+import qualified Opaleye.Internal.PGTypes as IPT
+import           Opaleye.Internal.PGTypes (IsSqlType(..))
+
+import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
+import qualified Opaleye.Internal.HaskellDB.Sql.Default as HSD
+
+import qualified Data.CaseInsensitive as CI
+import qualified Data.Aeson as Ae
+import qualified Data.Text as SText
+import qualified Data.Text.Lazy as LText
+import qualified Data.ByteString as SByteString
+import qualified Data.ByteString.Lazy as LByteString
+import           Data.Scientific as Sci
+import qualified Data.Time as Time
+import qualified Data.UUID as UUID
+
+import           Data.Int (Int64)
+
+import qualified Database.PostgreSQL.Simple.Range as R
+
+instance C.SqlNum SqlFloat8 where
+  sqlFromInteger = pgDouble . fromInteger
+
+instance C.SqlNum SqlInt4 where
+  sqlFromInteger = pgInt4 . fromInteger
+
+instance C.SqlNum SqlInt8 where
+  sqlFromInteger = pgInt8 . fromInteger
+
+instance C.SqlFractional SqlFloat8 where
+  sqlFromRational = pgDouble . fromRational
+
+instance C.SqlIntegral SqlInt2
+instance C.SqlIntegral SqlNumeric
+instance C.SqlIntegral SqlInt4
+instance C.SqlIntegral SqlInt8
+
+instance C.SqlString SqlText where
+  sqlFromString = pgString
+
+instance C.SqlString SqlCitext where
+  sqlFromString = pgCiLazyText . CI.mk . LText.pack
+
+-- * Creating SQL values
+
+pgString :: String -> Column PGText
+pgString = IPT.literalColumn . HPQ.StringLit
+
+pgLazyByteString :: LByteString.ByteString -> Column PGBytea
+pgLazyByteString = IPT.literalColumn . HPQ.ByteStringLit . LByteString.toStrict
+
+pgStrictByteString :: SByteString.ByteString -> Column PGBytea
+pgStrictByteString = IPT.literalColumn . HPQ.ByteStringLit
+
+pgStrictText :: SText.Text -> Column PGText
+pgStrictText = IPT.literalColumn . HPQ.StringLit . SText.unpack
+
+pgLazyText :: LText.Text -> Column PGText
+pgLazyText = IPT.literalColumn . HPQ.StringLit . LText.unpack
+
+pgNumeric :: Sci.Scientific -> Column PGNumeric
+pgNumeric = IPT.literalColumn . HPQ.NumericLit
+
+pgInt4 :: Int -> Column PGInt4
+pgInt4 = IPT.literalColumn . HPQ.IntegerLit . fromIntegral
+
+pgInt8 :: Int64 -> Column PGInt8
+pgInt8 = IPT.literalColumn . HPQ.IntegerLit . fromIntegral
+
+pgDouble :: Double -> Column PGFloat8
+pgDouble = IPT.literalColumn . HPQ.DoubleLit
+
+pgBool :: Bool -> Column PGBool
+pgBool = IPT.literalColumn . HPQ.BoolLit
+
+pgUUID :: UUID.UUID -> Column PGUuid
+pgUUID = IPT.literalColumn . HPQ.StringLit . UUID.toString
+
+pgDay :: Time.Day -> Column PGDate
+pgDay = IPT.unsafePgFormatTime "date" "'%F'"
+
+pgUTCTime :: Time.UTCTime -> Column PGTimestamptz
+pgUTCTime = IPT.unsafePgFormatTime "timestamptz" "'%FT%T%QZ'"
+
+pgLocalTime :: Time.LocalTime -> Column PGTimestamp
+pgLocalTime = IPT.unsafePgFormatTime "timestamp" "'%FT%T%Q'"
+
+pgZonedTime :: Time.ZonedTime -> Column PGTimestamptz
+pgZonedTime = IPT.unsafePgFormatTime "timestamptz" "'%FT%T%Q%z'"
+
+pgTimeOfDay :: Time.TimeOfDay -> Column PGTime
+pgTimeOfDay = IPT.unsafePgFormatTime "time" "'%T%Q'"
+
+-- "We recommend not using the type time with time zone"
+-- http://www.postgresql.org/docs/8.3/static/datatype-datetime.html
+
+
+pgCiStrictText :: CI.CI SText.Text -> Column PGCitext
+pgCiStrictText = IPT.literalColumn . HPQ.StringLit . SText.unpack . CI.original
+
+pgCiLazyText :: CI.CI LText.Text -> Column PGCitext
+pgCiLazyText = IPT.literalColumn . HPQ.StringLit . LText.unpack . CI.original
+
+-- No CI String instance since postgresql-simple doesn't define
+-- FromField (CI String)
+
+-- The json data type was introduced in PostgreSQL version 9.2
+-- JSON values must be SQL string quoted
+pgJSON :: String -> Column PGJson
+pgJSON = IPT.castToType "json" . HSD.quote
+
+pgStrictJSON :: SByteString.ByteString -> Column PGJson
+pgStrictJSON = pgJSON . IPT.strictDecodeUtf8
+
+pgLazyJSON :: LByteString.ByteString -> Column PGJson
+pgLazyJSON = pgJSON . IPT.lazyDecodeUtf8
+
+pgValueJSON :: Ae.ToJSON a => a -> Column PGJson
+pgValueJSON = pgLazyJSON . Ae.encode
+
+-- The jsonb data type was introduced in PostgreSQL version 9.4
+-- JSONB values must be SQL string quoted
+--
+-- TODO: We need to add literal JSON and JSONB types so we can say
+-- `castToTypeTyped JSONB` rather than `castToType "jsonb"`.
+pgJSONB :: String -> Column PGJsonb
+pgJSONB = IPT.castToType "jsonb" . HSD.quote
+
+pgStrictJSONB :: SByteString.ByteString -> Column PGJsonb
+pgStrictJSONB = pgJSONB . IPT.strictDecodeUtf8
+
+pgLazyJSONB :: LByteString.ByteString -> Column PGJsonb
+pgLazyJSONB = pgJSONB . IPT.lazyDecodeUtf8
+
+pgValueJSONB :: Ae.ToJSON a => a -> Column PGJsonb
+pgValueJSONB = pgLazyJSONB . Ae.encode
+
+pgArray :: forall a b. IsSqlType b
+        => (a -> C.Column b) -> [a] -> C.Column (PGArray b)
+pgArray pgEl xs = C.unsafeCast arrayTy $
+  C.Column (HPQ.ArrayExpr (map oneEl xs))
+  where
+    oneEl = C.unColumn . pgEl
+    arrayTy = showSqlType ([] :: [PGArray b])
+
+pgRange :: forall a b. IsRangeType b
+        => (a -> C.Column b) -> R.RangeBound a -> R.RangeBound a
+        -> C.Column (PGRange b)
+pgRange pgEl start end =
+  C.Column (HPQ.RangeExpr (showRangeType ([] :: [b])) (oneEl start) (oneEl end))
+  where oneEl (R.Inclusive a) = HPQ.Inclusive . C.unColumn $ pgEl a
+        oneEl (R.Exclusive a) = HPQ.Exclusive . C.unColumn $ pgEl a
+        oneEl R.NegInfinity   = HPQ.NegInfinity
+        oneEl R.PosInfinity   = HPQ.PosInfinity
+
+instance IsSqlType SqlBool where
+  showSqlType _ = "boolean"
+instance IsSqlType SqlDate where
+  showSqlType _ = "date"
+instance IsSqlType SqlFloat4 where
+  showSqlType _ = "real"
+instance IsSqlType SqlFloat8 where
+  showSqlType _ = "double precision"
+instance IsSqlType SqlInt8 where
+  showSqlType _ = "bigint"
+instance IsSqlType SqlInt4 where
+  showSqlType _ = "integer"
+instance IsSqlType SqlInt2 where
+  showSqlType _ = "smallint"
+instance IsSqlType SqlNumeric where
+  showSqlType _ = "numeric"
+instance IsSqlType SqlText where
+  showSqlType _ = "text"
+instance IsSqlType SqlTime where
+  showSqlType _ = "time"
+instance IsSqlType SqlTimestamp where
+  showSqlType _ = "timestamp"
+instance IsSqlType SqlTimestamptz where
+  showSqlType _ = "timestamp with time zone"
+instance IsSqlType SqlUuid where
+  showSqlType _ = "uuid"
+instance IsSqlType SqlCitext where
+  showSqlType _ =  "citext"
+instance IsSqlType SqlBytea where
+  showSqlType _ = "bytea"
+instance IsSqlType a => IsSqlType (SqlArray a) where
+  showSqlType _ = showSqlType ([] :: [a]) ++ "[]"
+instance IsSqlType SqlJson where
+  showSqlType _ = "json"
+instance IsSqlType SqlJsonb where
+  showSqlType _ = "jsonb"
+instance IsRangeType a => IsSqlType (SqlRange a) where
+  showSqlType _ = showRangeType ([] :: [a])
+
+class IsSqlType pgType => IsRangeType pgType where
+  showRangeType :: proxy pgType -> String
+
+instance IsRangeType SqlInt4 where
+  showRangeType _ = "int4range"
+
+instance IsRangeType SqlInt8 where
+  showRangeType _ = "int8range"
+
+instance IsRangeType SqlNumeric where
+  showRangeType _ = "numrange"
+
+instance IsRangeType SqlTimestamp where
+  showRangeType _ = "tsrange"
+
+instance IsRangeType SqlTimestamptz where
+  showRangeType _ = "tstzrange"
+
+instance IsRangeType SqlDate where
+  showRangeType _ = "daterange"
+
+-- * SQL datatypes
+
+data SqlBool
+data SqlDate
+data SqlFloat4
+data SqlFloat8
+data SqlInt8
+data SqlInt4
+data SqlInt2
+data SqlNumeric
+data SqlText
+data SqlTime
+data SqlTimestamp
+data SqlTimestamptz
+data SqlUuid
+data SqlCitext
+data SqlArray a
+data SqlBytea
+data SqlJson
+data SqlJsonb
+data SqlRange a
+
+type PGBool = SqlBool
+type PGDate = SqlDate
+type PGFloat4 = SqlFloat4
+type PGFloat8 = SqlFloat8
+type PGInt8 = SqlInt8
+type PGInt4 = SqlInt4
+type PGInt2 = SqlInt2
+type PGNumeric = SqlNumeric
+type PGText = SqlText
+type PGTime = SqlTime
+type PGTimestamp = SqlTimestamp
+type PGTimestamptz = SqlTimestamptz
+type PGUuid = SqlUuid
+type PGCitext = SqlCitext
+type PGArray = SqlArray
+type PGBytea = SqlBytea
+type PGJson = SqlJson
+type PGJsonb = SqlJsonb
+type PGRange = SqlRange
diff --git a/src/Opaleye/Internal/Print.hs b/src/Opaleye/Internal/Print.hs
--- a/src/Opaleye/Internal/Print.hs
+++ b/src/Opaleye/Internal/Print.hs
@@ -15,8 +15,12 @@
                                               SelectExists),
                                        From, Join, Values, Binary, Label, Exists)
 
+import qualified Opaleye.Internal.PrimQuery as PQ
+import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
 import qualified Opaleye.Internal.HaskellDB.Sql as HSql
 import qualified Opaleye.Internal.HaskellDB.Sql.Print as HPrint
+import qualified Opaleye.Internal.Optimize as Op
+import qualified Opaleye.Internal.Tag as T
 
 import           Text.PrettyPrint.HughesPJ (Doc, ($$), (<+>), text, empty,
                                             parens)
@@ -185,3 +189,12 @@
   HPrint.ppDelete delete
   $$ text "RETURNING"
   <+> HPrint.commaV HPrint.ppSqlExpr (NEL.toList returnExprs)
+
+-- * Bits from "Opaleye.Sql".  They don't really belong here but I
+-- * have to put them somewhere.
+
+formatAndShowSQL :: ([HPQ.PrimExpr], PQ.PrimQuery' a, T.Tag) -> Maybe String
+formatAndShowSQL = fmap (show . ppSql . Sql.sql) . traverse2Of3 Op.removeEmpty
+  where -- Just a lens
+        traverse2Of3 :: Functor f => (a -> f b) -> (x, a, y) -> f (x, b, y)
+        traverse2Of3 f (x, y, z) = fmap (\y' -> (x, y', z)) (f y)
diff --git a/src/Opaleye/Internal/QueryArr.hs b/src/Opaleye/Internal/QueryArr.hs
--- a/src/Opaleye/Internal/QueryArr.hs
+++ b/src/Opaleye/Internal/QueryArr.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE Arrows #-}
+{-# LANGUAGE TypeSynonymInstances #-}
 
 module Opaleye.Internal.QueryArr where
 
@@ -22,10 +23,16 @@
 
 -- Ideally this should be wrapped in a monad which automatically
 -- increments the Tag, but I couldn't be bothered to do that.
-newtype QueryArr a b = QueryArr ((a, PQ.PrimQuery, Tag) -> (b, PQ.PrimQuery, Tag))
 
-type Query = QueryArr ()
+-- | A parametrised 'Select'.  A @SelectArr a b@ accepts an argument
+-- of type @a@.
+--
+-- @SelectArr a b@ is analogous to a Haskell function @a -> [b]@.
+newtype SelectArr a b = QueryArr ((a, PQ.PrimQuery, Tag) -> (b, PQ.PrimQuery, Tag))
 
+type QueryArr = SelectArr
+type Query = SelectArr ()
+
 productQueryArr :: ((a, Tag) -> (b, PQ.PrimQuery, Tag)) -> QueryArr a b
 productQueryArr f = QueryArr g
   where g (a0, primQuery, t0) = (a1, PQ.times primQuery primQuery', t1)
@@ -58,12 +65,6 @@
 --
 -- @Select a@ is analogous to a Haskell value @[a]@.
 type Select = SelectArr ()
-
--- | A parametrised 'Select'.  A @SelectArr a b@ accepts an argument
--- of type @a@.
---
--- @SelectArr a b@ is analogous to a Haskell function @a -> [b]@.
-type SelectArr = QueryArr
 
 -- | Implements @LATERAL@ subqueries.
 --
diff --git a/src/Opaleye/Internal/RunQuery.hs b/src/Opaleye/Internal/RunQuery.hs
--- a/src/Opaleye/Internal/RunQuery.hs
+++ b/src/Opaleye/Internal/RunQuery.hs
@@ -6,6 +6,7 @@
 import           Control.Applicative
   (Applicative, pure, (<$>), (*>), (<*>), liftA2)
 
+import qualified Database.PostgreSQL.Simple as PGS
 import qualified Database.PostgreSQL.Simple.Cursor  as PGSC (Cursor)
 import           Database.PostgreSQL.Simple.Internal (RowParser)
 import qualified Database.PostgreSQL.Simple.FromField as PGS
@@ -17,10 +18,13 @@
 import           Opaleye.Column (Column)
 import           Opaleye.Internal.Column (Nullable)
 import qualified Opaleye.Internal.PackMap as PackMap
+import qualified Opaleye.Internal.QueryArr as Q
 import qualified Opaleye.Column as C
 import qualified Opaleye.Internal.Unpackspec as U
-import qualified Opaleye.PGTypes as T
+import qualified Opaleye.Internal.PGTypesExternal as T
 import qualified Opaleye.Internal.PGTypes as IPT (strictDecodeUtf8)
+import qualified Opaleye.Select as S
+import qualified Opaleye.Sql as S
 
 import qualified Data.Profunctor as P
 import           Data.Profunctor (dimap)
@@ -50,7 +54,6 @@
 -- }
 
 -- | A 'FromField' @sqlType@ @haskellType@
--- (or the old name, 'QueryRunnerColumn' @sqlType@ @haskellType@)
 -- encodes how to turn
 -- a value of Postgres type @sqlType@ into a value of Haskell type
 -- @haskellType@.  For example a value of type 'FromField'
@@ -68,15 +71,15 @@
 -- be that we can't add nullability to a RowParser, only to a
 -- FieldParser, so we have to have some type that we know contains
 -- just a FieldParser.
-data QueryRunnerColumn pgType haskellType =
+data FromField pgType haskellType =
   QueryRunnerColumn (U.Unpackspec (Column pgType) ()) (FieldParser haskellType)
 
 instance Functor (FromField u) where
   fmap f ~(QueryRunnerColumn u fp) = QueryRunnerColumn u ((fmap . fmap . fmap) f fp)
 
-type FromField = QueryRunnerColumn
+type QueryRunnerColumn = FromField
 
--- | A 'FromFields' (or the old name 'QueryRunner')
+-- | A 'FromFields'
 --   specifies how to convert Postgres values (@fields@)
 --   into Haskell values (@haskells@).  Most likely you will never need
 --   to create on of these or handle one directly.  It will be provided
@@ -86,7 +89,7 @@
 -- postgresql-simple's \"'RowParser' @haskells@\".  \"'Default'
 -- 'FromFields' @columns@ @haskells@\" corresponds to
 -- postgresql-simple's \"@FromRow@ @haskells@\".
-data QueryRunner columns haskells =
+data FromFields columns haskells =
   QueryRunner (U.Unpackspec columns ())
               (columns -> RowParser haskells)
               -- We never actually look at the columns except to see
@@ -102,10 +105,10 @@
               -- because we have a `SumProfunctor` instance.  For some
               -- values of 'columns' there may be zero columns and for
               -- other values one or more, for example, 'Maybe (Column
-              -- PGInt4)' has no columns when it is Nothing and one
+              -- SqlInt4)' has no columns when it is Nothing and one
               -- column when it is Just.
 
-type FromFields = QueryRunner
+type QueryRunner = FromFields
 
 fieldQueryRunnerColumn :: PGS.FromField haskell => FromField pgType haskell
 fieldQueryRunnerColumn = fromPGSFromField
@@ -117,7 +120,7 @@
 fieldParserQueryRunnerColumn = fromPGSFieldParser
 
 fromPGSFieldParser :: FieldParser haskell -> FromField pgType haskell
-fromPGSFieldParser = QueryRunnerColumn (P.rmap (const ()) U.unpackspecColumn)
+fromPGSFieldParser = QueryRunnerColumn (P.rmap (const ()) U.unpackspecField)
 
 queryRunner :: FromField a b -> FromFields (Column a) b
 queryRunner qrc = QueryRunner u (const (fieldWith fp)) (const 1)
@@ -135,7 +138,7 @@
 -- { Instances for automatic derivation
 
 instance DefaultFromField a b =>
-         QueryRunnerColumnDefault (Nullable a) (Maybe b) where
+         DefaultFromField (Nullable a) (Maybe b) where
   defaultFromField = queryRunnerColumnNullable defaultFromField
 
 instance DefaultFromField a b =>
@@ -147,24 +150,18 @@
 -- { Instances that must be provided once for each type.  Instances
 --   for Nullable are derived automatically from these.
 
--- | (Note that a better name for this class would be
--- 'DefaultFromField' and it probably will have this name in version
--- 0.7.  When you see 'QueryRunnerColumnDefault' please read
--- 'DefaultFromField' instead.  That will probably make things easier
--- to understand.)
---
--- A 'QueryRunnerColumnDefault' @sqlType@ @haskellType@ represents
+-- | A 'DefaultFromField' @sqlType@ @haskellType@ represents
 -- the default way to turn a @sqlType@ result from the database into a
 -- Haskell value of type @haskellType@.
 --
--- \"'QueryRunnerColumnDefault' @sqlType@ @haskellType@\" corresponds
+-- \"'DefaultFromField' @sqlType@ @haskellType@\" corresponds
 -- to postgresql-simple's \"'FromField' @haskellType@\".
 --
--- Creating an instance of 'QueryRunnerColumnDefault' for your own types is
+-- Creating an instance of 'DefaultFromField' for your own types is
 -- necessary for retrieving those types from the database.
 --
 -- You should use one of the three methods below for writing a
--- 'QueryRunnerColumnDefault' instance.
+-- 'DefaultFromField' instance.
 --
 -- 1. If you already have a postgresql-simple 'PGS.FromField' instance for
 -- your @haskellType@, use
@@ -179,9 +176,8 @@
 -- 3. If you have a more complicated case, but not a 'PGS.FromField' instance,
 -- write a 'FieldParser' for your type and use 'fromPGSFieldParser'.
 -- You can also add a 'FromField' instance using this.
-class QueryRunnerColumnDefault sqlType haskellType where
-  -- | Do not use @queryRunnerColumnDefault@.  It will be deprecated
-  -- in version 0.7.
+{-# DEPRECATED queryRunnerColumnDefault "Use defaultFromField instead.  It will be removed in 0.8" #-}
+class DefaultFromField sqlType haskellType where
   queryRunnerColumnDefault :: FromField sqlType haskellType
   queryRunnerColumnDefault = defaultFromField
   defaultFromField         :: FromField sqlType haskellType
@@ -189,91 +185,92 @@
 
   {-# MINIMAL queryRunnerColumnDefault | defaultFromField #-}
 
-type DefaultFromField = QueryRunnerColumnDefault
+type QueryRunnerColumnDefault = DefaultFromField
 
 instance DefaultFromField sqlType haskellType
     => D.Default FromField sqlType haskellType where
   def = defaultFromField
 
-instance QueryRunnerColumnDefault T.PGNumeric Sci.Scientific where
+instance DefaultFromField T.SqlNumeric Sci.Scientific where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGInt4 Int where
+instance DefaultFromField T.SqlInt4 Int where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGInt4 Int32 where
+instance DefaultFromField T.SqlInt4 Int32 where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGInt8 Int64 where
+instance DefaultFromField T.SqlInt8 Int64 where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGText String where
+instance DefaultFromField T.SqlText String where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGFloat8 Double where
+instance DefaultFromField T.SqlFloat8 Double where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGBool Bool where
+instance DefaultFromField T.SqlBool Bool where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGUuid UUID where
+instance DefaultFromField T.SqlUuid UUID where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGBytea SBS.ByteString where
+instance DefaultFromField T.SqlBytea SBS.ByteString where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGBytea LBS.ByteString where
+instance DefaultFromField T.SqlBytea LBS.ByteString where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGText ST.Text where
+instance DefaultFromField T.SqlText ST.Text where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGText LT.Text where
+instance DefaultFromField T.SqlText LT.Text where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGDate Time.Day where
+instance DefaultFromField T.SqlDate Time.Day where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGTimestamptz Time.UTCTime where
+instance DefaultFromField T.SqlTimestamptz Time.UTCTime where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGTimestamp Time.LocalTime where
+instance DefaultFromField T.SqlTimestamp Time.LocalTime where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGTimestamptz Time.ZonedTime where
+instance DefaultFromField T.SqlTimestamptz Time.ZonedTime where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGTime Time.TimeOfDay where
+instance DefaultFromField T.SqlTime Time.TimeOfDay where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGCitext (CI.CI ST.Text) where
+instance DefaultFromField T.SqlCitext (CI.CI ST.Text) where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGCitext (CI.CI LT.Text) where
+instance DefaultFromField T.SqlCitext (CI.CI LT.Text) where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGJson String where
+instance DefaultFromField T.SqlJson String where
   defaultFromField = fieldParserQueryRunnerColumn jsonFieldParser
 
-instance QueryRunnerColumnDefault T.PGJson Ae.Value where
+instance DefaultFromField T.SqlJson Ae.Value where
   defaultFromField = fromPGSFromField
 
-instance QueryRunnerColumnDefault T.PGJsonb String where
+instance DefaultFromField T.SqlJsonb String where
   defaultFromField = fieldParserQueryRunnerColumn jsonbFieldParser
 
-instance QueryRunnerColumnDefault T.PGJsonb Ae.Value where
+instance DefaultFromField T.SqlJsonb Ae.Value where
   defaultFromField = fromPGSFromField
 
 -- No CI String instance since postgresql-simple doesn't define FromField (CI String)
 
-arrayColumn :: Column (T.PGArray a) -> Column a
+arrayColumn :: Column (T.SqlArray a) -> Column a
 arrayColumn = C.unsafeCoerceColumn
 
 instance (Typeable b, DefaultFromField a b) =>
-         QueryRunnerColumnDefault (T.PGArray a) [b] where
-  defaultFromField = fromFieldArray defaultFromField
+         DefaultFromField (T.SqlArray a) [b] where
+  defaultFromField = QueryRunnerColumn (P.lmap arrayColumn c) ((fmap . fmap . fmap) fromPGArray (pgArrayFieldParser f))
+    where QueryRunnerColumn c f = defaultFromField
 
-fromFieldArray :: Typeable h => FromField f h -> FromField (T.PGArray f) [h]
+fromFieldArray :: Typeable h => FromField f h -> FromField (T.SqlArray f) [h]
 fromFieldArray q =
   QueryRunnerColumn (P.lmap arrayColumn c)
                     ((fmap . fmap . fmap) fromPGArray (pgArrayFieldParser f))
@@ -282,7 +279,7 @@
 -- }
 
 instance (Typeable b, PGS.FromField b, DefaultFromField a b) =>
-         QueryRunnerColumnDefault (T.PGRange a) (PGSR.PGRange b) where
+         DefaultFromField (T.PGRange a) (PGSR.PGRange b) where
   defaultFromField = fromPGSFromField
 
 -- Boilerplate instances
@@ -353,3 +350,11 @@
 
 -- | Cursor within a transaction.
 data Cursor haskells = EmptyCursor | Cursor (RowParser haskells) PGSC.Cursor
+
+prepareQuery :: FromFields fields haskells -> S.Select fields -> (Maybe PGS.Query, RowParser haskells)
+prepareQuery qr@(QueryRunner u _ _) q = (sql, parser)
+  where sql :: Maybe PGS.Query
+        sql = fmap String.fromString (S.showSqlExplicit u q)
+        -- FIXME: We're doing work twice here
+        (b, _, _) = Q.runSimpleQueryArrStart q ()
+        parser = prepareRowParser qr b
diff --git a/src/Opaleye/Internal/RunQueryExternal.hs b/src/Opaleye/Internal/RunQueryExternal.hs
new file mode 100644
--- /dev/null
+++ b/src/Opaleye/Internal/RunQueryExternal.hs
@@ -0,0 +1,117 @@
+{-# LANGUAGE FlexibleContexts #-}
+
+module Opaleye.Internal.RunQueryExternal
+                 (module Opaleye.Internal.RunQueryExternal,
+                         -- * Datatypes
+                         IRQ.Cursor,
+                         IRQ.FromFields,
+                         IRQ.FromField,
+                         QueryRunner,
+                         IRQ.QueryRunnerColumn,
+                         IRQ.QueryRunnerColumnDefault,
+                         -- * Creating new 'QueryRunnerColumn's
+                         IRQ.fieldQueryRunnerColumn,
+                         IRQ.fieldParserQueryRunnerColumn) where
+
+import           Control.Applicative (pure, (<$>))
+import qualified Database.PostgreSQL.Simple as PGS
+import qualified Database.PostgreSQL.Simple.Cursor  as PGSC
+
+import           Opaleye.Column (Column)
+import qualified Opaleye.Select as S
+import           Opaleye.Internal.RunQuery (QueryRunner, prepareQuery)
+import qualified Opaleye.Internal.RunQuery as IRQ
+
+import qualified Data.Profunctor as P
+import qualified Data.Profunctor.Product.Default as D
+
+-- * Running 'S.Select's
+
+{-# DEPRECATED runQuery "Use 'Opaleye.RunSelect.runSelect' instead.  @runQuery@ will be removed in 0.8." #-}
+runQuery :: D.Default IRQ.FromFields fields haskells
+         => PGS.Connection
+         -> S.Select fields
+         -> IO [haskells]
+runQuery = runQueryExplicit D.def
+
+{-# DEPRECATED runQueryFold "Use 'Opaleye.RunSelect.runSelectFold' instead.  @runQueryFold@ will be removed in 0.8." #-}
+runQueryFold
+  :: D.Default IRQ.FromFields fields haskells
+  => PGS.Connection
+  -> S.Select fields
+  -> b
+  -> (b -> haskells -> IO b)
+  -> IO b
+runQueryFold = runQueryFoldExplicit D.def
+
+-- * Creating new 'QueryRunnerColumn's
+
+{-# DEPRECATED queryRunnerColumn "Use 'Opaleye.RunSelect.unsafeFromField' instead. @queryRunnerColumn@ will be removed in 0.8." #-}
+queryRunnerColumn :: (Column a' -> Column a) -> (b -> b')
+                  -> IRQ.FromField a b -> IRQ.FromField a' b'
+queryRunnerColumn colF haskellF qrc = IRQ.QueryRunnerColumn (P.lmap colF u)
+                                                            (fmapFP haskellF fp)
+  where IRQ.QueryRunnerColumn u fp = qrc
+        fmapFP = fmap . fmap . fmap
+
+-- * Explicit versions
+
+{-# DEPRECATED runQueryExplicit "Use 'Opaleye.RunSelect.runSelectExplict' instead.  Will be removed in 0.8." #-}
+runQueryExplicit :: IRQ.FromFields fields haskells
+                 -> PGS.Connection
+                 -> S.Select fields
+                 -> IO [haskells]
+runQueryExplicit qr conn q = maybe (return []) (PGS.queryWith_ parser conn) sql
+  where (sql, parser) = IRQ.prepareQuery qr q
+
+{-# DEPRECATED runQueryFoldExplicit "Use 'Opaleye.RunSelect.runSelectFoldExplict' instead.  Will be deprecated in 0.8." #-}
+runQueryFoldExplicit
+  :: IRQ.FromFields fields haskells
+  -> PGS.Connection
+  -> S.Select fields
+  -> b
+  -> (b -> haskells -> IO b)
+  -> IO b
+runQueryFoldExplicit qr conn q z f = case sql of
+  Nothing   -> return z
+  Just sql' -> PGS.foldWith_ parser conn sql' z f
+  where (sql, parser) = prepareQuery qr q
+
+-- * Cursor interface
+
+{-# DEPRECATED declareCursor "Use 'Opaleye.RunSelect.declareCursor' instead.  Will be removed in 0.8." #-}
+declareCursor
+    :: D.Default IRQ.FromFields fields haskells
+    => PGS.Connection
+    -> S.Select fields
+    -> IO (IRQ.Cursor haskells)
+declareCursor = declareCursorExplicit D.def
+
+{-# DEPRECATED declareCursorExplicit "Use 'Opaleye.RunSelect.declareCursorExplicit' instead.  Will be removed in 0.8." #-}
+declareCursorExplicit
+    :: IRQ.FromFields fields haskells
+    -> PGS.Connection
+    -> S.Select fields
+    -> IO (IRQ.Cursor haskells)
+declareCursorExplicit qr conn q =
+    case mbQuery of
+      Nothing    -> pure IRQ.EmptyCursor
+      Just query -> IRQ.Cursor rowParser <$> PGSC.declareCursor conn query
+  where
+    (mbQuery, rowParser) = prepareQuery qr q
+
+{-# DEPRECATED closeCursor "Use 'Opaleye.RunSelect.closeCursor' instead.  Will be removed in 0.8." #-}
+closeCursor :: IRQ.Cursor fields -> IO ()
+closeCursor IRQ.EmptyCursor       = pure ()
+closeCursor (IRQ.Cursor _ cursor) = PGSC.closeCursor cursor
+
+{-# DEPRECATED foldForward "Use 'Opaleye.RunSelect.foldForward' instead.  Will be removed in 0.8." #-}
+foldForward
+    :: IRQ.Cursor haskells
+    -> Int
+    -> (a -> haskells -> IO a)
+    -> a
+    -> IO (Either a a)
+foldForward IRQ.EmptyCursor              _chunkSize _f z = pure $ Left z
+foldForward (IRQ.Cursor rowParser cursor) chunkSize  f z =
+    PGSC.foldForwardWithParser cursor rowParser chunkSize f z
diff --git a/src/Opaleye/Internal/Table.hs b/src/Opaleye/Internal/Table.hs
--- a/src/Opaleye/Internal/Table.hs
+++ b/src/Opaleye/Internal/Table.hs
@@ -50,14 +50,15 @@
 -- @
 --
 -- The constructors of Table are internal only and will be
--- deprecated in version 0.7.
+-- removed in version 0.8.
 data Table writeFields viewFields
   = Table String (TableFields writeFields viewFields)
     -- ^ For unqualified table names. Do not use the constructor.  It
-    -- is internal and will be deprecated in version 0.7.
+    -- is considered deprecated and will be removed in version 0.8.
   | TableWithSchema String String (TableFields writeFields viewFields)
     -- ^ Schema name, table name, table properties.  Do not use the
-    -- constructor.  It is internal and will be deprecated in version 0.7.
+    -- constructor.  It is considered deprecated and will be removed
+    -- in version 0.8.
 
 tableIdentifier :: Table writeColumns viewColumns -> PQ.TableIdentifier
 tableIdentifier (Table t _) = PQ.TableIdentifier Nothing t
@@ -71,19 +72,15 @@
 tableProperties :: Table writeColumns viewColumns -> TableFields writeColumns viewColumns
 tableProperties = tableColumns
 
--- | Use 'TableFields' instead. 'TableProperties' will be deprecated
--- in version 0.7.
-data TableProperties writeColumns viewColumns = TableProperties
+data TableFields writeColumns viewColumns = TableFields
    { tablePropertiesWriter :: Writer writeColumns viewColumns
    , tablePropertiesView   :: View viewColumns }
 
--- | Use 'TableFields' instead. 'TableColumns' will be deprecated in
--- version 0.7.
-type TableColumns = TableProperties
+{-# DEPRECATED TableColumns "Use 'TableFields' instead. 'TableColumns' will be removed in  version 0.8." #-}
+type TableColumns = TableFields
 
--- | The new name for 'TableColumns' and 'TableProperties' which will
--- replace them in version 0.7.
-type TableFields = TableProperties
+{-# DEPRECATED TableProperties "Use 'TableFields' instead. 'TableProperties' will be removed in  version 0.8." #-}
+type TableProperties = TableFields
 
 tableColumnsWriter :: TableFields writeColumns viewColumns
                    -> Writer writeColumns viewColumns
@@ -93,12 +90,10 @@
                  -> View viewColumns
 tableColumnsView = tablePropertiesView
 
--- | Internal only.  Do not use.  'View' will be deprecated in version
--- 0.7.
+{-# DEPRECATED View "Internal only.  Do not use.  'View' will be removed in version 0.8." #-}
 newtype View columns = View columns
 
--- | Internal only.  Do not use.  'Writer' will be deprecated in
--- version 0.7.
+{-# DEPRECATED Writer "Internal only.  Do not use.  'Writer' will be removed in 0.8." #-}
 
 -- There's no reason the second parameter should exist except that we
 -- use ProductProfunctors more than ProductContravariants so it makes
@@ -116,14 +111,15 @@
 -- | 'requiredTableField' is for fields which are not optional.  You
 -- must provide them on writes.
 requiredTableField :: String -> TableFields (Column a) (Column a)
-requiredTableField columnName = TableProperties
+requiredTableField columnName = TableFields
   (requiredW columnName)
   (View (Column (HPQ.BaseTableAttrExpr columnName)))
 
+
 -- | 'optionalTableField' is for fields that you can omit on writes, such as
 --  fields which have defaults or which are SERIAL.
 optionalTableField :: String -> TableFields (Maybe (Column a)) (Column a)
-optionalTableField columnName = TableProperties
+optionalTableField columnName = TableFields
   (optionalW columnName)
   (View (Column (HPQ.BaseTableAttrExpr columnName)))
 
@@ -132,24 +128,21 @@
 readOnlyTableField :: String -> TableFields () (Column a)
 readOnlyTableField = lmap (const Nothing) . optionalTableField
 
--- | Use 'requiredTableField' instead.  'required' will be deprecated
--- in 0.7.
+{-# DEPRECATED required  "Use 'requiredTableField' instead.  Will be removed in version 0.8." #-}
 required :: String -> TableFields (Column a) (Column a)
 required = requiredTableField
 
--- | Use 'optionalTableField' instead.  'optional' will be deprecated
--- in 0.7.
+{-# DEPRECATED optional "Use 'optionalTableField' instead.  Will be removed in version 0.8." #-}
 optional :: String -> TableFields (Maybe (Column a)) (Column a)
 optional = optionalTableField
 
--- | Use 'readOnlyTableField' instead.  'readOnly' will be deprecated
--- in 0.7.
+{-# DEPRECATED readOnly "Use 'readOnlyTableField' instead.  Will be removed in version 0.8." #-}
 readOnly :: String -> TableFields () (Column a)
 readOnly = readOnlyTableField
 
+{-# DEPRECATED tableColumn "Use 'tableField' instead.  Will be removed in 0.8." #-}
+
 class TableColumn writeType sqlType | writeType -> sqlType where
-    -- | Do not use.  Use 'tableField' instead.  Will be deprecated in
-    -- 0.7.
     tableColumn :: String -> TableFields writeType (Column sqlType)
     tableColumn = tableField
     -- | Infer either a required ('requiredTableField') or optional
@@ -243,18 +236,18 @@
   purePP = pure
   (****) = (<*>)
 
-instance Functor (TableProperties a) where
-  fmap f (TableProperties w (View v)) = TableProperties (fmap f w) (View (f v))
+instance Functor (TableFields a) where
+  fmap f (TableFields w (View v)) = TableFields (fmap f w) (View (f v))
 
-instance Applicative (TableProperties a) where
-  pure x = TableProperties (pure x) (View x)
-  TableProperties fw (View fv) <*> TableProperties xw (View xv) =
-    TableProperties (fw <*> xw) (View (fv xv))
+instance Applicative (TableFields a) where
+  pure x = TableFields (pure x) (View x)
+  TableFields fw (View fv) <*> TableFields xw (View xv) =
+    TableFields (fw <*> xw) (View (fv xv))
 
-instance Profunctor TableProperties where
-  dimap f g (TableProperties w (View v)) = TableProperties (dimap f g w)
+instance Profunctor TableFields where
+  dimap f g (TableFields w (View v)) = TableFields (dimap f g w)
                                                             (View (g v))
-instance ProductProfunctor TableProperties where
+instance ProductProfunctor TableFields where
   purePP = pure
   (****) = (<*>)
 
diff --git a/src/Opaleye/Internal/TableMaker.hs b/src/Opaleye/Internal/TableMaker.hs
--- a/src/Opaleye/Internal/TableMaker.hs
+++ b/src/Opaleye/Internal/TableMaker.hs
@@ -47,7 +47,7 @@
 
 {-# DEPRECATED column "Use unpackspecColumn instead" #-}
 column :: ColumnMaker (C.Column a) (C.Column a)
-column = U.unpackspecColumn
+column = U.unpackspecField
 
 -- {
 
diff --git a/src/Opaleye/Internal/TypeFamilies.hs b/src/Opaleye/Internal/TypeFamilies.hs
--- a/src/Opaleye/Internal/TypeFamilies.hs
+++ b/src/Opaleye/Internal/TypeFamilies.hs
@@ -74,8 +74,8 @@
 
 type RecordField f a b c = A f ('C '(a, b, c))
 type TableRecordField f a b c d = A f ('TC '( '(a, b, c), d))
--- | Do not use.  Use 'TableRecordField' instead.  Will be deprecated
--- in version 0.7.
+
+{-# DEPRECATED TableField "Use 'TableRecordField' instead.  Will be remoed in version 0.8." #-}
 type TableField f a b c d = TableRecordField f a b c d
 
 -- | Type families parameter for Haskell types ('String', 'Int', etc.)
diff --git a/src/Opaleye/Internal/Unpackspec.hs b/src/Opaleye/Internal/Unpackspec.hs
--- a/src/Opaleye/Internal/Unpackspec.hs
+++ b/src/Opaleye/Internal/Unpackspec.hs
@@ -35,8 +35,7 @@
   -- 'Profunctor', 'ProductProfunctor' and 'SumProfunctor' operations.
   Unpackspec (PM.PackMap HPQ.PrimExpr HPQ.PrimExpr columns columns')
 
--- | Use 'unpackspecField' instead.  @unpackspecColumn@ will be
--- deprecated in version 0.7.
+{-# DEPRECATED unpackspecColumn "Use 'unpackspecField' instead.  Will be removed in version 0.8." #-}
 unpackspecColumn :: Unpackspec (C.Column a) (C.Column a)
 unpackspecColumn = Unpackspec (PM.iso IC.unColumn IC.Column)
 
diff --git a/src/Opaleye/Internal/Values.hs b/src/Opaleye/Internal/Values.hs
--- a/src/Opaleye/Internal/Values.hs
+++ b/src/Opaleye/Internal/Values.hs
@@ -23,7 +23,7 @@
 -- FIXME: We don't currently handle the case of zero columns.  Need to
 -- emit a dummy column and data.
 valuesU :: U.Unpackspec columns columns'
-        -> Valuesspec columns columns'
+        -> ValuesspecUnsafe columns columns'
         -> [columns]
         -> ((), T.Tag) -> (columns', PQ.PrimQuery, T.Tag)
 valuesU unpack valuesspec rows ((), t) = (newColumns, primQ', T.next t)
@@ -55,21 +55,17 @@
                    -> PM.PM [(HPQ.Symbol, primExpr)] HPQ.PrimExpr
 extractValuesField = PM.extractAttr "values"
 
-newtype Valuesspec columns columns' =
+newtype ValuesspecUnsafe columns columns' =
   Valuesspec (PM.PackMap () HPQ.PrimExpr () columns')
 
-type ValuesspecUnsafe = Valuesspec
-
-runValuesspec :: Applicative f => Valuesspec columns columns'
+runValuesspec :: Applicative f => ValuesspecUnsafe columns columns'
               -> (() -> f HPQ.PrimExpr) -> f columns'
 runValuesspec (Valuesspec v) f = PM.traversePM v f ()
 
--- For 0.7 put an `IsSqlType a` constraint on here, so that we can
--- later use it without breaking the API
-instance Default Valuesspec (Column a) (Column a) where
+instance Default ValuesspecUnsafe (Column a) (Column a) where
   def = Valuesspec (PM.iso id Column)
 
-valuesUSafe :: ValuesspecSafe columns columns'
+valuesUSafe :: Valuesspec columns columns'
             -> [columns]
             -> ((), T.Tag) -> (columns', PQ.PrimQuery, T.Tag)
 valuesUSafe valuesspec@(ValuesspecSafe _ unpack) rows ((), t) =
@@ -101,25 +97,27 @@
 
         primQ' = wrap (PQ.Values valuesPEs values)
 
-data ValuesspecSafe columns columns' =
+data Valuesspec columns columns' =
   ValuesspecSafe (PM.PackMap HPQ.PrimExpr HPQ.PrimExpr () columns')
                  (U.Unpackspec columns columns')
 
+type ValuesspecSafe = Valuesspec
+
 runValuesspecSafe :: Applicative f
-                  => ValuesspecSafe columns columns'
+                  => Valuesspec columns columns'
                   -> (HPQ.PrimExpr -> f HPQ.PrimExpr)
                   -> f columns'
 runValuesspecSafe (ValuesspecSafe v _) f = PM.traversePM v f ()
 
 valuesspecField :: Opaleye.SqlTypes.IsSqlType a
-                => ValuesspecSafe (Column a) (Column a)
+                => Valuesspec (Column a) (Column a)
 valuesspecField = def
 
 instance Opaleye.Internal.PGTypes.IsSqlType a
-  => Default ValuesspecSafe (Column a) (Column a) where
+  => Default Valuesspec (Column a) (Column a) where
   def = def_
     where def_ = ValuesspecSafe (PM.PackMap (\f () -> fmap Column (f null_)))
-                                U.unpackspecColumn
+                                U.unpackspecField
           null_ = nullPE sqlType
 
           sqlType = columnProxy def_
@@ -131,7 +129,7 @@
                               (HPQ.ConstExpr HPQ.NullLit)
 
 -- Implementing this in terms of Valuesspec for convenience
-newtype Nullspec fields fields' = Nullspec (ValuesspecSafe fields fields')
+newtype Nullspec fields fields' = Nullspec (Valuesspec fields fields')
 
 nullspecField :: Opaleye.SqlTypes.IsSqlType b
               => Nullspec a (Column b)
@@ -167,32 +165,32 @@
 
 -- Boilerplate instance definitions.  Theoretically, these are derivable.
 
-instance Functor (Valuesspec a) where
+instance Functor (ValuesspecUnsafe a) where
   fmap f (Valuesspec g) = Valuesspec (fmap f g)
 
-instance Applicative (Valuesspec a) where
+instance Applicative (ValuesspecUnsafe a) where
   pure = Valuesspec . pure
   Valuesspec f <*> Valuesspec x = Valuesspec (f <*> x)
 
-instance Profunctor Valuesspec where
+instance Profunctor ValuesspecUnsafe where
   dimap _ g (Valuesspec q) = Valuesspec (rmap g q)
 
-instance ProductProfunctor Valuesspec where
+instance ProductProfunctor ValuesspecUnsafe where
   purePP = pure
   (****) = (<*>)
 
-instance Functor (ValuesspecSafe a) where
+instance Functor (Valuesspec a) where
   fmap f (ValuesspecSafe g h) = ValuesspecSafe (fmap f g) (fmap f h)
 
-instance Applicative (ValuesspecSafe a) where
+instance Applicative (Valuesspec a) where
   pure a = ValuesspecSafe (pure a) (pure a)
   ValuesspecSafe f f' <*> ValuesspecSafe x x' =
     ValuesspecSafe (f <*> x) (f' <*> x')
 
-instance Profunctor ValuesspecSafe where
+instance Profunctor Valuesspec where
   dimap f g (ValuesspecSafe q q') = ValuesspecSafe (rmap g q) (dimap f g q')
 
-instance ProductProfunctor ValuesspecSafe where
+instance ProductProfunctor Valuesspec where
   purePP = pure
   (****) = (<*>)
 
diff --git a/src/Opaleye/Join.hs b/src/Opaleye/Join.hs
--- a/src/Opaleye/Join.hs
+++ b/src/Opaleye/Join.hs
@@ -12,7 +12,7 @@
 import qualified Opaleye.Internal.Join as J
 import qualified Opaleye.Internal.MaybeFields as M
 import qualified Opaleye.Internal.PrimQuery as PQ
-import qualified Opaleye.Map as Map
+import qualified Opaleye.Internal.Map as Map
 import qualified Opaleye.Select   as S
 import qualified Opaleye.SqlTypes as T
 
@@ -253,7 +253,7 @@
 
 -- * Inferrable versions (deprecated)
 
--- | Do not use.  Will be deprecated in 0.7.  Use 'optionalRestrict' instead.
+{-# DEPRECATED leftJoinInferrable "Use 'optionalRestrict' instead." #-}
 leftJoinInferrable :: (D.Default U.Unpackspec fieldsL fieldsL,
                        D.Default U.Unpackspec fieldsR fieldsR,
                        D.Default J.NullMaker fieldsR nullableFieldsR,
@@ -268,8 +268,7 @@
                    -- ^ Left join
 leftJoinInferrable = leftJoin
 
--- | Do not use.  Will be deprecated in 0.7.  Use 'optionalRestrict'
--- instead.
+{-# DEPRECATED rightJoinInferrable "Use 'optionalRestrict' instead." #-}
 rightJoinInferrable :: (D.Default U.Unpackspec fieldsL fieldsL,
                         D.Default U.Unpackspec fieldsR fieldsR,
                         D.Default J.NullMaker fieldsL nullableFieldsL,
@@ -285,8 +284,7 @@
 rightJoinInferrable = rightJoin
 
 
--- | Do not use.  Will be deprecated in 0.7.  Use
--- 'Opaleye.FunctionalJoin.rightJoinF' instead.
+{-# DEPRECATED fullJoinInferrable "Use 'Opaleye.FunctionalJoin.rightJoinF' instead." #-}
 fullJoinInferrable  :: (D.Default U.Unpackspec fieldsL fieldsL,
                         D.Default U.Unpackspec fieldsR fieldsR,
                         D.Default J.NullMaker fieldsL nullableFieldsL,
diff --git a/src/Opaleye/Label.hs b/src/Opaleye/Label.hs
--- a/src/Opaleye/Label.hs
+++ b/src/Opaleye/Label.hs
@@ -1,4 +1,6 @@
-module Opaleye.Label where
+module Opaleye.Label (
+  label
+  ) where
 
 import qualified Opaleye.Internal.Label as L
 import qualified Opaleye.Internal.QueryArr as Q
diff --git a/src/Opaleye/Manipulation.hs b/src/Opaleye/Manipulation.hs
--- a/src/Opaleye/Manipulation.hs
+++ b/src/Opaleye/Manipulation.hs
@@ -23,35 +23,23 @@
 -- @
 
 module Opaleye.Manipulation (module Opaleye.Manipulation,
-                             -- * Other
-                             -- | Do not use the export of
-                             -- 'U.Unpackspec'.  It will not be
-                             -- exported in version 0.7.
-                             U.Unpackspec,
                              -- | Currently 'HSql.DoNothing' is the
                              -- only conflict action supported by
                              -- Opaleye.
                              HSql.OnConflict(..)) where
 
 import qualified Opaleye.Field        as F
-import qualified Opaleye.Internal.Sql as Sql
-import qualified Opaleye.Internal.Print as Print
-import qualified Opaleye.RunQuery as RQ
+import qualified Opaleye.RunSelect as RS
 import qualified Opaleye.Internal.RunQuery as IRQ
 import qualified Opaleye.Table as T
 import qualified Opaleye.Internal.Table as TI
-import           Opaleye.Internal.Column (Column(Column))
-import           Opaleye.Internal.Helpers ((.:), (.:.), (.::.))
+import           Opaleye.Internal.Column (Column)
+import           Opaleye.Internal.Helpers ((.:), (.:.))
 import           Opaleye.Internal.Manipulation (Updater(Updater))
 import qualified Opaleye.Internal.Manipulation as MI
-import qualified Opaleye.Internal.PrimQuery as PQ
-import qualified Opaleye.Internal.Unpackspec as U
 import           Opaleye.SqlTypes (SqlBool)
 
 import qualified Opaleye.Internal.HaskellDB.Sql as HSql
-import qualified Opaleye.Internal.HaskellDB.Sql.Print as HPrint
-import qualified Opaleye.Internal.HaskellDB.Sql.Default as SD
-import qualified Opaleye.Internal.HaskellDB.Sql.Generate as SG
 
 import qualified Database.PostgreSQL.Simple as PGS
 
@@ -175,7 +163,7 @@
 -- compiler will have trouble inferring types.  It is strongly
 -- recommended that you provide full type signatures when using
 -- 'rReturning'.
-rReturning :: D.Default RQ.FromFields fields haskells
+rReturning :: D.Default RS.FromFields fields haskells
            => (fieldsR -> fields)
            -- ^
            -> MI.Returning fieldsR [haskells]
@@ -183,7 +171,7 @@
 
 -- | Return a function of the inserted or updated rows.  Explicit
 -- version.  You probably just want to use 'rReturning' instead.
-rReturningExplicit :: RQ.FromFields fields haskells
+rReturningExplicit :: RS.FromFields fields haskells
                    -- ^
                    -> (fieldsR -> fields)
                    -- ^
@@ -192,138 +180,6 @@
 
 -- * Deprecated versions
 
--- | Returns the number of rows inserted
-
-{-# DEPRECATED runInsert
-    "'runInsert' will be removed in version 0.7. \
-    \Use 'runInsertMany' instead." #-}
-runInsert :: PGS.Connection -> T.Table fields fields' -> fields -> IO Int64
-runInsert conn = PGS.execute_ conn . fromString .: arrangeInsertSql
-
--- | @runInsertReturning@'s use of the 'D.Default' typeclass means that the
--- compiler will have trouble inferring types.  It is strongly
--- recommended that you provide full type signatures when using
--- @runInsertReturning@.
-
-{-# DEPRECATED runInsertReturning
-    "'runInsertReturning' will be removed in version 0.7. \
-    \Use 'runInsertManyReturning' instead." #-}
-runInsertReturning :: (D.Default RQ.QueryRunner fieldsReturned haskells)
-                   => PGS.Connection
-                   -> T.Table fieldsW fieldsR
-                   -> fieldsW
-                   -> (fieldsR -> fieldsReturned)
-                   -> IO [haskells]
-runInsertReturning = runInsertReturningExplicit D.def
-
-{-# DEPRECATED arrangeInsert
-    "You probably want 'runInsertMany' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeInsert :: T.Table columns a -> columns -> HSql.SqlInsert
-arrangeInsert t c = arrangeInsertMany t (return c)
-
-{-# DEPRECATED arrangeInsertSql
-    "You probably want 'runInsertMany' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeInsertSql :: T.Table columns a -> columns -> String
-arrangeInsertSql = show . HPrint.ppInsert .: arrangeInsert
-
-{-# DEPRECATED arrangeInsertMany
-    "You probably want 'runInsertMany' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeInsertMany :: T.Table columns a -> NEL.NonEmpty columns -> HSql.SqlInsert
-arrangeInsertMany t columns = MI.arrangeInsertMany t columns Nothing
-
-{-# DEPRECATED arrangeInsertManySql
-    "You probably want 'runInsertMany' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeInsertManySql :: T.Table columns a -> NEL.NonEmpty columns -> String
-arrangeInsertManySql t c  = MI.arrangeInsertManySql t c Nothing
-
-{-# DEPRECATED arrangeUpdate
-    "You probably want 'runUpdate' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeUpdate :: T.Table columnsW columnsR
-              -> (columnsR -> columnsW) -> (columnsR -> Column SqlBool)
-              -> HSql.SqlUpdate
-arrangeUpdate t update cond =
-  SG.sqlUpdate SD.defaultSqlGenerator
-               (PQ.tiToSqlTable (TI.tableIdentifier t))
-               [condExpr] (update' tableCols)
-  where TI.TableProperties writer (TI.View tableCols) = TI.tableColumns t
-        update' = map (\(x, y) -> (y, x)) . TI.runWriter writer . update
-        Column condExpr = cond tableCols
-
-{-# DEPRECATED arrangeUpdateSql
-    "You probably want 'runUpdate' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeUpdateSql :: T.Table columnsW columnsR
-              -> (columnsR -> columnsW) -> (columnsR -> Column SqlBool)
-              -> String
-arrangeUpdateSql = show . HPrint.ppUpdate .:. arrangeUpdate
-
-{-# DEPRECATED arrangeDelete
-    "You probably want 'runDelete' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeDelete :: T.Table a columnsR -> (columnsR -> Column SqlBool) -> HSql.SqlDelete
-arrangeDelete = MI.arrangeDelete
-
-{-# DEPRECATED arrangeDeleteSql
-    "You probably want 'runDelete' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeDeleteSql :: T.Table a columnsR -> (columnsR -> Column SqlBool) -> String
-arrangeDeleteSql = show . HPrint.ppDelete .: arrangeDelete
-
-{-# DEPRECATED arrangeInsertManyReturning
-    "You probably want 'runInsertMany' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeInsertManyReturning :: U.Unpackspec columnsReturned ignored
-                           -> T.Table columnsW columnsR
-                           -> NEL.NonEmpty columnsW
-                           -> (columnsR -> columnsReturned)
-                           -> Sql.Returning HSql.SqlInsert
-arrangeInsertManyReturning unpackspec t columns returningf =
-  MI.arrangeInsertManyReturning unpackspec t columns returningf Nothing
-
-{-# DEPRECATED arrangeInsertManyReturningSql
-    "You probably want 'runInsertManyReturning' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeInsertManyReturningSql :: U.Unpackspec columnsReturned ignored
-                              -> T.Table columnsW columnsR
-                              -> NEL.NonEmpty columnsW
-                              -> (columnsR -> columnsReturned)
-                              -> String
-arrangeInsertManyReturningSql u t c r =
-  MI.arrangeInsertManyReturningSql u t c r Nothing
-
-{-# DEPRECATED arrangeUpdateReturning
-    "You probably want 'runUpdateReturning' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeUpdateReturning :: U.Unpackspec columnsReturned ignored
-                       -> T.Table columnsW columnsR
-                       -> (columnsR -> columnsW)
-                       -> (columnsR -> Column SqlBool)
-                       -> (columnsR -> columnsReturned)
-                       -> Sql.Returning HSql.SqlUpdate
-arrangeUpdateReturning unpackspec t updatef cond returningf =
-  Sql.Returning update returningSEs
-  where update = arrangeUpdate t updatef cond
-        TI.View columnsR = TI.tableColumnsView (TI.tableColumns t)
-        returningPEs = U.collectPEs unpackspec (returningf columnsR)
-        returningSEs = Sql.ensureColumnsGen id (map Sql.sqlExpr returningPEs)
-
-{-# DEPRECATED arrangeUpdateReturningSql
-    "You probably want 'runUpdateReturning' instead. \
-    \Will be removed in version 0.7." #-}
-arrangeUpdateReturningSql :: U.Unpackspec columnsReturned ignored
-                          -> T.Table columnsW columnsR
-                          -> (columnsR -> columnsW)
-                          -> (columnsR -> Column SqlBool)
-                          -> (columnsR -> columnsReturned)
-                          -> String
-arrangeUpdateReturningSql =
-  show . Print.ppUpdateReturning .::. arrangeUpdateReturning
-
 -- | Insert rows into a table with @ON CONFLICT DO NOTHING@
 {-# DEPRECATED runInsertManyOnConflictDoNothing "Use 'runInsert_'.  Will be removed in version 0.8." #-}
 runInsertManyOnConflictDoNothing :: PGS.Connection
@@ -350,7 +206,7 @@
 -- type signatures when using it.
 {-# DEPRECATED runInsertManyReturningOnConflictDoNothing "Use 'runInsert_'. Will be removed in version 0.8." #-}
 runInsertManyReturningOnConflictDoNothing
-  :: (D.Default RQ.QueryRunner columnsReturned haskells)
+  :: (D.Default RS.FromFields columnsReturned haskells)
   => PGS.Connection
   -- ^
   -> T.Table columnsW columnsR
@@ -364,7 +220,7 @@
 runInsertManyReturningOnConflictDoNothing =
   runInsertManyReturningOnConflictDoNothingExplicit D.def
 
--- | Use 'runInsert_' instead.   Will be deprecated in version 0.7.
+{-# DEPRECATED runInsertMany "Use 'runInsert_' instead.   Will be removed in version 0.8." #-}
 runInsertMany :: PGS.Connection
               -- ^
               -> T.Table columns columns'
@@ -376,10 +232,10 @@
 runInsertMany conn t columns = case NEL.nonEmpty columns of
   -- Inserting the empty list is just the same as returning 0
   Nothing       -> return 0
-  Just columns' -> (PGS.execute_ conn . fromString .: arrangeInsertManySql) t columns'
+  Just columns' -> (PGS.execute_ conn . fromString .: MI.arrangeInsertManySqlI) t columns'
 
--- | Use 'runInsert_' instead.   Will be deprecated in version 0.7.
-runInsertManyReturning :: (D.Default RQ.QueryRunner columnsReturned haskells)
+{-# DEPRECATED runInsertManyReturning "Use 'runInsert_' instead.   Will be removed in version 0.8." #-}
+runInsertManyReturning :: (D.Default RS.FromFields columnsReturned haskells)
                        => PGS.Connection
                        -- ^
                        -> T.Table columnsW columnsR
@@ -392,29 +248,27 @@
                        -- ^ Returned rows after @f@ has been applied
 runInsertManyReturning = runInsertManyReturningExplicit D.def
 
--- | Use 'runInsert_' instead.   Will be deprecated in version 0.7.
-runInsertReturningExplicit :: RQ.QueryRunner columnsReturned haskells
+{-# DEPRECATED runInsertReturningExplicit "Use 'runInsert_' instead. Will be removed in version 0.8." #-}
+runInsertReturningExplicit :: RS.FromFields columnsReturned haskells
                            -> PGS.Connection
                            -> T.Table columnsW columnsR
                            -> columnsW
                            -> (columnsR -> columnsReturned)
                            -> IO [haskells]
-runInsertReturningExplicit qr conn t =
-  runInsertManyReturningExplicit qr conn t . return
+runInsertReturningExplicit = MI.runInsertReturningExplicit
 
--- | Use 'runInsert_' instead.   Will be deprecated in version 0.7.
-runInsertManyReturningExplicit :: RQ.QueryRunner columnsReturned haskells
+{-# DEPRECATED runInsertManyReturningExplicit "Use 'runInsert_' instead.  Will be removed in version 0.8." #-}
+runInsertManyReturningExplicit :: RS.FromFields columnsReturned haskells
                                -> PGS.Connection
                                -> T.Table columnsW columnsR
                                -> [columnsW]
                                -> (columnsR -> columnsReturned)
                                -> IO [haskells]
-runInsertManyReturningExplicit qr conn t columns f =
-  MI.runInsertManyReturningExplicit qr conn t columns f Nothing
+runInsertManyReturningExplicit = MI.runInsertManyReturningExplicitI
 
--- | Use 'runInsert_' instead.   Will be deprecated in version 0.7.
+{-# DEPRECATED runInsertManyReturningOnConflictDoNothingExplicit "Use 'runInsert_' instead.  Will be removed in version 0.8." #-}
 runInsertManyReturningOnConflictDoNothingExplicit
-  :: RQ.QueryRunner columnsReturned haskells
+  :: RS.FromFields columnsReturned haskells
   -> PGS.Connection
   -> T.Table columnsW columnsR
   -> [columnsW]
@@ -423,7 +277,7 @@
 runInsertManyReturningOnConflictDoNothingExplicit qr conn t columns f =
   MI.runInsertManyReturningExplicit qr conn t columns f (Just HSql.DoNothing)
 
--- | Use 'runUpdate_' instead.   Will be deprecated in version 0.7.
+{-# DEPRECATED runUpdateEasy "Use 'runUpdate_' instead.  Will be removed in version 0.8." #-}
 runUpdateEasy :: D.Default Updater columnsR columnsW
               => PGS.Connection
               -> T.Table columnsW columnsR
@@ -439,7 +293,7 @@
 runUpdateEasy conn table_ u = runUpdate conn table_ (u' . u)
   where Updater u' = D.def
 
--- | Use 'runUpdate_' instead.   Will be deprecated in version 0.7.
+{-# DEPRECATED runUpdate "Use 'runUpdate_' instead.  Will be removed in version 0.8." #-}
 runUpdate :: PGS.Connection
           -> T.Table columnsW columnsR
           -- ^ Table to update
@@ -451,10 +305,10 @@
           -- and leave unchanged rows for which @f@ returns @FALSE@.
           -> IO Int64
           -- ^ The number of rows updated
-runUpdate conn = PGS.execute_ conn . fromString .:. arrangeUpdateSql
+runUpdate conn = PGS.execute_ conn . fromString .:. MI.arrangeUpdateSql
 
--- | Use 'runUpdate_' instead.   Will be deprecated in version 0.7.
-runUpdateReturning :: (D.Default RQ.QueryRunner columnsReturned haskells)
+{-# DEPRECATED runUpdateReturning "Use 'runUpdate_' instead.  Will be removed in version 0.8." #-}
+runUpdateReturning :: (D.Default RS.FromFields columnsReturned haskells)
                    => PGS.Connection
                    -- ^
                    -> T.Table columnsW columnsR
@@ -472,8 +326,8 @@
                    -- ^ Returned rows after @g@ has been applied
 runUpdateReturning = runUpdateReturningExplicit D.def
 
--- | Use 'runUpdate_' instead.   Will be deprecated in version 0.7.
-runUpdateReturningExplicit :: RQ.QueryRunner columnsReturned haskells
+{-# DEPRECATED runUpdateReturningExplicit "Use 'runUpdate_' instead.  Will be removed in version 0.8." #-}
+runUpdateReturningExplicit :: RS.FromFields columnsReturned haskells
                            -> PGS.Connection
                            -> T.Table columnsW columnsR
                            -> (columnsR -> columnsW)
@@ -482,12 +336,12 @@
                            -> IO [haskells]
 runUpdateReturningExplicit qr conn t update cond r =
   PGS.queryWith_ parser conn
-                 (fromString (arrangeUpdateReturningSql u t update cond r))
+                 (fromString (MI.arrangeUpdateReturningSql u t update cond r))
   where IRQ.QueryRunner u _ _ = qr
         parser = IRQ.prepareRowParser qr (r v)
         TI.View v = TI.tableColumnsView (TI.tableColumns t)
 
--- | Use 'runDelete_' instead.  Will be deprecated in 0.7.
+{-# DEPRECATED runDelete "Use 'runDelete_' instead.  Will be removed in version 0.8." #-}
 runDelete :: PGS.Connection
           -- ^
           -> T.Table a columnsR
@@ -498,4 +352,4 @@
           -- and leave unchanged rows for which @f@ returns @FALSE@.
           -> IO Int64
           -- ^ The number of rows deleted
-runDelete conn = PGS.execute_ conn . fromString .: arrangeDeleteSql
+runDelete conn = PGS.execute_ conn . fromString .: MI.arrangeDeleteSql
diff --git a/src/Opaleye/Map.hs b/src/Opaleye/Map.hs
--- a/src/Opaleye/Map.hs
+++ b/src/Opaleye/Map.hs
@@ -1,24 +1,4 @@
-{-# LANGUAGE TypeFamilies #-}
-
--- | Do not use. This module will be deprecated in 0.7.
-
-module Opaleye.Map where
-
-type family Map f x
+module Opaleye.Map {-# DEPRECATED "This module will be removed in 0.8." #-}
+  (module Opaleye.Internal.Map) where
 
-type instance Map f (a1, a2)
-  = (Map f a1, Map f a2)
-type instance Map f (a1, a2, a3)
-  = (Map f a1, Map f a2, Map f a3)
-type instance Map f (a1, a2, a3, a4)
-  = (Map f a1, Map f a2, Map f a3, Map f a4)
-type instance Map f (a1, a2, a3, a4, a5)
-  = (Map f a1, Map f a2, Map f a3, Map f a4, Map f a5)
-type instance Map f (a1, a2, a3, a4, a5, a6)
-  = (Map f a1, Map f a2, Map f a3, Map f a4, Map f a5, Map f a6)
-type instance Map f (a1, a2, a3, a4, a5, a6, a7)
-  = (Map f a1, Map f a2, Map f a3, Map f a4, Map f a5, Map f a6,
-     Map f a7)
-type instance Map f (a1, a2, a3, a4, a5, a6, a7, a8)
-  = (Map f a1, Map f a2, Map f a3, Map f a4, Map f a5, Map f a6,
-     Map f a7, Map f a8)
+import Opaleye.Internal.Map
diff --git a/src/Opaleye/Operators.hs b/src/Opaleye/Operators.hs
--- a/src/Opaleye/Operators.hs
+++ b/src/Opaleye/Operators.hs
@@ -16,7 +16,8 @@
 import           Opaleye.Internal.Column (Column(Column), unsafeCase_,
                                           unsafeIfThenElse, unsafeGt)
 import qualified Opaleye.Internal.Column as C
-import           Opaleye.Internal.QueryArr (QueryArr(QueryArr), Query, runSimpleQueryArr)
+import           Opaleye.Internal.QueryArr (SelectArr(QueryArr),
+                                            Query, QueryArr, runSimpleQueryArr)
 import qualified Opaleye.Internal.PrimQuery as PQ
 import qualified Opaleye.Internal.Operators as O
 import           Opaleye.Internal.Helpers   ((.:))
@@ -247,23 +248,24 @@
 -- Used to overload functions and operators that work on both 'T.SqlJson' and 'T.SqlJsonb'.
 --
 -- Warning: making additional instances of this class can lead to broken code!
-class PGIsJson a
+class SqlIsJson a
 
-type SqlIsJson = PGIsJson
+{-# DEPRECATED PGIsJson "Use SqlIsJson instead" #-}
+type PGIsJson = SqlIsJson
 
-instance PGIsJson T.SqlJson
-instance PGIsJson T.SqlJsonb
+instance SqlIsJson T.SqlJson
+instance SqlIsJson T.SqlJsonb
 
 -- | Class of Postgres types that can be used to index json values.
 --
 -- Warning: making additional instances of this class can lead to broken code!
-class PGJsonIndex a
+class SqlJsonIndex a
 
-type SqlJsonIndex = PGJsonIndex
+type PGJsonIndex = SqlJsonIndex
 
-instance PGJsonIndex T.SqlInt4
-instance PGJsonIndex T.SqlInt8
-instance PGJsonIndex T.SqlText
+instance SqlJsonIndex T.SqlInt4
+instance SqlJsonIndex T.SqlInt8
+instance SqlJsonIndex T.SqlText
 
 -- | Get JSON object field by key.
 infixl 8 .->
@@ -398,21 +400,15 @@
 
 -- * Deprecated
 
-{-# DEPRECATED doubleOfInt
-    "Use 'C.unsafeCast' instead. \
-    \Will be removed in version 0.7." #-}
-doubleOfInt :: F.Field T.SqlInt4 -> F.Field T.SqlFloat8
-doubleOfInt (Column e) = Column (HPQ.CastExpr "float8" e)
-
--- | Identical to 'restrictExists'.  Will be deprecated in version 0.7.
+{-# DEPRECATED exists "Identical to 'restrictExists'.  Will be removed in version 0.8." #-}
 exists :: QueryArr a b -> QueryArr a ()
 exists = restrictExists
 
--- | Identical to 'restrictNotExists'.  Will be deprecated in version 0.7.
+{-# DEPRECATED notExists "Identical to 'restrictNotExists'.  Will be removed in version 0.8." #-}
 notExists :: QueryArr a b -> QueryArr a ()
 notExists = restrictNotExists
 
--- | Identical to 'inSelect'.  Will be deprecated in version 0.7.
+{-# DEPRECATED inQuery "Identical to 'inSelect'.  Will be removed in version 0.8." #-}
 inQuery :: D.Default O.EqPP fields fields
         => fields -> Query fields -> S.Select (F.Field T.SqlBool)
 inQuery = inSelect
diff --git a/src/Opaleye/Order.hs b/src/Opaleye/Order.hs
--- a/src/Opaleye/Order.hs
+++ b/src/Opaleye/Order.hs
@@ -143,22 +143,23 @@
 -- * Other
 
 -- | Typeclass for Postgres types which support ordering operations.
-class PGOrd a where
+class SqlOrd a where
 
-type SqlOrd = PGOrd
+{-# DEPRECATED PGOrd "Use SqlOrd instead" #-}
+type PGOrd = SqlOrd
 
-instance PGOrd T.SqlBool
-instance PGOrd T.SqlDate
-instance PGOrd T.SqlFloat8
-instance PGOrd T.SqlFloat4
-instance PGOrd T.SqlInt8
-instance PGOrd T.SqlInt4
-instance PGOrd T.SqlInt2
-instance PGOrd T.SqlNumeric
-instance PGOrd T.SqlText
-instance PGOrd T.SqlTime
-instance PGOrd T.SqlTimestamptz
-instance PGOrd T.SqlTimestamp
-instance PGOrd T.SqlCitext
-instance PGOrd T.SqlUuid
-instance PGOrd a => PGOrd (C.Nullable a)
+instance SqlOrd T.SqlBool
+instance SqlOrd T.SqlDate
+instance SqlOrd T.SqlFloat8
+instance SqlOrd T.SqlFloat4
+instance SqlOrd T.SqlInt8
+instance SqlOrd T.SqlInt4
+instance SqlOrd T.SqlInt2
+instance SqlOrd T.SqlNumeric
+instance SqlOrd T.SqlText
+instance SqlOrd T.SqlTime
+instance SqlOrd T.SqlTimestamptz
+instance SqlOrd T.SqlTimestamp
+instance SqlOrd T.SqlCitext
+instance SqlOrd T.SqlUuid
+instance SqlOrd a => SqlOrd (C.Nullable a)
diff --git a/src/Opaleye/PGTypes.hs b/src/Opaleye/PGTypes.hs
--- a/src/Opaleye/PGTypes.hs
+++ b/src/Opaleye/PGTypes.hs
@@ -1,259 +1,4 @@
--- | Use "Opaleye.SqlTypes" instead.  Will be deprecated in version 0.7.
-
-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Opaleye.PGTypes (module Opaleye.PGTypes, IsSqlType(..)) where
-
-import           Opaleye.Internal.Column (Column)
-import qualified Opaleye.Internal.Column as C
-import qualified Opaleye.Internal.PGTypes as IPT
-import           Opaleye.Internal.PGTypes (IsSqlType(..))
-
-import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
-import qualified Opaleye.Internal.HaskellDB.Sql.Default as HSD
-
-import qualified Data.CaseInsensitive as CI
-import qualified Data.Aeson as Ae
-import qualified Data.Text as SText
-import qualified Data.Text.Lazy as LText
-import qualified Data.ByteString as SByteString
-import qualified Data.ByteString.Lazy as LByteString
-import           Data.Scientific as Sci
-import qualified Data.Time as Time
-import qualified Data.UUID as UUID
-
-import           Data.Int (Int64)
-
-import qualified Database.PostgreSQL.Simple.Range as R
-
-instance C.PGNum PGFloat8 where
-  sqlFromInteger = pgDouble . fromInteger
-
-instance C.PGNum PGInt4 where
-  sqlFromInteger = pgInt4 . fromInteger
-
-instance C.PGNum PGInt8 where
-  sqlFromInteger = pgInt8 . fromInteger
-
-instance C.PGFractional PGFloat8 where
-  sqlFromRational = pgDouble . fromRational
-
-instance C.PGIntegral PGInt2
-instance C.PGIntegral PGNumeric
-instance C.PGIntegral PGInt4
-instance C.PGIntegral PGInt8
-
-instance C.PGString PGText where
-  sqlFromString = pgString
-
-instance C.PGString PGCitext where
-  sqlFromString = pgCiLazyText . CI.mk . LText.pack
-
--- * Creating SQL values
-
-pgString :: String -> Column PGText
-pgString = IPT.literalColumn . HPQ.StringLit
-
-pgLazyByteString :: LByteString.ByteString -> Column PGBytea
-pgLazyByteString = IPT.literalColumn . HPQ.ByteStringLit . LByteString.toStrict
-
-pgStrictByteString :: SByteString.ByteString -> Column PGBytea
-pgStrictByteString = IPT.literalColumn . HPQ.ByteStringLit
-
-pgStrictText :: SText.Text -> Column PGText
-pgStrictText = IPT.literalColumn . HPQ.StringLit . SText.unpack
-
-pgLazyText :: LText.Text -> Column PGText
-pgLazyText = IPT.literalColumn . HPQ.StringLit . LText.unpack
-
-pgNumeric :: Sci.Scientific -> Column PGNumeric
-pgNumeric = IPT.literalColumn . HPQ.NumericLit
-
-pgInt4 :: Int -> Column PGInt4
-pgInt4 = IPT.literalColumn . HPQ.IntegerLit . fromIntegral
-
-pgInt8 :: Int64 -> Column PGInt8
-pgInt8 = IPT.literalColumn . HPQ.IntegerLit . fromIntegral
-
-pgDouble :: Double -> Column PGFloat8
-pgDouble = IPT.literalColumn . HPQ.DoubleLit
-
-pgBool :: Bool -> Column PGBool
-pgBool = IPT.literalColumn . HPQ.BoolLit
-
-pgUUID :: UUID.UUID -> Column PGUuid
-pgUUID = IPT.literalColumn . HPQ.StringLit . UUID.toString
-
-pgDay :: Time.Day -> Column PGDate
-pgDay = IPT.unsafePgFormatTime "date" "'%F'"
-
-pgUTCTime :: Time.UTCTime -> Column PGTimestamptz
-pgUTCTime = IPT.unsafePgFormatTime "timestamptz" "'%FT%T%QZ'"
-
-pgLocalTime :: Time.LocalTime -> Column PGTimestamp
-pgLocalTime = IPT.unsafePgFormatTime "timestamp" "'%FT%T%Q'"
-
-pgZonedTime :: Time.ZonedTime -> Column PGTimestamptz
-pgZonedTime = IPT.unsafePgFormatTime "timestamptz" "'%FT%T%Q%z'"
-
-pgTimeOfDay :: Time.TimeOfDay -> Column PGTime
-pgTimeOfDay = IPT.unsafePgFormatTime "time" "'%T%Q'"
-
--- "We recommend not using the type time with time zone"
--- http://www.postgresql.org/docs/8.3/static/datatype-datetime.html
-
-
-pgCiStrictText :: CI.CI SText.Text -> Column PGCitext
-pgCiStrictText = IPT.literalColumn . HPQ.StringLit . SText.unpack . CI.original
-
-pgCiLazyText :: CI.CI LText.Text -> Column PGCitext
-pgCiLazyText = IPT.literalColumn . HPQ.StringLit . LText.unpack . CI.original
-
--- No CI String instance since postgresql-simple doesn't define
--- FromField (CI String)
-
--- The json data type was introduced in PostgreSQL version 9.2
--- JSON values must be SQL string quoted
-pgJSON :: String -> Column PGJson
-pgJSON = IPT.castToType "json" . HSD.quote
-
-pgStrictJSON :: SByteString.ByteString -> Column PGJson
-pgStrictJSON = pgJSON . IPT.strictDecodeUtf8
-
-pgLazyJSON :: LByteString.ByteString -> Column PGJson
-pgLazyJSON = pgJSON . IPT.lazyDecodeUtf8
-
-pgValueJSON :: Ae.ToJSON a => a -> Column PGJson
-pgValueJSON = pgLazyJSON . Ae.encode
-
--- The jsonb data type was introduced in PostgreSQL version 9.4
--- JSONB values must be SQL string quoted
---
--- TODO: We need to add literal JSON and JSONB types so we can say
--- `castToTypeTyped JSONB` rather than `castToType "jsonb"`.
-pgJSONB :: String -> Column PGJsonb
-pgJSONB = IPT.castToType "jsonb" . HSD.quote
-
-pgStrictJSONB :: SByteString.ByteString -> Column PGJsonb
-pgStrictJSONB = pgJSONB . IPT.strictDecodeUtf8
-
-pgLazyJSONB :: LByteString.ByteString -> Column PGJsonb
-pgLazyJSONB = pgJSONB . IPT.lazyDecodeUtf8
-
-pgValueJSONB :: Ae.ToJSON a => a -> Column PGJsonb
-pgValueJSONB = pgLazyJSONB . Ae.encode
-
-pgArray :: forall a b. IsSqlType b
-        => (a -> C.Column b) -> [a] -> C.Column (PGArray b)
-pgArray pgEl xs = C.unsafeCast arrayTy $
-  C.Column (HPQ.ArrayExpr (map oneEl xs))
-  where
-    oneEl = C.unColumn . pgEl
-    arrayTy = showSqlType ([] :: [PGArray b])
-
-pgRange :: forall a b. IsRangeType b
-        => (a -> C.Column b) -> R.RangeBound a -> R.RangeBound a
-        -> C.Column (PGRange b)
-pgRange pgEl start end =
-  C.Column (HPQ.RangeExpr (showRangeType ([] :: [b])) (oneEl start) (oneEl end))
-  where oneEl (R.Inclusive a) = HPQ.Inclusive . C.unColumn $ pgEl a
-        oneEl (R.Exclusive a) = HPQ.Exclusive . C.unColumn $ pgEl a
-        oneEl R.NegInfinity   = HPQ.NegInfinity
-        oneEl R.PosInfinity   = HPQ.PosInfinity
-
-instance IsSqlType PGBool where
-  showSqlType _ = "boolean"
-instance IsSqlType PGDate where
-  showSqlType _ = "date"
-instance IsSqlType PGFloat4 where
-  showSqlType _ = "real"
-instance IsSqlType PGFloat8 where
-  showSqlType _ = "double precision"
-instance IsSqlType PGInt8 where
-  showSqlType _ = "bigint"
-instance IsSqlType PGInt4 where
-  showSqlType _ = "integer"
-instance IsSqlType PGInt2 where
-  showSqlType _ = "smallint"
-instance IsSqlType PGNumeric where
-  showSqlType _ = "numeric"
-instance IsSqlType PGText where
-  showSqlType _ = "text"
-instance IsSqlType PGTime where
-  showSqlType _ = "time"
-instance IsSqlType PGTimestamp where
-  showSqlType _ = "timestamp"
-instance IsSqlType PGTimestamptz where
-  showSqlType _ = "timestamp with time zone"
-instance IsSqlType PGUuid where
-  showSqlType _ = "uuid"
-instance IsSqlType PGCitext where
-  showSqlType _ =  "citext"
-instance IsSqlType PGBytea where
-  showSqlType _ = "bytea"
-instance IsSqlType a => IsSqlType (PGArray a) where
-  showSqlType _ = showSqlType ([] :: [a]) ++ "[]"
-instance IsSqlType PGJson where
-  showSqlType _ = "json"
-instance IsSqlType PGJsonb where
-  showSqlType _ = "jsonb"
-instance IsRangeType a => IsSqlType (PGRange a) where
-  showSqlType _ = showRangeType ([] :: [a])
-
-class IsSqlType pgType => IsRangeType pgType where
-  showRangeType :: proxy pgType -> String
-
-instance IsRangeType PGInt4 where
-  showRangeType _ = "int4range"
-
-instance IsRangeType PGInt8 where
-  showRangeType _ = "int8range"
-
-instance IsRangeType PGNumeric where
-  showRangeType _ = "numrange"
-
-instance IsRangeType PGTimestamp where
-  showRangeType _ = "tsrange"
-
-instance IsRangeType PGTimestamptz where
-  showRangeType _ = "tstzrange"
-
-instance IsRangeType PGDate where
-  showRangeType _ = "daterange"
-
--- * SQL datatypes
-
-data PGBool
-data PGDate
-data PGFloat4
-data PGFloat8
-data PGInt8
-data PGInt4
-data PGInt2
-data PGNumeric
-data PGText
-data PGTime
-data PGTimestamp
-data PGTimestamptz
-data PGUuid
-data PGCitext
-data PGArray a
-data PGBytea
-data PGJson
-data PGJsonb
-data PGRange a
-
--- * Deprecated functions
-
-literalColumn :: HPQ.Literal -> Column a
-literalColumn = C.Column . HPQ.ConstExpr
-{-# DEPRECATED literalColumn
-    "'literalColumn' has been moved to Opaleye.Internal.PGTypes and will be removed in version 0.7."
-  #-}
+module Opaleye.PGTypes {-# DEPRECATED "Use \"Opaleye.SqlTypes\" instead." #-}
+  (module Opaleye.Internal.PGTypesExternal) where
 
-unsafePgFormatTime :: Time.FormatTime t => HPQ.Name -> String -> t -> Column c
-unsafePgFormatTime = IPT.unsafePgFormatTime
-{-# DEPRECATED unsafePgFormatTime
-    "'unsafePgFormatTime' has been moved to Opaleye.Internal.PGTypes and will be removed in version 0.7."
-  #-}
+import Opaleye.Internal.PGTypesExternal
diff --git a/src/Opaleye/QueryArr.hs b/src/Opaleye/QueryArr.hs
--- a/src/Opaleye/QueryArr.hs
+++ b/src/Opaleye/QueryArr.hs
@@ -1,6 +1,3 @@
--- | Use "Opaleye.Select" instead.  This module will be deprecated in
--- 0.7.
-
-module Opaleye.QueryArr (Query, QueryArr) where
+module Opaleye.QueryArr {-# DEPRECATED "Use \"Opaleye.Select\" instead.  This module will be removed in 0.8." #-} (Query, QueryArr) where
 
 import           Opaleye.Internal.QueryArr (QueryArr, Query)
diff --git a/src/Opaleye/RunQuery.hs b/src/Opaleye/RunQuery.hs
--- a/src/Opaleye/RunQuery.hs
+++ b/src/Opaleye/RunQuery.hs
@@ -1,142 +1,4 @@
-{-# LANGUAGE FlexibleContexts #-}
-
--- | This module will be deprecated in 0.7.  Use "Opaleye.RunSelect" instead.
-
-module Opaleye.RunQuery (module Opaleye.RunQuery,
-                         -- * Datatypes
-                         IRQ.Cursor,
-                         IRQ.FromFields,
-                         IRQ.FromField,
-                         QueryRunner,
-                         IRQ.QueryRunnerColumn,
-                         IRQ.QueryRunnerColumnDefault (..),
-                         -- * Creating new 'QueryRunnerColumn's
-                         IRQ.fieldQueryRunnerColumn,
-                         IRQ.fieldParserQueryRunnerColumn) where
-
-import           Control.Applicative (pure, (<$>))
-import qualified Database.PostgreSQL.Simple as PGS
-import qualified Database.PostgreSQL.Simple.Cursor  as PGSC
-import qualified Database.PostgreSQL.Simple.FromRow as FR
-import qualified Data.String as String
-
-import           Opaleye.Column (Column)
-import qualified Opaleye.Select as S
-import qualified Opaleye.Sql as S
-import           Opaleye.Internal.RunQuery (QueryRunner(QueryRunner))
-import qualified Opaleye.Internal.RunQuery as IRQ
-import qualified Opaleye.Internal.QueryArr as Q
-
-import qualified Data.Profunctor as P
-import qualified Data.Profunctor.Product.Default as D
-
--- * Running 'S.Select's
-
--- | Use 'Opaleye.RunSelect.runSelect' instead.  @runQuery@ will be
--- deprecated in 0.7.
-runQuery :: D.Default IRQ.FromFields fields haskells
-         => PGS.Connection
-         -> S.Select fields
-         -> IO [haskells]
-runQuery = runQueryExplicit D.def
-
--- | Use 'Opaleye.RunSelect.runSelectFold' instead.  @runQueryFold@
--- will be deprecated in 0.7.
-runQueryFold
-  :: D.Default IRQ.FromFields fields haskells
-  => PGS.Connection
-  -> S.Select fields
-  -> b
-  -> (b -> haskells -> IO b)
-  -> IO b
-runQueryFold = runQueryFoldExplicit D.def
-
--- * Creating new 'QueryRunnerColumn's
-
--- | Use 'Opaleye.RunSelect.unsafeFromField' instead.
--- @queryRunnerColumn@ will be deprecated in 0.7.
-queryRunnerColumn :: (Column a' -> Column a) -> (b -> b')
-                  -> IRQ.FromField a b -> IRQ.FromField a' b'
-queryRunnerColumn colF haskellF qrc = IRQ.QueryRunnerColumn (P.lmap colF u)
-                                                            (fmapFP haskellF fp)
-  where IRQ.QueryRunnerColumn u fp = qrc
-        fmapFP = fmap . fmap . fmap
-
--- * Explicit versions
-
--- | Use 'Opaleye.RunSelect.runSelectExplict' instead.  Will be
--- deprecated in 0.7.
-runQueryExplicit :: IRQ.FromFields fields haskells
-                 -> PGS.Connection
-                 -> S.Select fields
-                 -> IO [haskells]
-runQueryExplicit qr conn q = maybe (return []) (PGS.queryWith_ parser conn) sql
-  where (sql, parser) = prepareQuery qr q
-
--- | Use 'Opaleye.RunSelect.runSelectFoldExplict' instead.  Will be
--- deprecated in 0.7.
-runQueryFoldExplicit
-  :: IRQ.FromFields fields haskells
-  -> PGS.Connection
-  -> S.Select fields
-  -> b
-  -> (b -> haskells -> IO b)
-  -> IO b
-runQueryFoldExplicit qr conn q z f = case sql of
-  Nothing   -> return z
-  Just sql' -> PGS.foldWith_ parser conn sql' z f
-  where (sql, parser) = prepareQuery qr q
-
--- * Cursor interface
-
--- | Use 'Opaleye.RunSelect.declareCursor' instead.  Will be
--- deprecated in 0.7.
-declareCursor
-    :: D.Default IRQ.FromFields fields haskells
-    => PGS.Connection
-    -> S.Select fields
-    -> IO (IRQ.Cursor haskells)
-declareCursor = declareCursorExplicit D.def
-
--- | Use 'Opaleye.RunSelect.declareCursorExplicit' instead.  Will be
--- deprecated in 0.7.
-declareCursorExplicit
-    :: IRQ.FromFields fields haskells
-    -> PGS.Connection
-    -> S.Select fields
-    -> IO (IRQ.Cursor haskells)
-declareCursorExplicit qr conn q =
-    case mbQuery of
-      Nothing    -> pure IRQ.EmptyCursor
-      Just query -> IRQ.Cursor rowParser <$> PGSC.declareCursor conn query
-  where
-    (mbQuery, rowParser) = prepareQuery qr q
-
--- | Use 'Opaleye.RunSelect.closeCursor' instead.  Will be
--- deprecated in 0.7.
-closeCursor :: IRQ.Cursor fields -> IO ()
-closeCursor IRQ.EmptyCursor       = pure ()
-closeCursor (IRQ.Cursor _ cursor) = PGSC.closeCursor cursor
-
--- | Use 'Opaleye.RunSelect.foldForward' instead.  Will be
--- deprecated in 0.7.
-foldForward
-    :: IRQ.Cursor haskells
-    -> Int
-    -> (a -> haskells -> IO a)
-    -> a
-    -> IO (Either a a)
-foldForward IRQ.EmptyCursor              _chunkSize _f z = pure $ Left z
-foldForward (IRQ.Cursor rowParser cursor) chunkSize  f z =
-    PGSC.foldForwardWithParser cursor rowParser chunkSize f z
-
--- * Deprecated functions
+module Opaleye.RunQuery {-# DEPRECATED "Use \"Opaleye.RunSelect\" instead." #-}
+  (module Opaleye.Internal.RunQueryExternal) where
 
-{-# DEPRECATED prepareQuery "Will be removed in version 0.7" #-}
-prepareQuery :: IRQ.FromFields fields haskells -> S.Select fields -> (Maybe PGS.Query, FR.RowParser haskells)
-prepareQuery qr@(QueryRunner u _ _) q = (sql, parser)
-  where sql :: Maybe PGS.Query
-        sql = fmap String.fromString (S.showSqlForPostgresExplicit u q)
-        -- FIXME: We're doing work twice here
-        (b, _, _) = Q.runSimpleQueryArrStart q ()
-        parser = IRQ.prepareRowParser qr b
+import Opaleye.Internal.RunQueryExternal
diff --git a/src/Opaleye/RunSelect.hs b/src/Opaleye/RunSelect.hs
--- a/src/Opaleye/RunSelect.hs
+++ b/src/Opaleye/RunSelect.hs
@@ -3,13 +3,26 @@
 {-# LANGUAGE TypeFamilies #-}
 
 module Opaleye.RunSelect
-  (module Opaleye.RunSelect,
+  (-- * Running 'S.Select's
+   runSelect,
+   runSelectI,
+   runSelectTF,
+   runSelectFold,
+   -- * Cursor interface
+   declareCursor,
+   closeCursor,
+   foldForward,
+   -- * Creating new 'FromField's
+   unsafeFromField,
+   -- * Explicit versions
+   runSelectExplicit,
+   runSelectFoldExplicit,
+   declareCursorExplicit,
    -- * Datatypes
    IRQ.Cursor,
    IRQ.FromFields,
    IRQ.FromField,
-   IRQ.DefaultFromField,
-   IRQ.defaultFromField,
+   IRQ.DefaultFromField(defaultFromField),
    -- * Helper functions
    IRQ.fromPGSFromField,
    IRQ.fromPGSFieldParser) where
@@ -19,7 +32,7 @@
 
 import qualified Opaleye.Column as C
 import qualified Opaleye.Select as S
-import qualified Opaleye.RunQuery          as RQ
+import qualified Opaleye.Internal.RunQueryExternal as RQ
 import qualified Opaleye.TypeFamilies as TF
 import           Opaleye.Internal.RunQuery (FromFields)
 import qualified Opaleye.Internal.RunQuery as IRQ
@@ -27,8 +40,6 @@
 
 import qualified Data.Profunctor.Product.Default as D
 
--- * Running 'S.Select's
-
 -- | @runSelect@'s use of the @'D.Default' 'FromFields'@
 -- typeclass means that the
 -- compiler will have trouble inferring types.  It is strongly
@@ -83,8 +94,6 @@
   -> IO b
 runSelectFold = RQ.runQueryFold
 
--- * Cursor interface
-
 -- | Declare a temporary cursor. The cursor is given a unique name for the given
 -- connection.
 declareCursor
@@ -115,15 +124,13 @@
     -> IO (Either a a)
 foldForward = RQ.foldForward
 
--- * Creating new 'FromField's
-
 -- | Use 'unsafeFromField' to make an instance to allow you to run
 --   queries on your own datatypes.  For example:
 --
 -- @
 -- newtype Foo = Foo Int
 --
--- instance QueryRunnerColumnDefault Foo Foo where
+-- instance DefaultFromField Foo Foo where
 --    defaultFromField = unsafeFromField Foo defaultFromField
 -- @
 --
@@ -137,8 +144,6 @@
   where IRQ.QueryRunnerColumn u fp = qrc
         fmapFP = fmap . fmap . fmap
         colF = C.unsafeCoerceColumn
-
--- * Explicit versions
 
 runSelectExplicit :: FromFields fields haskells
                   -> PGS.Connection
diff --git a/src/Opaleye/Sql.hs b/src/Opaleye/Sql.hs
--- a/src/Opaleye/Sql.hs
+++ b/src/Opaleye/Sql.hs
@@ -1,24 +1,29 @@
 {-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}
 
-module Opaleye.Sql where
-
-import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
+module Opaleye.Sql (
+  -- * Showing SQL
+  showSql,
+  showSqlUnopt,
+  -- * Explicit versions
+  showSqlExplicit,
+  showSqlUnoptExplicit,
+  -- * Deprecated functions
+  showSqlForPostgres,
+  showSqlForPostgresUnopt,
+  showSqlForPostgresExplicit,
+  showSqlForPostgresUnoptExplicit,
+  ) where
 
 import qualified Opaleye.Internal.Unpackspec as U
-import qualified Opaleye.Internal.Sql as Sql
 import qualified Opaleye.Internal.Print as Pr
-import qualified Opaleye.Internal.PrimQuery as PQ
 import qualified Opaleye.Internal.Optimize as Op
 import           Opaleye.Internal.Helpers ((.:))
 import qualified Opaleye.Internal.QueryArr as Q
-import qualified Opaleye.Internal.Tag as T
 
 import qualified Opaleye.Select as S
 
 import qualified Data.Profunctor.Product.Default as D
 
--- * Showing SQL
-
 -- | Show the SQL query string generated from the 'S.Select'.
 --
 -- When 'Nothing' is returned it means that the 'S.Select' returns zero
@@ -49,41 +54,28 @@
              -> Maybe String
 showSqlUnopt = showSqlUnoptExplicit (D.def :: U.Unpackspec fields fields)
 
--- * Explicit versions
-
 showSqlExplicit :: U.Unpackspec fields b -> S.Select fields -> Maybe String
-showSqlExplicit = formatAndShowSQL
+showSqlExplicit = Pr.formatAndShowSQL
                   . (\(x, y, z) -> (x, Op.optimize y, z))
                   .: Q.runQueryArrUnpack
 
 showSqlUnoptExplicit :: U.Unpackspec fields b -> S.Select fields -> Maybe String
-showSqlUnoptExplicit = formatAndShowSQL .: Q.runQueryArrUnpack
-
--- * Deprecated functions
+showSqlUnoptExplicit = Pr.formatAndShowSQL .: Q.runQueryArrUnpack
 
--- | Will be deprecated in version 0.7.  Use 'showSql' instead.
+{-# DEPRECATED showSqlForPostgres "Will be removed in version 0.8.  Use 'showSql' instead." #-}
 showSqlForPostgres :: forall columns . D.Default U.Unpackspec columns columns =>
                       S.Select columns -> Maybe String
 showSqlForPostgres = showSql
 
--- | Will be deprecated in version 0.7.  Use 'showSqlUnopt' instead.
+{-# DEPRECATED showSqlForPostgresUnopt "Will be removed in version 0.8.  Use 'showSqlUnopt' instead." #-}
 showSqlForPostgresUnopt :: forall columns . D.Default U.Unpackspec columns columns =>
                            S.Select columns -> Maybe String
 showSqlForPostgresUnopt = showSqlUnopt
 
--- | Will be deprecated in version 0.7.  Use 'showSqlExplicit' instead.
+{-# DEPRECATED showSqlForPostgresExplicit "Will be removed in version 0.8.  Use 'showSqlExplicit' instead." #-}
 showSqlForPostgresExplicit :: U.Unpackspec columns b -> S.Select columns -> Maybe String
 showSqlForPostgresExplicit = showSqlExplicit
 
--- | Will be deprecated in version 0.7.  Use 'showSqlUnoptExplicit' instead.
+{-# DEPRECATED showSqlForPostgresUnoptExplicit "Will be removed in version 0.8.  Use 'showSqlUnoptExplicit' instead." #-}
 showSqlForPostgresUnoptExplicit :: U.Unpackspec columns b -> S.Select columns -> Maybe String
 showSqlForPostgresUnoptExplicit = showSqlUnoptExplicit
-
-{-# DEPRECATED formatAndShowSQL
-    "You probably want 'showSqlExplicit' or 'showSqlUnoptExplicit' instead. \
-    \Will be removed in version 0.7." #-}
-formatAndShowSQL :: ([HPQ.PrimExpr], PQ.PrimQuery' a, T.Tag) -> Maybe String
-formatAndShowSQL = fmap (show . Pr.ppSql . Sql.sql) . traverse2Of3 Op.removeEmpty
-  where -- Just a lens
-        traverse2Of3 :: Functor f => (a -> f b) -> (x, a, y) -> f (x, b, y)
-        traverse2Of3 f (x, y, z) = fmap (\y' -> (x, y', z)) (f y)
diff --git a/src/Opaleye/SqlTypes.hs b/src/Opaleye/SqlTypes.hs
--- a/src/Opaleye/SqlTypes.hs
+++ b/src/Opaleye/SqlTypes.hs
@@ -4,11 +4,50 @@
 
 module Opaleye.SqlTypes (module Opaleye.SqlTypes,
                          P.IsSqlType,
-                         P.IsRangeType) where
+                         P.IsRangeType,
+                         SqlBool,
+                         SqlDate,
+                         SqlFloat4,
+                         SqlFloat8,
+                         SqlInt8,
+                         SqlInt4,
+                         SqlInt2,
+                         SqlNumeric,
+                         SqlText,
+                         SqlTime,
+                         SqlTimestamp,
+                         SqlTimestamptz,
+                         SqlUuid,
+                         SqlCitext,
+                         SqlArray,
+                         SqlBytea,
+                         SqlJson,
+                         SqlJsonb,
+                         SqlRange,
+                        ) where
 
 import qualified Opaleye.Field   as F
-import qualified Opaleye.PGTypes as P
-import           Opaleye.PGTypes (IsSqlType, IsRangeType)
+import qualified Opaleye.Internal.PGTypesExternal as P
+import           Opaleye.Internal.PGTypesExternal (IsSqlType, IsRangeType)
+import           Opaleye.Internal.PGTypesExternal (SqlBool,
+                                                   SqlDate,
+                                                   SqlFloat4,
+                                                   SqlFloat8,
+                                                   SqlInt8,
+                                                   SqlInt4,
+                                                   SqlInt2,
+                                                   SqlNumeric,
+                                                   SqlText,
+                                                   SqlTime,
+                                                   SqlTimestamp,
+                                                   SqlTimestamptz,
+                                                   SqlUuid,
+                                                   SqlCitext,
+                                                   SqlArray,
+                                                   SqlBytea,
+                                                   SqlJson,
+                                                   SqlJsonb,
+                                                   SqlRange)
 
 import qualified Data.Aeson as Ae
 import qualified Data.ByteString as SByteString
@@ -125,25 +164,3 @@
          -> R.RangeBound a
          -> F.Field (SqlRange b)
 sqlRange = P.pgRange
-
--- * SQL datatypes
-
-type SqlBool = P.PGBool
-type SqlDate = P.PGDate
-type SqlFloat4 = P.PGFloat4
-type SqlFloat8 = P.PGFloat8
-type SqlInt8 = P.PGInt8
-type SqlInt4 = P.PGInt4
-type SqlInt2 = P.PGInt2
-type SqlNumeric = P.PGNumeric
-type SqlText = P.PGText
-type SqlTime = P.PGTime
-type SqlTimestamp = P.PGTimestamp
-type SqlTimestamptz = P.PGTimestamptz
-type SqlUuid = P.PGUuid
-type SqlCitext = P.PGCitext
-type SqlArray = P.PGArray
-type SqlBytea = P.PGBytea
-type SqlJson = P.PGJson
-type SqlJsonb = P.PGJsonb
-type SqlRange = P.PGRange
diff --git a/src/Opaleye/Table.hs b/src/Opaleye/Table.hs
--- a/src/Opaleye/Table.hs
+++ b/src/Opaleye/Table.hs
@@ -70,9 +70,11 @@
                       T.requiredTableField,
                       -- * Selecting from tables
                       selectTable,
-                      -- * Other
+                      -- * Data types
                       T.TableColumns,
                       TableFields,
+                      -- * Explicit versions
+                      selectTableExplicit,
                       -- * Deprecated
                       T.optional,
                       T.readOnly,
@@ -81,8 +83,8 @@
                       View,
                       Writer,
                       T.Table(T.Table, T.TableWithSchema),
-                      -- * Module reexport
-                      module Opaleye.Table) where
+                      queryTable,
+                      queryTableExplicit) where
 
 import qualified Opaleye.Internal.QueryArr as Q
 import qualified Opaleye.Internal.Table as T
@@ -145,13 +147,12 @@
 
 -- * Deprecated versions
 
--- | Use 'selectTable' instead.  Will be deprecated in version 0.7.
+{-# DEPRECATED queryTable "Use 'selectTable' instead.  Will be removed in version 0.8." #-}
 queryTable :: D.Default U.Unpackspec fields fields =>
               Table a fields -> S.Select fields
 queryTable = selectTable
 
--- | Use 'selectTableExplicit' instead.  Will be deprecated in version
--- 0.7.
+{-# DEPRECATED queryTableExplicit "Use 'selectTableExplicit' instead.  Will be removed in version 0.8." #-}
 queryTableExplicit :: U.Unpackspec tablefields fields ->
                      Table a tablefields -> S.Select fields
 queryTableExplicit = selectTableExplicit
diff --git a/src/Opaleye/ToFields.hs b/src/Opaleye/ToFields.hs
--- a/src/Opaleye/ToFields.hs
+++ b/src/Opaleye/ToFields.hs
@@ -1,8 +1,17 @@
 {-# LANGUAGE FlexibleContexts #-}
 
-module Opaleye.ToFields (C.toFields, toFieldsI, C.ToFields, module Opaleye.ToFields) where
+module Opaleye.ToFields (-- * Creating 'Field's from Haskell values
+                         toFields,
+                         toFieldsI,
+                         -- * Creating @ToFields@
+                         C.toToFields,
+                         -- * Explicit versions
+                         toFieldsExplicit,
+                         -- * Adaptor
+                         C.ToFields,
+                         ) where
 
-import qualified Opaleye.Constant as C
+import qualified Opaleye.Internal.Constant as C
 import           Opaleye.Internal.Inferrable (Inferrable, runInferrable)
 
 import qualified Data.Profunctor.Product.Default as D
@@ -10,8 +19,33 @@
 toFieldsExplicit :: C.ToFields haskells fields -> haskells -> fields
 toFieldsExplicit = C.constantExplicit
 
-toToFields :: (haskells -> fields) -> C.ToFields haskells fields
-toToFields = C.Constant
+-- | 'toFields' provides a convenient typeclass wrapper around the
+-- 'Opaleye.Field.Field_' creation functions in "Opaleye.SqlTypes".  Besides
+-- convenience it doesn't provide any additional functionality.
+--
+-- It can be used with functions like 'Opaleye.Manipulation.runInsert'
+-- to insert custom Haskell types into the database.
+-- The following is an example of a function for inserting custom types.
+--
+-- @
+--   customInsert
+--      :: ( 'D.Default' 'ToFields' haskells fields )
+--      => Connection
+--      -> 'Opaleye.Table' fields fields'
+--      -> [haskells]
+--      -> IO Int64
+--   customInsert conn table haskells = 'Opaleye.Manipulation.runInsert_' conn 'Opaleye.Manipulation.Insert' {
+--         iTable      = table
+--       , iRows       = map 'toFields' haskells
+--       , iReturning  = rCount
+--       , iOnConflict = Nothing
+--     }
+-- @
+--
+-- In order to use this function with your custom types, you need to define an
+-- instance of 'D.Default' 'ToFields' for your custom types.
+toFields :: D.Default C.ToFields haskells fields => haskells -> fields
+toFields = C.toFields
 
 -- | Version of 'C.toFields' with better type inference
 toFieldsI :: (D.Default (Inferrable C.ToFields) haskells fields)
diff --git a/src/Opaleye/Values.hs b/src/Opaleye/Values.hs
--- a/src/Opaleye/Values.hs
+++ b/src/Opaleye/Values.hs
@@ -1,17 +1,18 @@
 {-# LANGUAGE FlexibleContexts #-}
 
 module Opaleye.Values(
-  valuesSafe,
+  values,
   -- * Explicit versions
   valuesExplicit,
-  valuesSafeExplicit,
-  valuesUnsafeExplicit,
   -- * Adaptors
+  V.Valuesspec,
   V.ValuesspecSafe,
   V.valuesspecField,
   -- * Deprecated versions
-  values,
+  valuesSafe,
+  valuesSafeExplicit,
   valuesUnsafe,
+  valuesUnsafeExplicit,
   ) where
 
 import qualified Opaleye.Internal.QueryArr as Q
@@ -21,55 +22,49 @@
 
 import           Data.Profunctor.Product.Default (Default, def)
 
--- | Please note that 'values' of an empty list generates incorrect
--- queries when mixed with @OUTER@\/@LEFT@\/@RIGHT JOIN@.  You should
--- use 'valuesSafe' instead.  'valuesSafe' will replace 'values' in
--- version 0.7.
-values :: (Default V.Valuesspec fields fields,
-           Default U.Unpackspec fields fields) =>
-          [fields] -> S.Select fields
-values = valuesExplicit def def
+-- | Do not use.  Will be deprecated in 0.8.
+valuesUnsafe :: (Default V.ValuesspecUnsafe fields fields,
+                 Default U.Unpackspec fields fields) =>
+                [fields] -> S.Select fields
+valuesUnsafe = valuesUnsafeExplicit def def
 
-valuesExplicit :: U.Unpackspec fields fields'
-               -> V.Valuesspec fields fields'
-               -> [fields] -> S.Select fields'
-valuesExplicit unpack valuesspec fields =
+-- | Do not use.  Will be deprecated in 0.8.
+valuesUnsafeExplicit :: U.Unpackspec fields fields'
+                     -> V.ValuesspecUnsafe fields fields'
+                     -> [fields] -> S.Select fields'
+valuesUnsafeExplicit unpack valuesspec fields =
   Q.productQueryArr (V.valuesU unpack valuesspec fields)
 
--- | 'valuesSafe' implements Postgres's @VALUES@ construct and allows you
+-- | 'values' implements Postgres's @VALUES@ construct and allows you
 -- to create a @SELECT@ that consists of the given rows.
 --
 -- Example type specialization:
 --
 -- @
--- valuesSafe :: [(Field a, Field b)] -> Select (Field a, Field b)
+-- values :: [(Field a, Field b)] -> Select (Field a, Field b)
 -- @
 --
 -- Assuming the @makeAdaptorAndInstance@ splice has been run for the
 -- product type @Foo@:
 --
 -- @
--- valuesSafe :: [Foo (Field a) (Field b) (Field c)] -> S.Select (Foo (Field a) (Field b) (Field c))
+-- values :: [Foo (Field a) (Field b) (Field c)] -> S.Select (Foo (Field a) (Field b) (Field c))
 -- @
-valuesSafe :: Default V.ValuesspecSafe fields fields =>
-               [fields] -> S.Select fields
-valuesSafe = valuesSafeExplicit def
+values :: Default V.Valuesspec fields fields
+       => [fields] -> S.Select fields
+values = valuesExplicit def
 
-valuesSafeExplicit :: V.ValuesspecSafe fields fields'
-                   -> [fields] -> S.Select fields'
-valuesSafeExplicit valuesspec fields =
+valuesExplicit :: V.Valuesspec fields fields'
+               -> [fields] -> S.Select fields'
+valuesExplicit valuesspec fields =
   Q.productQueryArr (V.valuesUSafe valuesspec fields)
 
--- | Forward-compatible version of unsafe 'values' that will not be
--- deprecated in 0.7, but in 0.8.
-valuesUnsafe :: (Default V.ValuesspecUnsafe fields fields,
-                 Default U.Unpackspec fields fields) =>
-                [fields] -> S.Select fields
-valuesUnsafe = values
+-- | Use 'values' instead.  Will be deprecated in 0.8.
+valuesSafe :: Default V.Valuesspec fields fields
+           => [fields] -> S.Select fields
+valuesSafe = values
 
--- | Forward compatible version of unsafe 'valuesExplicit' that will
--- not be deprecated in 0.7, but in 0.8.
-valuesUnsafeExplicit :: U.Unpackspec fields fields'
-                     -> V.ValuesspecUnsafe fields fields'
-                     -> [fields] -> S.Select fields'
-valuesUnsafeExplicit = valuesExplicit
+-- | Use 'valuesExplicit' instead.  Will be deprecated in 0.8.
+valuesSafeExplicit :: V.Valuesspec fields fields'
+                   -> [fields] -> S.Select fields'
+valuesSafeExplicit = valuesExplicit
