diff --git a/Database/PostgreSQL/Typed/ErrCodes.hs b/Database/PostgreSQL/Typed/ErrCodes.hs
--- a/Database/PostgreSQL/Typed/ErrCodes.hs
+++ b/Database/PostgreSQL/Typed/ErrCodes.hs
@@ -1,4 +1,4 @@
--- Automatically generated from /src/postgresql-11.3/src/src/backend/utils/errcodes.txt using errcodes 2019-05-29 19:31:19.442545643 UTC.
+-- Automatically generated from /src/postgresql-12.0/src/src/backend/utils/errcodes.txt using errcodes 2019-10-05 16:38:46.694932074 UTC.
 {-# LANGUAGE OverloadedStrings #-}
 -- |PostgreSQL error codes.
 module Database.PostgreSQL.Typed.ErrCodes (names
@@ -101,6 +101,21 @@
   , invalid_xml_content
   , invalid_xml_comment
   , invalid_xml_processing_instruction
+  , duplicate_json_object_key_value
+  , invalid_json_text
+  , invalid_sql_json_subscript
+  , more_than_one_sql_json_item
+  , no_sql_json_item
+  , non_numeric_sql_json_item
+  , non_unique_keys_in_a_json_object
+  , singleton_sql_json_item_required
+  , sql_json_array_not_found
+  , sql_json_member_not_found
+  , sql_json_number_not_found
+  , sql_json_object_not_found
+  , too_many_json_array_elements
+  , too_many_json_object_members
+  , sql_json_scalar_required
   -- * Class 23 - Integrity Constraint Violation
   , integrity_constraint_violation
   , restrict_violation
@@ -237,6 +252,7 @@
   , object_in_use
   , cant_change_runtime_param
   , lock_not_available
+  , unsafe_new_enum_value_usage
   -- * Class 57 - Operator Intervention
   , operator_intervention
   , query_canceled
@@ -633,6 +649,66 @@
 invalid_xml_processing_instruction :: ByteString
 invalid_xml_processing_instruction = "2200T"
 
+-- |@DUPLICATE_JSON_OBJECT_KEY_VALUE@: 22030 (Error)
+duplicate_json_object_key_value :: ByteString
+duplicate_json_object_key_value = "22030"
+
+-- |@INVALID_JSON_TEXT@: 22032 (Error)
+invalid_json_text :: ByteString
+invalid_json_text = "22032"
+
+-- |@INVALID_SQL_JSON_SUBSCRIPT@: 22033 (Error)
+invalid_sql_json_subscript :: ByteString
+invalid_sql_json_subscript = "22033"
+
+-- |@MORE_THAN_ONE_SQL_JSON_ITEM@: 22034 (Error)
+more_than_one_sql_json_item :: ByteString
+more_than_one_sql_json_item = "22034"
+
+-- |@NO_SQL_JSON_ITEM@: 22035 (Error)
+no_sql_json_item :: ByteString
+no_sql_json_item = "22035"
+
+-- |@NON_NUMERIC_SQL_JSON_ITEM@: 22036 (Error)
+non_numeric_sql_json_item :: ByteString
+non_numeric_sql_json_item = "22036"
+
+-- |@NON_UNIQUE_KEYS_IN_A_JSON_OBJECT@: 22037 (Error)
+non_unique_keys_in_a_json_object :: ByteString
+non_unique_keys_in_a_json_object = "22037"
+
+-- |@SINGLETON_SQL_JSON_ITEM_REQUIRED@: 22038 (Error)
+singleton_sql_json_item_required :: ByteString
+singleton_sql_json_item_required = "22038"
+
+-- |@SQL_JSON_ARRAY_NOT_FOUND@: 22039 (Error)
+sql_json_array_not_found :: ByteString
+sql_json_array_not_found = "22039"
+
+-- |@SQL_JSON_MEMBER_NOT_FOUND@: 2203A (Error)
+sql_json_member_not_found :: ByteString
+sql_json_member_not_found = "2203A"
+
+-- |@SQL_JSON_NUMBER_NOT_FOUND@: 2203B (Error)
+sql_json_number_not_found :: ByteString
+sql_json_number_not_found = "2203B"
+
+-- |@SQL_JSON_OBJECT_NOT_FOUND@: 2203C (Error)
+sql_json_object_not_found :: ByteString
+sql_json_object_not_found = "2203C"
+
+-- |@TOO_MANY_JSON_ARRAY_ELEMENTS@: 2203D (Error)
+too_many_json_array_elements :: ByteString
+too_many_json_array_elements = "2203D"
+
+-- |@TOO_MANY_JSON_OBJECT_MEMBERS@: 2203E (Error)
+too_many_json_object_members :: ByteString
+too_many_json_object_members = "2203E"
+
+-- |@SQL_JSON_SCALAR_REQUIRED@: 2203F (Error)
+sql_json_scalar_required :: ByteString
+sql_json_scalar_required = "2203F"
+
 -- |@INTEGRITY_CONSTRAINT_VIOLATION@: 23000 (Error)
 integrity_constraint_violation :: ByteString
 integrity_constraint_violation = "23000"
@@ -1093,6 +1169,10 @@
 lock_not_available :: ByteString
 lock_not_available = "55P03"
 
+-- |@UNSAFE_NEW_ENUM_VALUE_USAGE@: 55P04 (Error)
+unsafe_new_enum_value_usage :: ByteString
+unsafe_new_enum_value_usage = "55P04"
+
 -- |@OPERATOR_INTERVENTION@: 57000 (Error)
 operator_intervention :: ByteString
 operator_intervention = "57000"
@@ -1366,6 +1446,21 @@
   ,(array_subscript_error,"array_subscript_error")
   ,(invalid_tablesample_repeat,"invalid_tablesample_repeat")
   ,(invalid_tablesample_argument,"invalid_tablesample_argument")
+  ,(duplicate_json_object_key_value,"duplicate_json_object_key_value")
+  ,(invalid_json_text,"invalid_json_text")
+  ,(invalid_sql_json_subscript,"invalid_sql_json_subscript")
+  ,(more_than_one_sql_json_item,"more_than_one_sql_json_item")
+  ,(no_sql_json_item,"no_sql_json_item")
+  ,(non_numeric_sql_json_item,"non_numeric_sql_json_item")
+  ,(non_unique_keys_in_a_json_object,"non_unique_keys_in_a_json_object")
+  ,(singleton_sql_json_item_required,"singleton_sql_json_item_required")
+  ,(sql_json_array_not_found,"sql_json_array_not_found")
+  ,(sql_json_member_not_found,"sql_json_member_not_found")
+  ,(sql_json_number_not_found,"sql_json_number_not_found")
+  ,(sql_json_object_not_found,"sql_json_object_not_found")
+  ,(too_many_json_array_elements,"too_many_json_array_elements")
+  ,(too_many_json_object_members,"too_many_json_object_members")
+  ,(sql_json_scalar_required,"sql_json_scalar_required")
   ,(floating_point_exception,"floating_point_exception")
   ,(invalid_text_representation,"invalid_text_representation")
   ,(invalid_binary_representation,"invalid_binary_representation")
@@ -1487,6 +1582,7 @@
   ,(object_in_use,"object_in_use")
   ,(cant_change_runtime_param,"cant_change_runtime_param")
   ,(lock_not_available,"lock_not_available")
+  ,(unsafe_new_enum_value_usage,"unsafe_new_enum_value_usage")
   ,(operator_intervention,"operator_intervention")
   ,(query_canceled,"query_canceled")
   ,(admin_shutdown,"admin_shutdown")
diff --git a/Database/PostgreSQL/Typed/Query.hs b/Database/PostgreSQL/Typed/Query.hs
--- a/Database/PostgreSQL/Typed/Query.hs
+++ b/Database/PostgreSQL/Typed/Query.hs
@@ -52,6 +52,7 @@
   --
   -- > [pgSQL|SELECT a FROM t|] `unsafeModifyQuery` (<> (" WHERE a = " <> pgSafeLiteral x))
   unsafeModifyQuery :: q -> (BS.ByteString -> BS.ByteString) -> q
+  getQueryString :: PGConnection -> q -> BS.ByteString
 class PGQuery q PGValues => PGRawQuery q
 
 -- |Execute a query that does not return results.
@@ -66,12 +67,14 @@
 instance PGQuery BS.ByteString PGValues where
   pgRunQuery c sql = pgSimpleQuery c (BSL.fromStrict sql)
   unsafeModifyQuery q f = f q
+  getQueryString _ = id
 
 newtype SimpleQuery = SimpleQuery BS.ByteString
   deriving (Show)
 instance PGQuery SimpleQuery PGValues where
   pgRunQuery c (SimpleQuery sql) = pgSimpleQuery c (BSL.fromStrict sql)
   unsafeModifyQuery (SimpleQuery sql) f = SimpleQuery $ f sql
+  getQueryString _ (SimpleQuery q) = q
 instance PGRawQuery SimpleQuery
 
 data PreparedQuery = PreparedQuery BS.ByteString [OID] PGValues [Bool]
@@ -79,6 +82,7 @@
 instance PGQuery PreparedQuery PGValues where
   pgRunQuery c (PreparedQuery sql types bind bc) = pgPreparedQuery c sql types bind bc
   unsafeModifyQuery (PreparedQuery sql types bind bc) f = PreparedQuery (f sql) types bind bc
+  getQueryString _ (PreparedQuery q _ _ _) = q
 instance PGRawQuery PreparedQuery
 
 
@@ -86,6 +90,7 @@
 instance PGRawQuery q => PGQuery (QueryParser q a) a where
   pgRunQuery c (QueryParser q p) = second (fmap $ p e) <$> pgRunQuery c (q e) where e = pgTypeEnv c
   unsafeModifyQuery (QueryParser q p) f = QueryParser (\e -> unsafeModifyQuery (q e) f) p
+  getQueryString c (QueryParser q _) = getQueryString c $ q $ pgTypeEnv c
 
 instance Functor (QueryParser q) where
   fmap f (QueryParser q p) = QueryParser q (\e -> f . p e)
diff --git a/postgresql-typed.cabal b/postgresql-typed.cabal
--- a/postgresql-typed.cabal
+++ b/postgresql-typed.cabal
@@ -1,5 +1,5 @@
 Name:          postgresql-typed
-Version:       0.6.0.1
+Version:       0.6.1.0
 Cabal-Version: >= 1.8
 License:       BSD3
 License-File:  COPYING
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -18,6 +18,7 @@
 import Database.PostgreSQL.Typed
 import Database.PostgreSQL.Typed.Types
 import Database.PostgreSQL.Typed.Protocol
+import Database.PostgreSQL.Typed.Query (PGSimpleQuery, getQueryString)
 import Database.PostgreSQL.Typed.Array ()
 import qualified Database.PostgreSQL.Typed.Range as Range
 import Database.PostgreSQL.Typed.Enum
@@ -136,6 +137,7 @@
     $ selectProp c
     Q..&&. tokenProp
     Q..&&. [pgSQL|#abc ${3.14::Float} def $f$ $$ ${1} $f$${2::Int32}|] Q.=== "abc 3.14::real def $f$ $$ ${1} $f$2::integer"
+    Q..&&. getQueryString c ([pgSQL|SELECT ${"ab'cd"::String}::text, ${3.14::Float}::float4|] :: PGSimpleQuery (Maybe String, Maybe Float)) Q.=== "SELECT 'ab''cd'::text, 3.14::float4"
     Q..&&. pgEnumValues Q.=== [(MyEnum_abc, "abc"), (MyEnum_DEF, "DEF"), (MyEnum_XX_ye, "XX_ye")]
     Q..&&. Q.conjoin (map (\(s, t) -> sqlTokens s Q.=== t)
       [ ("",
