diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.10.7.0
+
+* Added `unsafeCastSqlType`, `typedNull` and `untypedNull`, allowing
+  workaround for
+  [#621](https://github.com/tomjaguarpaw/haskell-opaleye/issues/621).
+  Thanks to @fpringle.
+
 ## 0.10.6.0
 
 * Added `int2` functions and instances (thanks to @fpringle)
diff --git a/Test/Test.hs b/Test/Test.hs
--- a/Test/Test.hs
+++ b/Test/Test.hs
@@ -1527,6 +1527,17 @@
         expectation :: Double
         expectation = 2.5
 
+-- See https://github.com/tomjaguarpaw/haskell-opaleye/issues/621
+testSelectCaseNull :: Test
+testSelectCaseNull = do
+  it "" $ testH query (`shouldBe` expectation)
+    where query :: Select (O.FieldNullable O.SqlInt4)
+          -- Fails with null instead of typedNull
+          query = O.values [O.toNullable 0, O.ifThenElse (O.toFields True) O.typedNull O.typedNull]
+
+          expectation :: [Maybe Int]
+          expectation = [Just 0, Nothing]
+
 main :: IO ()
 main = do
   let envVarName = "POSTGRES_CONNSTRING"
@@ -1672,6 +1683,7 @@
         testUpdate
         testDeleteReturning
         testInsertConflict
+        testSelectCaseNull
       describe "range" $ do
         testRangeOverlap
         testRangeDateOverlap
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-2025 Tom Ellis
-version:         0.10.6.0
+version:         0.10.7.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
diff --git a/src/Opaleye/Field.hs b/src/Opaleye/Field.hs
--- a/src/Opaleye/Field.hs
+++ b/src/Opaleye/Field.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+
 -- | Functions for working directly with 'Field_'s.
 --
 -- Please note that numeric 'Field_' types are instances of 'Num', so
@@ -25,11 +28,14 @@
   Nullability(..),
   -- * Casting fields
   C.unsafeCast,
+  unsafeCastSqlType,
   unsafeCoerceField,
   -- * Working with @NULL@
   -- | Instead of working with @NULL@ you are recommended to use
   -- "Opaleye.MaybeFields" instead.
   Opaleye.Field.null,
+  typedNull,
+  untypedNull,
   isNull,
   matchNullable,
   fromNullable,
@@ -45,11 +51,31 @@
 import qualified Opaleye.Internal.PGTypesExternal  as T
 import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
 
+import           Data.Proxy (Proxy(Proxy))
+
 -- FIXME Put Nullspec (or sqltype?) constraint on this
 
--- | A NULL of any type
+-- | A @NULL@ of any type.  This will change to become 'typedNull' in
+-- a future version.
 null :: FieldNullable a
 null = Column (HPQ.ConstExpr HPQ.NullLit)
+
+-- | Cast a column to any other type, as long as it has an instance of
+-- 'T.IsSqlType'.  Should be used in preference to 'C.unsafeCast'.
+unsafeCastSqlType :: forall a b n. (T.IsSqlType b) => Field_ n a -> Field_ n b
+unsafeCastSqlType = C.unsafeCast (T.showSqlType @b Proxy)
+
+-- | Same as 'null', but with an explicit type @CAST@. This can help
+-- in situations when PostgreSQL can't figure out the type of a
+-- @NULL@. In a future major version this will replace @null@.
+typedNull :: T.IsSqlType a => FieldNullable a
+typedNull = unsafeCastSqlType null
+
+-- | A @NULL@ of any type with no @CAST@ supplied.  Use this in
+-- preference to 'null' if you really don't want a type cast applied
+-- to your @NULL@.
+untypedNull :: FieldNullable a
+untypedNull = null
 
 -- | @TRUE@ if the value of the field is @NULL@, @FALSE@ otherwise.
 isNull :: FieldNullable a -> Field T.PGBool
