diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,8 +1,20 @@
+# 0.10.4.0
+
+## Added features
+
+* Added a `Generic` instance to `SqlNull`, `SqlBitString`, and `SqlSerial` (#736).
+* Added a note to `default_` to specify that it has more restrictions than its type may indicate (#744).
+* Added `limitMaybe_` and `offsetMaybe_` (#633).
+
+## Updated dependencies
+
+* Updated the upper bound to include `containers-0.8`.
+
 # 0.10.3.1
 
 ## Updated dependencies
 
-* Updated the upper bound to include `hashable-1.5`. 
+* Updated the upper bound to include `hashable-1.5`.
 
 ## Bug fixes
 
diff --git a/Database/Beam/Backend/SQL/Types.hs b/Database/Beam/Backend/SQL/Types.hs
--- a/Database/Beam/Backend/SQL/Types.hs
+++ b/Database/Beam/Backend/SQL/Types.hs
@@ -3,14 +3,15 @@
 
 import qualified Data.Aeson as Json
 import           Data.Bits
+import           GHC.Generics (Generic)
 
 data SqlNull = SqlNull
-  deriving (Show, Eq, Ord, Bounded, Enum)
+  deriving (Show, Eq, Ord, Bounded, Enum, Generic)
 newtype SqlBitString = SqlBitString Integer
-  deriving (Show, Eq, Ord, Enum, Bits)
+  deriving (Show, Eq, Ord, Enum, Bits, Generic)
 
 newtype SqlSerial a = SqlSerial { unSerial :: a }
-  deriving (Show, Read, Eq, Ord, Num, Integral, Real, Enum)
+  deriving (Show, Read, Eq, Ord, Num, Integral, Real, Enum, Generic)
 
 instance Json.FromJSON a => Json.FromJSON (SqlSerial a) where
   parseJSON a = SqlSerial <$> Json.parseJSON a
diff --git a/Database/Beam/Query/Combinators.hs b/Database/Beam/Query/Combinators.hs
--- a/Database/Beam/Query/Combinators.hs
+++ b/Database/Beam/Query/Combinators.hs
@@ -1,6 +1,5 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE CPP #-}
 
 module Database.Beam.Query.Combinators
     ( -- * Various SQL functions and constructs
@@ -41,7 +40,8 @@
     , QIfCond, QIfElse
     , (<|>.)
 
-    , limit_, offset_
+    , limit_, limitMaybe_
+    , offset_, offsetMaybe_
 
     , as_
 
@@ -66,8 +66,8 @@
     , orderBy_, asc_, desc_, nullsFirst_, nullsLast_
     ) where
 
-import Database.Beam.Backend.Types
 import Database.Beam.Backend.SQL
+import Database.Beam.Backend.Types
 
 import Database.Beam.Query.Internal
 import Database.Beam.Query.Ord
@@ -83,6 +83,7 @@
 import Data.Maybe
 import Data.Proxy
 import Data.Time (LocalTime)
+import Unsafe.Coerce (unsafeCoerce)
 
 import GHC.TypeLits (TypeError, ErrorMessage(Text))
 
@@ -328,6 +329,8 @@
 nub_ (Q sub) = Q $ liftF (QDistinct (\_ _ -> setQuantifierDistinct) sub id)
 
 -- | Limit the number of results returned by a query.
+--
+-- See also `limitMaybe_` to conditionally apply a limit.
 limit_ :: forall s a be db
         . ( Projectible be a
           , ThreadRewritable (QNested s) a )
@@ -335,7 +338,22 @@
 limit_ limit' (Q q) =
   Q (liftF (QLimit limit' q (rewriteThread (Proxy @s))))
 
--- | Drop the first `offset'` results.
+-- | Conditionally limit the number of results returned by a query.
+--
+-- @since 0.10.4.0
+limitMaybe_ :: forall s a be db
+        . ( Projectible be a
+          , ThreadRewritable (QNested s) a )
+        => Maybe Integer -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a)
+limitMaybe_ (Just limit') (Q q) =
+  Q (liftF (QLimit limit' q (rewriteThread (Proxy @s))))
+-- This uses unsafeCoerce, but should be safe since this function is tested.
+-- See discussion on https://github.com/haskell-beam/beam/pull/633.
+limitMaybe_ Nothing (Q q) = Q (unsafeCoerce q)
+
+-- | Drop the first `offset` results.
+--
+-- See also `offsetMaybe_` to conditionally apply an offset
 offset_ :: forall s a be db
          . ( Projectible be a
            , ThreadRewritable (QNested s) a )
@@ -343,6 +361,19 @@
 offset_ offset' (Q q) =
   Q (liftF (QOffset offset' q (rewriteThread (Proxy @s))))
 
+-- | Conditionally drop the first `offset` results.
+--
+-- @since 0.10.4.0
+offsetMaybe_ :: forall s a be db
+         . ( Projectible be a
+           , ThreadRewritable (QNested s) a )
+        => Maybe Integer -> Q be db (QNested s) a -> Q be db s (WithRewrittenThread (QNested s) s a)
+offsetMaybe_ (Just offset') (Q q) =
+  Q (liftF (QOffset offset' q (rewriteThread (Proxy @s))))
+-- This uses unsafeCoerce, but should be safe since this function is tested.
+-- See discussion on https://github.com/haskell-beam/beam/pull/633.
+offsetMaybe_ Nothing (Q q) = Q (unsafeCoerce q)
+
 -- | Use the SQL @EXISTS@ operator to determine if the given query returns any results
 exists_ :: ( BeamSqlBackend be, HasQBuilder be, Projectible be a)
         => Q be db s a -> QExpr be s Bool
@@ -564,7 +595,14 @@
     in changeBeamRep (\(Columnar' (WithConstraint x :: WithConstraint (BeamSqlBackendCanSerialize be) (Maybe x))) ->
                          Columnar' (QExpr (pure (valueE (sqlValueSyntax x))))) fields
 
+-- | SQL @DEFAULT@ support.
+--
+-- Note that  `default_` has restrictions not currently represented in the Haskell type system.
+-- For example, using `default_` as the argument to a function like `coalesce_`
+-- will result in a runtime error, just like the SQL code @COALESCE (NULL, DEFAULT)@
+-- would raise a runtime error.
 default_ :: BeamSqlBackend be => QGenExpr ctxt be s a
+-- See #744 for issues with `default_`.
 default_ = QExpr (pure defaultE)
 
 -- * Window functions
diff --git a/Database/Beam/Query/Internal.hs b/Database/Beam/Query/Internal.hs
--- a/Database/Beam/Query/Internal.hs
+++ b/Database/Beam/Query/Internal.hs
@@ -1,6 +1,5 @@
 {-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors#-}
 {-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE CPP #-}
 
 module Database.Beam.Query.Internal where
 
@@ -15,9 +14,6 @@
 import           Data.Typeable
 import           Data.Vector.Sized (Vector)
 import qualified Data.Vector.Sized as VS
-#if !MIN_VERSION_base(4, 11, 0)
-import           Data.Semigroup
-#endif
 
 import           Control.Monad.Free.Church
 import           Control.Monad.State
@@ -41,9 +37,14 @@
 
   QAll :: Projectible be r
        => (TablePrefix -> T.Text -> BeamSqlBackendFromSyntax be)
+           -- ^ build the FROM syntax using the table prefix and the table name
        -> (T.Text -> r)
+          -- ^ Given a table name, get the various Qs for all the expressions in that table
        -> (r -> Maybe (WithExprContext (BeamSqlBackendExpressionSyntax be)))
-       -> ((T.Text, r) -> next) -> QF be db s next
+          -- ^ on clause, if any
+       -> ((T.Text, r) -> next)
+          -- ^ Generate the result from the table name and projectible result
+       -> QF be db s next
 
   QArbitraryJoin :: Projectible be r
                  => QM be db (QNested s) r
diff --git a/Database/Beam/Schema/Tables.hs b/Database/Beam/Schema/Tables.hs
--- a/Database/Beam/Schema/Tables.hs
+++ b/Database/Beam/Schema/Tables.hs
@@ -19,6 +19,7 @@
     , DatabaseEntityDescriptor(..)
     , DatabaseEntity(..), TableEntity, ViewEntity, DomainTypeEntity
     , dbEntityDescriptor
+    , dbName, dbSchema, dbTableFields
     , DatabaseModification, EntityModification(..)
     , FieldModification(..)
     , dbModification, tableModification, withDbModification
@@ -96,7 +97,6 @@
 import           GHC.Types
 
 import           Lens.Micro hiding (to)
-import qualified Lens.Micro as Lens
 
 -- | Allows introspection into database types.
 --
@@ -398,8 +398,21 @@
       IsDatabaseEntity be entityType =>
       DatabaseEntityDescriptor be entityType ->  DatabaseEntity be db entityType
 
-dbEntityDescriptor :: SimpleGetter (DatabaseEntity be db entityType) (DatabaseEntityDescriptor be entityType)
-dbEntityDescriptor = Lens.to (\(DatabaseEntity e) -> e)
+dbEntityDescriptor :: Lens' (DatabaseEntity be db entityType) (DatabaseEntityDescriptor be entityType)
+dbEntityDescriptor f (DatabaseEntity d) = DatabaseEntity <$> f d
+
+dbName :: IsDatabaseEntity be entityType => Lens' (DatabaseEntity be db entityType) Text
+dbName = dbEntityDescriptor . dbEntityName
+
+dbSchema :: IsDatabaseEntity be entityType => Traversal' (DatabaseEntity be db entityType) (Maybe Text)
+dbSchema = dbEntityDescriptor . dbEntitySchema
+
+dbTableFields :: Lens' (DatabaseEntity be db (TableEntity table)) (TableSettings table)
+dbTableFields = dbEntityDescriptor . (\f DatabaseTable { dbTableSchema = sch
+                                                       , dbTableOrigName = nm
+                                                       , dbTableCurrentName = curNm
+                                                       , dbTableSettings = s } ->
+                                      DatabaseTable sch nm curNm <$> f s)
 
 -- | When parameterized by this entity tag, a database type will hold
 --   meta-information on the Haskell mappings of database entities. Under the
diff --git a/beam-core.cabal b/beam-core.cabal
--- a/beam-core.cabal
+++ b/beam-core.cabal
@@ -2,7 +2,7 @@
 -- see http://haskell.org/cabal/users-guide/
 
 name:                beam-core
-version:             0.10.3.1
+version:             0.10.4.0
 synopsis:            Type-safe, feature-complete SQL query and manipulation interface for Haskell
 description:         Beam is a Haskell library for type-safe querying and manipulation of SQL databases.
                      Beam is modular and supports various backends. In order to use beam, you will need to use
@@ -72,7 +72,7 @@
                        time         >=1.6     && <1.13,
                        hashable     >=1.2.4.0 && <1.6,
                        network-uri  >=2.6     && <2.7,
-                       containers   >=0.5     && <0.8,
+                       containers   >=0.5     && <0.9,
                        scientific   >=0.3     && <0.4,
                        vector       >=0.11    && <0.14,
                        vector-sized >=0.5     && <1.7,
@@ -84,8 +84,13 @@
                        DefaultSignatures, KindSignatures, MultiParamTypeClasses, DeriveGeneric, DeriveFunctor, DeriveDataTypeable,
                        TypeApplications, FunctionalDependencies, DataKinds, BangPatterns, InstanceSigs
   ghc-options:         -Wall
+                       -Widentities
+                       -Wincomplete-uni-patterns
+                       -Wincomplete-record-updates
   if impl(ghc >= 8.8)
     ghc-options: -Wcompat
+  if impl(ghc >= 8.10)
+    ghc-options: -Wunused-packages
   if flag(werror)
     ghc-options:       -Werror
   if impl(ghc >= 8.10)
diff --git a/test/Database/Beam/Test/SQL.hs b/test/Database/Beam/Test/SQL.hs
--- a/test/Database/Beam/Test/SQL.hs
+++ b/test/Database/Beam/Test/SQL.hs
@@ -1059,7 +1059,9 @@
 limitOffset :: TestTree
 limitOffset =
   testGroup "LIMIT/OFFSET support"
-  [ limitSupport, offsetSupport, limitOffsetSupport
+  [ limitSupport, maybeLimitSupportJust, maybeLimitSupportNothing
+  , offsetSupport, maybeOffsetSupportJust, maybeOffsetSupportNothing
+  , limitOffsetSupport
 
   , limitPlacedOnUnion ]
   where
@@ -1071,6 +1073,22 @@
          selectLimit @?= Just 20
          selectOffset @?= Nothing
 
+    maybeLimitSupportJust =
+      testCase "Maybe LIMIT support (Just)" $
+      do SqlSelect Select { selectLimit, selectOffset } <-
+           pure $ selectMock $ limitMaybe_ (Just 20) (all_ (_employees employeeDbSettings))
+
+         selectLimit @?= Just 20
+         selectOffset @?= Nothing
+
+    maybeLimitSupportNothing =
+      testCase "Maybe LIMIT support (Nothing)" $
+      do SqlSelect Select { selectLimit, selectOffset } <-
+           pure $ selectMock $ limitMaybe_ Nothing (all_ (_employees employeeDbSettings))
+
+         selectLimit @?= Nothing
+         selectOffset @?= Nothing
+
     offsetSupport =
       testCase "Basic OFFSET support" $
       do SqlSelect Select { selectLimit, selectOffset } <-
@@ -1078,6 +1096,22 @@
 
          selectLimit @?= Nothing
          selectOffset @?= Just 102
+
+    maybeOffsetSupportJust =
+      testCase "Maybe OFFSET support (Just)" $
+      do SqlSelect Select { selectLimit, selectOffset } <-
+           pure $ selectMock $ offsetMaybe_ (Just 2) $ offset_ 100 (all_ (_employees employeeDbSettings))
+
+         selectLimit @?= Nothing
+         selectOffset @?= Just 102
+
+    maybeOffsetSupportNothing =
+      testCase "Maybe OFFSET support (Nothing)" $
+      do SqlSelect Select { selectLimit, selectOffset } <-
+           pure $ selectMock $ offsetMaybe_ Nothing $ offset_ 100 (all_ (_employees employeeDbSettings))
+
+         selectLimit @?= Nothing
+         selectOffset @?= Just 100
 
     limitOffsetSupport =
       testCase "Basic LIMIT .. OFFSET .. support" $
