diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,28 @@
 # Changelog
 
+## 0.5.1.0
+
+The quoters of `Hasql.Check.Inferred.TH` now take the Haskell targets and
+`$1.$field` param fields of the `kronor-syntax` flag: the quoter builds the
+row decoder and the parameter encoder from them, and a record's columns are
+read at the type of the field each one names, so a statement may write the
+fields in any order. Add `rowsAffectedStatement`, and widen the tuple
+instances from eight components to twenty-four.
+
+`Target` and `Slots` carry the Postgres and the Haskell types at the type
+level, as `PostgresParams`, `PostgresColumns`, `HaskellParams` and
+`HaskellColumns`, so `hasql-check-hie` finds them in the `.hie` files.
+
+`--inferred` annotated the statement as written rather than as the quoter
+sends it, so a statement that writes its placeholders out of order, such as
+`set name = $2 where id = $1`, had its parameters' types paired with the
+wrong ones and was rejected. It now lowers the statement first, and reports
+an unused parameter by the number the statement was written with.
+
+Known gap: a param field reaches its type through `HasField`, whose
+`PgColumnType` stays stuck in the recorded type, so such a statement is
+reported as having no concrete type rather than being checked.
+
 ## 0.5.0.0
 
 Add `Hasql.Check.Inferred.TH`: quoters for statements without annotations,
diff --git a/hasql-check.cabal b/hasql-check.cabal
--- a/hasql-check.cabal
+++ b/hasql-check.cabal
@@ -1,6 +1,6 @@
 cabal-version:   3.0
 name:            hasql-check
-version:         0.5.0.0
+version:         0.5.1.0
 synopsis:        Check hasql-th statements against a live PostgreSQL schema
 description:
   Finds the hasql-th quasiquotes in Haskell source files and PREPAREs each
@@ -223,13 +223,19 @@
 test-suite hasql-check-test
   type:               exitcode-stdio-1.0
   main-is:            Main.hs
+  other-modules:      Inferred.Shapes
   hs-source-dirs:     test
   default-language:   GHC2021
   default-extensions:
     BlockArguments
     DataKinds
+    DerivingVia
     LambdaCase
+    OverloadedRecordDot
     OverloadedStrings
+    QuasiQuotes
+    TemplateHaskell
+    UndecidableInstances
 
   ghc-options:        -Wall -threaded -rtsopts -with-rtsopts=-N
 
diff --git a/src/Hasql/Check.hs b/src/Hasql/Check.hs
--- a/src/Hasql/Check.hs
+++ b/src/Hasql/Check.hs
@@ -1,13 +1,14 @@
 {-# LANGUAGE CPP #-}
 
--- |
--- Module      : Hasql.Check
--- Copyright   : (c) 2022 Kronor.io
---
--- License     : BSD-3-Clause
--- Maintainer  : lorenzo@kronor.io
--- Stability   : experimental
--- Portability : GHC
+{- |
+Module      : Hasql.Check
+Copyright   : (c) 2022 Kronor.io
+
+License     : BSD-3-Clause
+Maintainer  : lorenzo@kronor.io
+Stability   : experimental
+Portability : GHC
+-}
 module Hasql.Check where
 
 import Data.ByteString (ByteString)
@@ -18,30 +19,35 @@
 import Pqi qualified
 import Prelude
 
-
--- | Turn the SQL text inside a quasiquote into the SQL the splice actually
--- sends to Postgres, mirroring @Hasql.TH.expPreparableStmtAstParser@ composed
--- with @Hasql.TH.Extraction.Exp.sql@ line for line. Rendering at 'mempty'
--- drops the nullability markers.
+{- | Turn the SQL text inside a quasiquote into the SQL the splice actually
+sends to Postgres, mirroring @Hasql.TH.expPreparableStmtAstParser@ composed
+with @Hasql.TH.Extraction.Exp.sql@ line for line. Rendering at 'mempty'
+drops the nullability markers.
+-}
 renderSql :: Text -> Either String ByteString
 renderSql sql = renderStmt <$> parseStmt sql
 
-
 -- | The statement in a quasiquote, as the splice would render it.
 parseStmt :: Text -> Either String Ast.PreparableStmt
 parseStmt sql = either (Left . Text.unpack) (Right . lowerAst) (Ast.parse quoterSettings sql)
 
+{- | A statement in plain SQL, as Postgres reads it, whatever syntax this
+build takes in hasql-th's quotes: for the quoters of
+"Hasql.Check.Inferred.TH", and the annotated statements that stand for
+theirs, which hasql-th's nullability markers may annotate.
 
--- | A statement in plain SQL, as Postgres reads it, whatever syntax this
--- build takes in hasql-th's quotes: for the quoters of
--- "Hasql.Check.Inferred.TH", and the annotated statements that stand for
--- theirs, which hasql-th's nullability markers may annotate.
---
--- Not lowered: Kronor's fork numbers the placeholders afresh as it lowers
--- its parameter fields, which would turn a lone @$2@ into @$1@.
+Not lowered: Kronor's fork numbers the placeholders afresh as it lowers
+its parameter fields, which would turn a lone @$2@ into @$1@.
+-}
 parsePlainStmt :: Bool -> Text -> Either String Ast.PreparableStmt
 parsePlainStmt markers sql = either (Left . Text.unpack) Right (Ast.parse (Ast.nullabilityMarkers markers) sql)
 
+{- | A statement in whatever syntax this build's quotes take, left exactly as
+parsed: the quoters of "Hasql.Check.Inferred.TH" read Kronor's Haskell
+targets off it, and lower it themselves.
+-}
+parseForkStmt :: Text -> Either String Ast.PreparableStmt
+parseForkStmt sql = either (Left . Text.unpack) Right (Ast.parse quoterSettings sql)
 
 renderStmt :: Ast.PreparableStmt -> ByteString
 renderStmt = Text.encodeUtf8 . Ast.toText mempty
@@ -81,11 +87,9 @@
 
 #endif
 
-
 prepare :: Pqi.Connection -> Text -> Text -> IO (Either String ())
 prepare conn stmtName unParsedStmt =
     either (pure . Left) (prepareStmt conn (Text.encodeUtf8 stmtName)) (parseStmt unParsedStmt)
-
 
 -- | Prepare a statement under a name, returning the server's error if it fails.
 prepareStmt :: Pqi.Connection -> ByteString -> Ast.PreparableStmt -> IO (Either String ())
diff --git a/src/Hasql/Check/Inferred.hs b/src/Hasql/Check/Inferred.hs
--- a/src/Hasql/Check/Inferred.hs
+++ b/src/Hasql/Check/Inferred.hs
@@ -5,28 +5,29 @@
 -- statement is used, which is what puts them in the .hie files.
 {-# OPTIONS_GHC -Wno-redundant-constraints #-}
 
--- |
--- Module      : Hasql.Check.Inferred
--- Copyright   : (c) 2026 Kronor.io
---
--- License     : BSD-3-Clause
--- Maintainer  : lorenzo@kronor.io
--- Stability   : experimental
--- Portability : GHC
---
--- Statements whose encoders and decoders are chosen by the Haskell types they
--- are used with, for the quoters in "Hasql.Check.Inferred.TH".
---
--- Each Haskell type stands for one Postgres type, named at the type level by
--- 'PgType', and the statement sends the annotations hasql-th would ask for:
--- @select email from customer@ used as a @Statement Int64 Text@ is sent as
--- @select (email)::text from customer@. A @varchar@ column is then read as
--- 'Text', and an @int4@ one as 'Int64', where an exact decoder would fail.
---
--- Because the names are types, GHC works them out where a statement is used,
--- and records them in its @.hie@ files, where @hasql-check-hie@ reads them:
--- a @newtype@ deriving 'Value' is checked as the type it wraps, with no list
--- of types to keep in step.
+{- |
+Module      : Hasql.Check.Inferred
+Copyright   : (c) 2026 Kronor.io
+
+License     : BSD-3-Clause
+Maintainer  : lorenzo@kronor.io
+Stability   : experimental
+Portability : GHC
+
+Statements whose encoders and decoders are chosen by the Haskell types they
+are used with, for the quoters in "Hasql.Check.Inferred.TH".
+
+Each Haskell type stands for one Postgres type, named at the type level by
+'PgType', and the statement sends the annotations hasql-th would ask for:
+@select email from customer@ used as a @Statement Int64 Text@ is sent as
+@select (email)::text from customer@. A @varchar@ column is then read as
+'Text', and an @int4@ one as 'Int64', where an exact decoder would fail.
+
+Because the names are types, GHC works them out where a statement is used,
+and records them in its @.hie@ files, where @hasql-check-hie@ reads them:
+a @newtype@ deriving 'Value' is checked as the type it wraps, with no list
+of types to keep in step.
+-}
 module Hasql.Check.Inferred (
     -- * Types
     Value (..),
@@ -52,12 +53,29 @@
     PostgresParams,
     PostgresColumns,
 
+    -- * Targets and slots, for the quoters' own statements
+    Target (..),
+    HaskellColumns,
+    HaskellParams,
+    targetPure,
+    targetColumn,
+    targetAp,
+    Slots (..),
+    slotsNone,
+    slotsOne,
+    slotsAp,
+
     -- * Statements
     Template (..),
     Wrapped (..),
     Piece (..),
     statement,
+    statementWith,
+    statementRow,
     resultless,
+    resultlessWith,
+    rowsAffected,
+    rowsAffectedWith,
     render,
 ) where
 
@@ -84,151 +102,131 @@
 import PostgresqlSyntax qualified as Ast
 import Prelude
 
+{- | A Haskell type, and the Postgres type it is sent and read as.
 
--- | A Haskell type, and the Postgres type it is sent and read as.
---
--- A @newtype@ can derive the instance of the type it wraps:
---
--- > newtype Email = Email Text
--- >     deriving newtype (Value)
+A @newtype@ can derive the instance of the type it wraps:
+
+> newtype Email = Email Text
+>     deriving newtype (Value)
+-}
 class Value a where
-    -- | The Postgres type's name, as an annotation would give it: @"int8"@,
-    -- @"public.payment_state"@.
+    {- | The Postgres type's name, as an annotation would give it: @"int8"@,
+    @"public.payment_state"@.
+    -}
     type PgType a :: Symbol
 
-
     -- | The labels of the Postgres enum it is, if it is one, for the checker.
     type PgLabels a :: [Symbol]
 
-
     type PgLabels a = '[]
 
-
     encodeValue :: E.Value a
     decodeValue :: D.Value a
 
-
 -- | The name of a type's Postgres type.
-typeName :: forall a. KnownSymbol (PgType a) => Text
+typeName :: forall a. (KnownSymbol (PgType a)) => Text
 typeName = Text.pack (symbolVal (Proxy @(PgType a)))
 
-
 instance Value Bool where
     type PgType Bool = "bool"
     encodeValue = E.bool
     decodeValue = D.bool
 
-
 instance Value Int16 where
     type PgType Int16 = "int2"
     encodeValue = E.int2
     decodeValue = D.int2
 
-
 instance Value Int32 where
     type PgType Int32 = "int4"
     encodeValue = E.int4
     decodeValue = D.int4
 
-
 instance Value Int64 where
     type PgType Int64 = "int8"
     encodeValue = E.int8
     decodeValue = D.int8
 
-
 instance Value Float where
     type PgType Float = "float4"
     encodeValue = E.float4
     decodeValue = D.float4
 
-
 instance Value Double where
     type PgType Double = "float8"
     encodeValue = E.float8
     decodeValue = D.float8
 
-
 instance Value Scientific where
     type PgType Scientific = "numeric"
     encodeValue = E.numeric
     decodeValue = D.numeric
 
-
 instance Value Text where
     type PgType Text = "text"
     encodeValue = E.text
     decodeValue = D.text
 
-
 instance Value ByteString where
     type PgType ByteString = "bytea"
     encodeValue = E.bytea
     decodeValue = D.bytea
 
-
 instance Value UUID where
     type PgType UUID = "uuid"
     encodeValue = E.uuid
     decodeValue = D.uuid
 
-
 instance Value Day where
     type PgType Day = "date"
     encodeValue = E.date
     decodeValue = D.date
 
-
 instance Value LocalTime where
     type PgType LocalTime = "timestamp"
     encodeValue = E.timestamp
     decodeValue = D.timestamp
 
-
 instance Value UTCTime where
     type PgType UTCTime = "timestamptz"
     encodeValue = E.timestamptz
     decodeValue = D.timestamptz
 
-
 instance Value TimeOfDay where
     type PgType TimeOfDay = "time"
     encodeValue = E.time
     decodeValue = D.time
 
-
 instance Value Aeson.Value where
     type PgType Aeson.Value = "jsonb"
     encodeValue = E.jsonb
     decodeValue = D.jsonb
 
+{- | A type sent and read as the one it wraps, under the name of a Postgres
+domain over it, so that Postgres checks the domain's constraints:
 
--- | A type sent and read as the one it wraps, under the name of a Postgres
--- domain over it, so that Postgres checks the domain's constraints:
---
--- > newtype Cents = Cents Int64
--- >     deriving (Value) via Domain "cents" Int64
+> newtype Cents = Cents Int64
+>     deriving (Value) via Domain "cents" Int64
+-}
 newtype Domain (name :: Symbol) a = Domain a
 
-
-instance Value a => Value (Domain name a) where
+instance (Value a) => Value (Domain name a) where
     type PgType (Domain name a) = name
     type PgLabels (Domain name a) = PgLabels a
     encodeValue = (\(Domain a) -> a) >$< encodeValue
     decodeValue = Domain <$> decodeValue
 
+{- | A Haskell enumeration sent and read as a Postgres enum, by the enum's
+name: each constructor, which takes no fields, as the label of the same
+name.
 
--- | A Haskell enumeration sent and read as a Postgres enum, by the enum's
--- name: each constructor, which takes no fields, as the label of the same
--- name.
---
--- > data PaymentState = PENDING | PAID
--- >     deriving stock (Generic)
--- >     deriving (Value) via PgEnum "payment_state" PaymentState
---
--- The checker compares the labels with the enum's in the database.
-newtype PgEnum (name :: Symbol) a = PgEnum a
+> data PaymentState = PENDING | PAID
+>     deriving stock (Generic)
+>     deriving (Value) via PgEnum "payment_state" PaymentState
 
+The checker compares the labels with the enum's in the database.
+-}
+newtype PgEnum (name :: Symbol) a = PgEnum a
 
 instance (KnownSymbol name, Generic a, GEnum (Rep a)) => Value (PgEnum name a) where
     type PgType (PgEnum name a) = name
@@ -236,11 +234,11 @@
     encodeValue = uncurry E.enum (qualifiedName (Text.pack (symbolVal (Proxy @name)))) (\(PgEnum a) -> glabel (from a))
     decodeValue = uncurry D.enum (qualifiedName (Text.pack (symbolVal (Proxy @name)))) (\t -> PgEnum . to <$> lookup t gvalues)
 
-
--- | A type's schema, if its name has one, and its own name, as the
--- identifiers they are: the name is SQL, as a cast takes it, so a quoted
--- part is taken as it is and an unquoted one in lower case, as Postgres
--- takes them.
+{- | A type's schema, if its name has one, and its own name, as the
+identifiers they are: the name is SQL, as a cast takes it, so a quoted
+part is taken as it is and an unquoted one in lower case, as Postgres
+takes them.
+-}
 qualifiedName :: Text -> (Maybe Text, Text)
 qualifiedName n = case Ast.parse mempty n of
     Right (Ast.Typename _ (Ast.GenericTypeSimpleTypename (Ast.GenericType i attrs _)) _ _) ->
@@ -257,106 +255,90 @@
         Ast.QuotedIdent t -> t
         Ast.UnquotedIdent t -> t
 
-
 -- | The constructors of an enumeration, by name.
 class GEnum f where
     gvalues :: [(Text, f p)]
     glabel :: f p -> Text
 
-
-instance GEnum f => GEnum (D1 m f) where
+instance (GEnum f) => GEnum (D1 m f) where
     gvalues = [(l, M1 x) | (l, x) <- gvalues]
     glabel (M1 x) = glabel x
 
-
 instance (GEnum f, GEnum g) => GEnum (f :+: g) where
     gvalues = [(l, L1 x) | (l, x) <- gvalues] <> [(l, R1 x) | (l, x) <- gvalues]
     glabel = \case
         L1 x -> glabel x
         R1 x -> glabel x
 
-
-instance KnownSymbol label => GEnum (C1 ('MetaCons label fixity strict) U1) where
+instance (KnownSymbol label) => GEnum (C1 ('MetaCons label fixity strict) U1) where
     gvalues = [(Text.pack (symbolVal (Proxy @label)), M1 U1)]
     glabel _ = Text.pack (symbolVal (Proxy @label))
 
-
 -- | An enumeration's constructor names.
 type family ConstructorNames (f :: Type -> Type) :: [Symbol] where
     ConstructorNames (D1 m f) = ConstructorNames f
     ConstructorNames (f :+: g) = Append (ConstructorNames f) (ConstructorNames g)
     ConstructorNames (C1 ('MetaCons label fixity strict) U1) = '[label]
 
-
 type family Append (xs :: [k]) (ys :: [k]) :: [k] where
     Append '[] ys = ys
     Append (x ': xs) ys = x ': Append xs ys
 
-
--- | A one-dimensional array, whose elements may be NULL when they are
--- 'Maybe's: a @Vector Int64@ is an @int8[]@.
-instance Column a => Value (Vector a) where
+{- | A one-dimensional array, whose elements may be NULL when they are
+'Maybe's: a @Vector Int64@ is an @int8[]@.
+-}
+instance (Column a) => Value (Vector a) where
     type PgType (Vector a) = AppendSymbol (PgColumnType a) "[]"
     type PgLabels (Vector a) = PgColumnLabels a
     encodeValue = E.foldableArray encodeColumn
     decodeValue = D.vectorArray decodeColumn
 
-
--- | A one-dimensional array, as a list. A 'String' is not one: 'Char' has no
--- Postgres type; use 'Text'.
-instance Column a => Value [a] where
+{- | A one-dimensional array, as a list. A 'String' is not one: 'Char' has no
+Postgres type; use 'Text'.
+-}
+instance (Column a) => Value [a] where
     type PgType [a] = AppendSymbol (PgColumnType a) "[]"
     type PgLabels [a] = PgColumnLabels a
     encodeValue = E.foldableArray encodeColumn
     decodeValue = D.listArray decodeColumn
 
-
 -- | A column or parameter, which may be NULL when it is a 'Maybe'.
 class Column a where
     encodeColumn :: E.NullableOrNot E.Value a
     decodeColumn :: D.NullableOrNot D.Value a
 
-
-instance {-# OVERLAPPABLE #-} Value a => Column a where
+instance {-# OVERLAPPABLE #-} (Value a) => Column a where
     encodeColumn = E.nonNullable encodeValue
     decodeColumn = D.nonNullable decodeValue
 
-
-instance Value a => Column (Maybe a) where
+instance (Value a) => Column (Maybe a) where
     encodeColumn = E.nullable encodeValue
     decodeColumn = D.nullable decodeValue
 
-
 -- | A column's enum labels, if it is one.
 type family PgColumnLabels (a :: Type) :: [Symbol] where
     PgColumnLabels (Maybe a) = PgLabels a
     PgColumnLabels a = PgLabels a
 
-
 -- | A column's Postgres type.
 type family PgColumnType (a :: Type) :: Symbol where
     PgColumnType (Maybe a) = PgType a
     PgColumnType a = PgType a
 
-
 -- | A statement's parameters: none, one, or a tuple of them.
 class Params a where
     params :: E.Params a
 
-
 instance Params () where
     params = E.noParams
 
-
-instance {-# OVERLAPPABLE #-} Column a => Params a where
+instance {-# OVERLAPPABLE #-} (Column a) => Params a where
     params = E.param encodeColumn
 
-
 instance (Column a, Column b) => Params (a, b) where
     params =
-        (fst >$< E.param encodeColumn)
-            <> (snd >$< E.param encodeColumn)
-
+        ((\(x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x) -> x) >$< E.param encodeColumn)
 
 instance (Column a, Column b, Column c) => Params (a, b, c) where
     params =
@@ -364,7 +346,6 @@
             <> ((\(_, x, _) -> x) >$< E.param encodeColumn)
             <> ((\(_, _, x) -> x) >$< E.param encodeColumn)
 
-
 instance (Column a, Column b, Column c, Column d) => Params (a, b, c, d) where
     params =
         ((\(x, _, _, _) -> x) >$< E.param encodeColumn)
@@ -372,7 +353,6 @@
             <> ((\(_, _, x, _) -> x) >$< E.param encodeColumn)
             <> ((\(_, _, _, x) -> x) >$< E.param encodeColumn)
 
-
 instance (Column a, Column b, Column c, Column d, Column e) => Params (a, b, c, d, e) where
     params =
         ((\(x, _, _, _, _) -> x) >$< E.param encodeColumn)
@@ -381,7 +361,6 @@
             <> ((\(_, _, _, x, _) -> x) >$< E.param encodeColumn)
             <> ((\(_, _, _, _, x) -> x) >$< E.param encodeColumn)
 
-
 instance (Column a, Column b, Column c, Column d, Column e, Column f) => Params (a, b, c, d, e, f) where
     params =
         ((\(x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
@@ -391,7 +370,6 @@
             <> ((\(_, _, _, _, x, _) -> x) >$< E.param encodeColumn)
             <> ((\(_, _, _, _, _, x) -> x) >$< E.param encodeColumn)
 
-
 instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g) => Params (a, b, c, d, e, f, g) where
     params =
         ((\(x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
@@ -402,7 +380,6 @@
             <> ((\(_, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
             <> ((\(_, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
 
-
 instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h) => Params (a, b, c, d, e, f, g, h) where
     params =
         ((\(x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
@@ -414,7 +391,318 @@
             <> ((\(_, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
             <> ((\(_, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
 
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i) => Params (a, b, c, d, e, f, g, h, i) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
 
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j) => Params (a, b, c, d, e, f, g, h, i, j) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k) => Params (a, b, c, d, e, f, g, h, i, j, k) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l) => Params (a, b, c, d, e, f, g, h, i, j, k, l) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t, Column u) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t, Column u, Column v) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t, Column u, Column v, Column w) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t, Column u, Column v, Column w, Column x) => Params (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) where
+    params =
+        ((\(x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x, _) -> x) >$< E.param encodeColumn)
+            <> ((\(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, x) -> x) >$< E.param encodeColumn)
+
 -- | The Postgres types of a statement's parameters.
 type family PgParamTypes (p :: Type) :: [Symbol] where
     PgParamTypes () = '[]
@@ -425,9 +713,24 @@
     PgParamTypes (a, b, c, d, e, f) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f]
     PgParamTypes (a, b, c, d, e, f, g) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g]
     PgParamTypes (a, b, c, d, e, f, g, h) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h]
+    PgParamTypes (a, b, c, d, e, f, g, h, i) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t, PgColumnType u]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t, PgColumnType u, PgColumnType v]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t, PgColumnType u, PgColumnType v, PgColumnType w]
+    PgParamTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t, PgColumnType u, PgColumnType v, PgColumnType w, PgColumnType x]
     PgParamTypes a = '[PgColumnType a]
 
-
 -- | The enum labels of a statement's parameters, one list each.
 type family PgParamLabels (p :: Type) :: [[Symbol]] where
     PgParamLabels () = '[]
@@ -438,46 +741,100 @@
     PgParamLabels (a, b, c, d, e, f) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f]
     PgParamLabels (a, b, c, d, e, f, g) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g]
     PgParamLabels (a, b, c, d, e, f, g, h) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h]
+    PgParamLabels (a, b, c, d, e, f, g, h, i) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t, PgColumnLabels u]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t, PgColumnLabels u, PgColumnLabels v]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t, PgColumnLabels u, PgColumnLabels v, PgColumnLabels w]
+    PgParamLabels (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t, PgColumnLabels u, PgColumnLabels v, PgColumnLabels w, PgColumnLabels x]
     PgParamLabels a = '[PgColumnLabels a]
 
-
 -- | A result row: one column, or a tuple of them.
 class Row a where
     row :: D.Row a
 
-
-instance {-# OVERLAPPABLE #-} Column a => Row a where
+instance {-# OVERLAPPABLE #-} (Column a) => Row a where
     row = D.column decodeColumn
 
-
 instance (Column a, Column b) => Row (a, b) where
     row = (,) <$> D.column decodeColumn <*> D.column decodeColumn
 
-
 instance (Column a, Column b, Column c) => Row (a, b, c) where
     row = (,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
 
-
 instance (Column a, Column b, Column c, Column d) => Row (a, b, c, d) where
     row = (,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
 
-
 instance (Column a, Column b, Column c, Column d, Column e) => Row (a, b, c, d, e) where
     row = (,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
 
-
 instance (Column a, Column b, Column c, Column d, Column e, Column f) => Row (a, b, c, d, e, f) where
     row = (,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
 
-
 instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g) => Row (a, b, c, d, e, f, g) where
     row = (,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
 
-
 instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h) => Row (a, b, c, d, e, f, g, h) where
     row = (,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
 
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i) => Row (a, b, c, d, e, f, g, h, i) where
+    row = (,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
 
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j) => Row (a, b, c, d, e, f, g, h, i, j) where
+    row = (,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k) => Row (a, b, c, d, e, f, g, h, i, j, k) where
+    row = (,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l) => Row (a, b, c, d, e, f, g, h, i, j, k, l) where
+    row = (,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m) where
+    row = (,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where
+    row = (,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where
+    row = (,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) where
+    row = (,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) where
+    row = (,,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) where
+    row = (,,,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) where
+    row = (,,,,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) where
+    row = (,,,,,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t, Column u) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) where
+    row = (,,,,,,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t, Column u, Column v) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) where
+    row = (,,,,,,,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t, Column u, Column v, Column w) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) where
+    row = (,,,,,,,,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
+instance (Column a, Column b, Column c, Column d, Column e, Column f, Column g, Column h, Column i, Column j, Column k, Column l, Column m, Column n, Column o, Column p, Column q, Column r, Column s, Column t, Column u, Column v, Column w, Column x) => Row (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) where
+    row = (,,,,,,,,,,,,,,,,,,,,,,,) <$> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn <*> D.column decodeColumn
+
 -- | The Postgres types of a statement's result columns.
 type family PgColumnTypes (r :: Type) :: [Symbol] where
     PgColumnTypes (a, b) = '[PgColumnType a, PgColumnType b]
@@ -487,9 +844,24 @@
     PgColumnTypes (a, b, c, d, e, f) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f]
     PgColumnTypes (a, b, c, d, e, f, g) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g]
     PgColumnTypes (a, b, c, d, e, f, g, h) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t, PgColumnType u]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t, PgColumnType u, PgColumnType v]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t, PgColumnType u, PgColumnType v, PgColumnType w]
+    PgColumnTypes (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) = '[PgColumnType a, PgColumnType b, PgColumnType c, PgColumnType d, PgColumnType e, PgColumnType f, PgColumnType g, PgColumnType h, PgColumnType i, PgColumnType j, PgColumnType k, PgColumnType l, PgColumnType m, PgColumnType n, PgColumnType o, PgColumnType p, PgColumnType q, PgColumnType r, PgColumnType s, PgColumnType t, PgColumnType u, PgColumnType v, PgColumnType w, PgColumnType x]
     PgColumnTypes a = '[PgColumnType a]
 
-
 -- | The enum labels of a statement's result columns, one list each.
 type family PgColumnLabelLists (r :: Type) :: [[Symbol]] where
     PgColumnLabelLists (a, b) = '[PgColumnLabels a, PgColumnLabels b]
@@ -499,65 +871,86 @@
     PgColumnLabelLists (a, b, c, d, e, f) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f]
     PgColumnLabelLists (a, b, c, d, e, f, g) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g]
     PgColumnLabelLists (a, b, c, d, e, f, g, h) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t, PgColumnLabels u]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t, PgColumnLabels u, PgColumnLabels v]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t, PgColumnLabels u, PgColumnLabels v, PgColumnLabels w]
+    PgColumnLabelLists (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) = '[PgColumnLabels a, PgColumnLabels b, PgColumnLabels c, PgColumnLabels d, PgColumnLabels e, PgColumnLabels f, PgColumnLabels g, PgColumnLabels h, PgColumnLabels i, PgColumnLabels j, PgColumnLabels k, PgColumnLabels l, PgColumnLabels m, PgColumnLabels n, PgColumnLabels o, PgColumnLabels p, PgColumnLabels q, PgColumnLabels r, PgColumnLabels s, PgColumnLabels t, PgColumnLabels u, PgColumnLabels v, PgColumnLabels w, PgColumnLabels x]
     PgColumnLabelLists a = '[PgColumnLabels a]
 
-
 -- | Type-level names, as text.
 class KnownSymbols (ss :: [Symbol]) where
     symbolTexts :: [Text]
 
-
 instance KnownSymbols '[] where
     symbolTexts = []
 
-
 instance (KnownSymbol s, KnownSymbols ss) => KnownSymbols (s ': ss) where
     symbolTexts = Text.pack (symbolVal (Proxy @s)) : symbolTexts @ss
 
-
--- | The Postgres types of a statement's parameters, as GHC worked them out
--- where it is used. A class of its own, rather than 'KnownSymbols' itself,
--- so that @hasql-check-hie@ finds the whole list in a @.hie@ file, and not
--- only the tails 'KnownSymbols' is built from.
-class KnownSymbols ps => PostgresParams ps
+{- | The Postgres types of a statement's parameters, as GHC worked them out
+where it is used. A class of its own, rather than 'KnownSymbols' itself,
+so that @hasql-check-hie@ finds the whole list in a @.hie@ file, and not
+only the tails 'KnownSymbols' is built from.
+-}
+class (KnownSymbols ps) => PostgresParams ps
 
+instance (KnownSymbols ps) => PostgresParams ps
 
-instance KnownSymbols ps => PostgresParams ps
+{- | The Haskell types a statement's parameters are sent from, for
+@hasql-check-hie@ to find; see 'PostgresParams'.
+-}
+class HaskellParams (hs :: [Type])
 
+instance HaskellParams hs
 
--- | The Postgres types of a statement's result columns; see 'PostgresParams'.
-class KnownSymbols cs => PostgresColumns cs
+{- | The Haskell types a statement's result columns are read as; see
+'PostgresParams'.
+-}
+class HaskellColumns (hs :: [Type])
 
+instance HaskellColumns hs
 
-instance KnownSymbols cs => PostgresColumns cs
+-- | The Postgres types of a statement's result columns; see 'PostgresParams'.
+class (KnownSymbols cs) => PostgresColumns cs
 
+instance (KnownSymbols cs) => PostgresColumns cs
 
--- | The enum labels of a statement's parameters, as GHC worked them out where
--- it is used, for @hasql-check-hie@ to find; see 'PostgresParams'.
+{- | The enum labels of a statement's parameters, as GHC worked them out where
+it is used, for @hasql-check-hie@ to find; see 'PostgresParams'.
+-}
 class PostgresParamLabels (ls :: [[Symbol]])
 
-
 instance PostgresParamLabels ls
 
-
 -- | The enum labels of a statement's result columns; see 'PostgresParams'.
 class PostgresColumnLabels (ls :: [[Symbol]])
 
-
 instance PostgresColumnLabels ls
 
+{- | A statement's text, as the quoter cut it.
 
--- | A statement's text, as the quoter cut it.
---
--- Its result columns are cast in a projection around it,
---
--- > WITH <its own WITH list,> r (c1, c2) AS (<the statement>) SELECT c1 :: int8, c2 :: text FROM r
---
--- rather than where they are selected, so that the statement means what it
--- did: a cast column is another expression to DISTINCT ON, ORDER BY and
--- GROUP BY, and no longer the primary key other columns depend on. The
--- statement's own WITH list goes first, since one with a data-modifying
--- statement must stay at the top.
+Its result columns are cast in a projection around it,
+
+> WITH <its own WITH list,> r (c1, c2) AS (<the statement>) SELECT c1 :: int8, c2 :: text FROM r
+
+rather than where they are selected, so that the statement means what it
+did: a cast column is another expression to DISTINCT ON, ORDER BY and
+GROUP BY, and no longer the primary key other columns depend on. The
+statement's own WITH list goes first, since one with a data-modifying
+statement must stay at the top.
+-}
 data Template = Template
     { whole :: [Piece]
     -- ^ The statement, for one returning no rows.
@@ -566,7 +959,6 @@
     }
     deriving stock (Eq, Show, Lift)
 
-
 data Wrapped = Wrapped
     { with :: Maybe [Piece]
     -- ^ Its own WITH list, with the WITH.
@@ -577,7 +969,6 @@
     }
     deriving stock (Eq, Show, Lift)
 
-
 -- | Some SQL, or the place of a parameter's annotation.
 data Piece
     = Sql Text
@@ -585,9 +976,9 @@
       ParamType Int
     deriving stock (Eq, Show, Lift)
 
-
--- | The statement's text, given the Postgres types of its parameters and
--- result columns.
+{- | The statement's text, given the Postgres types of its parameters and
+result columns.
+-}
 render :: [Text] -> [Text] -> Template -> Text
 render paramTypes' columnTypes' t = case (columnTypes', t.wrapped) of
     (_ : _, Just w) ->
@@ -612,7 +1003,110 @@
             ty : _ | n >= 1 -> " :: " <> ty
             _ -> ""
 
+{- | A row decoder the quoter built out of a statement's target list, carrying
+the Postgres types and enum labels its columns are read as. Kronor's
+Haskell targets need it: only the statement knows the row's shape, and the
+column types are the constructor's fields'.
+-}
+newtype Target (cs :: [Symbol]) (ls :: [[Symbol]]) (hs :: [Type]) r = Target {targetRow :: D.Row r}
 
+-- | A target that reads no columns: a constructor, before its arguments.
+targetPure :: r -> Target '[] '[] '[] r
+targetPure = Target . pure
+
+-- | One column, read as whatever Haskell reads it as.
+targetColumn :: forall a. (Column a) => Target '[PgColumnType a] '[PgColumnLabels a] '[a] a
+targetColumn = Target (D.column decodeColumn)
+
+-- | A constructor applied to one more column, appending its type.
+targetAp :: Target cs ls hs (a -> b) -> Target ds ms is a -> Target (Append cs ds) (Append ls ms) (Append hs is) b
+targetAp (Target f) (Target x) = Target (f <*> x)
+
+{- | A parameter encoder the quoter built out of a statement's placeholders,
+carrying the Postgres types they are sent as. Kronor's @$1.$field@ param
+fields need it: each sends a field of a parameter, not the whole of it.
+-}
+newtype Slots (ps :: [Symbol]) (ls :: [[Symbol]]) (hs :: [Type]) p = Slots {slotsParams :: E.Params p}
+
+-- | No parameters.
+slotsNone :: Slots '[] '[] '[] p
+slotsNone = Slots mempty
+
+-- | One parameter slot, sending what the projection picks out.
+slotsOne :: forall a p. (Column a) => (p -> a) -> Slots '[PgColumnType a] '[PgColumnLabels a] '[a] p
+slotsOne f = Slots (f >$< E.param encodeColumn)
+
+-- | One more slot, appending its type.
+slotsAp :: Slots ps ls hs p -> Slots qs ms is p -> Slots (Append ps qs) (Append ls ms) (Append hs is) p
+slotsAp (Slots a) (Slots b) = Slots (a <> b)
+
+{- | A statement returning rows, whose decoder and encoder the quoter built
+because the statement's own syntax decides them.
+-}
+statementWith ::
+    forall p r a ps cs pl cl ph ch.
+    ( PostgresParams ps
+    , PostgresColumns cs
+    , PostgresParamLabels pl
+    , PostgresColumnLabels cl
+    , HaskellParams ph
+    , HaskellColumns ch
+    ) =>
+    Template ->
+    Slots ps pl ph p ->
+    Target cs cl ch r ->
+    (D.Row r -> D.Result a) ->
+    Statement p a
+statementWith template slots target result =
+    Statement.preparable
+        (render (symbolTexts @ps) (symbolTexts @cs) template)
+        (slotsParams slots)
+        (result (targetRow target))
+
+{- | A statement whose encoder the quoter built, but whose row the Haskell
+type decides: a target list the quoter cannot count, such as a @*@.
+-}
+statementRow ::
+    forall p r a ps cs pl cl ph.
+    ( Row r
+    , cs ~ PgColumnTypes r
+    , cl ~ PgColumnLabelLists r
+    , PostgresParams ps
+    , PostgresColumns cs
+    , PostgresParamLabels pl
+    , PostgresColumnLabels cl
+    , HaskellParams ph
+    ) =>
+    Template ->
+    Slots ps pl ph p ->
+    (D.Row r -> D.Result a) ->
+    Statement p a
+statementRow template slots result =
+    Statement.preparable
+        (render (symbolTexts @ps) (symbolTexts @cs) template)
+        (slotsParams slots)
+        (result row)
+
+-- | A statement returning no rows, whose encoder the quoter built.
+resultlessWith ::
+    forall p ps pl ph.
+    (PostgresParams ps, PostgresParamLabels pl, HaskellParams ph) =>
+    Template ->
+    Slots ps pl ph p ->
+    Statement p ()
+resultlessWith template slots =
+    Statement.preparable (render (symbolTexts @ps) [] template) (slotsParams slots) D.noResult
+
+-- | A statement counting the rows it affected, whose encoder the quoter built.
+rowsAffectedWith ::
+    forall p ps pl ph.
+    (PostgresParams ps, PostgresParamLabels pl, HaskellParams ph) =>
+    Template ->
+    Slots ps pl ph p ->
+    Statement p Int64
+rowsAffectedWith template slots =
+    Statement.preparable (render (symbolTexts @ps) [] template) (slotsParams slots) D.rowsAffected
+
 -- | A statement returning rows, given what to make of them.
 statement ::
     forall p r a ps cs pl cl.
@@ -633,6 +1127,13 @@
 statement template result =
     Statement.preparable (render (symbolTexts @ps) (symbolTexts @cs) template) params (result row)
 
+-- | A statement whose result is the number of rows it affected.
+rowsAffected ::
+    forall p ps pl.
+    (Params p, ps ~ PgParamTypes p, PostgresParams ps, pl ~ PgParamLabels p, PostgresParamLabels pl) =>
+    Template ->
+    Statement p Int64
+rowsAffected template = Statement.preparable (render (symbolTexts @ps) [] template) params D.rowsAffected
 
 -- | A statement returning no rows.
 resultless ::
diff --git a/src/Hasql/Check/Inferred/Quote.hs b/src/Hasql/Check/Inferred/Quote.hs
--- a/src/Hasql/Check/Inferred/Quote.hs
+++ b/src/Hasql/Check/Inferred/Quote.hs
@@ -1,18 +1,19 @@
--- |
--- Module      : Hasql.Check.Inferred.Quote
--- Copyright   : (c) 2026 Kronor.io
---
--- License     : BSD-3-Clause
--- Maintainer  : lorenzo@kronor.io
--- Stability   : experimental
--- Portability : GHC
---
--- Quotes of "Hasql.Check.Inferred.TH", with the Haskell types GHC used them
--- at, as @hasql-check-hie@ writes them: one JSON object a line.
---
--- Each is checked as the hasql-th quote it stands for - the same SQL, with
--- the annotations the Haskell types give it - so that every check of an
--- annotated quote applies to it too.
+{- |
+Module      : Hasql.Check.Inferred.Quote
+Copyright   : (c) 2026 Kronor.io
+
+License     : BSD-3-Clause
+Maintainer  : lorenzo@kronor.io
+Stability   : experimental
+Portability : GHC
+
+Quotes of "Hasql.Check.Inferred.TH", with the Haskell types GHC used them
+at, as @hasql-check-hie@ writes them: one JSON object a line.
+
+Each is checked as the hasql-th quote it stands for - the same SQL, with
+the annotations the Haskell types give it - so that every check of an
+annotated quote applies to it too.
+-}
 module Hasql.Check.Inferred.Quote (
     Inferred (..),
     Column (..),
@@ -33,11 +34,11 @@
 import Data.Text qualified as Text
 import Data.Text.Encoding qualified as Text
 import Data.Word (Word32)
-import Hasql.Check (parsePlainStmt, quoterSettings, renderStmt)
+import Hasql.Check (parsePlainStmt, parseStmt, quoterSettings, renderStmt)
 import Hasql.Check.Annotate (annotate, typename, untypedLiterals)
 import Hasql.Check.Finding (Finding (..), statementHash)
-import Hasql.Check.Inferred (Piece (..), Template (..), render)
-import Hasql.Check.Inferred.TH (template)
+import Hasql.Check.Inferred (Template (..), render)
+import Hasql.Check.Inferred.TH (Parsed (..), parsed)
 import Hasql.Check.Nullability (Catalogue, query)
 import Hasql.Check.Nullability qualified as Nullability
 import Hasql.Check.Types qualified as Types
@@ -46,7 +47,6 @@
 import Text.Read (readMaybe)
 import Prelude
 
-
 data Inferred = Inferred
     { file :: FilePath
     , line :: Int
@@ -58,9 +58,9 @@
     -- ^ Nothing for a statement that returns no rows.
     }
 
-
--- | A parameter or result column: the qualified name of its Haskell type,
--- its Postgres type, and whether it is a 'Maybe'.
+{- | A parameter or result column: the qualified name of its Haskell type,
+its Postgres type, and whether it is a 'Maybe'.
+-}
 data Column = Column
     { haskellType :: Text
     , postgres :: Text
@@ -70,7 +70,6 @@
     , nullable :: Bool
     }
 
-
 instance Aeson.FromJSON Inferred where
     parseJSON = Aeson.withObject "quote" \o ->
         Inferred
@@ -82,15 +81,14 @@
             <*> o .: "params"
             <*> o .:? "row"
 
-
 instance Aeson.FromJSON Column where
     parseJSON = Aeson.withObject "column" \o -> Column <$> o .: "type" <*> o .: "postgres" <*> (o .:? "labels" .!= []) <*> o .: "nullable"
 
-
--- | Everything checking an inferred statement finds: why it fails, or the
--- warnings asked for - nullability, narrowing - in terms of its Haskell
--- types, and its fingerprint for baselines: the SQL it sends, so that
--- reading a column as another type is another statement.
+{- | Everything checking an inferred statement finds: why it fails, or the
+warnings asked for - nullability, narrowing - in terms of its Haskell
+types, and its fingerprint for baselines: the SQL it sends, so that
+reading a column as another type is another statement.
+-}
 checkInferred :: Pqi.Connection -> Maybe Catalogue -> Bool -> Bool -> Inferred -> IO (Either String ([Finding], Text))
 checkInferred conn catalogue nullable narrowing q =
     checkSent conn q >>= \case
@@ -111,9 +109,9 @@
                 let fingerprint = either (const (statementHash (renderStmt ast))) (statementHash . Text.encodeUtf8) (sent q)
                 pure (Right ([f{message = inHaskellTerms f.message} | f <- found], fingerprint))
 
-
--- | A finding about an inferred quote, in terms of its Haskell types rather
--- than the annotations they stand for.
+{- | A finding about an inferred quote, in terms of its Haskell types rather
+than the annotations they stand for.
+-}
 inHaskellTerms :: String -> String
 inHaskellTerms m =
     Text.unpack
@@ -123,7 +121,6 @@
   where
     t = Text.pack m
 
-
 -- | Quotes, one JSON object a line.
 readInferred :: ByteString -> Either String [Inferred]
 readInferred contents =
@@ -131,54 +128,56 @@
         (\(n, l) -> either (\e -> Left ("line " <> show n <> ": " <> e)) Right (Aeson.eitherDecodeStrict l))
         [(n, l) | (n :: Int, l) <- zip [1 ..] (ByteString.Char8.lines contents), not (ByteString.Char8.null l)]
 
-
--- | The statement with its parameters annotated, as a hasql-th quote: its
--- result columns are cast around it, which the warnings see through
--- 'columns'.
+{- | The statement with its parameters annotated, as a hasql-th quote: its
+result columns are cast around it, which the warnings see through
+'columns'.
+-}
 annotated :: Inferred -> Either String Text
 annotated q = do
-    stmt <- parsePlainStmt False q.sql
+    -- Lowered, as the quoter sends it: the types come one per placeholder in
+    -- that order, which is not the order the statement writes them in when it
+    -- uses a parameter more than once, out of order, or by field.
+    stmt <- parseStmt q.sql
     params <- traverse (\c -> typename c.postgres c.nullable) q.params
     let param n = case drop (n - 1) params of
             t : _ | n >= 1 -> Just t
             _ -> Nothing
     pure (Ast.toText quoterSettings (annotate param stmt))
 
-
 -- | The statement as the quoter sends it, casts and all.
 sent :: Inferred -> Either String Text
 sent q = do
-    t <- template q.sql
+    t <- parsedTemplate <$> parsed q.sql
     params <- traverse postgresType q.params
     row <- traverse (traverse postgresType) q.row
     pure (render (map fst params) (maybe [] (map fst) row) t)
 
-
--- | The Postgres type each result column is read as, and whether it may be
--- NULL.
+{- | The Postgres type each result column is read as, and whether it may be
+NULL.
+-}
 columns :: Inferred -> Maybe [(Text, Bool)]
 columns q = either (const Nothing) Just . traverse postgresType =<< q.row
 
-
 postgresType :: Column -> Either String (Text, Bool)
 postgresType c = Right (c.postgres, c.nullable)
 
+{- | Whether the statement, as the quoter sends it, prepares; whether it
+takes as many parameters as the Haskell type sends, and returns as many
+columns as it reads, each of a type it can be read as. Prepared, as hasql
+prepares it, with the parameters' types, which Postgres could not tell for
+a parameter the statement does not use.
 
--- | Whether the statement, as the quoter sends it, prepares; whether it
--- takes as many parameters as the Haskell type sends, and returns as many
--- columns as it reads, each of a type it can be read as. Prepared, as hasql
--- prepares it, with the parameters' types, which Postgres could not tell for
--- a parameter the statement does not use.
---
--- A result column is cast to the type it is read as, and Postgres casts
--- anything it can convert, even text to a number, which fails at runtime for
--- text that is not one. So the column must have that type already, or one
--- Postgres converts to it without being told to: implicitly, or on
--- assignment.
+A result column is cast to the type it is read as, and Postgres casts
+anything it can convert, even text to a number, which fails at runtime for
+text that is not one. So the column must have that type already, or one
+Postgres converts to it without being told to: implicitly, or on
+assignment.
+-}
 checkSent :: Pqi.Connection -> Inferred -> IO [String]
-checkSent conn q = case (,,) <$> template q.sql <*> traverse postgresType q.params <*> traverse (traverse postgresType) q.row of
+checkSent conn q = case (,,) <$> parsed q.sql <*> traverse postgresType q.params <*> traverse (traverse postgresType) q.row of
     Left err -> pure [err]
-    Right (t, params, row) -> do
+    Right (p, params, row) -> do
+        let t = p.parsedTemplate
         oids <- traverse (oid . fst) params
         case sequence oids of
             Nothing -> pure ["a parameter's type does not exist: " <> unwords [Text.unpack name | ((name, _), Nothing) <- zip params oids]]
@@ -189,7 +188,10 @@
                     Right found -> do
                         -- From the statement itself: prepared with the
                         -- types hasql sends, it takes them all, used or not.
-                        let used = [n | ParamType n <- t.whole]
+                        -- In the numbering the statement was written in,
+                        -- which lowering renumbers: each slot knows the
+                        -- parameter it came from.
+                        let used = p.parsedUsed
                             sends = length q.params
                             paramErrors =
                                 [ concat ["the Haskell type sends parameter $", show n, ", which the statement does not use"]
@@ -386,7 +388,6 @@
             Right [[Just name]] -> pure (Text.unpack (Text.decodeUtf8Lenient name))
             _ -> pure ("type " <> show o)
     quoteLiteral name = mconcat ["'", Text.encodeUtf8 (Text.replace "'" "''" name), "'"]
-
 
 zip4 :: [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
 zip4 (a : as) (b : bs) (c : cs) (d : ds) = (a, b, c, d) : zip4 as bs cs ds
diff --git a/src/Hasql/Check/Inferred/TH.hs b/src/Hasql/Check/Inferred/TH.hs
--- a/src/Hasql/Check/Inferred/TH.hs
+++ b/src/Hasql/Check/Inferred/TH.hs
@@ -1,71 +1,290 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE TemplateHaskell #-}
 
--- |
--- Module      : Hasql.Check.Inferred.TH
--- Copyright   : (c) 2026 Kronor.io
---
--- License     : BSD-3-Clause
--- Maintainer  : lorenzo@kronor.io
--- Stability   : experimental
--- Portability : GHC
---
--- Quoters for SQL without annotations: the Haskell types a statement is used
--- with decide its parameter and result types.
---
--- > profile :: Statement Int64 (Maybe (Text, Maybe Text))
--- > profile = [maybeStatement| select email, nickname from customer where id = $1 |]
---
--- sends
---
--- > WITH hasql_check_result (c1, c2) AS (SELECT email, nickname FROM customer WHERE id = $1 :: int8)
--- > SELECT c1 :: text, c2 :: text FROM hasql_check_result
---
--- GHC can only tell whether those types fit the schema with a database; see
--- the README for checking them with @hasql-check --inferred@.
+{- |
+Module      : Hasql.Check.Inferred.TH
+Copyright   : (c) 2026 Kronor.io
+
+License     : BSD-3-Clause
+Maintainer  : lorenzo@kronor.io
+Stability   : experimental
+Portability : GHC
+
+Quoters for SQL without annotations: the Haskell types a statement is used
+with decide its parameter and result types.
+
+> profile :: Statement Int64 (Maybe (Text, Maybe Text))
+> profile = [maybeStatement| select email, nickname from customer where id = $1 |]
+
+sends
+
+> WITH hasql_check_result (c1, c2) AS (SELECT email, nickname FROM customer WHERE id = $1 :: int8)
+> SELECT c1 :: text, c2 :: text FROM hasql_check_result
+
+Kronor's Haskell targets and @$1.$field@ param fields work too: the quoter
+builds the row decoder and the parameter encoder out of them, and the column
+types come from the constructor's fields rather than from a tuple.
+
+GHC can only tell whether those types fit the schema with a database; see
+the README for checking them with @hasql-check --inferred@.
+-}
 module Hasql.Check.Inferred.TH (
     singletonStatement,
     maybeStatement,
     vectorStatement,
     resultlessStatement,
+    rowsAffectedStatement,
+    Parsed (..),
+    Slot (..),
+    Tgt (..),
+    parsed,
     template,
 ) where
 
 import Data.Char (isAlphaNum)
+import Data.List (foldl1')
+import Data.Maybe (fromMaybe)
+#ifdef KRONOR_SYNTAX
+import Data.List.NonEmpty qualified as NonEmpty
+import Data.Map.Strict qualified as Map
+#endif
 import Data.Text (Text)
 import Data.Text qualified as Text
 import Data.Text.Encoding qualified as Text
-import Hasql.Check (parsePlainStmt, renderStmt)
+import GHC.Records (getField)
+import Hasql.Check (parseForkStmt, parsePlainStmt, renderStmt)
 import Hasql.Check.Annotate (annotate, placeholder)
-import Hasql.Check.Inferred (Piece (..), Template (..), Wrapped (..), resultless, statement)
+import Hasql.Check.Inferred (
+    Piece (..),
+    Template (..),
+    Wrapped (..),
+    resultlessWith,
+    rowsAffectedWith,
+    slotsAp,
+    slotsNone,
+    slotsOne,
+    statementRow,
+    statementWith,
+    targetAp,
+    targetColumn,
+    targetPure,
+ )
 import Hasql.Decoders qualified as D
-import Language.Haskell.TH (Exp, Q)
+import Language.Haskell.TH (Exp, Q, appTypeE, conE, litT, mkName, newName, strTyLit, varE)
+import Language.Haskell.TH qualified as TH
 import Language.Haskell.TH.Quote (QuasiQuoter (..))
 import Language.Haskell.TH.Syntax (lift)
 import PostgresqlSyntax qualified as Ast
 import Text.Read (readMaybe)
 import Prelude
 
+{- | One SQL placeholder: which Haskell parameter it comes from, and which of
+its fields, for Kronor's @$1.$field@.
+-}
+data Slot = Slot Int (Maybe Text)
+    deriving stock (Eq, Show)
 
-quoter :: (Q Exp -> Q Exp) -> QuasiQuoter
+-- | A result column, or a Haskell constructor applied to some.
+data Tgt
+    = TgtColumn
+    | -- | A constructor applied to its arguments in order.
+      TgtApply Text [Tgt]
+    | {- | A constructor whose fields are named, so the statement may write
+      them in any order.
+      -}
+      TgtRecord Text [(Text, Tgt)]
+    deriving stock (Eq, Show)
+
+-- | Everything the quoter reads off a statement.
+data Parsed = Parsed
+    { parsedTemplate :: Template
+    , parsedSlots :: [Slot]
+    -- ^ One per SQL placeholder, in the order they are sent.
+    , parsedArity :: Int
+    -- ^ How many parameters the statement takes in Haskell.
+    , parsedUsed :: [Int]
+    {- ^ The parameters the statement actually refers to, numbered as it was
+    written: lowering renumbers the placeholders, so this is not the same
+    as the slots' positions.
+    -}
+    , parsedTargets :: Maybe [Tgt]
+    -- ^ Its result columns, unless they cannot be counted here: a @*@.
+    }
+    deriving stock (Eq, Show)
+
+quoter :: (Parsed -> Q Exp) -> QuasiQuoter
 quoter make =
     QuasiQuoter
-        { quoteExp = either fail (make . lift) . template . Text.pack
+        { quoteExp = either fail make . parsed . Text.pack
         , quotePat = const (fail "Not supported in patterns")
         , quoteType = const (fail "Not supported in types")
         , quoteDec = const (fail "Not supported in declarations")
         }
 
+-- | A quoter for a statement that returns rows, given what to make of them.
+rowQuoter :: Q Exp -> QuasiQuoter
+rowQuoter result = quoter \p -> do
+    let t = lift p.parsedTemplate
+        s = slotsExp p
+    case p.parsedTargets of
+        Just ts -> [|statementWith $t $s $(targetsExp ts) $result|]
+        Nothing -> [|statementRow $t $s $result|]
 
-singletonStatement, maybeStatement, vectorStatement, resultlessStatement :: QuasiQuoter
-singletonStatement = quoter \t -> [|statement $t D.singleRow|]
-maybeStatement = quoter \t -> [|statement $t D.rowMaybe|]
-vectorStatement = quoter \t -> [|statement $t D.rowVector|]
-resultlessStatement = quoter \t -> [|resultless $t|]
+singletonStatement, maybeStatement, vectorStatement, resultlessStatement, rowsAffectedStatement :: QuasiQuoter
+singletonStatement = rowQuoter [|D.singleRow|]
+maybeStatement = rowQuoter [|D.rowMaybe|]
+vectorStatement = rowQuoter [|D.rowVector|]
+resultlessStatement = quoter \p -> [|resultlessWith $(lift p.parsedTemplate) $(slotsExp p)|]
+rowsAffectedStatement = quoter \p -> [|rowsAffectedWith $(lift p.parsedTemplate) $(slotsExp p)|]
 
+{- | The statement's parameter encoder: one slot per placeholder, each picking
+its parameter out of the tuple, and its field out of that.
+-}
+slotsExp :: Parsed -> Q Exp
+slotsExp p = case p.parsedSlots of
+    [] -> [|slotsNone|]
+    ss -> foldl1' (\a b -> [|slotsAp $a $b|]) (map (slotExp p.parsedArity) ss)
 
--- | The statement, rendered as hasql-th would render it, cut where its
--- parameters' annotations go, and split where its result columns' cast
--- goes around it.
+slotExp :: Int -> Slot -> Q Exp
+slotExp arity (Slot n field) = do
+    y <- newName "y"
+    -- Wildcards elsewhere: an unused binding warns in the splice's module.
+    let pat
+            | arity <= 1 = TH.varP y
+            | otherwise = TH.tupP [if i == n then TH.varP y else TH.wildP | i <- [1 .. arity]]
+        body = case field of
+            Nothing -> varE y
+            Just f -> [|$(appTypeE (varE 'getField) (litT (strTyLit (Text.unpack f)))) $(varE y)|]
+    [|slotsOne $(TH.lamE [pat] body)|]
+
+-- | The statement's row decoder, built out of its target list.
+targetsExp :: [Tgt] -> Q Exp
+targetsExp = \case
+    [t] -> targetExp t
+    ts -> applied [|targetPure $(conE (TH.tupleDataName (length ts)))|] ts
+
+targetExp :: Tgt -> Q Exp
+targetExp = \case
+    TgtColumn -> [|targetColumn|]
+    TgtApply ctor args -> applied [|targetPure $(conE (mkName (Text.unpack ctor)))|] args
+    TgtRecord ctor fields -> do
+        -- Bound in the statement's order and assigned by name: applying the
+        -- constructor positionally would cross the values over.
+        xs <- traverse (const (newName "c")) fields
+        let make =
+                TH.lamE
+                    (map TH.varP xs)
+                    (TH.recConE (mkName (Text.unpack ctor)) [TH.fieldExp (mkName (Text.unpack n)) (varE x) | ((n, _), x) <- zip fields xs])
+        applied [|targetPure $make|] (map snd fields)
+
+applied :: Q Exp -> [Tgt] -> Q Exp
+applied = foldl \f a -> [|targetAp $f $(targetExp a)|]
+
+{- | Everything the quoters need: the statement cut where its parameters'
+annotations go, which parameter each placeholder sends, and the shape of
+its result row.
+-}
+parsed :: Text -> Either String Parsed
+parsed sql = do
+    forked <- parseForkStmt sql
+    -- The targets are read off the lowered statement, before they are erased
+    -- for the one that is sent.
+    let (sent, lowered, slots') = lowerStmt forked
+    t <- template (Text.decodeUtf8Lenient (renderStmt sent))
+    let (slots, arity) = fromMaybe (plainSlots t) slots'
+        -- Where the statement was lowered the slots carry what each
+        -- placeholder was written as; where it was not, the template does.
+        used = maybe [i | ParamType i <- t.whole] (\_ -> [n | Slot n _ <- slots]) slots'
+    pure
+        Parsed
+            { parsedTemplate = t
+            , parsedSlots = slots
+            , parsedArity = arity
+            , parsedUsed = used
+            , parsedTargets = targets lowered
+            }
+
+{- | One slot per placeholder, each sending the whole of its parameter, for a
+statement with no param fields to lower.
+-}
+plainSlots :: Template -> ([Slot], Int)
+plainSlots t = ([Slot i Nothing | i <- [1 .. n]], n)
+  where
+    n = maximum (0 : [i | ParamType i <- t.whole])
+
+#ifdef KRONOR_SYNTAX
+
+-- | The statement as it is sent (lowered, with the Haskell targets erased),
+-- as its targets are read (lowered, with them still there), and which
+-- parameter each of its placeholders sends.
+lowerStmt :: Ast.PreparableStmt -> (Ast.PreparableStmt, Ast.PreparableStmt, Maybe ([Slot], Int))
+lowerStmt stmt =
+    ( Ast.eraseHaskellTargets lowered
+    , lowered
+    , -- InputParams maps each ($n, field) to its lowered placeholder.
+      Just
+        ( [Slot n field | (_, (n, field)) <- Map.toAscList (Map.fromList [(v, k) | (k, v) <- Map.toList inputs])]
+        , maximum (0 : [n | ((n, _), _) <- Map.toList inputs])
+        )
+    )
+  where
+    (lowered, inputs) = Ast.lower stmt
+
+#else
+
+-- | Upstream hasql-th has no param fields and no targets to erase, so the
+-- statement is sent as parsed and its placeholders are its parameters.
+lowerStmt :: Ast.PreparableStmt -> (Ast.PreparableStmt, Ast.PreparableStmt, Maybe ([Slot], Int))
+lowerStmt stmt = (stmt, stmt, Nothing)
+
+#endif
+
+#ifdef KRONOR_SYNTAX
+
+-- | The outermost SELECT's target list, as Haskell targets: 'Nothing' when it
+-- is not a list this can count, such as a @*@, where the Haskell row type
+-- decides the columns instead.
+targets :: Ast.PreparableStmt -> Maybe [Tgt]
+targets = \case
+    Ast.SelectPreparableStmt s -> traverse targetOf . NonEmpty.toList =<< selectStmt s
+    _ -> Nothing
+  where
+    selectStmt = \case
+        Ast.NoParensSelectStmt (Ast.SelectNoParens _ c _ _ _) -> selectClause c
+        Ast.WithParensSelectStmt p -> withParens p
+    withParens = \case
+        Ast.NoParensSelectWithParens (Ast.SelectNoParens _ c _ _ _) -> selectClause c
+        Ast.WithParensSelectWithParens p -> withParens p
+    selectClause = \case
+        Ast.SimpleSelectSelectClause (Ast.NormalSimpleSelect (Just (Ast.NormalTargeting (Ast.HsTargetList ts))) _ _ _ _ _ _) -> Just ts
+        Ast.WithParensSelectClause p -> withParens p
+        _ -> Nothing
+
+
+-- | What a target element reads, or 'Nothing' when it stands for however many
+-- columns a table has: a @*@ or a @t.*@, which only the schema can count.
+targetOf :: Ast.HsTargetEl -> Maybe Tgt
+targetOf = \case
+    Ast.SqlTargetEl Ast.AsteriskTargetEl -> Nothing
+    Ast.SqlTargetEl (Ast.ExprTargetEl (Ast.CExprAExpr (Ast.ColumnrefCExpr (Ast.Columnref _ (Just (Ast.Indirection is))))))
+        | Ast.AllIndirectionEl <- NonEmpty.last is -> Nothing
+    Ast.SqlTargetEl _ -> Just TgtColumn
+    Ast.HsFuncTargetEl ctor args -> TgtApply ctor <$> traverse targetOf args
+    Ast.HsRecTargetEl ctor fields -> TgtRecord ctor <$> traverse (\(Ast.HsFieldEl n t) -> (,) n <$> targetOf t) (NonEmpty.toList fields)
+
+#else
+
+-- | Upstream hasql-th has no Haskell targets, so the Haskell row type always
+-- decides the columns.
+targets :: Ast.PreparableStmt -> Maybe [Tgt]
+targets _ = Nothing
+
+#endif
+
+{- | The statement, rendered as hasql-th would render it, cut where its
+parameters' annotations go, and split where its result columns' cast
+goes around it.
+-}
 template :: Text -> Either String Template
 template sql = do
     stmt <- parsePlainStmt False sql
@@ -90,7 +309,6 @@
                     <$> splitWith annotated
             }
 
-
 -- | The statement's own WITH list, and the rest of it.
 splitWith :: Ast.PreparableStmt -> Maybe (Maybe Ast.WithClause, Ast.PreparableStmt)
 splitWith = \case
@@ -106,14 +324,13 @@
     Ast.DeletePreparableStmt (Ast.DeleteStmt w a b c d) -> Just (w, Ast.DeletePreparableStmt (Ast.DeleteStmt Nothing a b c d))
     Ast.CallPreparableStmt _ -> Nothing
 
-
--- | A parenthesised SELECT's WITH list, and the rest of it: the list can go
--- outside the parentheses, and must, if it has a data-modifying statement.
+{- | A parenthesised SELECT's WITH list, and the rest of it: the list can go
+outside the parentheses, and must, if it has a data-modifying statement.
+-}
 inParens :: Ast.SelectWithParens -> (Maybe Ast.WithClause, Ast.SelectWithParens)
 inParens = \case
     Ast.NoParensSelectWithParens (Ast.SelectNoParens w c s l f) -> (w, Ast.NoParensSelectWithParens (Ast.SelectNoParens Nothing c s l f))
     Ast.WithParensSelectWithParens s -> Ast.WithParensSelectWithParens <$> inParens s
-
 
 cutWith :: Text -> Text -> [Piece]
 cutWith prefix = cut
diff --git a/test/Inferred/Shapes.hs b/test/Inferred/Shapes.hs
new file mode 100644
--- /dev/null
+++ b/test/Inferred/Shapes.hs
@@ -0,0 +1,144 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingVia #-}
+{-# LANGUAGE OverloadedRecordDot #-}
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+{- | Every shape the inferred quoters must take. Nothing runs: the types are
+the assertion, and a quoter that builds the wrong row, or reads a column at
+the wrong type, fails to compile.
+-}
+module Inferred.Shapes where
+
+import Data.Int (Int64)
+#ifdef KRONOR_SYNTAX
+import Data.Int (Int32)
+import GHC.Generics (Generic)
+#endif
+import Data.Text (Text)
+import Data.Vector (Vector)
+import Hasql.Check.Inferred (Value)
+import Hasql.Check.Inferred.TH
+import Hasql.Statement (Statement)
+import Prelude
+
+-- A plain tuple row, as before.
+plain :: Statement Int64 (Maybe (Text, Maybe Text))
+plain = [maybeStatement| select email, nickname from customer where id = $1 |]
+
+-- A row of more than eight columns, past the old tuple cap.
+wide :: Statement () (Vector (Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64))
+wide = [vectorStatement| select a, b, c, d, e, f, g, h, i, j from wide |]
+
+-- Seventeen parameters, the widest statement in the repository.
+manyParams :: Statement (Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64) ()
+manyParams =
+    [resultlessStatement|
+        insert into wide
+            ( a
+            , b
+            , c
+            , d
+            , e
+            , f
+            , g
+            , h
+            , i
+            , j
+            , k
+            , l
+            , m
+            , n
+            , o
+            , p
+            , q
+            )
+        values
+            ( $1
+            , $2
+            , $3
+            , $4
+            , $5
+            , $6
+            , $7
+            , $8
+            , $9
+            , $10
+            , $11
+            , $12
+            , $13
+            , $14
+            , $15
+            , $16
+            , $17
+            )
+    |]
+
+#ifdef KRONOR_SYNTAX
+
+data CartItem = CartItem
+    { productId :: Text
+    , quantity :: Int32
+    , title :: Maybe Text
+    }
+    deriving stock (Show, Eq)
+
+
+-- A record target, with its fields deliberately out of declaration order:
+-- they are assigned by name, so a positional quoter would not compile.
+record :: Statement Int64 (Vector CartItem)
+record =
+    [vectorStatement|
+        select
+            $CartItem
+                { title = title
+                , productId = product_id
+                , quantity = quantity
+                }
+        from cart_item
+        where cart_id = $1
+    |]
+
+
+-- A constructor applied positionally, and nested inside a record.
+nested :: Statement () (Maybe (Maybe Text))
+nested = [maybeStatement| select $Just (name) from account |]
+
+
+data Payload = Payload
+    { reportId :: Int64
+    , orgId :: Int64
+    }
+    deriving stock (Generic)
+
+
+-- A param field: one placeholder per field of a record parameter.
+paramField :: Statement (Payload, Text) ()
+paramField =
+    [resultlessStatement|
+        update report
+        set link = $2
+        where id = $1.$reportId
+          and organization_id = $1.$orgId
+    |]
+
+
+#endif
+
+-- rowsAffected, which had no inferred quoter.
+affected :: Statement Int64 Int64
+affected = [rowsAffectedStatement| update session set last_seen = now() where id = $1 |]
+
+-- A star, whose columns only the Haskell type can count.
+star :: Statement () (Vector (Int64, Text))
+star = [vectorStatement| select * from pair |]
+
+newtype Email = Email Text
+    deriving newtype (Value)
+
+-- A newtype column, read as the type it wraps.
+newtyped :: Statement Int64 Email
+newtyped = [singletonStatement| select email from customer where id = $1 |]
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -39,7 +39,6 @@
 import Test.Syd
 import Prelude
 
-
 main :: IO ()
 main = sydTest do
     describe "parseQuasiQuotes" lexerSpec
@@ -54,14 +53,12 @@
     -- so they run one at a time, in order.
     describe "Hasql.Check.TH" $ sequential $ doNotRandomiseExecutionOrder $ aroundAll withPostgres thSpec
 
-
 -- | The quoter, its line and column, and the SQL, of every quasiquote found.
 quotes :: Text -> Either String [(Text, Int, Int, Text)]
 quotes source =
     map (\(QuasiQuote (AlexPn _ line col, quoter) (_, sql)) -> (quoter, line, col, sql))
         <$> parseQuasiQuotes (ByteString.Lazy.fromStrict (Text.Encoding.encodeUtf8 source))
 
-
 lexerSpec :: Spec
 lexerSpec = do
     it "finds a quote" $
@@ -116,9 +113,9 @@
         quotes "f = [singletonStatement|select 1 :: int4\n"
             `shouldSatisfy` either ("not closed" `isInfixOf`) (const False)
 
-
--- | A connection string for a throwaway server, reachable only over a socket
--- in a temporary directory.
+{- | A connection string for a throwaway server, reachable only over a socket
+in a temporary directory.
+-}
 withPostgres :: (Text -> IO ()) -> IO ()
 withPostgres action =
     withSystemTempDirectory "hasql-check" \dir -> do
@@ -136,9 +133,9 @@
                 callProcess "psql" [Text.unpack conn, "--quiet", "--command", "create table account (id int4 primary key, name text not null, nickname text); create index on account (nickname); create table note (account_id int4 not null references account, body text not null); create domain cents as int8; create domain positive_cents as cents check (value > 0); create table wallet (balance positive_cents not null); create table ledger (id int8 primary key, small int2, amount int8 not null, rate float8, at timestamptz, price cents); create table tag (id int4 primary key, label varchar(20) not null); insert into tag values (1, 'red'); create table tagged (id int4 primary key, labels text[] not null, scores int4[]); insert into tagged values (1, '{a,b}', '{1,NULL,3}'); create table totals (id int4 primary key, amounts int8[] not null); create type payment_state as enum ('PENDING', 'PAID', 'REFUNDED'); create table payment (id int4 primary key, state payment_state not null); insert into payment values (1, 'PAID'); create domain payment_status as payment_state; create table payment_log (id int4 primary key, status payment_status not null); insert into payment_log values (1, 'REFUNDED')"]
                 action conn
 
-
--- | Run the executable on a source file and the given flags, with extra
--- environment variables; return the exit code and stdout.
+{- | Run the executable on a source file and the given flags, with extra
+environment variables; return the exit code and stdout.
+-}
 runOn :: [(String, String)] -> [String] -> Text -> IO (ExitCode, String)
 runOn env args source =
     withSystemTempDirectory "hasql-check-src" \dir -> do
@@ -153,7 +150,6 @@
                 ""
         pure (code, out <> err)
 
-
 executableSpec :: TestDef '[Text] ()
 executableSpec = do
     itWithOuter "accepts a statement that matches the schema" \conn -> do
@@ -209,7 +205,6 @@
   where
     isSuffixOfStr suffix s = Text.pack suffix `Text.isSuffixOf` Text.pack s
 
-
 -- | The syntax only Kronor's fork of hasql-th accepts.
 syntaxSpec :: TestDef '[Text] ()
 #ifdef KRONOR_SYNTAX
@@ -222,6 +217,14 @@
         (code, out) <- runOn [] ["--database", Text.unpack conn] "f = [maybeStatement|select $Just (nope :: text) from account|]\n"
         code `shouldBe` ExitFailure 1
         out `shouldSatisfy` ("column \"nope\" does not exist" `isInfixOf`)
+
+    -- The types come one per placeholder in the order the quoter sends them,
+    -- which lowering renumbers: this writes $2 before $1, so pairing them
+    -- with the numbering as written puts the label's text on tag.id and
+    -- rejects a statement that is perfectly fine.
+    itWithOuter "annotates the parameters in the order they are sent, not written" \conn ->
+        runInferred conn [] [inferredQuote "resultlessStatement" "insert into tag (label, id) values ($2, $1)" [text, int32] Nothing]
+            `shouldReturn` (ExitSuccess, "")
 #else
 syntaxSpec =
     itWithOuter "rejects Haskell targets, which upstream hasql-th does not accept" \conn -> do
@@ -230,13 +233,11 @@
         out `shouldSatisfy` ("Fixture.hs:1:5" `isInfixOf`)
 #endif
 
-
 -- | Run with --nullability on one statement; return the exit code and output.
 nullability :: Text -> Text -> IO (ExitCode, String)
 nullability conn statement =
     runOn [] ["--database", Text.unpack conn, "--nullability"] ("f = [vectorStatement|" <> statement <> "|]\n")
 
-
 nullabilitySpec :: TestDef '[Text] ()
 nullabilitySpec = do
     itWithOuter "warns about a nullable column annotated non-null, without failing" \conn -> do
@@ -316,14 +317,13 @@
         out `shouldSatisfy` ("column 1 (nickname)" `isInfixOf`)
         out `shouldNotSatisfy` ("column 2" `isInfixOf`)
 
-
--- | Run a checked quoter as a splice would. Outside GHC a failing splice only
--- says that it failed - the message goes to stderr - so the tests that expect
--- a failure pair it with the same statement passing when nothing is checked.
+{- | Run a checked quoter as a splice would. Outside GHC a failing splice only
+says that it failed - the message goes to stderr - so the tests that expect
+a failure pair it with the same statement passing when nothing is checked.
+-}
 quote :: QuasiQuoter -> String -> IO (Either String ())
 quote quoter sql = either (Left . show) (const (Right ())) <$> (try (void (runQ (quoteExp quoter sql))) :: IO (Either SomeException ()))
 
-
 thSpec :: TestDef '[Text] ()
 thSpec = do
     it "checks nothing when no database is set" do
@@ -356,13 +356,11 @@
         setEnv "HASQL_CHECK_DATABASE_URL" "host=/nonexistent"
         quote Checked.vectorStatement "select nope :: text from account" `shouldReturn` Right ()
 
-
 -- | Run with --types on one quote; return the exit code and output.
 types :: Text -> Text -> Text -> IO (ExitCode, String)
 types conn quoter statement =
     runOn [] ["--database", Text.unpack conn, "--types"] ("f = [" <> quoter <> "|" <> statement <> "|]\n")
 
-
 typesSpec :: TestDef '[Text] ()
 typesSpec = do
     itWithOuter "warns about a column read as a narrower type, without failing" \conn -> do
@@ -435,12 +433,10 @@
         out `shouldSatisfy` ("column 1 (id) is annotated smallint, but is an integer" `isInfixOf`)
         out `shouldSatisfy` ("parameter $1" `isInfixOf`)
 
-
 -- | Run on a whole source with the given flags; return the exit code and output.
 checkSource :: Text -> [String] -> Text -> IO (ExitCode, String)
 checkSource conn flags = runOn [] (["--database", Text.unpack conn] <> flags)
 
-
 suppressionSpec :: TestDef '[Text] ()
 suppressionSpec = do
     itWithOuter "a directive above the quote suppresses the finding it names" \conn ->
@@ -525,13 +521,12 @@
             checkSource conn ["--nullability", "--fail-on-warnings"] ("-- hasql-check: allow nullable(\"display name\")\n" <> source)
                 `shouldReturn` (ExitSuccess, "")
 
-
--- | The SQL the inferred quoters send for a statement, given the Postgres
--- types of its parameters and result columns.
+{- | The SQL the inferred quoters send for a statement, given the Postgres
+types of its parameters and result columns.
+-}
 sent :: Text -> [Text] -> [Text] -> Either String Text
 sent sql paramTypes columnTypes = render paramTypes columnTypes <$> Inferred.template sql
 
-
 piecesSpec :: Spec
 piecesSpec = do
     it "annotates each parameter, and casts each result column around the statement" $
@@ -591,38 +586,31 @@
     it "rejects SQL it cannot parse" $
         Inferred.template "select from where" `shouldSatisfy` isLeft
 
-
 data PaymentState = PENDING | PAID | REFUNDED
     deriving stock (Eq, Show, Generic)
     deriving (Value) via PgEnum "payment_state" PaymentState
 
-
 newtype Qualified = Qualified PaymentState
     deriving stock (Eq, Show)
     deriving (Value) via PgEnum "public.\"payment_state\"" PaymentState
 
-
 -- The test database is "postgres".
 newtype InDatabase = InDatabase PaymentState
     deriving stock (Eq, Show)
     deriving (Value) via PgEnum "postgres.public.payment_state" PaymentState
 
-
 newtype Status = Status PaymentState
     deriving stock (Eq, Show)
     deriving (Value) via Domain "payment_status" PaymentState
 
-
 newtype Label = Label Text
     deriving stock (Eq, Show)
     deriving newtype (Value)
 
-
 newtype Cents = Cents Int64
     deriving stock (Eq, Show)
     deriving (Value) via Domain "cents" Int64
 
-
 -- | Run a statement on the test database.
 runStatement :: Text -> params -> Statement params result -> IO result
 runStatement conn params statement = do
@@ -631,7 +619,6 @@
     Connection.release c
     either (\e -> expectationFailure (show e) >> error "unreachable") pure result
 
-
 runtimeSpec :: TestDef '[Text] ()
 runtimeSpec = do
     itWithOuter "reads a varchar column as Text" \conn ->
@@ -715,9 +702,9 @@
         runStatement conn ("blue" :: Text, 2 :: Int64) [Inferred.resultlessStatement|insert into tag (label, id) values ($1, $2)|]
             `shouldReturn` ()
 
-
--- | A quote as hasql-check-hie writes it: its SQL, and the qualified name and
--- Postgres type of each parameter and result column.
+{- | A quote as hasql-check-hie writes it: its SQL, and the qualified name and
+Postgres type of each parameter and result column.
+-}
 inferredQuote :: Text -> Text -> [Column] -> Maybe [Column] -> Text
 inferredQuote quoter sql params row =
     "{\"file\":\"src/Fixture.hs\",\"line\":3,\"column\":7,\"quoter\":\""
@@ -742,15 +729,12 @@
             <> (if c.nullable then "true" else "false")
             <> "}"
 
-
 data Column = Column {haskell :: Text, postgres :: Text, nullable :: Bool, labels :: [Text]}
 
-
 -- | The same column, as a 'Maybe'.
 optional :: Column -> Column
 optional c = c{nullable = True}
 
-
 -- | Run with --inferred on the given quotes and flags.
 runInferred :: Text -> [String] -> [Text] -> IO (ExitCode, String)
 runInferred conn args quotes' =
@@ -760,12 +744,10 @@
         (code, out, err) <- readCreateProcessWithExitCode (proc "hasql-check" (["--database", Text.unpack conn, "--inferred", file] <> args)) ""
         pure (code, out <> err)
 
-
 int32, int64, text :: Column
 int32 = Column "GHC.Internal.Int.Int32" "int4" False []
 int64 = Column "GHC.Internal.Int.Int64" "int8" False []
 text = Column "Data.Text.Internal.Text" "text" False []
-
 
 inferredSpec :: TestDef '[Text] ()
 inferredSpec = do
