From e06bba8374ba486c8593138b10a256aeef42a8af Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandbossart@gmail.com>
Date: Thu, 23 Feb 2023 10:31:24 -0800
Subject: [PATCH v4 1/1] add details to pg_input_error_message and rename to
 pg_input_error_info

---
 contrib/cube/expected/cube.out                |   8 +-
 contrib/cube/sql/cube.sql                     |   2 +-
 contrib/hstore/expected/hstore.out            |  16 +--
 contrib/hstore/sql/hstore.sql                 |   4 +-
 contrib/intarray/expected/_int.out            |  12 +-
 contrib/intarray/sql/_int.sql                 |   2 +-
 contrib/isn/expected/isn.out                  |  12 +-
 contrib/isn/sql/isn.sql                       |   2 +-
 contrib/ltree/expected/ltree.out              |  22 ++--
 contrib/ltree/sql/ltree.sql                   |   2 +-
 contrib/seg/expected/seg.out                  |  18 +--
 contrib/seg/sql/seg.sql                       |   2 +-
 doc/src/sgml/func.sgml                        |  33 +++--
 src/backend/utils/adt/misc.c                  |  42 +++++--
 src/include/catalog/pg_proc.dat               |  10 +-
 src/test/regress/expected/arrays.out          |   8 +-
 src/test/regress/expected/bit.out             |  40 +++---
 src/test/regress/expected/boolean.out         |   8 +-
 src/test/regress/expected/box.out             |  16 +--
 src/test/regress/expected/char.out            |   8 +-
 src/test/regress/expected/char_1.out          |   8 +-
 src/test/regress/expected/char_2.out          |   8 +-
 src/test/regress/expected/date.out            |  16 +--
 src/test/regress/expected/domain.out          |  34 +++---
 src/test/regress/expected/enum.out            |  16 +--
 .../expected/float4-misrounded-input.out      |   4 +-
 src/test/regress/expected/float4.out          |   8 +-
 src/test/regress/expected/float8.out          |   8 +-
 src/test/regress/expected/geometry.out        |  16 +--
 src/test/regress/expected/inet.out            |  24 ++--
 src/test/regress/expected/int2.out            |  24 ++--
 src/test/regress/expected/int4.out            |   8 +-
 src/test/regress/expected/int8.out            |   8 +-
 src/test/regress/expected/interval.out        |  16 +--
 src/test/regress/expected/json.out            |   8 +-
 src/test/regress/expected/json_encoding.out   |   8 +-
 src/test/regress/expected/json_encoding_1.out |   8 +-
 src/test/regress/expected/jsonb.out           |  16 +--
 src/test/regress/expected/jsonpath.out        |  16 +--
 src/test/regress/expected/line.out            |  40 +++---
 src/test/regress/expected/lseg.out            |   8 +-
 src/test/regress/expected/macaddr.out         |  16 +--
 src/test/regress/expected/macaddr8.out        |  16 +--
 src/test/regress/expected/money.out           |  16 +--
 src/test/regress/expected/multirangetypes.out |  16 +--
 src/test/regress/expected/numeric.out         |  24 ++--
 src/test/regress/expected/oid.out             |  32 ++---
 src/test/regress/expected/path.out            |  16 +--
 src/test/regress/expected/pg_lsn.out          |   8 +-
 src/test/regress/expected/point.out           |   8 +-
 src/test/regress/expected/polygon.out         |  16 +--
 src/test/regress/expected/privileges.out      |  24 ++--
 src/test/regress/expected/rangetypes.out      |  40 +++---
 src/test/regress/expected/regproc.out         | 114 +++++++++---------
 src/test/regress/expected/rowtypes.out        |  16 +--
 src/test/regress/expected/strings.out         |  24 ++--
 src/test/regress/expected/tid.out             |  16 +--
 src/test/regress/expected/time.out            |  16 +--
 src/test/regress/expected/timestamp.out       |  16 +--
 src/test/regress/expected/timestamptz.out     |  16 +--
 src/test/regress/expected/timetz.out          |  16 +--
 src/test/regress/expected/tstypes.out         |  24 ++--
 src/test/regress/expected/uuid.out            |   8 +-
 src/test/regress/expected/varchar.out         |   8 +-
 src/test/regress/expected/varchar_1.out       |   8 +-
 src/test/regress/expected/varchar_2.out       |   8 +-
 src/test/regress/expected/xid.out             |  32 ++---
 src/test/regress/expected/xml.out             |  10 +-
 src/test/regress/expected/xml_1.out           |   4 +-
 src/test/regress/expected/xml_2.out           |   8 +-
 src/test/regress/sql/arrays.sql               |   2 +-
 src/test/regress/sql/bit.sql                  |  10 +-
 src/test/regress/sql/boolean.sql              |   2 +-
 src/test/regress/sql/box.sql                  |   4 +-
 src/test/regress/sql/char.sql                 |   2 +-
 src/test/regress/sql/date.sql                 |   4 +-
 src/test/regress/sql/domain.sql               |  10 +-
 src/test/regress/sql/enum.sql                 |   4 +-
 src/test/regress/sql/float4.sql               |   2 +-
 src/test/regress/sql/float8.sql               |   2 +-
 src/test/regress/sql/geometry.sql             |   4 +-
 src/test/regress/sql/inet.sql                 |   6 +-
 src/test/regress/sql/int2.sql                 |   6 +-
 src/test/regress/sql/int4.sql                 |   2 +-
 src/test/regress/sql/int8.sql                 |   2 +-
 src/test/regress/sql/interval.sql             |   4 +-
 src/test/regress/sql/json.sql                 |   2 +-
 src/test/regress/sql/json_encoding.sql        |   2 +-
 src/test/regress/sql/jsonb.sql                |   4 +-
 src/test/regress/sql/jsonpath.sql             |   2 +-
 src/test/regress/sql/line.sql                 |  10 +-
 src/test/regress/sql/lseg.sql                 |   2 +-
 src/test/regress/sql/macaddr.sql              |   4 +-
 src/test/regress/sql/macaddr8.sql             |   4 +-
 src/test/regress/sql/money.sql                |   4 +-
 src/test/regress/sql/multirangetypes.sql      |   4 +-
 src/test/regress/sql/numeric.sql              |   6 +-
 src/test/regress/sql/oid.sql                  |   8 +-
 src/test/regress/sql/path.sql                 |   4 +-
 src/test/regress/sql/pg_lsn.sql               |   2 +-
 src/test/regress/sql/point.sql                |   2 +-
 src/test/regress/sql/polygon.sql              |   4 +-
 src/test/regress/sql/privileges.sql           |   6 +-
 src/test/regress/sql/rangetypes.sql           |  10 +-
 src/test/regress/sql/regproc.sql              |  34 +++---
 src/test/regress/sql/rowtypes.sql             |   4 +-
 src/test/regress/sql/strings.sql              |   6 +-
 src/test/regress/sql/tid.sql                  |   4 +-
 src/test/regress/sql/time.sql                 |   4 +-
 src/test/regress/sql/timestamp.sql            |   4 +-
 src/test/regress/sql/timestamptz.sql          |   4 +-
 src/test/regress/sql/timetz.sql               |   4 +-
 src/test/regress/sql/tstypes.sql              |   6 +-
 src/test/regress/sql/uuid.sql                 |   2 +-
 src/test/regress/sql/varchar.sql              |   2 +-
 src/test/regress/sql/xid.sql                  |   8 +-
 src/test/regress/sql/xml.sql                  |   4 +-
 117 files changed, 708 insertions(+), 669 deletions(-)

diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out
index dc23e5ccc0..5e2bade19c 100644
--- a/contrib/cube/expected/cube.out
+++ b/contrib/cube/expected/cube.out
@@ -344,10 +344,10 @@ SELECT pg_input_is_valid('-1e-700', 'cube');
  f
 (1 row)
 
-SELECT pg_input_error_message('-1e-700', 'cube');
-               pg_input_error_message                
------------------------------------------------------
- "-1e-700" is out of range for type double precision
+SELECT pg_input_error_info('-1e-700', 'cube');
+                        pg_input_error_info                        
+-------------------------------------------------------------------
+ ("""-1e-700"" is out of range for type double precision",,,22003)
 (1 row)
 
 --
diff --git a/contrib/cube/sql/cube.sql b/contrib/cube/sql/cube.sql
index 384883d16e..2bb96e3490 100644
--- a/contrib/cube/sql/cube.sql
+++ b/contrib/cube/sql/cube.sql
@@ -83,7 +83,7 @@ SELECT '-1e-700'::cube AS cube; -- out of range
 SELECT pg_input_is_valid('(1,2)', 'cube');
 SELECT pg_input_is_valid('[(1),]', 'cube');
 SELECT pg_input_is_valid('-1e-700', 'cube');
-SELECT pg_input_error_message('-1e-700', 'cube');
+SELECT pg_input_error_info('-1e-700', 'cube');
 
 --
 -- Testing building cubes from float8 values
diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out
index d6faa91867..3d391a3453 100644
--- a/contrib/hstore/expected/hstore.out
+++ b/contrib/hstore/expected/hstore.out
@@ -265,16 +265,16 @@ select pg_input_is_valid('a=b', 'hstore');
  f
 (1 row)
 
-select pg_input_error_message('a=b', 'hstore');
-             pg_input_error_message             
-------------------------------------------------
- syntax error in hstore, near "b" at position 2
+select pg_input_error_info('a=b', 'hstore');
+                     pg_input_error_info                      
+--------------------------------------------------------------
+ ("syntax error in hstore, near ""b"" at position 2",,,42601)
 (1 row)
 
-select pg_input_error_message(' =>b', 'hstore');
-             pg_input_error_message             
-------------------------------------------------
- syntax error in hstore, near "=" at position 1
+select pg_input_error_info(' =>b', 'hstore');
+                     pg_input_error_info                      
+--------------------------------------------------------------
+ ("syntax error in hstore, near ""="" at position 1",,,42601)
 (1 row)
 
 -- -> operator
diff --git a/contrib/hstore/sql/hstore.sql b/contrib/hstore/sql/hstore.sql
index 15f4f71416..3cd009c62a 100644
--- a/contrib/hstore/sql/hstore.sql
+++ b/contrib/hstore/sql/hstore.sql
@@ -60,8 +60,8 @@ select 'aa=>"'::hstore;
 -- also try it with non-error-throwing API
 select pg_input_is_valid('a=>b', 'hstore');
 select pg_input_is_valid('a=b', 'hstore');
-select pg_input_error_message('a=b', 'hstore');
-select pg_input_error_message(' =>b', 'hstore');
+select pg_input_error_info('a=b', 'hstore');
+select pg_input_error_info(' =>b', 'hstore');
 
 
 -- -> operator
diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out
index c953065a5c..3645426165 100644
--- a/contrib/intarray/expected/_int.out
+++ b/contrib/intarray/expected/_int.out
@@ -401,16 +401,16 @@ SELECT '1&(2&(4&(5|!6)))'::query_int;
 -- test non-error-throwing input
 SELECT str as "query_int",
        pg_input_is_valid(str,'query_int') as ok,
-       pg_input_error_message(str,'query_int') as errmsg
+       pg_input_error_info(str,'query_int') as errmsg
 FROM (VALUES ('1&(2&(4&(5|6)))'),
              ('1#(2&(4&(5&6)))'),
              ('foo'))
       AS a(str);
-    query_int    | ok |    errmsg    
------------------+----+--------------
- 1&(2&(4&(5|6))) | t  | 
- 1#(2&(4&(5&6))) | f  | syntax error
- foo             | f  | syntax error
+    query_int    | ok |          errmsg          
+-----------------+----+--------------------------
+ 1&(2&(4&(5|6))) | t  | (,,,)
+ 1#(2&(4&(5&6))) | f  | ("syntax error",,,42601)
+ foo             | f  | ("syntax error",,,42601)
 (3 rows)
 
 CREATE TABLE test__int( a int[] );
diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql
index 4c9ba4c1fb..6dde5c5e33 100644
--- a/contrib/intarray/sql/_int.sql
+++ b/contrib/intarray/sql/_int.sql
@@ -79,7 +79,7 @@ SELECT '1&(2&(4&(5|!6)))'::query_int;
 
 SELECT str as "query_int",
        pg_input_is_valid(str,'query_int') as ok,
-       pg_input_error_message(str,'query_int') as errmsg
+       pg_input_error_info(str,'query_int') as errmsg
 FROM (VALUES ('1&(2&(4&(5|6)))'),
              ('1#(2&(4&(5&6)))'),
              ('foo'))
diff --git a/contrib/isn/expected/isn.out b/contrib/isn/expected/isn.out
index 72171b2790..efc999ab37 100644
--- a/contrib/isn/expected/isn.out
+++ b/contrib/isn/expected/isn.out
@@ -263,16 +263,16 @@ SELECT '12345679'::ISSN = '9771234567003'::EAN13 AS "ok",
 -- test non-error-throwing input API
 SELECT str as isn, typ as "type",
        pg_input_is_valid(str,typ) as ok,
-       pg_input_error_message(str,typ) as errmsg
+       pg_input_error_info(str,typ) as errmsg
 FROM (VALUES ('9780123456786', 'UPC'),
              ('postgresql...','EAN13'),
              ('9771234567003','ISSN'))
       AS a(str,typ);
-      isn      | type  | ok |                         errmsg                         
----------------+-------+----+--------------------------------------------------------
- 9780123456786 | UPC   | f  | cannot cast ISBN to UPC for number: "9780123456786"
- postgresql... | EAN13 | f  | invalid input syntax for EAN13 number: "postgresql..."
- 9771234567003 | ISSN  | t  | 
+      isn      | type  | ok |                                errmsg                                
+---------------+-------+----+----------------------------------------------------------------------
+ 9780123456786 | UPC   | f  | ("cannot cast ISBN to UPC for number: ""9780123456786""",,,22P02)
+ postgresql... | EAN13 | f  | ("invalid input syntax for EAN13 number: ""postgresql...""",,,22P02)
+ 9771234567003 | ISSN  | t  | (,,,)
 (3 rows)
 
 --
diff --git a/contrib/isn/sql/isn.sql b/contrib/isn/sql/isn.sql
index 6426cb42a0..9fcb1f5bfe 100644
--- a/contrib/isn/sql/isn.sql
+++ b/contrib/isn/sql/isn.sql
@@ -110,7 +110,7 @@ SELECT '12345679'::ISSN = '9771234567003'::EAN13 AS "ok",
 -- test non-error-throwing input API
 SELECT str as isn, typ as "type",
        pg_input_is_valid(str,typ) as ok,
-       pg_input_error_message(str,typ) as errmsg
+       pg_input_error_info(str,typ) as errmsg
 FROM (VALUES ('9780123456786', 'UPC'),
              ('postgresql...','EAN13'),
              ('9771234567003','ISSN'))
diff --git a/contrib/ltree/expected/ltree.out b/contrib/ltree/expected/ltree.out
index d2a53b9f0c..bc2eda125c 100644
--- a/contrib/ltree/expected/ltree.out
+++ b/contrib/ltree/expected/ltree.out
@@ -8101,7 +8101,7 @@ SELECT count(*) FROM _ltreetest WHERE t ? '{23.*.1,23.*.2}' ;
 -- test non-error-throwing input
 SELECT str as "value", typ as "type",
        pg_input_is_valid(str,typ) as ok,
-       pg_input_error_message(str,typ) as errmsg
+       pg_input_error_info(str,typ) as errmsg
 FROM (VALUES ('.2.3', 'ltree'),
              ('1.2.', 'ltree'),
              ('1.2.3','ltree'),
@@ -8111,15 +8111,15 @@ FROM (VALUES ('.2.3', 'ltree'),
              ('$tree & aWdf@*','ltxtquery'),
              ('!tree & aWdf@*','ltxtquery'))
       AS a(str,typ);
-     value      |   type    | ok |               errmsg               
-----------------+-----------+----+------------------------------------
- .2.3           | ltree     | f  | ltree syntax error at character 1
- 1.2.           | ltree     | f  | ltree syntax error
- 1.2.3          | ltree     | t  | 
- @.2.3          | lquery    | f  | lquery syntax error at character 1
-  2.3           | lquery    | f  | lquery syntax error at character 1
- 1.2.3          | lquery    | t  | 
- $tree & aWdf@* | ltxtquery | f  | operand syntax error
- !tree & aWdf@* | ltxtquery | t  | 
+     value      |   type    | ok |                          errmsg                          
+----------------+-----------+----+----------------------------------------------------------
+ .2.3           | ltree     | f  | ("ltree syntax error at character 1",,,42601)
+ 1.2.           | ltree     | f  | ("ltree syntax error","Unexpected end of input.",,42601)
+ 1.2.3          | ltree     | t  | (,,,)
+ @.2.3          | lquery    | f  | ("lquery syntax error at character 1",,,42601)
+  2.3           | lquery    | f  | ("lquery syntax error at character 1",,,42601)
+ 1.2.3          | lquery    | t  | (,,,)
+ $tree & aWdf@* | ltxtquery | f  | ("operand syntax error",,,42601)
+ !tree & aWdf@* | ltxtquery | t  | (,,,)
 (8 rows)
 
diff --git a/contrib/ltree/sql/ltree.sql b/contrib/ltree/sql/ltree.sql
index 4a6e6266c3..ab30792354 100644
--- a/contrib/ltree/sql/ltree.sql
+++ b/contrib/ltree/sql/ltree.sql
@@ -393,7 +393,7 @@ SELECT count(*) FROM _ltreetest WHERE t ? '{23.*.1,23.*.2}' ;
 
 SELECT str as "value", typ as "type",
        pg_input_is_valid(str,typ) as ok,
-       pg_input_error_message(str,typ) as errmsg
+       pg_input_error_info(str,typ) as errmsg
 FROM (VALUES ('.2.3', 'ltree'),
              ('1.2.', 'ltree'),
              ('1.2.3','ltree'),
diff --git a/contrib/seg/expected/seg.out b/contrib/seg/expected/seg.out
index 7a06113ed8..6d8831d077 100644
--- a/contrib/seg/expected/seg.out
+++ b/contrib/seg/expected/seg.out
@@ -1276,20 +1276,20 @@ FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s;
 -- test non error throwing API
 SELECT str as seg,
        pg_input_is_valid(str,'seg') as ok,
-       pg_input_error_message(str,'seg') as errmsg
+       pg_input_error_info(str,'seg') as errmsg
 FROM unnest(ARRAY['-1 .. 1'::text,
                   '100(+-)1',
                   '',
                   'ABC',
                   '1 e7',
                   '1e700']) str;
-   seg    | ok |                errmsg                 
-----------+----+---------------------------------------
- -1 .. 1  | t  | 
- 100(+-)1 | t  | 
-          | f  | bad seg representation
- ABC      | f  | bad seg representation
- 1 e7     | f  | bad seg representation
- 1e700    | f  | "1e700" is out of range for type real
+   seg    | ok |                              errmsg                               
+----------+----+-------------------------------------------------------------------
+ -1 .. 1  | t  | (,,,)
+ 100(+-)1 | t  | (,,,)
+          | f  | ("bad seg representation","syntax error at end of input",,42601)
+ ABC      | f  | ("bad seg representation","syntax error at or near ""A""",,42601)
+ 1 e7     | f  | ("bad seg representation","syntax error at or near ""e""",,42601)
+ 1e700    | f  | ("""1e700"" is out of range for type real",,,22003)
 (6 rows)
 
diff --git a/contrib/seg/sql/seg.sql b/contrib/seg/sql/seg.sql
index b9a5d05d09..b2a96e84ba 100644
--- a/contrib/seg/sql/seg.sql
+++ b/contrib/seg/sql/seg.sql
@@ -244,7 +244,7 @@ FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s;
 
 SELECT str as seg,
        pg_input_is_valid(str,'seg') as ok,
-       pg_input_error_message(str,'seg') as errmsg
+       pg_input_error_info(str,'seg') as errmsg
 FROM unnest(ARRAY['-1 .. 1'::text,
                   '100(+-)1',
                   '',
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 0cbdf63632..97b3f1c1a6 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -24775,19 +24775,23 @@ SELECT collation for ('foo' COLLATE "de_DE");
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <indexterm>
-         <primary>pg_input_error_message</primary>
+         <primary>pg_input_error_info</primary>
         </indexterm>
-        <function>pg_input_error_message</function> (
+        <function>pg_input_error_info</function> (
           <parameter>string</parameter> <type>text</type>,
           <parameter>type</parameter> <type>text</type>
         )
-        <returnvalue>text</returnvalue>
+        <returnvalue>record</returnvalue>
+        ( <parameter>message</parameter> <type>text</type>,
+        <parameter>detail</parameter> <type>text</type>,
+        <parameter>hint</parameter> <type>text</type>,
+        <parameter>sql_error_code</parameter> <type>text</type> )
        </para>
        <para>
         Tests whether the given <parameter>string</parameter> is valid
-        input for the specified data type; if not, return the error
-        message that would have been thrown.  If the input is valid, the
-        result is NULL.  The inputs are the same as
+        input for the specified data type; if not, return the details of
+        the error would have been thrown.  If the input is valid, the
+        results are NULL.  The inputs are the same as
         for <function>pg_input_is_valid</function>.
        </para>
        <para>
@@ -24798,12 +24802,17 @@ SELECT collation for ('foo' COLLATE "de_DE");
         directly.
         </para>
         <para>
-         <literal>pg_input_error_message('42000000000', 'integer')</literal>
-         <returnvalue>value "42000000000" is out of range for type integer</returnvalue>
-        </para>
-        <para>
-         <literal>pg_input_error_message('1234.567', 'numeric(7,4)')</literal>
-         <returnvalue>numeric field overflow</returnvalue>
+<programlisting>
+SELECT * FROM pg_input_error_info('42000000000', 'integer');
+                       message                        | detail | hint | sql_error_code
+------------------------------------------------------+--------+------+----------------
+ value "42000000000" is out of range for type integer |        |      | 22003
+
+SELECT * FROM pg_input_error_info('1234.567', 'numeric(7,4)');
+        message         |                                      detail                                       | hint | sql_error_code
+------------------------+-----------------------------------------------------------------------------------+------+----------------
+ numeric field overflow | A field with precision 7, scale 4 must round to an absolute value less than 10^3. |      | 22003
+</programlisting>
        </para></entry>
       </row>
      </tbody>
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index f95256efd3..182d16cdcd 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -660,32 +660,58 @@ pg_input_is_valid(PG_FUNCTION_ARGS)
 }
 
 /*
- * pg_input_error_message - test whether string is valid input for datatype.
+ * pg_input_error_info - test whether string is valid input for datatype.
  *
- * Returns NULL if OK, else the primary message string from the error.
+ * Returns NULL if OK, else the primary message, detail message, hint message,
+ * and sql error code from the error.
  *
  * This will only work usefully if the datatype's input function has been
  * updated to return "soft" errors via errsave/ereturn.
  */
 Datum
-pg_input_error_message(PG_FUNCTION_ARGS)
+pg_input_error_info(PG_FUNCTION_ARGS)
 {
 	text	   *txt = PG_GETARG_TEXT_PP(0);
 	text	   *typname = PG_GETARG_TEXT_PP(1);
 	ErrorSaveContext escontext = {T_ErrorSaveContext};
+	TupleDesc   tupdesc;
+	Datum       values[4];
+	bool        isnull[4];
+
+	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+		elog(ERROR, "return type must be a row type");
 
 	/* Enable details_wanted */
 	escontext.details_wanted = true;
 
 	if (pg_input_is_valid_common(fcinfo, txt, typname,
 								 &escontext))
-		PG_RETURN_NULL();
+		memset(isnull, true, sizeof(isnull));
+	else
+	{
+		Assert(escontext.error_occurred);
+		Assert(escontext.error_data != NULL);
+		Assert(escontext.error_data->message != NULL);
+
+		memset(isnull, false, sizeof(isnull));
+
+		values[0] = CStringGetTextDatum(escontext.error_data->message);
 
-	Assert(escontext.error_occurred);
-	Assert(escontext.error_data != NULL);
-	Assert(escontext.error_data->message != NULL);
+		if (escontext.error_data->detail != NULL)
+			values[1] = CStringGetTextDatum(escontext.error_data->detail);
+		else
+			isnull[1] = true;
+
+		if (escontext.error_data->hint != NULL)
+			values[2] = CStringGetTextDatum(escontext.error_data->hint);
+		else
+			isnull[2] = true;
+
+		values[3] = CStringGetTextDatum(
+			unpack_sql_state(escontext.error_data->sqlerrcode));
+	}
 
-	PG_RETURN_TEXT_P(cstring_to_text(escontext.error_data->message));
+	return HeapTupleGetDatum(heap_form_tuple(tupdesc, values, isnull));
 }
 
 /* Common subroutine for the above */
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index e2a7642a2b..505595620e 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7118,9 +7118,13 @@
   proname => 'pg_input_is_valid', provolatile => 's', prorettype => 'bool',
   proargtypes => 'text text', prosrc => 'pg_input_is_valid' },
 { oid => '8051',
-  descr => 'get error message if string is not valid input for data type',
-  proname => 'pg_input_error_message', provolatile => 's', prorettype => 'text',
-  proargtypes => 'text text', prosrc => 'pg_input_error_message' },
+  descr => 'get error details if string is not valid input for data type',
+  proname => 'pg_input_error_info', provolatile => 's', prorettype => 'record',
+  proargtypes => 'text text',
+  proallargtypes => '{text,text,text,text,text,text}',
+  proargmodes => '{i,i,o,o,o,o}',
+  proargnames => '{value,type_name,message,detail,hint,sql_error_code}',
+  prosrc => 'pg_input_error_info' },
 
 { oid => '1268',
   descr => 'parse qualified identifier to array of identifiers',
diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out
index a2f9d7ed16..c840cc7765 100644
--- a/src/test/regress/expected/arrays.out
+++ b/src/test/regress/expected/arrays.out
@@ -201,10 +201,10 @@ SELECT pg_input_is_valid('{1,zed}', 'integer[]');
  f
 (1 row)
 
-SELECT pg_input_error_message('{1,zed}', 'integer[]');
-            pg_input_error_message            
-----------------------------------------------
- invalid input syntax for type integer: "zed"
+SELECT pg_input_error_info('{1,zed}', 'integer[]');
+                    pg_input_error_info                     
+------------------------------------------------------------
+ ("invalid input syntax for type integer: ""zed""",,,22P02)
 (1 row)
 
 -- test mixed slice/scalar subscripting
diff --git a/src/test/regress/expected/bit.out b/src/test/regress/expected/bit.out
index 209044713c..411e2abe23 100644
--- a/src/test/regress/expected/bit.out
+++ b/src/test/regress/expected/bit.out
@@ -753,10 +753,10 @@ SELECT pg_input_is_valid('01010001', 'bit(10)');
  f
 (1 row)
 
-SELECT pg_input_error_message('01010001', 'bit(10)');
-             pg_input_error_message              
--------------------------------------------------
- bit string length 8 does not match type bit(10)
+SELECT pg_input_error_info('01010001', 'bit(10)');
+                     pg_input_error_info                     
+-------------------------------------------------------------
+ ("bit string length 8 does not match type bit(10)",,,22026)
 (1 row)
 
 SELECT pg_input_is_valid('01010Z01', 'bit(8)');
@@ -765,10 +765,10 @@ SELECT pg_input_is_valid('01010Z01', 'bit(8)');
  f
 (1 row)
 
-SELECT pg_input_error_message('01010Z01', 'bit(8)');
-     pg_input_error_message      
----------------------------------
- "Z" is not a valid binary digit
+SELECT pg_input_error_info('01010Z01', 'bit(8)');
+              pg_input_error_info              
+-----------------------------------------------
+ ("""Z"" is not a valid binary digit",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('x01010Z01', 'bit(32)');
@@ -777,10 +777,10 @@ SELECT pg_input_is_valid('x01010Z01', 'bit(32)');
  f
 (1 row)
 
-SELECT pg_input_error_message('x01010Z01', 'bit(32)');
-        pg_input_error_message        
---------------------------------------
- "Z" is not a valid hexadecimal digit
+SELECT pg_input_error_info('x01010Z01', 'bit(32)');
+                pg_input_error_info                 
+----------------------------------------------------
+ ("""Z"" is not a valid hexadecimal digit",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('01010Z01', 'varbit');
@@ -789,10 +789,10 @@ SELECT pg_input_is_valid('01010Z01', 'varbit');
  f
 (1 row)
 
-SELECT pg_input_error_message('01010Z01', 'varbit');
-     pg_input_error_message      
----------------------------------
- "Z" is not a valid binary digit
+SELECT pg_input_error_info('01010Z01', 'varbit');
+              pg_input_error_info              
+-----------------------------------------------
+ ("""Z"" is not a valid binary digit",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('x01010Z01', 'varbit');
@@ -801,9 +801,9 @@ SELECT pg_input_is_valid('x01010Z01', 'varbit');
  f
 (1 row)
 
-SELECT pg_input_error_message('x01010Z01', 'varbit');
-        pg_input_error_message        
---------------------------------------
- "Z" is not a valid hexadecimal digit
+SELECT pg_input_error_info('x01010Z01', 'varbit');
+                pg_input_error_info                 
+----------------------------------------------------
+ ("""Z"" is not a valid hexadecimal digit",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/boolean.out b/src/test/regress/expected/boolean.out
index 977124b20b..cbc4429a11 100644
--- a/src/test/regress/expected/boolean.out
+++ b/src/test/regress/expected/boolean.out
@@ -155,10 +155,10 @@ SELECT pg_input_is_valid('asdf', 'bool');
  f
 (1 row)
 
-SELECT pg_input_error_message('junk', 'bool');
-            pg_input_error_message             
------------------------------------------------
- invalid input syntax for type boolean: "junk"
+SELECT pg_input_error_info('junk', 'bool');
+                     pg_input_error_info                     
+-------------------------------------------------------------
+ ("invalid input syntax for type boolean: ""junk""",,,22P02)
 (1 row)
 
 -- and, or, not in qualifications
diff --git a/src/test/regress/expected/box.out b/src/test/regress/expected/box.out
index 0d70194def..406ee5b815 100644
--- a/src/test/regress/expected/box.out
+++ b/src/test/regress/expected/box.out
@@ -646,10 +646,10 @@ SELECT pg_input_is_valid('200', 'box');
  f
 (1 row)
 
-SELECT pg_input_error_message('200', 'box');
-          pg_input_error_message          
-------------------------------------------
- invalid input syntax for type box: "200"
+SELECT pg_input_error_info('200', 'box');
+                  pg_input_error_info                   
+--------------------------------------------------------
+ ("invalid input syntax for type box: ""200""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('((200,300),(500, xyz))', 'box');
@@ -658,9 +658,9 @@ SELECT pg_input_is_valid('((200,300),(500, xyz))', 'box');
  f
 (1 row)
 
-SELECT pg_input_error_message('((200,300),(500, xyz))', 'box');
-                   pg_input_error_message                    
--------------------------------------------------------------
- invalid input syntax for type box: "((200,300),(500, xyz))"
+SELECT pg_input_error_info('((200,300),(500, xyz))', 'box');
+                            pg_input_error_info                            
+---------------------------------------------------------------------------
+ ("invalid input syntax for type box: ""((200,300),(500, xyz))""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/char.out b/src/test/regress/expected/char.out
index 199001b2fe..58cdd54ffb 100644
--- a/src/test/regress/expected/char.out
+++ b/src/test/regress/expected/char.out
@@ -132,10 +132,10 @@ SELECT pg_input_is_valid('abcde', 'char(4)');
  f
 (1 row)
 
-SELECT pg_input_error_message('abcde', 'char(4)');
-        pg_input_error_message        
---------------------------------------
- value too long for type character(4)
+SELECT pg_input_error_info('abcde', 'char(4)');
+               pg_input_error_info                
+--------------------------------------------------
+ ("value too long for type character(4)",,,22001)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/char_1.out b/src/test/regress/expected/char_1.out
index 3dcb0daa0d..c45fe2a400 100644
--- a/src/test/regress/expected/char_1.out
+++ b/src/test/regress/expected/char_1.out
@@ -132,10 +132,10 @@ SELECT pg_input_is_valid('abcde', 'char(4)');
  f
 (1 row)
 
-SELECT pg_input_error_message('abcde', 'char(4)');
-        pg_input_error_message        
---------------------------------------
- value too long for type character(4)
+SELECT pg_input_error_info('abcde', 'char(4)');
+               pg_input_error_info                
+--------------------------------------------------
+ ("value too long for type character(4)",,,22001)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/char_2.out b/src/test/regress/expected/char_2.out
index dd5d34fe8d..1281ba4394 100644
--- a/src/test/regress/expected/char_2.out
+++ b/src/test/regress/expected/char_2.out
@@ -132,10 +132,10 @@ SELECT pg_input_is_valid('abcde', 'char(4)');
  f
 (1 row)
 
-SELECT pg_input_error_message('abcde', 'char(4)');
-        pg_input_error_message        
---------------------------------------
- value too long for type character(4)
+SELECT pg_input_error_info('abcde', 'char(4)');
+               pg_input_error_info                
+--------------------------------------------------
+ ("value too long for type character(4)",,,22001)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/date.out b/src/test/regress/expected/date.out
index c0dec448e1..4a496aec5b 100644
--- a/src/test/regress/expected/date.out
+++ b/src/test/regress/expected/date.out
@@ -859,16 +859,16 @@ SELECT pg_input_is_valid('6874898-01-01', 'date');
  f
 (1 row)
 
-SELECT pg_input_error_message('garbage', 'date');
-            pg_input_error_message             
------------------------------------------------
- invalid input syntax for type date: "garbage"
+SELECT pg_input_error_info('garbage', 'date');
+                     pg_input_error_info                     
+-------------------------------------------------------------
+ ("invalid input syntax for type date: ""garbage""",,,22007)
 (1 row)
 
-SELECT pg_input_error_message('6874898-01-01', 'date');
-       pg_input_error_message       
-------------------------------------
- date out of range: "6874898-01-01"
+SELECT pg_input_error_info('6874898-01-01', 'date');
+               pg_input_error_info                
+--------------------------------------------------
+ ("date out of range: ""6874898-01-01""",,,22008)
 (1 row)
 
 RESET datestyle;
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 25f6bb9e1f..b832b146f7 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -108,32 +108,32 @@ select pg_input_is_valid('-1', 'positiveint');
  f
 (1 row)
 
-select pg_input_error_message('junk', 'positiveint');
-            pg_input_error_message             
------------------------------------------------
- invalid input syntax for type integer: "junk"
+select pg_input_error_info('junk', 'positiveint');
+                     pg_input_error_info                     
+-------------------------------------------------------------
+ ("invalid input syntax for type integer: ""junk""",,,22P02)
 (1 row)
 
-select pg_input_error_message('-1', 'positiveint');
-                           pg_input_error_message                           
-----------------------------------------------------------------------------
- value for domain positiveint violates check constraint "positiveint_check"
+select pg_input_error_info('-1', 'positiveint');
+                                   pg_input_error_info                                    
+------------------------------------------------------------------------------------------
+ ("value for domain positiveint violates check constraint ""positiveint_check""",,,23514)
 (1 row)
 
-select pg_input_error_message('junk', 'weirdfloat');
-                 pg_input_error_message                 
---------------------------------------------------------
- invalid input syntax for type double precision: "junk"
+select pg_input_error_info('junk', 'weirdfloat');
+                         pg_input_error_info                          
+----------------------------------------------------------------------
+ ("invalid input syntax for type double precision: ""junk""",,,22P02)
 (1 row)
 
-select pg_input_error_message('0.01', 'weirdfloat');
-                          pg_input_error_message                          
---------------------------------------------------------------------------
- value for domain weirdfloat violates check constraint "weirdfloat_check"
+select pg_input_error_info('0.01', 'weirdfloat');
+                                  pg_input_error_info                                   
+----------------------------------------------------------------------------------------
+ ("value for domain weirdfloat violates check constraint ""weirdfloat_check""",,,23514)
 (1 row)
 
 -- We currently can't trap errors raised in the CHECK expression itself
-select pg_input_error_message('0', 'weirdfloat');
+select pg_input_error_info('0', 'weirdfloat');
 ERROR:  division by zero
 drop domain positiveint;
 drop domain weirdfloat;
diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out
index 4b45fcf8f0..26671b23b7 100644
--- a/src/test/regress/expected/enum.out
+++ b/src/test/regress/expected/enum.out
@@ -37,16 +37,16 @@ SELECT pg_input_is_valid('mauve', 'rainbow');
  f
 (1 row)
 
-SELECT pg_input_error_message('mauve', 'rainbow');
-            pg_input_error_message             
------------------------------------------------
- invalid input value for enum rainbow: "mauve"
+SELECT pg_input_error_info('mauve', 'rainbow');
+                     pg_input_error_info                     
+-------------------------------------------------------------
+ ("invalid input value for enum rainbow: ""mauve""",,,22P02)
 (1 row)
 
-SELECT pg_input_error_message(repeat('too_long', 32), 'rainbow');
-                                                                                                                                          pg_input_error_message                                                                                                                                          
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- invalid input value for enum rainbow: "too_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_long"
+SELECT pg_input_error_info(repeat('too_long', 32), 'rainbow');
+                                                                                                                                                  pg_input_error_info                                                                                                                                                   
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ ("invalid input value for enum rainbow: ""too_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_long""",,,22P02)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/float4-misrounded-input.out b/src/test/regress/expected/float4-misrounded-input.out
index 24fde6cc9f..12e18ff465 100644
--- a/src/test/regress/expected/float4-misrounded-input.out
+++ b/src/test/regress/expected/float4-misrounded-input.out
@@ -100,8 +100,8 @@ SELECT pg_input_is_valid('1e400', 'float4');
  f
 (1 row)
 
-SELECT pg_input_error_message('1e400', 'float4');
-        pg_input_error_message         
+SELECT pg_input_error_info('1e400', 'float4');
+          pg_input_error_info          
 ---------------------------------------
  "1e400" is out of range for type real
 (1 row)
diff --git a/src/test/regress/expected/float4.out b/src/test/regress/expected/float4.out
index 1d7090a90d..94d68adb7b 100644
--- a/src/test/regress/expected/float4.out
+++ b/src/test/regress/expected/float4.out
@@ -100,10 +100,10 @@ SELECT pg_input_is_valid('1e400', 'float4');
  f
 (1 row)
 
-SELECT pg_input_error_message('1e400', 'float4');
-        pg_input_error_message         
----------------------------------------
- "1e400" is out of range for type real
+SELECT pg_input_error_info('1e400', 'float4');
+                 pg_input_error_info                 
+-----------------------------------------------------
+ ("""1e400"" is out of range for type real",,,22003)
 (1 row)
 
 -- special inputs
diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out
index 2b25784f7f..06cc8c6537 100644
--- a/src/test/regress/expected/float8.out
+++ b/src/test/regress/expected/float8.out
@@ -87,10 +87,10 @@ SELECT pg_input_is_valid('1e4000', 'float8');
  f
 (1 row)
 
-SELECT pg_input_error_message('1e4000', 'float8');
-               pg_input_error_message               
-----------------------------------------------------
- "1e4000" is out of range for type double precision
+SELECT pg_input_error_info('1e4000', 'float8');
+                       pg_input_error_info                        
+------------------------------------------------------------------
+ ("""1e4000"" is out of range for type double precision",,,22003)
 (1 row)
 
 -- special inputs
diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out
index 291cacdf4f..76ad614b61 100644
--- a/src/test/regress/expected/geometry.out
+++ b/src/test/regress/expected/geometry.out
@@ -5302,10 +5302,10 @@ SELECT pg_input_is_valid('(1', 'circle');
  f
 (1 row)
 
-SELECT pg_input_error_message('1,', 'circle');
-           pg_input_error_message           
---------------------------------------------
- invalid input syntax for type circle: "1,"
+SELECT pg_input_error_info('1,', 'circle');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("invalid input syntax for type circle: ""1,""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('(1,2),-1', 'circle');
@@ -5314,9 +5314,9 @@ SELECT pg_input_is_valid('(1,2),-1', 'circle');
  f
 (1 row)
 
-SELECT pg_input_error_message('(1,2),-1', 'circle');
-              pg_input_error_message              
---------------------------------------------------
- invalid input syntax for type circle: "(1,2),-1"
+SELECT pg_input_error_info('(1,2),-1', 'circle');
+                      pg_input_error_info                       
+----------------------------------------------------------------
+ ("invalid input syntax for type circle: ""(1,2),-1""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out
index c9f466ac1d..ada484642a 100644
--- a/src/test/regress/expected/inet.out
+++ b/src/test/regress/expected/inet.out
@@ -1063,10 +1063,10 @@ SELECT pg_input_is_valid('1234', 'cidr');
  f
 (1 row)
 
-SELECT pg_input_error_message('1234', 'cidr');
-           pg_input_error_message           
---------------------------------------------
- invalid input syntax for type cidr: "1234"
+SELECT pg_input_error_info('1234', 'cidr');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("invalid input syntax for type cidr: ""1234""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('192.168.198.200/24', 'cidr');
@@ -1075,10 +1075,10 @@ SELECT pg_input_is_valid('192.168.198.200/24', 'cidr');
  f
 (1 row)
 
-SELECT pg_input_error_message('192.168.198.200/24', 'cidr');
-          pg_input_error_message          
-------------------------------------------
- invalid cidr value: "192.168.198.200/24"
+SELECT pg_input_error_info('192.168.198.200/24', 'cidr');
+                                     pg_input_error_info                                      
+----------------------------------------------------------------------------------------------
+ ("invalid cidr value: ""192.168.198.200/24""","Value has bits set to right of mask.",,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('1234', 'inet');
@@ -1087,9 +1087,9 @@ SELECT pg_input_is_valid('1234', 'inet');
  f
 (1 row)
 
-SELECT pg_input_error_message('1234', 'inet');
-           pg_input_error_message           
---------------------------------------------
- invalid input syntax for type inet: "1234"
+SELECT pg_input_error_info('1234', 'inet');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("invalid input syntax for type inet: ""1234""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/int2.out b/src/test/regress/expected/int2.out
index 73b4ee023c..c0b06a1aa4 100644
--- a/src/test/regress/expected/int2.out
+++ b/src/test/regress/expected/int2.out
@@ -64,10 +64,10 @@ SELECT pg_input_is_valid('50000', 'int2');
  f
 (1 row)
 
-SELECT pg_input_error_message('50000', 'int2');
-             pg_input_error_message              
--------------------------------------------------
- value "50000" is out of range for type smallint
+SELECT pg_input_error_info('50000', 'int2');
+                      pg_input_error_info                      
+---------------------------------------------------------------
+ ("value ""50000"" is out of range for type smallint",,,22003)
 (1 row)
 
 -- While we're here, check int2vector as well
@@ -77,16 +77,16 @@ SELECT pg_input_is_valid(' 1 3  5 ', 'int2vector');
  t
 (1 row)
 
-SELECT pg_input_error_message('1 asdf', 'int2vector');
-             pg_input_error_message             
-------------------------------------------------
- invalid input syntax for type smallint: "asdf"
+SELECT pg_input_error_info('1 asdf', 'int2vector');
+                     pg_input_error_info                      
+--------------------------------------------------------------
+ ("invalid input syntax for type smallint: ""asdf""",,,22P02)
 (1 row)
 
-SELECT pg_input_error_message('50000', 'int2vector');
-             pg_input_error_message              
--------------------------------------------------
- value "50000" is out of range for type smallint
+SELECT pg_input_error_info('50000', 'int2vector');
+                      pg_input_error_info                      
+---------------------------------------------------------------
+ ("value ""50000"" is out of range for type smallint",,,22003)
 (1 row)
 
 SELECT * FROM INT2_TBL AS f(a, b);
diff --git a/src/test/regress/expected/int4.out b/src/test/regress/expected/int4.out
index 9c20574ca5..f0c469d8ab 100644
--- a/src/test/regress/expected/int4.out
+++ b/src/test/regress/expected/int4.out
@@ -64,10 +64,10 @@ SELECT pg_input_is_valid('1000000000000', 'int4');
  f
 (1 row)
 
-SELECT pg_input_error_message('1000000000000', 'int4');
-                 pg_input_error_message                 
---------------------------------------------------------
- value "1000000000000" is out of range for type integer
+SELECT pg_input_error_info('1000000000000', 'int4');
+                         pg_input_error_info                          
+----------------------------------------------------------------------
+ ("value ""1000000000000"" is out of range for type integer",,,22003)
 (1 row)
 
 SELECT i.* FROM INT4_TBL i WHERE i.f1 <> int2 '0';
diff --git a/src/test/regress/expected/int8.out b/src/test/regress/expected/int8.out
index d9dca64e88..7a788a15d7 100644
--- a/src/test/regress/expected/int8.out
+++ b/src/test/regress/expected/int8.out
@@ -61,10 +61,10 @@ SELECT pg_input_is_valid('10000000000000000000', 'int8');
  f
 (1 row)
 
-SELECT pg_input_error_message('10000000000000000000', 'int8');
-                    pg_input_error_message                    
---------------------------------------------------------------
- value "10000000000000000000" is out of range for type bigint
+SELECT pg_input_error_info('10000000000000000000', 'int8');
+                            pg_input_error_info                             
+----------------------------------------------------------------------------
+ ("value ""10000000000000000000"" is out of range for type bigint",,,22003)
 (1 row)
 
 -- int8/int8 cmp
diff --git a/src/test/regress/expected/interval.out b/src/test/regress/expected/interval.out
index a154840c85..7b654e77b2 100644
--- a/src/test/regress/expected/interval.out
+++ b/src/test/regress/expected/interval.out
@@ -91,16 +91,16 @@ SELECT pg_input_is_valid('@ 30 eons ago', 'interval');
  f
 (1 row)
 
-SELECT pg_input_error_message('garbage', 'interval');
-              pg_input_error_message               
----------------------------------------------------
- invalid input syntax for type interval: "garbage"
+SELECT pg_input_error_info('garbage', 'interval');
+                       pg_input_error_info                       
+-----------------------------------------------------------------
+ ("invalid input syntax for type interval: ""garbage""",,,22007)
 (1 row)
 
-SELECT pg_input_error_message('@ 30 eons ago', 'interval');
-                 pg_input_error_message                  
----------------------------------------------------------
- invalid input syntax for type interval: "@ 30 eons ago"
+SELECT pg_input_error_info('@ 30 eons ago', 'interval');
+                          pg_input_error_info                          
+-----------------------------------------------------------------------
+ ("invalid input syntax for type interval: ""@ 30 eons ago""",,,22007)
 (1 row)
 
 -- test interval operators
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index af96ce4180..7d574c25af 100644
--- a/src/test/regress/expected/json.out
+++ b/src/test/regress/expected/json.out
@@ -333,10 +333,10 @@ select pg_input_is_valid('{"a":true', 'json');
  f
 (1 row)
 
-select pg_input_error_message('{"a":true', 'json');
-       pg_input_error_message       
-------------------------------------
- invalid input syntax for type json
+select pg_input_error_info('{"a":true', 'json');
+                                 pg_input_error_info                                  
+--------------------------------------------------------------------------------------
+ ("invalid input syntax for type json","The input string ended unexpectedly.",,22P02)
 (1 row)
 
 --constructors
diff --git a/src/test/regress/expected/json_encoding.out b/src/test/regress/expected/json_encoding.out
index 083621fb21..21b0d11787 100644
--- a/src/test/regress/expected/json_encoding.out
+++ b/src/test/regress/expected/json_encoding.out
@@ -261,9 +261,9 @@ SELECT jsonb '{ "a":  "null \\u0000 escape" }' ->> 'a' as not_an_escape;
 (1 row)
 
 -- soft error for input-time failure
-select pg_input_error_message('{ "a":  "\ud83d\ude04\ud83d\udc36" }', 'jsonb');
- pg_input_error_message 
-------------------------
- 
+select pg_input_error_info('{ "a":  "\ud83d\ude04\ud83d\udc36" }', 'jsonb');
+ pg_input_error_info 
+---------------------
+ (,,,)
 (1 row)
 
diff --git a/src/test/regress/expected/json_encoding_1.out b/src/test/regress/expected/json_encoding_1.out
index 021d226f8d..39d439e684 100644
--- a/src/test/regress/expected/json_encoding_1.out
+++ b/src/test/regress/expected/json_encoding_1.out
@@ -257,9 +257,9 @@ SELECT jsonb '{ "a":  "null \\u0000 escape" }' ->> 'a' as not_an_escape;
 (1 row)
 
 -- soft error for input-time failure
-select pg_input_error_message('{ "a":  "\ud83d\ude04\ud83d\udc36" }', 'jsonb');
-       pg_input_error_message        
--------------------------------------
- unsupported Unicode escape sequence
+select pg_input_error_info('{ "a":  "\ud83d\ude04\ud83d\udc36" }', 'jsonb');
+                                                        pg_input_error_info                                                        
+-----------------------------------------------------------------------------------------------------------------------------------
+ ("unsupported Unicode escape sequence","Unicode escape value could not be translated to the server's encoding SQL_ASCII.",,22P05)
 (1 row)
 
diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out
index d3248aa0fd..cfda43589e 100644
--- a/src/test/regress/expected/jsonb.out
+++ b/src/test/regress/expected/jsonb.out
@@ -323,16 +323,16 @@ select pg_input_is_valid('{"a":true', 'jsonb');
  f
 (1 row)
 
-select pg_input_error_message('{"a":true', 'jsonb');
-       pg_input_error_message       
-------------------------------------
- invalid input syntax for type json
+select pg_input_error_info('{"a":true', 'jsonb');
+                                 pg_input_error_info                                  
+--------------------------------------------------------------------------------------
+ ("invalid input syntax for type json","The input string ended unexpectedly.",,22P02)
 (1 row)
 
-select pg_input_error_message('{"a":1e1000000}', 'jsonb');
-     pg_input_error_message     
---------------------------------
- value overflows numeric format
+select pg_input_error_info('{"a":1e1000000}', 'jsonb');
+            pg_input_error_info             
+--------------------------------------------
+ ("value overflows numeric format",,,22003)
 (1 row)
 
 -- make sure jsonb is passed through json generators without being escaped
diff --git a/src/test/regress/expected/jsonpath.out b/src/test/regress/expected/jsonpath.out
index ca0cdf1ab2..eba11d485f 100644
--- a/src/test/regress/expected/jsonpath.out
+++ b/src/test/regress/expected/jsonpath.out
@@ -1035,18 +1035,18 @@ select '1?(2>3)'::jsonpath;
 -- test non-error-throwing API
 SELECT str as jsonpath,
        pg_input_is_valid(str,'jsonpath') as ok,
-       pg_input_error_message(str,'jsonpath') as errmsg
+       pg_input_error_info(str,'jsonpath') as errmsg
 FROM unnest(ARRAY['$ ? (@ like_regex "pattern" flag "smixq")'::text,
                   '$ ? (@ like_regex "pattern" flag "a")',
                   '@ + 1',
                   '00',
                   '1a']) str;
-                 jsonpath                  | ok |                                errmsg                                 
--------------------------------------------+----+-----------------------------------------------------------------------
- $ ? (@ like_regex "pattern" flag "smixq") | t  | 
- $ ? (@ like_regex "pattern" flag "a")     | f  | invalid input syntax for type jsonpath
- @ + 1                                     | f  | @ is not allowed in root expressions
- 00                                        | f  | trailing junk after numeric literal at or near "00" of jsonpath input
- 1a                                        | f  | trailing junk after numeric literal at or near "1a" of jsonpath input
+                 jsonpath                  | ok |                                                     errmsg                                                     
+-------------------------------------------+----+----------------------------------------------------------------------------------------------------------------
+ $ ? (@ like_regex "pattern" flag "smixq") | t  | (,,,)
+ $ ? (@ like_regex "pattern" flag "a")     | f  | ("invalid input syntax for type jsonpath","Unrecognized flag character ""a"" in LIKE_REGEX predicate.",,42601)
+ @ + 1                                     | f  | ("@ is not allowed in root expressions",,,42601)
+ 00                                        | f  | ("trailing junk after numeric literal at or near ""00"" of jsonpath input",,,42601)
+ 1a                                        | f  | ("trailing junk after numeric literal at or near ""1a"" of jsonpath input",,,42601)
 (5 rows)
 
diff --git a/src/test/regress/expected/line.out b/src/test/regress/expected/line.out
index 6baea8fdbd..5682e49c4f 100644
--- a/src/test/regress/expected/line.out
+++ b/src/test/regress/expected/line.out
@@ -92,10 +92,10 @@ SELECT pg_input_is_valid('{1, 1}', 'line');
  f
 (1 row)
 
-SELECT pg_input_error_message('{1, 1}', 'line');
-            pg_input_error_message            
-----------------------------------------------
- invalid input syntax for type line: "{1, 1}"
+SELECT pg_input_error_info('{1, 1}', 'line');
+                    pg_input_error_info                     
+------------------------------------------------------------
+ ("invalid input syntax for type line: ""{1, 1}""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('{0, 0, 0}', 'line');
@@ -104,10 +104,10 @@ SELECT pg_input_is_valid('{0, 0, 0}', 'line');
  f
 (1 row)
 
-SELECT pg_input_error_message('{0, 0, 0}', 'line');
-                 pg_input_error_message                  
----------------------------------------------------------
- invalid line specification: A and B cannot both be zero
+SELECT pg_input_error_info('{0, 0, 0}', 'line');
+                         pg_input_error_info                         
+---------------------------------------------------------------------
+ ("invalid line specification: A and B cannot both be zero",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('{1, 1, a}', 'line');
@@ -116,10 +116,10 @@ SELECT pg_input_is_valid('{1, 1, a}', 'line');
  f
 (1 row)
 
-SELECT pg_input_error_message('{1, 1, a}', 'line');
-             pg_input_error_message              
--------------------------------------------------
- invalid input syntax for type line: "{1, 1, a}"
+SELECT pg_input_error_info('{1, 1, a}', 'line');
+                      pg_input_error_info                      
+---------------------------------------------------------------
+ ("invalid input syntax for type line: ""{1, 1, a}""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('{1, 1, 1e400}', 'line');
@@ -128,10 +128,10 @@ SELECT pg_input_is_valid('{1, 1, 1e400}', 'line');
  f
 (1 row)
 
-SELECT pg_input_error_message('{1, 1, 1e400}', 'line');
-              pg_input_error_message               
----------------------------------------------------
- "1e400" is out of range for type double precision
+SELECT pg_input_error_info('{1, 1, 1e400}', 'line');
+                       pg_input_error_info                       
+-----------------------------------------------------------------
+ ("""1e400"" is out of range for type double precision",,,22003)
 (1 row)
 
 SELECT pg_input_is_valid('(1, 1), (1, 1e400)', 'line');
@@ -140,9 +140,9 @@ SELECT pg_input_is_valid('(1, 1), (1, 1e400)', 'line');
  f
 (1 row)
 
-SELECT pg_input_error_message('(1, 1), (1, 1e400)', 'line');
-              pg_input_error_message               
----------------------------------------------------
- "1e400" is out of range for type double precision
+SELECT pg_input_error_info('(1, 1), (1, 1e400)', 'line');
+                       pg_input_error_info                       
+-----------------------------------------------------------------
+ ("""1e400"" is out of range for type double precision",,,22003)
 (1 row)
 
diff --git a/src/test/regress/expected/lseg.out b/src/test/regress/expected/lseg.out
index afb323fe04..ffefbfb507 100644
--- a/src/test/regress/expected/lseg.out
+++ b/src/test/regress/expected/lseg.out
@@ -49,9 +49,9 @@ SELECT pg_input_is_valid('[(1,2),(3)]', 'lseg');
  f
 (1 row)
 
-SELECT pg_input_error_message('[(1,2),(3)]', 'lseg');
-              pg_input_error_message               
----------------------------------------------------
- invalid input syntax for type lseg: "[(1,2),(3)]"
+SELECT pg_input_error_info('[(1,2),(3)]', 'lseg');
+                       pg_input_error_info                       
+-----------------------------------------------------------------
+ ("invalid input syntax for type lseg: ""[(1,2),(3)]""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/macaddr.out b/src/test/regress/expected/macaddr.out
index cb646af79b..7ebc9da757 100644
--- a/src/test/regress/expected/macaddr.out
+++ b/src/test/regress/expected/macaddr.out
@@ -165,10 +165,10 @@ SELECT pg_input_is_valid('08:00:2b:01:02:ZZ', 'macaddr');
  f
 (1 row)
 
-SELECT pg_input_error_message('08:00:2b:01:02:ZZ', 'macaddr');
-                   pg_input_error_message                   
-------------------------------------------------------------
- invalid input syntax for type macaddr: "08:00:2b:01:02:ZZ"
+SELECT pg_input_error_info('08:00:2b:01:02:ZZ', 'macaddr');
+                           pg_input_error_info                            
+--------------------------------------------------------------------------
+ ("invalid input syntax for type macaddr: ""08:00:2b:01:02:ZZ""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('08:00:2b:01:02:', 'macaddr');
@@ -177,9 +177,9 @@ SELECT pg_input_is_valid('08:00:2b:01:02:', 'macaddr');
  f
 (1 row)
 
-SELECT pg_input_error_message('08:00:2b:01:02:', 'macaddr');
-                  pg_input_error_message                  
-----------------------------------------------------------
- invalid input syntax for type macaddr: "08:00:2b:01:02:"
+SELECT pg_input_error_info('08:00:2b:01:02:', 'macaddr');
+                          pg_input_error_info                           
+------------------------------------------------------------------------
+ ("invalid input syntax for type macaddr: ""08:00:2b:01:02:""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/macaddr8.out b/src/test/regress/expected/macaddr8.out
index bf681988f8..b047eafade 100644
--- a/src/test/regress/expected/macaddr8.out
+++ b/src/test/regress/expected/macaddr8.out
@@ -359,10 +359,10 @@ SELECT pg_input_is_valid('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
  f
 (1 row)
 
-SELECT pg_input_error_message('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
-                      pg_input_error_message                       
--------------------------------------------------------------------
- invalid input syntax for type macaddr8: "08:00:2b:01:02:03:04:ZZ"
+SELECT pg_input_error_info('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
+                               pg_input_error_info                               
+---------------------------------------------------------------------------------
+ ("invalid input syntax for type macaddr8: ""08:00:2b:01:02:03:04:ZZ""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8');
@@ -371,9 +371,9 @@ SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8');
  f
 (1 row)
 
-SELECT pg_input_error_message('08:00:2b:01:02:03:04:', 'macaddr8');
-                     pg_input_error_message                      
------------------------------------------------------------------
- invalid input syntax for type macaddr8: "08:00:2b:01:02:03:04:"
+SELECT pg_input_error_info('08:00:2b:01:02:03:04:', 'macaddr8');
+                              pg_input_error_info                              
+-------------------------------------------------------------------------------
+ ("invalid input syntax for type macaddr8: ""08:00:2b:01:02:03:04:""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/money.out b/src/test/regress/expected/money.out
index 46b2eab51a..b87106a0f8 100644
--- a/src/test/regress/expected/money.out
+++ b/src/test/regress/expected/money.out
@@ -338,10 +338,10 @@ SELECT pg_input_is_valid('\x0001', 'money');
  f
 (1 row)
 
-SELECT pg_input_error_message('\x0001', 'money');
-            pg_input_error_message             
------------------------------------------------
- invalid input syntax for type money: "\x0001"
+SELECT pg_input_error_info('\x0001', 'money');
+                     pg_input_error_info                      
+--------------------------------------------------------------
+ ("invalid input syntax for type money: ""\\x0001""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('192233720368547758.07', 'money');
@@ -350,10 +350,10 @@ SELECT pg_input_is_valid('192233720368547758.07', 'money');
  f
 (1 row)
 
-SELECT pg_input_error_message('192233720368547758.07', 'money');
-                    pg_input_error_message                    
---------------------------------------------------------------
- value "192233720368547758.07" is out of range for type money
+SELECT pg_input_error_info('192233720368547758.07', 'money');
+                            pg_input_error_info                             
+----------------------------------------------------------------------------
+ ("value ""192233720368547758.07"" is out of range for type money",,,22003)
 (1 row)
 
 -- documented minimums and maximums
diff --git a/src/test/regress/expected/multirangetypes.out b/src/test/regress/expected/multirangetypes.out
index e70896b754..64b8d5fdda 100644
--- a/src/test/regress/expected/multirangetypes.out
+++ b/src/test/regress/expected/multirangetypes.out
@@ -287,10 +287,10 @@ select pg_input_is_valid('{[1,2], [4,5]', 'int4multirange');
  f
 (1 row)
 
-select pg_input_error_message('{[1,2], [4,5]', 'int4multirange');
-            pg_input_error_message             
------------------------------------------------
- malformed multirange literal: "{[1,2], [4,5]"
+select pg_input_error_info('{[1,2], [4,5]', 'int4multirange');
+                                  pg_input_error_info                                  
+---------------------------------------------------------------------------------------
+ ("malformed multirange literal: ""{[1,2], [4,5]""","Unexpected end of input.",,22P02)
 (1 row)
 
 select pg_input_is_valid('{[1,2], [4,zed]}', 'int4multirange');
@@ -299,10 +299,10 @@ select pg_input_is_valid('{[1,2], [4,zed]}', 'int4multirange');
  f
 (1 row)
 
-select pg_input_error_message('{[1,2], [4,zed]}', 'int4multirange');
-            pg_input_error_message            
-----------------------------------------------
- invalid input syntax for type integer: "zed"
+select pg_input_error_info('{[1,2], [4,zed]}', 'int4multirange');
+                    pg_input_error_info                     
+------------------------------------------------------------
+ ("invalid input syntax for type integer: ""zed""",,,22P02)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.out
index 56a3f3630a..f9c8334ecc 100644
--- a/src/test/regress/expected/numeric.out
+++ b/src/test/regress/expected/numeric.out
@@ -2312,10 +2312,10 @@ SELECT pg_input_is_valid('1e400000', 'numeric');
  f
 (1 row)
 
-SELECT pg_input_error_message('1e400000', 'numeric');
-     pg_input_error_message     
---------------------------------
- value overflows numeric format
+SELECT pg_input_error_info('1e400000', 'numeric');
+            pg_input_error_info             
+--------------------------------------------
+ ("value overflows numeric format",,,22003)
 (1 row)
 
 SELECT pg_input_is_valid('1234.567', 'numeric(8,4)');
@@ -2330,16 +2330,16 @@ SELECT pg_input_is_valid('1234.567', 'numeric(7,4)');
  f
 (1 row)
 
-SELECT pg_input_error_message('1234.567', 'numeric(7,4)');
- pg_input_error_message 
-------------------------
- numeric field overflow
+SELECT pg_input_error_info('1234.567', 'numeric(7,4)');
+                                                  pg_input_error_info                                                  
+-----------------------------------------------------------------------------------------------------------------------
+ ("numeric field overflow","A field with precision 7, scale 4 must round to an absolute value less than 10^3.",,22003)
 (1 row)
 
-SELECT pg_input_error_message('0x1234.567', 'numeric');
-               pg_input_error_message                
------------------------------------------------------
- invalid input syntax for type numeric: "0x1234.567"
+SELECT pg_input_error_info('0x1234.567', 'numeric');
+                        pg_input_error_info                        
+-------------------------------------------------------------------
+ ("invalid input syntax for type numeric: ""0x1234.567""",,,22P02)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/oid.out b/src/test/regress/expected/oid.out
index b664bab5f9..574e07c0fc 100644
--- a/src/test/regress/expected/oid.out
+++ b/src/test/regress/expected/oid.out
@@ -78,10 +78,10 @@ SELECT pg_input_is_valid('01XYZ', 'oid');
  f
 (1 row)
 
-SELECT pg_input_error_message('01XYZ', 'oid');
-           pg_input_error_message           
---------------------------------------------
- invalid input syntax for type oid: "01XYZ"
+SELECT pg_input_error_info('01XYZ', 'oid');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("invalid input syntax for type oid: ""01XYZ""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('9999999999', 'oid');
@@ -90,10 +90,10 @@ SELECT pg_input_is_valid('9999999999', 'oid');
  f
 (1 row)
 
-SELECT pg_input_error_message('9999999999', 'oid');
-             pg_input_error_message              
--------------------------------------------------
- value "9999999999" is out of range for type oid
+SELECT pg_input_error_info('9999999999', 'oid');
+                      pg_input_error_info                      
+---------------------------------------------------------------
+ ("value ""9999999999"" is out of range for type oid",,,22003)
 (1 row)
 
 -- While we're here, check oidvector as well
@@ -109,10 +109,10 @@ SELECT pg_input_is_valid('01 01XYZ', 'oidvector');
  f
 (1 row)
 
-SELECT pg_input_error_message('01 01XYZ', 'oidvector');
-          pg_input_error_message          
-------------------------------------------
- invalid input syntax for type oid: "XYZ"
+SELECT pg_input_error_info('01 01XYZ', 'oidvector');
+                  pg_input_error_info                   
+--------------------------------------------------------
+ ("invalid input syntax for type oid: ""XYZ""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('01 9999999999', 'oidvector');
@@ -121,10 +121,10 @@ SELECT pg_input_is_valid('01 9999999999', 'oidvector');
  f
 (1 row)
 
-SELECT pg_input_error_message('01 9999999999', 'oidvector');
-             pg_input_error_message              
--------------------------------------------------
- value "9999999999" is out of range for type oid
+SELECT pg_input_error_info('01 9999999999', 'oidvector');
+                      pg_input_error_info                      
+---------------------------------------------------------------
+ ("value ""9999999999"" is out of range for type oid",,,22003)
 (1 row)
 
 SELECT o.* FROM OID_TBL o WHERE o.f1 = 1234;
diff --git a/src/test/regress/expected/path.out b/src/test/regress/expected/path.out
index 529a5e6fc2..92e6469946 100644
--- a/src/test/regress/expected/path.out
+++ b/src/test/regress/expected/path.out
@@ -87,10 +87,10 @@ SELECT pg_input_is_valid('[(1,2),(3)]', 'path');
  f
 (1 row)
 
-SELECT pg_input_error_message('[(1,2),(3)]', 'path');
-              pg_input_error_message               
----------------------------------------------------
- invalid input syntax for type path: "[(1,2),(3)]"
+SELECT pg_input_error_info('[(1,2),(3)]', 'path');
+                       pg_input_error_info                       
+-----------------------------------------------------------------
+ ("invalid input syntax for type path: ""[(1,2),(3)]""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('[(1,2,6),(3,4,6)]', 'path');
@@ -99,9 +99,9 @@ SELECT pg_input_is_valid('[(1,2,6),(3,4,6)]', 'path');
  f
 (1 row)
 
-SELECT pg_input_error_message('[(1,2,6),(3,4,6)]', 'path');
-                 pg_input_error_message                  
----------------------------------------------------------
- invalid input syntax for type path: "[(1,2,6),(3,4,6)]"
+SELECT pg_input_error_info('[(1,2,6),(3,4,6)]', 'path');
+                          pg_input_error_info                          
+-----------------------------------------------------------------------
+ ("invalid input syntax for type path: ""[(1,2,6),(3,4,6)]""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/pg_lsn.out b/src/test/regress/expected/pg_lsn.out
index 01501f8c9b..cbbdc9a1d7 100644
--- a/src/test/regress/expected/pg_lsn.out
+++ b/src/test/regress/expected/pg_lsn.out
@@ -33,10 +33,10 @@ SELECT pg_input_is_valid('16AE7F7', 'pg_lsn');
  f
 (1 row)
 
-SELECT pg_input_error_message('16AE7F7', 'pg_lsn');
-             pg_input_error_message              
--------------------------------------------------
- invalid input syntax for type pg_lsn: "16AE7F7"
+SELECT pg_input_error_info('16AE7F7', 'pg_lsn');
+                      pg_input_error_info                      
+---------------------------------------------------------------
+ ("invalid input syntax for type pg_lsn: ""16AE7F7""",,,22P02)
 (1 row)
 
 -- Min/Max aggregation
diff --git a/src/test/regress/expected/point.out b/src/test/regress/expected/point.out
index a716ceb881..76d053cc27 100644
--- a/src/test/regress/expected/point.out
+++ b/src/test/regress/expected/point.out
@@ -470,9 +470,9 @@ SELECT pg_input_is_valid('1,y', 'point');
  f
 (1 row)
 
-SELECT pg_input_error_message('1,y', 'point');
-           pg_input_error_message           
---------------------------------------------
- invalid input syntax for type point: "1,y"
+SELECT pg_input_error_info('1,y', 'point');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("invalid input syntax for type point: ""1,y""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/polygon.out b/src/test/regress/expected/polygon.out
index c7d565ad53..22b972f907 100644
--- a/src/test/regress/expected/polygon.out
+++ b/src/test/regress/expected/polygon.out
@@ -313,10 +313,10 @@ SELECT pg_input_is_valid('(2.0,0.8,0.1)', 'polygon');
  f
 (1 row)
 
-SELECT pg_input_error_message('(2.0,0.8,0.1)', 'polygon');
-                 pg_input_error_message                 
---------------------------------------------------------
- invalid input syntax for type polygon: "(2.0,0.8,0.1)"
+SELECT pg_input_error_info('(2.0,0.8,0.1)', 'polygon');
+                         pg_input_error_info                          
+----------------------------------------------------------------------
+ ("invalid input syntax for type polygon: ""(2.0,0.8,0.1)""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('(2.0,xyz)', 'polygon');
@@ -325,9 +325,9 @@ SELECT pg_input_is_valid('(2.0,xyz)', 'polygon');
  f
 (1 row)
 
-SELECT pg_input_error_message('(2.0,xyz)', 'polygon');
-               pg_input_error_message               
-----------------------------------------------------
- invalid input syntax for type polygon: "(2.0,xyz)"
+SELECT pg_input_error_info('(2.0,xyz)', 'polygon');
+                       pg_input_error_info                        
+------------------------------------------------------------------
+ ("invalid input syntax for type polygon: ""(2.0,xyz)""",,,22P02)
 (1 row)
 
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 95d1e5515f..1a91ee123f 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -2246,10 +2246,10 @@ SELECT pg_input_is_valid('regress_priv_user1=r/', 'aclitem');
  f
 (1 row)
 
-SELECT pg_input_error_message('regress_priv_user1=r/', 'aclitem');
-     pg_input_error_message      
----------------------------------
- a name must follow the "/" sign
+SELECT pg_input_error_info('regress_priv_user1=r/', 'aclitem');
+              pg_input_error_info              
+-----------------------------------------------
+ ("a name must follow the ""/"" sign",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('regress_priv_user1=r/regress_no_such_user', 'aclitem');
@@ -2258,10 +2258,10 @@ SELECT pg_input_is_valid('regress_priv_user1=r/regress_no_such_user', 'aclitem')
  f
 (1 row)
 
-SELECT pg_input_error_message('regress_priv_user1=r/regress_no_such_user', 'aclitem');
-           pg_input_error_message           
---------------------------------------------
- role "regress_no_such_user" does not exist
+SELECT pg_input_error_info('regress_priv_user1=r/regress_no_such_user', 'aclitem');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("role ""regress_no_such_user"" does not exist",,,42704)
 (1 row)
 
 SELECT pg_input_is_valid('regress_priv_user1=rY', 'aclitem');
@@ -2270,10 +2270,10 @@ SELECT pg_input_is_valid('regress_priv_user1=rY', 'aclitem');
  f
 (1 row)
 
-SELECT pg_input_error_message('regress_priv_user1=rY', 'aclitem');
-                  pg_input_error_message                  
-----------------------------------------------------------
- invalid mode character: must be one of "arwdDxtXUCTcsAm"
+SELECT pg_input_error_info('regress_priv_user1=rY', 'aclitem');
+                          pg_input_error_info                           
+------------------------------------------------------------------------
+ ("invalid mode character: must be one of ""arwdDxtXUCTcsAm""",,,22P02)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out
index a3e9e447af..0571e72534 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -188,10 +188,10 @@ select pg_input_is_valid('(1,4', 'int4range');
  f
 (1 row)
 
-select pg_input_error_message('(1,4', 'int4range');
-     pg_input_error_message      
----------------------------------
- malformed range literal: "(1,4"
+select pg_input_error_info('(1,4', 'int4range');
+                           pg_input_error_info                           
+-------------------------------------------------------------------------
+ ("malformed range literal: ""(1,4""","Unexpected end of input.",,22P02)
 (1 row)
 
 select pg_input_is_valid('(4,1)', 'int4range');
@@ -200,10 +200,10 @@ select pg_input_is_valid('(4,1)', 'int4range');
  f
 (1 row)
 
-select pg_input_error_message('(4,1)', 'int4range');
-                      pg_input_error_message                       
--------------------------------------------------------------------
- range lower bound must be less than or equal to range upper bound
+select pg_input_error_info('(4,1)', 'int4range');
+                              pg_input_error_info                              
+-------------------------------------------------------------------------------
+ ("range lower bound must be less than or equal to range upper bound",,,22000)
 (1 row)
 
 select pg_input_is_valid('(4,zed)', 'int4range');
@@ -212,10 +212,10 @@ select pg_input_is_valid('(4,zed)', 'int4range');
  f
 (1 row)
 
-select pg_input_error_message('(4,zed)', 'int4range');
-            pg_input_error_message            
-----------------------------------------------
- invalid input syntax for type integer: "zed"
+select pg_input_error_info('(4,zed)', 'int4range');
+                    pg_input_error_info                     
+------------------------------------------------------------
+ ("invalid input syntax for type integer: ""zed""",,,22P02)
 (1 row)
 
 select pg_input_is_valid('[1,2147483647]', 'int4range');
@@ -224,10 +224,10 @@ select pg_input_is_valid('[1,2147483647]', 'int4range');
  f
 (1 row)
 
-select pg_input_error_message('[1,2147483647]', 'int4range');
- pg_input_error_message 
-------------------------
- integer out of range
+select pg_input_error_info('[1,2147483647]', 'int4range');
+       pg_input_error_info        
+----------------------------------
+ ("integer out of range",,,22003)
 (1 row)
 
 select pg_input_is_valid('[2000-01-01,5874897-12-31]', 'daterange');
@@ -236,10 +236,10 @@ select pg_input_is_valid('[2000-01-01,5874897-12-31]', 'daterange');
  f
 (1 row)
 
-select pg_input_error_message('[2000-01-01,5874897-12-31]', 'daterange');
- pg_input_error_message 
-------------------------
- date out of range
+select pg_input_error_info('[2000-01-01,5874897-12-31]', 'daterange');
+      pg_input_error_info      
+-------------------------------
+ ("date out of range",,,22008)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index a034fbb346..13e3b7eda9 100644
--- a/src/test/regress/expected/regproc.out
+++ b/src/test/regress/expected/regproc.out
@@ -448,10 +448,10 @@ SELECT to_regnamespace('foo.bar');
 (1 row)
 
 -- Test soft-error API
-SELECT pg_input_error_message('ng_catalog.pg_class', 'regclass');
-            pg_input_error_message             
------------------------------------------------
- relation "ng_catalog.pg_class" does not exist
+SELECT pg_input_error_info('ng_catalog.pg_class', 'regclass');
+                     pg_input_error_info                     
+-------------------------------------------------------------
+ ("relation ""ng_catalog.pg_class"" does not exist",,,42P01)
 (1 row)
 
 SELECT pg_input_is_valid('ng_catalog."POSIX"', 'regcollation');
@@ -460,87 +460,87 @@ SELECT pg_input_is_valid('ng_catalog."POSIX"', 'regcollation');
  f
 (1 row)
 
-SELECT pg_input_error_message('no_such_config', 'regconfig');
-                  pg_input_error_message                   
------------------------------------------------------------
- text search configuration "no_such_config" does not exist
+SELECT pg_input_error_info('no_such_config', 'regconfig');
+                           pg_input_error_info                           
+-------------------------------------------------------------------------
+ ("text search configuration ""no_such_config"" does not exist",,,42704)
 (1 row)
 
-SELECT pg_input_error_message('no_such_dictionary', 'regdictionary');
-                   pg_input_error_message                   
-------------------------------------------------------------
- text search dictionary "no_such_dictionary" does not exist
+SELECT pg_input_error_info('no_such_dictionary', 'regdictionary');
+                           pg_input_error_info                            
+--------------------------------------------------------------------------
+ ("text search dictionary ""no_such_dictionary"" does not exist",,,42704)
 (1 row)
 
-SELECT pg_input_error_message('Nonexistent', 'regnamespace');
-       pg_input_error_message        
--------------------------------------
- schema "nonexistent" does not exist
+SELECT pg_input_error_info('Nonexistent', 'regnamespace');
+                pg_input_error_info                
+---------------------------------------------------
+ ("schema ""nonexistent"" does not exist",,,3F000)
 (1 row)
 
-SELECT pg_input_error_message('ng_catalog.||/', 'regoper');
-         pg_input_error_message          
------------------------------------------
- operator does not exist: ng_catalog.||/
+SELECT pg_input_error_info('ng_catalog.||/', 'regoper');
+                 pg_input_error_info                 
+-----------------------------------------------------
+ ("operator does not exist: ng_catalog.||/",,,42883)
 (1 row)
 
-SELECT pg_input_error_message('-', 'regoper');
-     pg_input_error_message     
---------------------------------
- more than one operator named -
+SELECT pg_input_error_info('-', 'regoper');
+            pg_input_error_info             
+--------------------------------------------
+ ("more than one operator named -",,,42725)
 (1 row)
 
-SELECT pg_input_error_message('ng_catalog.+(int4,int4)', 'regoperator');
-              pg_input_error_message              
---------------------------------------------------
- operator does not exist: ng_catalog.+(int4,int4)
+SELECT pg_input_error_info('ng_catalog.+(int4,int4)', 'regoperator');
+                     pg_input_error_info                      
+--------------------------------------------------------------
+ ("operator does not exist: ng_catalog.+(int4,int4)",,,42883)
 (1 row)
 
-SELECT pg_input_error_message('-', 'regoperator');
-   pg_input_error_message    
------------------------------
- expected a left parenthesis
+SELECT pg_input_error_info('-', 'regoperator');
+           pg_input_error_info           
+-----------------------------------------
+ ("expected a left parenthesis",,,22P02)
 (1 row)
 
-SELECT pg_input_error_message('ng_catalog.now', 'regproc');
-          pg_input_error_message          
-------------------------------------------
- function "ng_catalog.now" does not exist
+SELECT pg_input_error_info('ng_catalog.now', 'regproc');
+                  pg_input_error_info                   
+--------------------------------------------------------
+ ("function ""ng_catalog.now"" does not exist",,,42883)
 (1 row)
 
-SELECT pg_input_error_message('ng_catalog.abs(numeric)', 'regprocedure');
-              pg_input_error_message               
----------------------------------------------------
- function "ng_catalog.abs(numeric)" does not exist
+SELECT pg_input_error_info('ng_catalog.abs(numeric)', 'regprocedure');
+                       pg_input_error_info                       
+-----------------------------------------------------------------
+ ("function ""ng_catalog.abs(numeric)"" does not exist",,,42883)
 (1 row)
 
-SELECT pg_input_error_message('ng_catalog.abs(numeric', 'regprocedure');
-    pg_input_error_message    
-------------------------------
- expected a right parenthesis
+SELECT pg_input_error_info('ng_catalog.abs(numeric', 'regprocedure');
+           pg_input_error_info            
+------------------------------------------
+ ("expected a right parenthesis",,,22P02)
 (1 row)
 
-SELECT pg_input_error_message('regress_regrole_test', 'regrole');
-           pg_input_error_message           
---------------------------------------------
- role "regress_regrole_test" does not exist
+SELECT pg_input_error_info('regress_regrole_test', 'regrole');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("role ""regress_regrole_test"" does not exist",,,42704)
 (1 row)
 
-SELECT pg_input_error_message('no_such_type', 'regtype');
-       pg_input_error_message       
-------------------------------------
- type "no_such_type" does not exist
+SELECT pg_input_error_info('no_such_type', 'regtype');
+               pg_input_error_info                
+--------------------------------------------------
+ ("type ""no_such_type"" does not exist",,,42704)
 (1 row)
 
 -- Some cases that should be soft errors, but are not yet
-SELECT pg_input_error_message('incorrect type name syntax', 'regtype');
+SELECT pg_input_error_info('incorrect type name syntax', 'regtype');
 ERROR:  syntax error at or near "type"
-LINE 1: SELECT pg_input_error_message('incorrect type name syntax', ...
+LINE 1: SELECT pg_input_error_info('incorrect type name syntax', 're...
                   ^
 CONTEXT:  invalid type name "incorrect type name syntax"
-SELECT pg_input_error_message('numeric(1,2,3)', 'regtype');  -- bogus typmod
+SELECT pg_input_error_info('numeric(1,2,3)', 'regtype');  -- bogus typmod
 ERROR:  invalid NUMERIC type modifier
-SELECT pg_input_error_message('way.too.many.names', 'regtype');
+SELECT pg_input_error_info('way.too.many.names', 'regtype');
 ERROR:  improper qualified name (too many dotted names): way.too.many.names
-SELECT pg_input_error_message('no_such_catalog.schema.name', 'regtype');
+SELECT pg_input_error_info('no_such_catalog.schema.name', 'regtype');
 ERROR:  cross-database references are not implemented: no_such_catalog.schema.name
diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out
index 801d9e556b..f00453c31f 100644
--- a/src/test/regress/expected/rowtypes.out
+++ b/src/test/regress/expected/rowtypes.out
@@ -88,16 +88,16 @@ SELECT pg_input_is_valid('(1,zed)', 'complex');
  f
 (1 row)
 
-SELECT pg_input_error_message('(1,zed)', 'complex');
-                pg_input_error_message                 
--------------------------------------------------------
- invalid input syntax for type double precision: "zed"
+SELECT pg_input_error_info('(1,zed)', 'complex');
+                         pg_input_error_info                         
+---------------------------------------------------------------------
+ ("invalid input syntax for type double precision: ""zed""",,,22P02)
 (1 row)
 
-SELECT pg_input_error_message('(1,1e400)', 'complex');
-              pg_input_error_message               
----------------------------------------------------
- "1e400" is out of range for type double precision
+SELECT pg_input_error_info('(1,1e400)', 'complex');
+                       pg_input_error_info                       
+-----------------------------------------------------------------
+ ("""1e400"" is out of range for type double precision",,,22003)
 (1 row)
 
 create temp table quadtable(f1 int, q quad);
diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out
index f028c1f10f..d6046de7bc 100644
--- a/src/test/regress/expected/strings.out
+++ b/src/test/regress/expected/strings.out
@@ -280,22 +280,22 @@ SELECT pg_input_is_valid(E'\\xDeAdBeE', 'bytea');
  f
 (1 row)
 
-SELECT pg_input_error_message(E'\\xDeAdBeE', 'bytea');
-             pg_input_error_message             
-------------------------------------------------
- invalid hexadecimal data: odd number of digits
+SELECT pg_input_error_info(E'\\xDeAdBeE', 'bytea');
+                    pg_input_error_info                     
+------------------------------------------------------------
+ ("invalid hexadecimal data: odd number of digits",,,22023)
 (1 row)
 
-SELECT pg_input_error_message(E'\\xDeAdBeEx', 'bytea');
-     pg_input_error_message     
---------------------------------
- invalid hexadecimal digit: "x"
+SELECT pg_input_error_info(E'\\xDeAdBeEx', 'bytea');
+             pg_input_error_info              
+----------------------------------------------
+ ("invalid hexadecimal digit: ""x""",,,22023)
 (1 row)
 
-SELECT pg_input_error_message(E'foo\\99bar', 'bytea');
-       pg_input_error_message        
--------------------------------------
- invalid input syntax for type bytea
+SELECT pg_input_error_info(E'foo\\99bar', 'bytea');
+               pg_input_error_info               
+-------------------------------------------------
+ ("invalid input syntax for type bytea",,,22P02)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/tid.out b/src/test/regress/expected/tid.out
index ff67ed43f0..bd9a57910f 100644
--- a/src/test/regress/expected/tid.out
+++ b/src/test/regress/expected/tid.out
@@ -24,10 +24,10 @@ SELECT pg_input_is_valid('(0)', 'tid');
  f
 (1 row)
 
-SELECT pg_input_error_message('(0)', 'tid');
-          pg_input_error_message          
-------------------------------------------
- invalid input syntax for type tid: "(0)"
+SELECT pg_input_error_info('(0)', 'tid');
+                  pg_input_error_info                   
+--------------------------------------------------------
+ ("invalid input syntax for type tid: ""(0)""",,,22P02)
 (1 row)
 
 SELECT pg_input_is_valid('(0,-1)', 'tid');
@@ -36,10 +36,10 @@ SELECT pg_input_is_valid('(0,-1)', 'tid');
  f
 (1 row)
 
-SELECT pg_input_error_message('(0,-1)', 'tid');
-           pg_input_error_message            
----------------------------------------------
- invalid input syntax for type tid: "(0,-1)"
+SELECT pg_input_error_info('(0,-1)', 'tid');
+                    pg_input_error_info                    
+-----------------------------------------------------------
+ ("invalid input syntax for type tid: ""(0,-1)""",,,22P02)
 (1 row)
 
 -- tests for functions related to TID handling
diff --git a/src/test/regress/expected/time.out b/src/test/regress/expected/time.out
index a44caededd..d982d591e1 100644
--- a/src/test/regress/expected/time.out
+++ b/src/test/regress/expected/time.out
@@ -133,16 +133,16 @@ SELECT pg_input_is_valid('15:36:39 America/New_York', 'time');
  f
 (1 row)
 
-SELECT pg_input_error_message('25:00:00', 'time');
-             pg_input_error_message             
-------------------------------------------------
- date/time field value out of range: "25:00:00"
+SELECT pg_input_error_info('25:00:00', 'time');
+                     pg_input_error_info                      
+--------------------------------------------------------------
+ ("date/time field value out of range: ""25:00:00""",,,22008)
 (1 row)
 
-SELECT pg_input_error_message('15:36:39 America/New_York', 'time');
-                     pg_input_error_message                      
------------------------------------------------------------------
- invalid input syntax for type time: "15:36:39 America/New_York"
+SELECT pg_input_error_info('15:36:39 America/New_York', 'time');
+                              pg_input_error_info                              
+-------------------------------------------------------------------------------
+ ("invalid input syntax for type time: ""15:36:39 America/New_York""",,,22007)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/timestamp.out b/src/test/regress/expected/timestamp.out
index eef2f7001c..7efa86d509 100644
--- a/src/test/regress/expected/timestamp.out
+++ b/src/test/regress/expected/timestamp.out
@@ -144,16 +144,16 @@ SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp');
  f
 (1 row)
 
-SELECT pg_input_error_message('garbage', 'timestamp');
-               pg_input_error_message               
-----------------------------------------------------
- invalid input syntax for type timestamp: "garbage"
+SELECT pg_input_error_info('garbage', 'timestamp');
+                       pg_input_error_info                        
+------------------------------------------------------------------
+ ("invalid input syntax for type timestamp: ""garbage""",,,22007)
 (1 row)
 
-SELECT pg_input_error_message('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp');
-           pg_input_error_message           
---------------------------------------------
- time zone "nehwon/lankhmar" not recognized
+SELECT pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("time zone ""nehwon/lankhmar"" not recognized",,,22023)
 (1 row)
 
 -- Check date conversion and date arithmetic
diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out
index b85a93a3c2..6e9c4152f4 100644
--- a/src/test/regress/expected/timestamptz.out
+++ b/src/test/regress/expected/timestamptz.out
@@ -195,16 +195,16 @@ SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz');
  f
 (1 row)
 
-SELECT pg_input_error_message('garbage', 'timestamptz');
-                      pg_input_error_message                       
--------------------------------------------------------------------
- invalid input syntax for type timestamp with time zone: "garbage"
+SELECT pg_input_error_info('garbage', 'timestamptz');
+                               pg_input_error_info                               
+---------------------------------------------------------------------------------
+ ("invalid input syntax for type timestamp with time zone: ""garbage""",,,22007)
 (1 row)
 
-SELECT pg_input_error_message('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz');
-           pg_input_error_message           
---------------------------------------------
- time zone "nehwon/lankhmar" not recognized
+SELECT pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("time zone ""nehwon/lankhmar"" not recognized",,,22023)
 (1 row)
 
 -- Check date conversion and date arithmetic
diff --git a/src/test/regress/expected/timetz.out b/src/test/regress/expected/timetz.out
index 984285663b..8e8fd215f4 100644
--- a/src/test/regress/expected/timetz.out
+++ b/src/test/regress/expected/timetz.out
@@ -150,16 +150,16 @@ SELECT pg_input_is_valid('15:36:39 America/New_York', 'timetz');
  f
 (1 row)
 
-SELECT pg_input_error_message('25:00:00 PDT', 'timetz');
-               pg_input_error_message               
-----------------------------------------------------
- date/time field value out of range: "25:00:00 PDT"
+SELECT pg_input_error_info('25:00:00 PDT', 'timetz');
+                       pg_input_error_info                        
+------------------------------------------------------------------
+ ("date/time field value out of range: ""25:00:00 PDT""",,,22008)
 (1 row)
 
-SELECT pg_input_error_message('15:36:39 America/New_York', 'timetz');
-                             pg_input_error_message                             
---------------------------------------------------------------------------------
- invalid input syntax for type time with time zone: "15:36:39 America/New_York"
+SELECT pg_input_error_info('15:36:39 America/New_York', 'timetz');
+                                     pg_input_error_info                                      
+----------------------------------------------------------------------------------------------
+ ("invalid input syntax for type time with time zone: ""15:36:39 America/New_York""",,,22007)
 (1 row)
 
 --
diff --git a/src/test/regress/expected/tstypes.out b/src/test/regress/expected/tstypes.out
index a8785cd708..ee885872d3 100644
--- a/src/test/regress/expected/tstypes.out
+++ b/src/test/regress/expected/tstypes.out
@@ -102,10 +102,10 @@ SELECT pg_input_is_valid($$''$$, 'tsvector');
  f
 (1 row)
 
-SELECT pg_input_error_message($$''$$, 'tsvector');
-     pg_input_error_message     
---------------------------------
- syntax error in tsvector: "''"
+SELECT pg_input_error_info($$''$$, 'tsvector');
+             pg_input_error_info              
+----------------------------------------------
+ ("syntax error in tsvector: ""''""",,,42601)
 (1 row)
 
 --Base tsquery test
@@ -404,16 +404,16 @@ SELECT pg_input_is_valid('foo!', 'tsquery');
  f
 (1 row)
 
-SELECT pg_input_error_message('foo!', 'tsquery');
-     pg_input_error_message      
----------------------------------
- syntax error in tsquery: "foo!"
+SELECT pg_input_error_info('foo!', 'tsquery');
+              pg_input_error_info              
+-----------------------------------------------
+ ("syntax error in tsquery: ""foo!""",,,42601)
 (1 row)
 
-SELECT pg_input_error_message('a <100000> b', 'tsquery');
-                                pg_input_error_message                                 
----------------------------------------------------------------------------------------
- distance in phrase operator must be an integer value between zero and 16384 inclusive
+SELECT pg_input_error_info('a <100000> b', 'tsquery');
+                                        pg_input_error_info                                        
+---------------------------------------------------------------------------------------------------
+ ("distance in phrase operator must be an integer value between zero and 16384 inclusive",,,22023)
 (1 row)
 
 --comparisons
diff --git a/src/test/regress/expected/uuid.out b/src/test/regress/expected/uuid.out
index 0f47232009..7cfbd45b86 100644
--- a/src/test/regress/expected/uuid.out
+++ b/src/test/regress/expected/uuid.out
@@ -46,10 +46,10 @@ SELECT pg_input_is_valid('11', 'uuid');
  f
 (1 row)
 
-SELECT pg_input_error_message('11', 'uuid');
-          pg_input_error_message          
-------------------------------------------
- invalid input syntax for type uuid: "11"
+SELECT pg_input_error_info('11', 'uuid');
+                  pg_input_error_info                   
+--------------------------------------------------------
+ ("invalid input syntax for type uuid: ""11""",,,22P02)
 (1 row)
 
 --inserting three input formats
diff --git a/src/test/regress/expected/varchar.out b/src/test/regress/expected/varchar.out
index 62b683d86f..96ce47490d 100644
--- a/src/test/regress/expected/varchar.out
+++ b/src/test/regress/expected/varchar.out
@@ -124,9 +124,9 @@ SELECT pg_input_is_valid('abcde', 'varchar(4)');
  f
 (1 row)
 
-SELECT pg_input_error_message('abcde', 'varchar(4)');
-            pg_input_error_message            
-----------------------------------------------
- value too long for type character varying(4)
+SELECT pg_input_error_info('abcde', 'varchar(4)');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("value too long for type character varying(4)",,,22001)
 (1 row)
 
diff --git a/src/test/regress/expected/varchar_1.out b/src/test/regress/expected/varchar_1.out
index 6690f81c0b..d65a4d80df 100644
--- a/src/test/regress/expected/varchar_1.out
+++ b/src/test/regress/expected/varchar_1.out
@@ -124,9 +124,9 @@ SELECT pg_input_is_valid('abcde', 'varchar(4)');
  f
 (1 row)
 
-SELECT pg_input_error_message('abcde', 'varchar(4)');
-            pg_input_error_message            
-----------------------------------------------
- value too long for type character varying(4)
+SELECT pg_input_error_info('abcde', 'varchar(4)');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("value too long for type character varying(4)",,,22001)
 (1 row)
 
diff --git a/src/test/regress/expected/varchar_2.out b/src/test/regress/expected/varchar_2.out
index ad8aa7c693..14f7655239 100644
--- a/src/test/regress/expected/varchar_2.out
+++ b/src/test/regress/expected/varchar_2.out
@@ -124,9 +124,9 @@ SELECT pg_input_is_valid('abcde', 'varchar(4)');
  f
 (1 row)
 
-SELECT pg_input_error_message('abcde', 'varchar(4)');
-            pg_input_error_message            
-----------------------------------------------
- value too long for type character varying(4)
+SELECT pg_input_error_info('abcde', 'varchar(4)');
+                   pg_input_error_info                    
+----------------------------------------------------------
+ ("value too long for type character varying(4)",,,22001)
 (1 row)
 
diff --git a/src/test/regress/expected/xid.out b/src/test/regress/expected/xid.out
index e62f701943..ddda75e57e 100644
--- a/src/test/regress/expected/xid.out
+++ b/src/test/regress/expected/xid.out
@@ -43,10 +43,10 @@ SELECT pg_input_is_valid('asdf', 'xid');
  f
 (1 row)
 
-SELECT pg_input_error_message('0xffffffffff', 'xid');
-              pg_input_error_message               
----------------------------------------------------
- value "0xffffffffff" is out of range for type xid
+SELECT pg_input_error_info('0xffffffffff', 'xid');
+                       pg_input_error_info                       
+-----------------------------------------------------------------
+ ("value ""0xffffffffff"" is out of range for type xid",,,22003)
 (1 row)
 
 SELECT pg_input_is_valid('42', 'xid8');
@@ -61,10 +61,10 @@ SELECT pg_input_is_valid('asdf', 'xid8');
  f
 (1 row)
 
-SELECT pg_input_error_message('0xffffffffffffffffffff', 'xid8');
-                    pg_input_error_message                    
---------------------------------------------------------------
- value "0xffffffffffffffffffff" is out of range for type xid8
+SELECT pg_input_error_info('0xffffffffffffffffffff', 'xid8');
+                            pg_input_error_info                             
+----------------------------------------------------------------------------
+ ("value ""0xffffffffffffffffffff"" is out of range for type xid8",,,22003)
 (1 row)
 
 -- equality
@@ -223,10 +223,10 @@ select pg_input_is_valid('31:12:', 'pg_snapshot');
  f
 (1 row)
 
-select pg_input_error_message('31:12:', 'pg_snapshot');
-               pg_input_error_message                
------------------------------------------------------
- invalid input syntax for type pg_snapshot: "31:12:"
+select pg_input_error_info('31:12:', 'pg_snapshot');
+                        pg_input_error_info                        
+-------------------------------------------------------------------
+ ("invalid input syntax for type pg_snapshot: ""31:12:""",,,22P02)
 (1 row)
 
 select pg_input_is_valid('12:16:14,13', 'pg_snapshot');
@@ -235,10 +235,10 @@ select pg_input_is_valid('12:16:14,13', 'pg_snapshot');
  f
 (1 row)
 
-select pg_input_error_message('12:16:14,13', 'pg_snapshot');
-                  pg_input_error_message                  
-----------------------------------------------------------
- invalid input syntax for type pg_snapshot: "12:16:14,13"
+select pg_input_error_info('12:16:14,13', 'pg_snapshot');
+                          pg_input_error_info                           
+------------------------------------------------------------------------
+ ("invalid input syntax for type pg_snapshot: ""12:16:14,13""",,,22P02)
 (1 row)
 
 create temp table snapshot_test (
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 3c357a9c7e..ad852dc2f7 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -31,9 +31,9 @@ SELECT pg_input_is_valid('<value>one</', 'xml');
  f
 (1 row)
 
-SELECT pg_input_error_message('<value>one</', 'xml');
- pg_input_error_message 
-------------------------
+SELECT message FROM pg_input_error_info('<value>one</', 'xml');
+       message       
+---------------------
  invalid XML content
 (1 row)
 
@@ -43,8 +43,8 @@ SELECT pg_input_is_valid('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
  f
 (1 row)
 
-SELECT pg_input_error_message('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
-            pg_input_error_message            
+SELECT message FROM pg_input_error_info('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
+                   message                    
 ----------------------------------------------
  invalid XML content: invalid XML declaration
 (1 row)
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index 378b412db0..70fe34a04f 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -29,13 +29,13 @@ DETAIL:  This functionality requires the server to be built with libxml support.
 SELECT pg_input_is_valid('<value>one</', 'xml');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires the server to be built with libxml support.
-SELECT pg_input_error_message('<value>one</', 'xml');
+SELECT message FROM pg_input_error_info('<value>one</', 'xml');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires the server to be built with libxml support.
 SELECT pg_input_is_valid('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires the server to be built with libxml support.
-SELECT pg_input_error_message('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
+SELECT message FROM pg_input_error_info('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires the server to be built with libxml support.
 SELECT xmlcomment('test');
diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out
index 42055c5003..e01f431219 100644
--- a/src/test/regress/expected/xml_2.out
+++ b/src/test/regress/expected/xml_2.out
@@ -29,8 +29,8 @@ SELECT pg_input_is_valid('<value>one</', 'xml');
  f
 (1 row)
 
-SELECT pg_input_error_message('<value>one</', 'xml');
- pg_input_error_message 
+SELECT message FROM pg_input_error_info('<value>one</', 'xml');
+       message          
 ------------------------
  invalid XML content
 (1 row)
@@ -41,8 +41,8 @@ SELECT pg_input_is_valid('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
  f
 (1 row)
 
-SELECT pg_input_error_message('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
-            pg_input_error_message            
+SELECT message FROM pg_input_error_info('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
+                   message                    
 ----------------------------------------------
  invalid XML content: invalid XML declaration
 (1 row)
diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql
index 38e8dd440b..954c1225b4 100644
--- a/src/test/regress/sql/arrays.sql
+++ b/src/test/regress/sql/arrays.sql
@@ -117,7 +117,7 @@ SELECT a,b,c FROM arrtest;
 SELECT pg_input_is_valid('{1,2,3}', 'integer[]');
 SELECT pg_input_is_valid('{1,2', 'integer[]');
 SELECT pg_input_is_valid('{1,zed}', 'integer[]');
-SELECT pg_input_error_message('{1,zed}', 'integer[]');
+SELECT pg_input_error_info('{1,zed}', 'integer[]');
 
 -- test mixed slice/scalar subscripting
 select '{{1,2,3},{4,5,6},{7,8,9}}'::int[];
diff --git a/src/test/regress/sql/bit.sql b/src/test/regress/sql/bit.sql
index 8814249c2a..5765ee8672 100644
--- a/src/test/regress/sql/bit.sql
+++ b/src/test/regress/sql/bit.sql
@@ -232,13 +232,13 @@ TABLE bit_defaults;
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('01010001', 'bit(10)');
-SELECT pg_input_error_message('01010001', 'bit(10)');
+SELECT pg_input_error_info('01010001', 'bit(10)');
 SELECT pg_input_is_valid('01010Z01', 'bit(8)');
-SELECT pg_input_error_message('01010Z01', 'bit(8)');
+SELECT pg_input_error_info('01010Z01', 'bit(8)');
 SELECT pg_input_is_valid('x01010Z01', 'bit(32)');
-SELECT pg_input_error_message('x01010Z01', 'bit(32)');
+SELECT pg_input_error_info('x01010Z01', 'bit(32)');
 
 SELECT pg_input_is_valid('01010Z01', 'varbit');
-SELECT pg_input_error_message('01010Z01', 'varbit');
+SELECT pg_input_error_info('01010Z01', 'varbit');
 SELECT pg_input_is_valid('x01010Z01', 'varbit');
-SELECT pg_input_error_message('x01010Z01', 'varbit');
+SELECT pg_input_error_info('x01010Z01', 'varbit');
diff --git a/src/test/regress/sql/boolean.sql b/src/test/regress/sql/boolean.sql
index dfaa55dd0f..9126831dba 100644
--- a/src/test/regress/sql/boolean.sql
+++ b/src/test/regress/sql/boolean.sql
@@ -65,7 +65,7 @@ SELECT bool '' AS error;
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('true', 'bool');
 SELECT pg_input_is_valid('asdf', 'bool');
-SELECT pg_input_error_message('junk', 'bool');
+SELECT pg_input_error_info('junk', 'bool');
 
 -- and, or, not in qualifications
 
diff --git a/src/test/regress/sql/box.sql b/src/test/regress/sql/box.sql
index 02e100391b..cbf967f3ae 100644
--- a/src/test/regress/sql/box.sql
+++ b/src/test/regress/sql/box.sql
@@ -284,6 +284,6 @@ RESET enable_bitmapscan;
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('200', 'box');
-SELECT pg_input_error_message('200', 'box');
+SELECT pg_input_error_info('200', 'box');
 SELECT pg_input_is_valid('((200,300),(500, xyz))', 'box');
-SELECT pg_input_error_message('((200,300),(500, xyz))', 'box');
+SELECT pg_input_error_info('((200,300),(500, xyz))', 'box');
diff --git a/src/test/regress/sql/char.sql b/src/test/regress/sql/char.sql
index 8aa43b0fb8..f8e3304053 100644
--- a/src/test/regress/sql/char.sql
+++ b/src/test/regress/sql/char.sql
@@ -75,7 +75,7 @@ SELECT * FROM CHAR_TBL;
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('abcd  ', 'char(4)');
 SELECT pg_input_is_valid('abcde', 'char(4)');
-SELECT pg_input_error_message('abcde', 'char(4)');
+SELECT pg_input_error_info('abcde', 'char(4)');
 
 --
 -- Also test "char", which is an ad-hoc one-byte type.  It can only
diff --git a/src/test/regress/sql/date.sql b/src/test/regress/sql/date.sql
index 89982dd2f8..8ced2c9bc5 100644
--- a/src/test/regress/sql/date.sql
+++ b/src/test/regress/sql/date.sql
@@ -197,8 +197,8 @@ SELECT date '5874898-01-01';  -- out of range
 SELECT pg_input_is_valid('now', 'date');
 SELECT pg_input_is_valid('garbage', 'date');
 SELECT pg_input_is_valid('6874898-01-01', 'date');
-SELECT pg_input_error_message('garbage', 'date');
-SELECT pg_input_error_message('6874898-01-01', 'date');
+SELECT pg_input_error_info('garbage', 'date');
+SELECT pg_input_error_info('6874898-01-01', 'date');
 
 RESET datestyle;
 
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index 1558bd9a33..8ee0170369 100644
--- a/src/test/regress/sql/domain.sql
+++ b/src/test/regress/sql/domain.sql
@@ -77,12 +77,12 @@ create domain weirdfloat float8 check((1 / value) < 10);
 select pg_input_is_valid('1', 'positiveint');
 select pg_input_is_valid('junk', 'positiveint');
 select pg_input_is_valid('-1', 'positiveint');
-select pg_input_error_message('junk', 'positiveint');
-select pg_input_error_message('-1', 'positiveint');
-select pg_input_error_message('junk', 'weirdfloat');
-select pg_input_error_message('0.01', 'weirdfloat');
+select pg_input_error_info('junk', 'positiveint');
+select pg_input_error_info('-1', 'positiveint');
+select pg_input_error_info('junk', 'weirdfloat');
+select pg_input_error_info('0.01', 'weirdfloat');
 -- We currently can't trap errors raised in the CHECK expression itself
-select pg_input_error_message('0', 'weirdfloat');
+select pg_input_error_info('0', 'weirdfloat');
 
 drop domain positiveint;
 drop domain weirdfloat;
diff --git a/src/test/regress/sql/enum.sql b/src/test/regress/sql/enum.sql
index c87656589b..417fa6eddd 100644
--- a/src/test/regress/sql/enum.sql
+++ b/src/test/regress/sql/enum.sql
@@ -18,8 +18,8 @@ SELECT 'mauve'::rainbow;
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('red', 'rainbow');
 SELECT pg_input_is_valid('mauve', 'rainbow');
-SELECT pg_input_error_message('mauve', 'rainbow');
-SELECT pg_input_error_message(repeat('too_long', 32), 'rainbow');
+SELECT pg_input_error_info('mauve', 'rainbow');
+SELECT pg_input_error_info(repeat('too_long', 32), 'rainbow');
 
 --
 -- adding new values
diff --git a/src/test/regress/sql/float4.sql b/src/test/regress/sql/float4.sql
index 061477726b..4f344997e9 100644
--- a/src/test/regress/sql/float4.sql
+++ b/src/test/regress/sql/float4.sql
@@ -40,7 +40,7 @@ INSERT INTO FLOAT4_TBL(f1) VALUES ('123            5');
 SELECT pg_input_is_valid('34.5', 'float4');
 SELECT pg_input_is_valid('xyz', 'float4');
 SELECT pg_input_is_valid('1e400', 'float4');
-SELECT pg_input_error_message('1e400', 'float4');
+SELECT pg_input_error_info('1e400', 'float4');
 
 -- special inputs
 SELECT 'NaN'::float4;
diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql
index c276a5324c..d5fd409580 100644
--- a/src/test/regress/sql/float8.sql
+++ b/src/test/regress/sql/float8.sql
@@ -38,7 +38,7 @@ INSERT INTO FLOAT8_TBL(f1) VALUES ('123           5');
 SELECT pg_input_is_valid('34.5', 'float8');
 SELECT pg_input_is_valid('xyz', 'float8');
 SELECT pg_input_is_valid('1e4000', 'float8');
-SELECT pg_input_error_message('1e4000', 'float8');
+SELECT pg_input_error_info('1e4000', 'float8');
 
 -- special inputs
 SELECT 'NaN'::float8;
diff --git a/src/test/regress/sql/geometry.sql b/src/test/regress/sql/geometry.sql
index 309234b76c..70576ab7ff 100644
--- a/src/test/regress/sql/geometry.sql
+++ b/src/test/regress/sql/geometry.sql
@@ -526,6 +526,6 @@ SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('(1', 'circle');
-SELECT pg_input_error_message('1,', 'circle');
+SELECT pg_input_error_info('1,', 'circle');
 SELECT pg_input_is_valid('(1,2),-1', 'circle');
-SELECT pg_input_error_message('(1,2),-1', 'circle');
+SELECT pg_input_error_info('(1,2),-1', 'circle');
diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql
index abfcd4242f..ae3f19d285 100644
--- a/src/test/regress/sql/inet.sql
+++ b/src/test/regress/sql/inet.sql
@@ -255,9 +255,9 @@ SELECT a FROM (VALUES
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('1234', 'cidr');
-SELECT pg_input_error_message('1234', 'cidr');
+SELECT pg_input_error_info('1234', 'cidr');
 SELECT pg_input_is_valid('192.168.198.200/24', 'cidr');
-SELECT pg_input_error_message('192.168.198.200/24', 'cidr');
+SELECT pg_input_error_info('192.168.198.200/24', 'cidr');
 
 SELECT pg_input_is_valid('1234', 'inet');
-SELECT pg_input_error_message('1234', 'inet');
+SELECT pg_input_error_info('1234', 'inet');
diff --git a/src/test/regress/sql/int2.sql b/src/test/regress/sql/int2.sql
index ce8ac97963..7da875c402 100644
--- a/src/test/regress/sql/int2.sql
+++ b/src/test/regress/sql/int2.sql
@@ -21,12 +21,12 @@ SELECT * FROM INT2_TBL;
 SELECT pg_input_is_valid('34', 'int2');
 SELECT pg_input_is_valid('asdf', 'int2');
 SELECT pg_input_is_valid('50000', 'int2');
-SELECT pg_input_error_message('50000', 'int2');
+SELECT pg_input_error_info('50000', 'int2');
 
 -- While we're here, check int2vector as well
 SELECT pg_input_is_valid(' 1 3  5 ', 'int2vector');
-SELECT pg_input_error_message('1 asdf', 'int2vector');
-SELECT pg_input_error_message('50000', 'int2vector');
+SELECT pg_input_error_info('1 asdf', 'int2vector');
+SELECT pg_input_error_info('50000', 'int2vector');
 
 SELECT * FROM INT2_TBL AS f(a, b);
 
diff --git a/src/test/regress/sql/int4.sql b/src/test/regress/sql/int4.sql
index 146963edfb..659d1ab939 100644
--- a/src/test/regress/sql/int4.sql
+++ b/src/test/regress/sql/int4.sql
@@ -21,7 +21,7 @@ SELECT * FROM INT4_TBL;
 SELECT pg_input_is_valid('34', 'int4');
 SELECT pg_input_is_valid('asdf', 'int4');
 SELECT pg_input_is_valid('1000000000000', 'int4');
-SELECT pg_input_error_message('1000000000000', 'int4');
+SELECT pg_input_error_info('1000000000000', 'int4');
 
 SELECT i.* FROM INT4_TBL i WHERE i.f1 <> int2 '0';
 
diff --git a/src/test/regress/sql/int8.sql b/src/test/regress/sql/int8.sql
index c85717c072..14bc99bd5e 100644
--- a/src/test/regress/sql/int8.sql
+++ b/src/test/regress/sql/int8.sql
@@ -20,7 +20,7 @@ SELECT * FROM INT8_TBL;
 SELECT pg_input_is_valid('34', 'int8');
 SELECT pg_input_is_valid('asdf', 'int8');
 SELECT pg_input_is_valid('10000000000000000000', 'int8');
-SELECT pg_input_error_message('10000000000000000000', 'int8');
+SELECT pg_input_error_info('10000000000000000000', 'int8');
 
 -- int8/int8 cmp
 SELECT * FROM INT8_TBL WHERE q2 = 4567890123456789;
diff --git a/src/test/regress/sql/interval.sql b/src/test/regress/sql/interval.sql
index af8e1ca0f4..171bbbf653 100644
--- a/src/test/regress/sql/interval.sql
+++ b/src/test/regress/sql/interval.sql
@@ -36,8 +36,8 @@ INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 30 eons ago');
 SELECT pg_input_is_valid('1.5 weeks', 'interval');
 SELECT pg_input_is_valid('garbage', 'interval');
 SELECT pg_input_is_valid('@ 30 eons ago', 'interval');
-SELECT pg_input_error_message('garbage', 'interval');
-SELECT pg_input_error_message('@ 30 eons ago', 'interval');
+SELECT pg_input_error_info('garbage', 'interval');
+SELECT pg_input_error_info('@ 30 eons ago', 'interval');
 
 -- test interval operators
 
diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql
index 21534ed959..68e4c9af8f 100644
--- a/src/test/regress/sql/json.sql
+++ b/src/test/regress/sql/json.sql
@@ -84,7 +84,7 @@ SELECT '{
 -- test non-error-throwing input
 select pg_input_is_valid('{"a":true}', 'json');
 select pg_input_is_valid('{"a":true', 'json');
-select pg_input_error_message('{"a":true', 'json');
+select pg_input_error_info('{"a":true', 'json');
 
 --constructors
 -- array_to_json
diff --git a/src/test/regress/sql/json_encoding.sql b/src/test/regress/sql/json_encoding.sql
index f87b3bd4f3..e7d11fd25b 100644
--- a/src/test/regress/sql/json_encoding.sql
+++ b/src/test/regress/sql/json_encoding.sql
@@ -79,4 +79,4 @@ SELECT jsonb '{ "a":  "null \\u0000 escape" }' ->> 'a' as not_an_escape;
 
 -- soft error for input-time failure
 
-select pg_input_error_message('{ "a":  "\ud83d\ude04\ud83d\udc36" }', 'jsonb');
+select pg_input_error_info('{ "a":  "\ud83d\ude04\ud83d\udc36" }', 'jsonb');
diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql
index 9f67f4c71d..651e9408ec 100644
--- a/src/test/regress/sql/jsonb.sql
+++ b/src/test/regress/sql/jsonb.sql
@@ -89,8 +89,8 @@ SELECT '{
 -- test non-error-throwing input
 select pg_input_is_valid('{"a":true}', 'jsonb');
 select pg_input_is_valid('{"a":true', 'jsonb');
-select pg_input_error_message('{"a":true', 'jsonb');
-select pg_input_error_message('{"a":1e1000000}', 'jsonb');
+select pg_input_error_info('{"a":true', 'jsonb');
+select pg_input_error_info('{"a":1e1000000}', 'jsonb');
 
 -- make sure jsonb is passed through json generators without being escaped
 SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']);
diff --git a/src/test/regress/sql/jsonpath.sql b/src/test/regress/sql/jsonpath.sql
index 99d21d2af7..2fba9c1057 100644
--- a/src/test/regress/sql/jsonpath.sql
+++ b/src/test/regress/sql/jsonpath.sql
@@ -192,7 +192,7 @@ select '1?(2>3)'::jsonpath;
 
 SELECT str as jsonpath,
        pg_input_is_valid(str,'jsonpath') as ok,
-       pg_input_error_message(str,'jsonpath') as errmsg
+       pg_input_error_info(str,'jsonpath') as errmsg
 FROM unnest(ARRAY['$ ? (@ like_regex "pattern" flag "smixq")'::text,
                   '$ ? (@ like_regex "pattern" flag "a")',
                   '@ + 1',
diff --git a/src/test/regress/sql/line.sql b/src/test/regress/sql/line.sql
index f706a41184..42b37138e9 100644
--- a/src/test/regress/sql/line.sql
+++ b/src/test/regress/sql/line.sql
@@ -43,12 +43,12 @@ select '{nan, 1, nan}'::line = '{nan, 1, nan}'::line as true,
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('{1, 1}', 'line');
-SELECT pg_input_error_message('{1, 1}', 'line');
+SELECT pg_input_error_info('{1, 1}', 'line');
 SELECT pg_input_is_valid('{0, 0, 0}', 'line');
-SELECT pg_input_error_message('{0, 0, 0}', 'line');
+SELECT pg_input_error_info('{0, 0, 0}', 'line');
 SELECT pg_input_is_valid('{1, 1, a}', 'line');
-SELECT pg_input_error_message('{1, 1, a}', 'line');
+SELECT pg_input_error_info('{1, 1, a}', 'line');
 SELECT pg_input_is_valid('{1, 1, 1e400}', 'line');
-SELECT pg_input_error_message('{1, 1, 1e400}', 'line');
+SELECT pg_input_error_info('{1, 1, 1e400}', 'line');
 SELECT pg_input_is_valid('(1, 1), (1, 1e400)', 'line');
-SELECT pg_input_error_message('(1, 1), (1, 1e400)', 'line');
+SELECT pg_input_error_info('(1, 1), (1, 1e400)', 'line');
diff --git a/src/test/regress/sql/lseg.sql b/src/test/regress/sql/lseg.sql
index 0fece162e0..095a798017 100644
--- a/src/test/regress/sql/lseg.sql
+++ b/src/test/regress/sql/lseg.sql
@@ -25,4 +25,4 @@ select * from LSEG_TBL;
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('[(1,2),(3)]', 'lseg');
-SELECT pg_input_error_message('[(1,2),(3)]', 'lseg');
+SELECT pg_input_error_info('[(1,2),(3)]', 'lseg');
diff --git a/src/test/regress/sql/macaddr.sql b/src/test/regress/sql/macaddr.sql
index 211397c8f3..56a24cd88f 100644
--- a/src/test/regress/sql/macaddr.sql
+++ b/src/test/regress/sql/macaddr.sql
@@ -44,6 +44,6 @@ DROP TABLE macaddr_data;
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('08:00:2b:01:02:ZZ', 'macaddr');
-SELECT pg_input_error_message('08:00:2b:01:02:ZZ', 'macaddr');
+SELECT pg_input_error_info('08:00:2b:01:02:ZZ', 'macaddr');
 SELECT pg_input_is_valid('08:00:2b:01:02:', 'macaddr');
-SELECT pg_input_error_message('08:00:2b:01:02:', 'macaddr');
+SELECT pg_input_error_info('08:00:2b:01:02:', 'macaddr');
diff --git a/src/test/regress/sql/macaddr8.sql b/src/test/regress/sql/macaddr8.sql
index b29f785b41..a796034cc5 100644
--- a/src/test/regress/sql/macaddr8.sql
+++ b/src/test/regress/sql/macaddr8.sql
@@ -90,6 +90,6 @@ DROP TABLE macaddr8_data;
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
-SELECT pg_input_error_message('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
+SELECT pg_input_error_info('08:00:2b:01:02:03:04:ZZ', 'macaddr8');
 SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8');
-SELECT pg_input_error_message('08:00:2b:01:02:03:04:', 'macaddr8');
+SELECT pg_input_error_info('08:00:2b:01:02:03:04:', 'macaddr8');
diff --git a/src/test/regress/sql/money.sql b/src/test/regress/sql/money.sql
index cd9a089e01..073aa0a38b 100644
--- a/src/test/regress/sql/money.sql
+++ b/src/test/regress/sql/money.sql
@@ -90,9 +90,9 @@ SELECT '($123,456.78)'::money;
 
 -- test non-error-throwing API
 SELECT pg_input_is_valid('\x0001', 'money');
-SELECT pg_input_error_message('\x0001', 'money');
+SELECT pg_input_error_info('\x0001', 'money');
 SELECT pg_input_is_valid('192233720368547758.07', 'money');
-SELECT pg_input_error_message('192233720368547758.07', 'money');
+SELECT pg_input_error_info('192233720368547758.07', 'money');
 
 -- documented minimums and maximums
 SELECT '-92233720368547758.08'::money;
diff --git a/src/test/regress/sql/multirangetypes.sql b/src/test/regress/sql/multirangetypes.sql
index fc369a550c..724af7f8d3 100644
--- a/src/test/regress/sql/multirangetypes.sql
+++ b/src/test/regress/sql/multirangetypes.sql
@@ -61,9 +61,9 @@ select '{(a,a)}'::textmultirange;
 -- Also try it with non-error-throwing API
 select pg_input_is_valid('{[1,2], [4,5]}', 'int4multirange');
 select pg_input_is_valid('{[1,2], [4,5]', 'int4multirange');
-select pg_input_error_message('{[1,2], [4,5]', 'int4multirange');
+select pg_input_error_info('{[1,2], [4,5]', 'int4multirange');
 select pg_input_is_valid('{[1,2], [4,zed]}', 'int4multirange');
-select pg_input_error_message('{[1,2], [4,zed]}', 'int4multirange');
+select pg_input_error_info('{[1,2], [4,zed]}', 'int4multirange');
 
 --
 -- test the constructor
diff --git a/src/test/regress/sql/numeric.sql b/src/test/regress/sql/numeric.sql
index 2db7656e84..4abc47a363 100644
--- a/src/test/regress/sql/numeric.sql
+++ b/src/test/regress/sql/numeric.sql
@@ -1086,11 +1086,11 @@ SELECT * FROM num_input_test;
 SELECT pg_input_is_valid('34.5', 'numeric');
 SELECT pg_input_is_valid('34xyz', 'numeric');
 SELECT pg_input_is_valid('1e400000', 'numeric');
-SELECT pg_input_error_message('1e400000', 'numeric');
+SELECT pg_input_error_info('1e400000', 'numeric');
 SELECT pg_input_is_valid('1234.567', 'numeric(8,4)');
 SELECT pg_input_is_valid('1234.567', 'numeric(7,4)');
-SELECT pg_input_error_message('1234.567', 'numeric(7,4)');
-SELECT pg_input_error_message('0x1234.567', 'numeric');
+SELECT pg_input_error_info('1234.567', 'numeric(7,4)');
+SELECT pg_input_error_info('0x1234.567', 'numeric');
 
 --
 -- Test precision and scale typemods
diff --git a/src/test/regress/sql/oid.sql b/src/test/regress/sql/oid.sql
index 39937c2f1d..e2bc32a8b6 100644
--- a/src/test/regress/sql/oid.sql
+++ b/src/test/regress/sql/oid.sql
@@ -31,16 +31,16 @@ SELECT * FROM OID_TBL;
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('1234', 'oid');
 SELECT pg_input_is_valid('01XYZ', 'oid');
-SELECT pg_input_error_message('01XYZ', 'oid');
+SELECT pg_input_error_info('01XYZ', 'oid');
 SELECT pg_input_is_valid('9999999999', 'oid');
-SELECT pg_input_error_message('9999999999', 'oid');
+SELECT pg_input_error_info('9999999999', 'oid');
 
 -- While we're here, check oidvector as well
 SELECT pg_input_is_valid(' 1 2  4 ', 'oidvector');
 SELECT pg_input_is_valid('01 01XYZ', 'oidvector');
-SELECT pg_input_error_message('01 01XYZ', 'oidvector');
+SELECT pg_input_error_info('01 01XYZ', 'oidvector');
 SELECT pg_input_is_valid('01 9999999999', 'oidvector');
-SELECT pg_input_error_message('01 9999999999', 'oidvector');
+SELECT pg_input_error_info('01 9999999999', 'oidvector');
 
 SELECT o.* FROM OID_TBL o WHERE o.f1 = 1234;
 
diff --git a/src/test/regress/sql/path.sql b/src/test/regress/sql/path.sql
index 42c90afe53..3dad134bbb 100644
--- a/src/test/regress/sql/path.sql
+++ b/src/test/regress/sql/path.sql
@@ -45,6 +45,6 @@ SELECT popen(f1) AS open_path FROM PATH_TBL;
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('[(1,2),(3)]', 'path');
-SELECT pg_input_error_message('[(1,2),(3)]', 'path');
+SELECT pg_input_error_info('[(1,2),(3)]', 'path');
 SELECT pg_input_is_valid('[(1,2,6),(3,4,6)]', 'path');
-SELECT pg_input_error_message('[(1,2,6),(3,4,6)]', 'path');
+SELECT pg_input_error_info('[(1,2,6),(3,4,6)]', 'path');
diff --git a/src/test/regress/sql/pg_lsn.sql b/src/test/regress/sql/pg_lsn.sql
index 3d57d66e0c..7ba54b9c1b 100644
--- a/src/test/regress/sql/pg_lsn.sql
+++ b/src/test/regress/sql/pg_lsn.sql
@@ -17,7 +17,7 @@ INSERT INTO PG_LSN_TBL VALUES ('/ABCD');
 
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('16AE7F7', 'pg_lsn');
-SELECT pg_input_error_message('16AE7F7', 'pg_lsn');
+SELECT pg_input_error_info('16AE7F7', 'pg_lsn');
 
 -- Min/Max aggregation
 SELECT MIN(f1), MAX(f1) FROM PG_LSN_TBL;
diff --git a/src/test/regress/sql/point.sql b/src/test/regress/sql/point.sql
index 7bd1ebe2b5..49c2e85de5 100644
--- a/src/test/regress/sql/point.sql
+++ b/src/test/regress/sql/point.sql
@@ -99,4 +99,4 @@ RESET enable_bitmapscan;
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('1,y', 'point');
-SELECT pg_input_error_message('1,y', 'point');
+SELECT pg_input_error_info('1,y', 'point');
diff --git a/src/test/regress/sql/polygon.sql b/src/test/regress/sql/polygon.sql
index da644e34e3..2ca1a5ac2b 100644
--- a/src/test/regress/sql/polygon.sql
+++ b/src/test/regress/sql/polygon.sql
@@ -143,6 +143,6 @@ RESET enable_bitmapscan;
 
 -- test non-error-throwing API for some core types
 SELECT pg_input_is_valid('(2.0,0.8,0.1)', 'polygon');
-SELECT pg_input_error_message('(2.0,0.8,0.1)', 'polygon');
+SELECT pg_input_error_info('(2.0,0.8,0.1)', 'polygon');
 SELECT pg_input_is_valid('(2.0,xyz)', 'polygon');
-SELECT pg_input_error_message('(2.0,xyz)', 'polygon');
+SELECT pg_input_error_info('(2.0,xyz)', 'polygon');
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 0bcea77ff4..5db53b97ca 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -1433,11 +1433,11 @@ SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
 -- Test non-throwing aclitem I/O
 SELECT pg_input_is_valid('regress_priv_user1=r/regress_priv_user2', 'aclitem');
 SELECT pg_input_is_valid('regress_priv_user1=r/', 'aclitem');
-SELECT pg_input_error_message('regress_priv_user1=r/', 'aclitem');
+SELECT pg_input_error_info('regress_priv_user1=r/', 'aclitem');
 SELECT pg_input_is_valid('regress_priv_user1=r/regress_no_such_user', 'aclitem');
-SELECT pg_input_error_message('regress_priv_user1=r/regress_no_such_user', 'aclitem');
+SELECT pg_input_error_info('regress_priv_user1=r/regress_no_such_user', 'aclitem');
 SELECT pg_input_is_valid('regress_priv_user1=rY', 'aclitem');
-SELECT pg_input_error_message('regress_priv_user1=rY', 'aclitem');
+SELECT pg_input_error_info('regress_priv_user1=rY', 'aclitem');
 
 --
 -- Testing blanket default grants is very hazardous since it might change
diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql
index 4e6a0912de..4729a1c2d4 100644
--- a/src/test/regress/sql/rangetypes.sql
+++ b/src/test/regress/sql/rangetypes.sql
@@ -43,15 +43,15 @@ select '(a,a)'::textrange;
 -- Also try it with non-error-throwing API
 select pg_input_is_valid('(1,4)', 'int4range');
 select pg_input_is_valid('(1,4', 'int4range');
-select pg_input_error_message('(1,4', 'int4range');
+select pg_input_error_info('(1,4', 'int4range');
 select pg_input_is_valid('(4,1)', 'int4range');
-select pg_input_error_message('(4,1)', 'int4range');
+select pg_input_error_info('(4,1)', 'int4range');
 select pg_input_is_valid('(4,zed)', 'int4range');
-select pg_input_error_message('(4,zed)', 'int4range');
+select pg_input_error_info('(4,zed)', 'int4range');
 select pg_input_is_valid('[1,2147483647]', 'int4range');
-select pg_input_error_message('[1,2147483647]', 'int4range');
+select pg_input_error_info('[1,2147483647]', 'int4range');
 select pg_input_is_valid('[2000-01-01,5874897-12-31]', 'daterange');
-select pg_input_error_message('[2000-01-01,5874897-12-31]', 'daterange');
+select pg_input_error_info('[2000-01-01,5874897-12-31]', 'daterange');
 
 --
 -- create some test data and test the operators
diff --git a/src/test/regress/sql/regproc.sql b/src/test/regress/sql/regproc.sql
index 2cb8c9a253..e8c7394c5c 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -125,23 +125,23 @@ SELECT to_regnamespace('foo.bar');
 
 -- Test soft-error API
 
-SELECT pg_input_error_message('ng_catalog.pg_class', 'regclass');
+SELECT pg_input_error_info('ng_catalog.pg_class', 'regclass');
 SELECT pg_input_is_valid('ng_catalog."POSIX"', 'regcollation');
-SELECT pg_input_error_message('no_such_config', 'regconfig');
-SELECT pg_input_error_message('no_such_dictionary', 'regdictionary');
-SELECT pg_input_error_message('Nonexistent', 'regnamespace');
-SELECT pg_input_error_message('ng_catalog.||/', 'regoper');
-SELECT pg_input_error_message('-', 'regoper');
-SELECT pg_input_error_message('ng_catalog.+(int4,int4)', 'regoperator');
-SELECT pg_input_error_message('-', 'regoperator');
-SELECT pg_input_error_message('ng_catalog.now', 'regproc');
-SELECT pg_input_error_message('ng_catalog.abs(numeric)', 'regprocedure');
-SELECT pg_input_error_message('ng_catalog.abs(numeric', 'regprocedure');
-SELECT pg_input_error_message('regress_regrole_test', 'regrole');
-SELECT pg_input_error_message('no_such_type', 'regtype');
+SELECT pg_input_error_info('no_such_config', 'regconfig');
+SELECT pg_input_error_info('no_such_dictionary', 'regdictionary');
+SELECT pg_input_error_info('Nonexistent', 'regnamespace');
+SELECT pg_input_error_info('ng_catalog.||/', 'regoper');
+SELECT pg_input_error_info('-', 'regoper');
+SELECT pg_input_error_info('ng_catalog.+(int4,int4)', 'regoperator');
+SELECT pg_input_error_info('-', 'regoperator');
+SELECT pg_input_error_info('ng_catalog.now', 'regproc');
+SELECT pg_input_error_info('ng_catalog.abs(numeric)', 'regprocedure');
+SELECT pg_input_error_info('ng_catalog.abs(numeric', 'regprocedure');
+SELECT pg_input_error_info('regress_regrole_test', 'regrole');
+SELECT pg_input_error_info('no_such_type', 'regtype');
 
 -- Some cases that should be soft errors, but are not yet
-SELECT pg_input_error_message('incorrect type name syntax', 'regtype');
-SELECT pg_input_error_message('numeric(1,2,3)', 'regtype');  -- bogus typmod
-SELECT pg_input_error_message('way.too.many.names', 'regtype');
-SELECT pg_input_error_message('no_such_catalog.schema.name', 'regtype');
+SELECT pg_input_error_info('incorrect type name syntax', 'regtype');
+SELECT pg_input_error_info('numeric(1,2,3)', 'regtype');  -- bogus typmod
+SELECT pg_input_error_info('way.too.many.names', 'regtype');
+SELECT pg_input_error_info('no_such_catalog.schema.name', 'regtype');
diff --git a/src/test/regress/sql/rowtypes.sql b/src/test/regress/sql/rowtypes.sql
index 0844e7488d..951f0e60e2 100644
--- a/src/test/regress/sql/rowtypes.sql
+++ b/src/test/regress/sql/rowtypes.sql
@@ -35,8 +35,8 @@ select '(Joe,Blow) /'::fullname;  -- bad
 SELECT pg_input_is_valid('(1,2)', 'complex');
 SELECT pg_input_is_valid('(1,2', 'complex');
 SELECT pg_input_is_valid('(1,zed)', 'complex');
-SELECT pg_input_error_message('(1,zed)', 'complex');
-SELECT pg_input_error_message('(1,1e400)', 'complex');
+SELECT pg_input_error_info('(1,zed)', 'complex');
+SELECT pg_input_error_info('(1,1e400)', 'complex');
 
 create temp table quadtable(f1 int, q quad);
 
diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql
index 932f71cbca..7d774315c6 100644
--- a/src/test/regress/sql/strings.sql
+++ b/src/test/regress/sql/strings.sql
@@ -87,9 +87,9 @@ SELECT E'De\\123dBeEf'::bytea;
 
 -- Test non-error-throwing API too
 SELECT pg_input_is_valid(E'\\xDeAdBeE', 'bytea');
-SELECT pg_input_error_message(E'\\xDeAdBeE', 'bytea');
-SELECT pg_input_error_message(E'\\xDeAdBeEx', 'bytea');
-SELECT pg_input_error_message(E'foo\\99bar', 'bytea');
+SELECT pg_input_error_info(E'\\xDeAdBeE', 'bytea');
+SELECT pg_input_error_info(E'\\xDeAdBeEx', 'bytea');
+SELECT pg_input_error_info(E'foo\\99bar', 'bytea');
 
 --
 -- test conversions between various string types
diff --git a/src/test/regress/sql/tid.sql b/src/test/regress/sql/tid.sql
index 8196194c04..2d2dcb05c1 100644
--- a/src/test/regress/sql/tid.sql
+++ b/src/test/regress/sql/tid.sql
@@ -11,9 +11,9 @@ SELECT '(1,65536)'::tid;  -- error
 
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('(0)', 'tid');
-SELECT pg_input_error_message('(0)', 'tid');
+SELECT pg_input_error_info('(0)', 'tid');
 SELECT pg_input_is_valid('(0,-1)', 'tid');
-SELECT pg_input_error_message('(0,-1)', 'tid');
+SELECT pg_input_error_info('(0,-1)', 'tid');
 
 
 -- tests for functions related to TID handling
diff --git a/src/test/regress/sql/time.sql b/src/test/regress/sql/time.sql
index b439cd6b41..a40e725eab 100644
--- a/src/test/regress/sql/time.sql
+++ b/src/test/regress/sql/time.sql
@@ -44,8 +44,8 @@ SELECT '25:00:00'::time;  -- not allowed
 SELECT pg_input_is_valid('12:00:00', 'time');
 SELECT pg_input_is_valid('25:00:00', 'time');
 SELECT pg_input_is_valid('15:36:39 America/New_York', 'time');
-SELECT pg_input_error_message('25:00:00', 'time');
-SELECT pg_input_error_message('15:36:39 America/New_York', 'time');
+SELECT pg_input_error_info('25:00:00', 'time');
+SELECT pg_input_error_info('15:36:39 America/New_York', 'time');
 
 --
 -- TIME simple math
diff --git a/src/test/regress/sql/timestamp.sql b/src/test/regress/sql/timestamp.sql
index 2d5f01ab86..ca4c44130a 100644
--- a/src/test/regress/sql/timestamp.sql
+++ b/src/test/regress/sql/timestamp.sql
@@ -100,8 +100,8 @@ INSERT INTO TIMESTAMP_TBL VALUES ('19970710 173201 America/Does_not_exist');
 SELECT pg_input_is_valid('now', 'timestamp');
 SELECT pg_input_is_valid('garbage', 'timestamp');
 SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp');
-SELECT pg_input_error_message('garbage', 'timestamp');
-SELECT pg_input_error_message('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp');
+SELECT pg_input_error_info('garbage', 'timestamp');
+SELECT pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp');
 
 -- Check date conversion and date arithmetic
 INSERT INTO TIMESTAMP_TBL VALUES ('1997-06-10 18:32:01 PDT');
diff --git a/src/test/regress/sql/timestamptz.sql b/src/test/regress/sql/timestamptz.sql
index 6d10937d86..96cd82fa08 100644
--- a/src/test/regress/sql/timestamptz.sql
+++ b/src/test/regress/sql/timestamptz.sql
@@ -113,8 +113,8 @@ SELECT '205000-01-10 17:32:01 Europe/Helsinki'::timestamptz; -- non-DST
 SELECT pg_input_is_valid('now', 'timestamptz');
 SELECT pg_input_is_valid('garbage', 'timestamptz');
 SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz');
-SELECT pg_input_error_message('garbage', 'timestamptz');
-SELECT pg_input_error_message('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz');
+SELECT pg_input_error_info('garbage', 'timestamptz');
+SELECT pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz');
 
 -- Check date conversion and date arithmetic
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-06-10 18:32:01 PDT');
diff --git a/src/test/regress/sql/timetz.sql b/src/test/regress/sql/timetz.sql
index b62aa3fe05..857408b88b 100644
--- a/src/test/regress/sql/timetz.sql
+++ b/src/test/regress/sql/timetz.sql
@@ -49,8 +49,8 @@ SELECT '25:00:00 PDT'::timetz;  -- not allowed
 SELECT pg_input_is_valid('12:00:00 PDT', 'timetz');
 SELECT pg_input_is_valid('25:00:00 PDT', 'timetz');
 SELECT pg_input_is_valid('15:36:39 America/New_York', 'timetz');
-SELECT pg_input_error_message('25:00:00 PDT', 'timetz');
-SELECT pg_input_error_message('15:36:39 America/New_York', 'timetz');
+SELECT pg_input_error_info('25:00:00 PDT', 'timetz');
+SELECT pg_input_error_info('15:36:39 America/New_York', 'timetz');
 
 --
 -- TIME simple math
diff --git a/src/test/regress/sql/tstypes.sql b/src/test/regress/sql/tstypes.sql
index b73dd1cb07..9343266fd5 100644
--- a/src/test/regress/sql/tstypes.sql
+++ b/src/test/regress/sql/tstypes.sql
@@ -22,7 +22,7 @@ SELECT $$'' '1' '2'$$::tsvector;  -- error, empty lexeme is not allowed
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('foo', 'tsvector');
 SELECT pg_input_is_valid($$''$$, 'tsvector');
-SELECT pg_input_error_message($$''$$, 'tsvector');
+SELECT pg_input_error_info($$''$$, 'tsvector');
 
 --Base tsquery test
 SELECT '1'::tsquery;
@@ -76,8 +76,8 @@ SELECT '!!a & !!b'::tsquery;
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('foo', 'tsquery');
 SELECT pg_input_is_valid('foo!', 'tsquery');
-SELECT pg_input_error_message('foo!', 'tsquery');
-SELECT pg_input_error_message('a <100000> b', 'tsquery');
+SELECT pg_input_error_info('foo!', 'tsquery');
+SELECT pg_input_error_info('a <100000> b', 'tsquery');
 
 --comparisons
 SELECT 'a' < 'b & c'::tsquery as "true";
diff --git a/src/test/regress/sql/uuid.sql b/src/test/regress/sql/uuid.sql
index 37d954eda1..076cf1b21e 100644
--- a/src/test/regress/sql/uuid.sql
+++ b/src/test/regress/sql/uuid.sql
@@ -25,7 +25,7 @@ INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111');
 
 -- test non-error-throwing API
 SELECT pg_input_is_valid('11', 'uuid');
-SELECT pg_input_error_message('11', 'uuid');
+SELECT pg_input_error_info('11', 'uuid');
 
 --inserting three input formats
 INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
diff --git a/src/test/regress/sql/varchar.sql b/src/test/regress/sql/varchar.sql
index df16da37a7..32dbee58b1 100644
--- a/src/test/regress/sql/varchar.sql
+++ b/src/test/regress/sql/varchar.sql
@@ -70,4 +70,4 @@ SELECT * FROM VARCHAR_TBL;
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('abcd  ', 'varchar(4)');
 SELECT pg_input_is_valid('abcde', 'varchar(4)');
-SELECT pg_input_error_message('abcde', 'varchar(4)');
+SELECT pg_input_error_info('abcde', 'varchar(4)');
diff --git a/src/test/regress/sql/xid.sql b/src/test/regress/sql/xid.sql
index b6996588ef..3e5e880473 100644
--- a/src/test/regress/sql/xid.sql
+++ b/src/test/regress/sql/xid.sql
@@ -19,10 +19,10 @@ select 'asdf'::xid8;
 -- Also try it with non-error-throwing API
 SELECT pg_input_is_valid('42', 'xid');
 SELECT pg_input_is_valid('asdf', 'xid');
-SELECT pg_input_error_message('0xffffffffff', 'xid');
+SELECT pg_input_error_info('0xffffffffff', 'xid');
 SELECT pg_input_is_valid('42', 'xid8');
 SELECT pg_input_is_valid('asdf', 'xid8');
-SELECT pg_input_error_message('0xffffffffffffffffffff', 'xid8');
+SELECT pg_input_error_info('0xffffffffffffffffffff', 'xid8');
 
 -- equality
 select '1'::xid = '1'::xid;
@@ -79,9 +79,9 @@ select '12:16:14,13'::pg_snapshot;
 -- also try it with non-error-throwing API
 select pg_input_is_valid('12:13:', 'pg_snapshot');
 select pg_input_is_valid('31:12:', 'pg_snapshot');
-select pg_input_error_message('31:12:', 'pg_snapshot');
+select pg_input_error_info('31:12:', 'pg_snapshot');
 select pg_input_is_valid('12:16:14,13', 'pg_snapshot');
-select pg_input_error_message('12:16:14,13', 'pg_snapshot');
+select pg_input_error_info('12:16:14,13', 'pg_snapshot');
 
 create temp table snapshot_test (
 	nr	integer,
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index ddff459297..24e40d2653 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -12,9 +12,9 @@ SELECT * FROM xmltest;
 -- test non-throwing API, too
 SELECT pg_input_is_valid('<value>one</value>', 'xml');
 SELECT pg_input_is_valid('<value>one</', 'xml');
-SELECT pg_input_error_message('<value>one</', 'xml');
+SELECT message FROM pg_input_error_info('<value>one</', 'xml');
 SELECT pg_input_is_valid('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
-SELECT pg_input_error_message('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
+SELECT message FROM pg_input_error_info('<?xml version="1.0" standalone="y"?><foo/>', 'xml');
 
 
 SELECT xmlcomment('test');
-- 
2.25.1

