diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -48,9 +48,6 @@
 
 ## Most important features not currently implemented
 
-* Prepared statement parameters
-    * See the haddock documentation for how to get haskell values into
-      your sql statements.
 * `ON CONFLICT` clause for `INSERT` statements.
 
 ## Other features not currently implemented
@@ -125,6 +122,7 @@
   select * from public.users [✔]
   SELECT * FROM "users" AS "users" [✔]
   select * from users where name = 'bob' [✔]
+  select * from users where id = $1 [✔]
   select users.name from users [✔]
   select name from users [✔]
   select count(*) from users group by () [✔]
@@ -155,6 +153,7 @@
   insert into emails (id, user_id, email) values (1, 'user-1', 'foo@bar') [✔]
   insert into emails (id, user_id, email) values (1, 'user-1', $1) [✔]
   insert into emails (id, user_id, email) values (1, $2, $1) [✔]
+  insert into users_copy (id, name, bio) values ($1, $2, $3) [✔]
   insert into emails (id, user_id, email) values (inline(i), inline(uid), inline_param(e)) [✔]
   default keyword
     insert into emails (id, user_id, email) values (default, 'foo', 'bar') [✔]
@@ -176,6 +175,7 @@
 deletes
   delete from users where true [✔]
   delete from emails where id = 1 [✔]
+  delete from emails where id = $1 [✔]
   delete from emails where email = inline(e) [✔]
   delete from users where id = 'some-id' returning id [✔]
   with common table expressions
@@ -185,6 +185,7 @@
   update users set name = 'new name' where id = 'some-id' [✔]
   update users set name = 'new name', bio = 'new bio' where id = 'some-id' [✔]
   update users set name = inline(n) where id = 'some-id' [✔]
+  update users set name = $1 where id = $2 [✔]
   update users set name = 'new name' where id = 'some-id' returning id [✔]
   with common table expressions
     with to_update as (select id from users where name = 'Alice') update users set name = 'Alicia' from to_update where users.id = to_update.id [✔]
@@ -217,6 +218,7 @@
     haskell variables in expressions [✔]
   select (emails.id + 1) * 2 as calc from emails [✔]
   select * from users where users.name in ('Alice', 'Bob') [✔]
+  select * from users where users.id in (select emails.user_id from emails) [✔]
   select * from users where users.name not in ('Alice', 'Bob') [✔]
   select * from emails where emails.id between 0 and 10 [✔]
   select * from emails where emails.id not between 0 and 10 [✔]
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,21 @@
+### 0.1.2.0
+
+* New features
+  * Officially support statement parameters
+
+    They where technically working prior to this version, but now that I realize
+    they can't be made monomorphic I have decided to support them officially in
+    their polymorphic form. See the Haddocks for more information.
+
+    I am electing to escalate this to a minor version bump when I think it
+    could technically be a patch version (from the standpoint of "whether it
+    compiles") to reflect the "officially supported" nature of the feature.
+
+* No-Op improvements
+  * Expand and improve the documentation
+  * Some internal refactors
+
+
 ### 0.1.1.1
 
 No feature or behavior changes. Only documentation.
diff --git a/squeal-postgresql-qq.cabal b/squeal-postgresql-qq.cabal
--- a/squeal-postgresql-qq.cabal
+++ b/squeal-postgresql-qq.cabal
@@ -1,6 +1,6 @@
 cabal-version:       3.0
 name:                squeal-postgresql-qq
-version:             0.1.1.1
+version:             0.1.2.0
 synopsis:            QuasiQuoter transforming raw sql into Squeal expressions.
 -- description:         
 homepage:            https://github.com/owensmurray/squeal-postgresql-qq
@@ -44,8 +44,8 @@
   other-modules:
     Squeal.QuasiQuotes.Delete
     Squeal.QuasiQuotes.Insert
+    Squeal.QuasiQuotes.MonoRow
     Squeal.QuasiQuotes.Query
-    Squeal.QuasiQuotes.RowType
     Squeal.QuasiQuotes.Update
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/Squeal/QuasiQuotes.hs b/src/Squeal/QuasiQuotes.hs
--- a/src/Squeal/QuasiQuotes.hs
+++ b/src/Squeal/QuasiQuotes.hs
@@ -27,10 +27,10 @@
   )
 import Squeal.QuasiQuotes.Delete (toSquealDelete)
 import Squeal.QuasiQuotes.Insert (toSquealInsert)
-import Squeal.QuasiQuotes.Query (toSquealQuery)
-import Squeal.QuasiQuotes.RowType
+import Squeal.QuasiQuotes.MonoRow
   ( Field(Field, unField), monoManipulation, monoQuery
   )
+import Squeal.QuasiQuotes.Query (toSquealQuery)
 import Squeal.QuasiQuotes.Update (toSquealUpdate)
 import qualified Data.Text as Text
 import qualified PostgresqlSyntax.Ast as PGT_AST
@@ -40,8 +40,18 @@
 {- |
   Splice in a squeal expression with the following type:
 
-  > Statement db () <Canonical-Haskell-Row-Type>
+  > Statement db params <Concrete-Haskell-Row-Type>
 
+  = Input parameters
+
+  The input parameters @params@ is a polymorphic type that gets encoded into
+  SQL statement parameters. It is a direct pass-through to Squeal using Squeal's
+  `Squeal.PostgreSQL.genericParams`. The upshot is that we don't monomorphize
+  this type the same way we do for the statement's resulting row type. See the
+  [Polymorphic Params Discussion](#polymorphic-params) for the reason why not.
+
+  = Resulting Row Type
+
   @\<Canonical-Haskell-Row-Type\>@ is going to be some concrete tuple of the
   form:
 
@@ -60,11 +70,16 @@
 
   = Haskell values
 
-  The way you get Haskell values into your sql statements is with special bulit-in sql functions:
+  The way you get Haskell values into your sql statements is with special
+  bulit-in sql functions:
 
-  * @inline(\<ident\>)@: Corresponds to 'Squeal.PostgreSQL.Expression.Inline.inline' (value being inlined must not be null)
-  * @inline_param(\<ident\>)@: Corresponds to 'Squeal.PostgreSQL.Expression.Inline.inlineParam' (value can be null)
+  * @inline(\<ident\>)@: Corresponds to
+    'Squeal.PostgreSQL.Expression.Inline.inline' (value being inlined must
+    not be null)
 
+  * @inline_param(\<ident\>)@: Corresponds to
+    'Squeal.PostgreSQL.Expression.Inline.inlineParam' (value can be null)
+
   where @\<ident\>@ is a haskell identifier in scope, whose type has an
   'Squeal.PostgreSQL.Inline' instance.
 
@@ -180,6 +195,10 @@
 
   #discussion#
 
+  #monomorphized-output-rows#
+
+  == Monomorphized Output Rows
+
   The reason we monomorphize the SQL statement using the nested tuple
   structure (see 'ssql') is that Squeal by default allows for generic
   based polymorphic input row types and output row types. This is
@@ -210,6 +229,66 @@
   failing to align with your expected types, you can put your expected
   row type in a type signature and get a much better error message about
   how and why the SQL statement is failing to type check.
+
+  #polymorphic-params#
+
+  == Polymorphic Input Parameters
+
+  Type inferencing of statement parameters is not supported, unlike the
+  type inferencing of statement output row types. That is to say you
+  can write this (i.e. a type hole in the /output/ slot) and expect to
+  get a concrete type in your GHC error message.
+
+  > statement :: Statement DB (Only Text) _ 
+  > statement [ssql| select name from users where id = $1 |]
+
+  But GHC will not give you anything useful if you type this instead (i.e. a
+  type hole in the /input/ slot):
+
+  > statement :: Statement DB _ (Field "name" Text, ())
+  > statement [ssql| select name from users where id = $1 |]
+
+  The TLDR is that it can't easily be made to work without some pretty
+  extensive machinery to cope with SQL's type system and even then it
+  would come with some unpalatable trade-offs.
+
+  The basic problem is that SQL comparisons and other operators support
+  null polymorphic values as their parameters. So for instance, an SQL
+  statement can compare a non-null column with the literal value @null@,
+  and that is valid SQL.  So if you compare the non-null column with a
+  parameter instead, what should the type of the parameter be?
+
+
+  E.g.: 
+
+  > select * from users where id = null -- compare with `null`.
+  > select * from users where id = $1   -- compare with a param.
+  > select * from users where id = id   -- compare with non-nullable column.
+
+  Should the parameter be nullable or not nullable? It can be
+  either! Therefore the corresponding Haskell type can be either! How do we choose?
+
+  We could say, by fiat, that input params always nullable (and make the
+  user type a bunch of 'Just's everywhere), but then consider this insert
+  statement where the parameter is being used to specify the value of
+  a non-null column.
+
+  > insert into users (id) values ($1)
+
+  This instance of the parameter can't be nullable.  It must be
+  non-nullable.
+
+  So sometimes statement parameters can be null polymorphic and sometimes
+  they can't. Sometimes a Haskell type of /either/ @Something@ /or/
+  @(Maybe Something)@ will work, and sometimes it won't.
+
+  I think the decision requires semantic knowledge of a non-trivial
+  subset of SQL. A design goal of this library is specifically to offload
+  semantic knowledge of SQL to Squeal, not to re-implement it. So unless
+  I can think of (or someone contributes) a really clever trick, I think
+  input params are going to stay polymorphic, with all the inscrutable
+  Squeal and @Generics.SOP@ type errors you get when your types don't
+  quite align.
 -}
 
 
diff --git a/src/Squeal/QuasiQuotes/MonoRow.hs b/src/Squeal/QuasiQuotes/MonoRow.hs
new file mode 100644
--- /dev/null
+++ b/src/Squeal/QuasiQuotes/MonoRow.hs
@@ -0,0 +1,150 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeFamilyDependencies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+{- |
+  Description: Monomorphic squeal row types.
+
+  This module provides a type family that converts a squeal row type into
+  a specific, monomorphic tuple representation meant to be consumed by the
+  user. The purpose of this so that the squeal quasiquoter won't produce
+  polymorphic types, though it will produce a *different* monomorphic
+  type depending on the columns returned by the query. The reason we want
+  this is to help type inference as much as possible. Squeal already
+  has some problems with type inference, and the burden on the user of
+  navigating them is only likely to increase when a lot of the squeal
+  "code" itself is hidden behind a quasiquoter.
+-}
+module Squeal.QuasiQuotes.MonoRow (
+  MonoRow,
+  monoQuery,
+  monoManipulation,
+  Field (..),
+) where
+
+import Data.Aeson (Value)
+import Data.Int (Int32, Int64)
+import Data.Text (Text)
+import Data.Time (Day, UTCTime)
+import Data.UUID (UUID)
+import GHC.TypeLits (Symbol)
+import Generics.SOP (SListI)
+import Prelude (Applicative(pure), (<$>), Bool, Maybe)
+import Squeal.PostgreSQL
+  ( FromValue(fromValue), IsLabel(fromLabel), NullType(NotNull, Null)
+  , PGType(PGbool, PGdate, PGint4, PGint8, PGjson, PGjsonb, PGtext, PGtimestamptz, PGuuid)
+  , (:::), Json, Jsonb
+  )
+import qualified Squeal.PostgreSQL as Squeal
+
+
+
+
+{- FOURMOLU_DISABLE -}
+type family MonoRow a = b | b -> a where
+  {-
+    It would be more convenient to use a helper type family here that
+    would map PGtypes to Haskell types. But if we did that, we would
+    not be able to make this type family injective.
+
+    This is Because GHC would not be able to tell that the right-hand
+    side of this type family did not overlap even if that the helper
+    type family were itself injective. Injectivity of the helper is not
+    enough. The specific helper definition must happen to not produce
+    instances that overlap with any Maybe type when used here.
+
+    For instance, this example helper type family is injective, but when
+    used here it would produce overlapping values for the `NotNull PGint4`
+    and `Null PGbool` equations.
+
+    type family Helper x = a | a -> x where
+      Helper Int32 = Maybe Bool
+      Helper Bool = Bool
+  -}
+  MonoRow (fld ::: 'NotNull PGbool ': more) = (Field fld Bool, MonoRow more)
+  MonoRow (fld ::: 'NotNull PGint4 ': more) = (Field fld Int32, MonoRow more)
+  MonoRow (fld ::: 'NotNull PGint8 ': more) = (Field fld Int64, MonoRow more)
+  MonoRow (fld ::: 'NotNull PGtext ': more) = (Field fld Text, MonoRow more)
+  MonoRow (fld ::: 'NotNull PGuuid ': more) = (Field fld UUID, MonoRow more)
+  MonoRow (fld ::: 'NotNull PGdate ': more) = (Field fld Day, MonoRow more)
+  MonoRow (fld ::: 'NotNull PGtimestamptz ': more) = (Field fld UTCTime, MonoRow more)
+  MonoRow (fld ::: 'NotNull PGjsonb ': more) = (Field fld (Jsonb Value), MonoRow more)
+  MonoRow (fld ::: 'NotNull PGjson ': more) = (Field fld (Json Value), MonoRow more)
+
+  MonoRow (fld ::: 'Null PGbool ': more) = (Field fld (Maybe Bool), MonoRow more)
+  MonoRow (fld ::: 'Null PGint4 ': more) = (Field fld (Maybe Int32), MonoRow more)
+  MonoRow (fld ::: 'Null PGint8 ': more) = (Field fld (Maybe Int64), MonoRow more)
+  MonoRow (fld ::: 'Null PGtext ': more) = (Field fld (Maybe Text), MonoRow more)
+  MonoRow (fld ::: 'Null PGuuid ': more) = (Field fld (Maybe UUID), MonoRow more)
+  MonoRow (fld ::: 'Null PGdate ': more) = (Field fld (Maybe Day), MonoRow more)
+  MonoRow (fld ::: 'Null PGtimestamptz ': more) = (Field fld (Maybe UTCTime), MonoRow more)
+  MonoRow (fld ::: 'Null PGjsonb ': more) = (Field fld (Maybe (Jsonb Value)), MonoRow more)
+  MonoRow (fld ::: 'Null PGjson ': more) = (Field fld (Maybe (Json Value)), MonoRow more)
+  MonoRow '[] = ()
+{- FOURMOLU_ENABLE -}
+
+
+newtype Field (name :: Symbol) a = Field
+  { unField :: a
+  }
+instance
+    (Squeal.FromValue pg hask)
+  =>
+    Squeal.FromValue pg (Field name hask)
+  where
+    fromValue mbs = Field @name <$> Squeal.fromValue @pg mbs
+
+
+{- |
+  Like 'Squeal.query', but use the monomorphizing 'MonoRow' family to
+  fully specify the output rows. This is mainly a convenience to the
+  template haskell code so it can simply quote this function instead of
+  having to basically inline it directly in TH.
+-}
+monoQuery
+  :: forall db params input row ignored.
+     ( HasRowDecoder row (MonoRow row)
+     , SListI row
+     , Squeal.GenericParams db params input ignored
+     )
+  => Squeal.Query '[] '[] db params row
+  -> Squeal.Statement db input (MonoRow row)
+monoQuery = Squeal.Query Squeal.genericParams getRowDecoder
+
+
+monoManipulation
+  :: forall db params input row ignored.
+     ( HasRowDecoder row (MonoRow row)
+     , SListI row
+     , Squeal.GenericParams db params input ignored
+     )
+  => Squeal.Manipulation '[] db params row
+  -> Squeal.Statement db input (MonoRow row)
+monoManipulation = Squeal.Manipulation Squeal.genericParams getRowDecoder
+
+
+class HasRowDecoder row x where
+  getRowDecoder :: Squeal.DecodeRow row x
+instance
+    ( HasRowDecoder moreRow moreFields
+    , Squeal.FromValue typ t
+    )
+  =>
+    HasRowDecoder ((fld ::: typ) ': moreRow) (Field fld t, moreFields)
+  where
+    getRowDecoder =
+      Squeal.consRow
+        (,)
+        (fromLabel @fld)
+        (getRowDecoder @moreRow @moreFields)
+instance HasRowDecoder '[] () where
+  getRowDecoder = pure ()
+
+
diff --git a/src/Squeal/QuasiQuotes/RowType.hs b/src/Squeal/QuasiQuotes/RowType.hs
deleted file mode 100644
--- a/src/Squeal/QuasiQuotes/RowType.hs
+++ /dev/null
@@ -1,150 +0,0 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE TypeFamilyDependencies #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE UndecidableInstances #-}
-
-{- |
-  Description: Monomorphic squeal row types.
-
-  This module provides a type family that converts a squeal row type into
-  a specific, monomorphic tuple representation meant to be consumed by the
-  user. The purpose of this so that the squeal quasiquoter won't produce
-  polymorphic types, though it will produce a *different* monomorphic
-  type depending on the columns returned by the query. The reason we want
-  this is to help type inference as much as possible. Squeal already
-  has some problems with type inference, and the burden on the user of
-  navigating them is only likely to increase when a lot of the squeal
-  "code" itself is hidden behind a quasiquoter.
--}
-module Squeal.QuasiQuotes.RowType (
-  RowType,
-  monoQuery,
-  monoManipulation,
-  Field (..),
-) where
-
-import Data.Aeson (Value)
-import Data.Int (Int32, Int64)
-import Data.Text (Text)
-import Data.Time (Day, UTCTime)
-import Data.UUID (UUID)
-import GHC.TypeLits (Symbol)
-import Generics.SOP (SListI)
-import Prelude (Applicative(pure), (<$>), Bool, Maybe)
-import Squeal.PostgreSQL
-  ( FromValue(fromValue), IsLabel(fromLabel), NullType(NotNull, Null)
-  , PGType(PGbool, PGdate, PGint4, PGint8, PGjson, PGjsonb, PGtext, PGtimestamptz, PGuuid)
-  , (:::), Json, Jsonb
-  )
-import qualified Squeal.PostgreSQL as Squeal
-
-
-
-
-{- FOURMOLU_DISABLE -}
-type family RowType a = b | b -> a where
-  {-
-    It would be more convenient to use a helper type family here that
-    would map PGtypes to Haskell types. But if we did that, we would
-    not be able to make this type family injective.
-
-    This is Because GHC would not be able to tell that the right-hand
-    side of this type family did not overlap even if that the helper
-    type family were itself injective. Injectivity of the helper is not
-    enough. The specific helper definition must happen to not produce
-    instances that overlap with any Maybe type when used here.
-
-    For instance, this example helper type family is injective, but when
-    used here it would produce overlapping values for the `NotNull PGint4`
-    and `Null PGbool` equations.
-
-    type family Helper x = a | a -> x where
-      Helper Int32 = Maybe Bool
-      Helper Bool = Bool
-  -}
-  RowType (fld ::: 'NotNull PGbool ': more) = (Field fld Bool, RowType more)
-  RowType (fld ::: 'NotNull PGint4 ': more) = (Field fld Int32, RowType more)
-  RowType (fld ::: 'NotNull PGint8 ': more) = (Field fld Int64, RowType more)
-  RowType (fld ::: 'NotNull PGtext ': more) = (Field fld Text, RowType more)
-  RowType (fld ::: 'NotNull PGuuid ': more) = (Field fld UUID, RowType more)
-  RowType (fld ::: 'NotNull PGdate ': more) = (Field fld Day, RowType more)
-  RowType (fld ::: 'NotNull PGtimestamptz ': more) = (Field fld UTCTime, RowType more)
-  RowType (fld ::: 'NotNull PGjsonb ': more) = (Field fld (Jsonb Value), RowType more)
-  RowType (fld ::: 'NotNull PGjson ': more) = (Field fld (Json Value), RowType more)
-
-  RowType (fld ::: 'Null PGbool ': more) = (Field fld (Maybe Bool), RowType more)
-  RowType (fld ::: 'Null PGint4 ': more) = (Field fld (Maybe Int32), RowType more)
-  RowType (fld ::: 'Null PGint8 ': more) = (Field fld (Maybe Int64), RowType more)
-  RowType (fld ::: 'Null PGtext ': more) = (Field fld (Maybe Text), RowType more)
-  RowType (fld ::: 'Null PGuuid ': more) = (Field fld (Maybe UUID), RowType more)
-  RowType (fld ::: 'Null PGdate ': more) = (Field fld (Maybe Day), RowType more)
-  RowType (fld ::: 'Null PGtimestamptz ': more) = (Field fld (Maybe UTCTime), RowType more)
-  RowType (fld ::: 'Null PGjsonb ': more) = (Field fld (Maybe (Jsonb Value)), RowType more)
-  RowType (fld ::: 'Null PGjson ': more) = (Field fld (Maybe (Json Value)), RowType more)
-  RowType '[] = ()
-{- FOURMOLU_ENABLE -}
-
-
-newtype Field (name :: Symbol) a = Field
-  { unField :: a
-  }
-instance
-    (Squeal.FromValue pg hask)
-  =>
-    Squeal.FromValue pg (Field name hask)
-  where
-    fromValue mbs = Field @name <$> Squeal.fromValue @pg mbs
-
-
-{- |
-  Like 'Squeal.query', but use the monomorphizing 'RowType' family to
-  fully specify the output rows. This is mainly a convenience to the
-  template haskell code so it can simply quote this function instead of
-  having to basically inline it directly in TH.
--}
-monoQuery
-  :: forall db params input row ignored.
-     ( HasRowDecoder row (RowType row)
-     , SListI row
-     , Squeal.GenericParams db params input ignored
-     )
-  => Squeal.Query '[] '[] db params row
-  -> Squeal.Statement db input (RowType row)
-monoQuery = Squeal.Query Squeal.genericParams getRowDecoder
-
-
-monoManipulation
-  :: forall db params input row ignored.
-     ( HasRowDecoder row (RowType row)
-     , SListI row
-     , Squeal.GenericParams db params input ignored
-     )
-  => Squeal.Manipulation '[] db params row
-  -> Squeal.Statement db input (RowType row)
-monoManipulation = Squeal.Manipulation Squeal.genericParams getRowDecoder
-
-
-class HasRowDecoder row x where
-  getRowDecoder :: Squeal.DecodeRow row x
-instance
-    ( HasRowDecoder moreRow moreFields
-    , Squeal.FromValue typ t
-    )
-  =>
-    HasRowDecoder ((fld ::: typ) ': moreRow) (Field fld t, moreFields)
-  where
-    getRowDecoder =
-      Squeal.consRow
-        (,)
-        (fromLabel @fld)
-        (getRowDecoder @moreRow @moreFields)
-instance () => HasRowDecoder '[] () where
-  getRowDecoder = pure ()
-
-
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -169,6 +169,26 @@
           squealRendering = "SELECT * FROM \"users\" AS \"users\" WHERE (\"name\" = (E'bob' :: text))"
         checkStatement squealRendering statement
 
+      it "select * from users where id = $1" $ do
+        let
+          statement
+            :: Statement
+                 DB
+                 (Only Text)
+                 ( Field "id" Text
+                 , ( Field "name" Text
+                   , ( Field "employee_id" UUID
+                     , ( Field "bio" (Maybe Text)
+                       , ()
+                       )
+                     )
+                   )
+                 )
+          statement = [ssql| select * from users where id = $1 |]
+          squealRendering :: Text
+          squealRendering = "SELECT * FROM \"users\" AS \"users\" WHERE (\"id\" = ($1 :: text))"
+        checkStatement squealRendering statement
+
       it "select users.name from users" $ do
         let
           statement :: Statement DB () (Field "name" Text, ())
@@ -669,6 +689,24 @@
             "INSERT INTO \"emails\" AS \"emails\" (\"id\", \"user_id\", \"email\") VALUES (1, ($2 :: text), ($1 :: text))"
         checkStatement squealRendering statement
 
+      it "insert into users_copy (id, name, bio) values ($1, $2, $3)" $ do
+        let
+          statement
+            :: Statement
+                 DB
+                 (Text, Text, Maybe Text)
+                 ()
+          statement =
+            [ssql|
+              insert into
+                users_copy (id, name, bio)
+                values ($1, $2, $3)
+            |]
+          squealRendering :: Text
+          squealRendering =
+            "INSERT INTO \"users_copy\" AS \"users_copy\" (\"id\", \"name\", \"bio\") VALUES (($1 :: text), ($2 :: text), ($3 :: text))"
+        checkStatement squealRendering statement
+
       it
         "insert into emails (id, user_id, email) values (inline(i), inline(uid), inline_param(e))"
         $ do
@@ -922,6 +960,14 @@
             "DELETE FROM \"emails\" AS \"emails\" WHERE (\"id\" = 1)"
         checkStatement squealRendering statement
 
+      it "delete from emails where id = $1" $ do
+        let
+          statement :: Statement DB (Only Int32) ()
+          statement = [ssql| delete from emails where id = $1 |]
+          squealRendering :: Text
+          squealRendering = "DELETE FROM \"emails\" AS \"emails\" WHERE (\"id\" = ($1 :: int4))"
+        checkStatement squealRendering statement
+
       it "delete from emails where email = inline(e)" $ do
         let
           statement :: Statement DB () ()
@@ -1007,6 +1053,15 @@
             "UPDATE \"users\" AS \"users\" SET \"name\" = (E'new name' :: text) WHERE (\"id\" = (E'some-id' :: text))"
         checkStatement squealRendering statement
 
+      it "update users set name = $1 where id = $2" $ do
+        let
+          statement :: Statement DB (Text, Text) ()
+          statement = [ssql| update users set name = $1 where id = $2 |]
+          squealRendering :: Text
+          squealRendering =
+            "UPDATE \"users\" AS \"users\" SET \"name\" = ($1 :: text) WHERE (\"id\" = ($2 :: text))"
+        checkStatement squealRendering statement
+
       it "update users set name = 'new name' where id = 'some-id' returning id" $ do
         let
           statement :: Statement DB () (Field "id" Text, ())
@@ -1384,7 +1439,8 @@
                  ( Field "id" Text
                  , (Field "name" Text, (Field "employee_id" UUID, (Field "bio" (Maybe Text), ())))
                  )
-          stmt = [ssql| select * from users where users.id in (select emails.user_id from emails) |]
+          stmt =
+            [ssql| select * from users where users.id in (select emails.user_id from emails) |]
           squealRendering :: Text
           squealRendering =
             "SELECT * FROM \"users\" AS \"users\" WHERE (\"users\".\"id\" = ANY (SELECT \"emails\".\"user_id\" AS \"user_id\" FROM \"emails\" AS \"emails\"))"
