@@ -27,6 +27,7 @@ module Database.PostgreSQL.Simple.Types
2727 , (:.)(..)
2828 , Savepoint(..)
2929 , PGArray(..)
30+ , Values(..)
3031 ) where
3132
3233import Blaze.ByteString.Builder (toByteString)
@@ -173,3 +174,44 @@ infixr 3 :.
173174
174175newtype Savepoint = Savepoint Query
175176 deriving (Eq, Ord, Show, Read, Typeable)
177+
178+-- | Represents a @VALUES@ table literal, usable as an alternative
179+-- to @executeMany@ and @returning@. For example:
180+--
181+-- > execute c "INSERT INTO table (key,val) ?"
182+-- > (Only (Values ["int4","text"]
183+-- > [(1,"hello"),(2,"world")]))
184+--
185+-- Issues the following query:
186+--
187+-- > INSERT INTO table (key,val) (VALUES (1::"int4",'hello'::"text"),(2,'world'))
188+--
189+-- When the list of values is empty, the following query will be issued:
190+--
191+-- > INSERT INTO table (key,val) (VALUES (null::"int4",null::"text") LIMIT 0)
192+--
193+-- By contrast, @executeMany@ and @returning@ don't issue the query
194+-- in the empty case, and simply return @0@ and @[]@ respectively.
195+--
196+-- The advantage over @executeMany@ is in cases when you want to
197+-- parameterize table literals in addition to other parameters, as can
198+-- occur with writable common table expressions, for example.
199+--
200+-- The first argument is a list of postgresql type names. Because this
201+-- is turned into a properly quoted identifier, the type name is case
202+-- sensitive and must be as it appears in the @pg_type@ table. Thus,
203+-- you must write @timestamptz@ instead of @timestamp with time zone@,
204+-- @int4@ instead of @integer@, @_int8@ instead of @bigint[]@, etcetera.
205+--
206+-- You may omit the type names, however, if you do so the list
207+-- of values must be non-empty, and postgresql must be able to infer
208+-- the types of the columns from the surrounding context. If these
209+-- conditions are not met, postgresql-simple will throw an exception
210+-- without issuing the query in the former case, and in the latter
211+-- the postgres server will return an error which will be turned into
212+-- a @SqlError@ exception.
213+--
214+-- See <http://www.postgresql.org/docs/9.3/static/sql-values.html> for
215+-- more information.
216+data Values a = Values [QualifiedIdentifier] [a]
217+ deriving (Eq, Ord, Show, Read, Typeable)