Understanding PostgreSQL’s pg_input_error_info() Function

PostgreSQL has a pg_input_error_info() function that allows us to see the error details that would be returned if we were to pass an invalid value for the specified data type.

Basically it tests whether the given string is valid input for the specified data type. If invalid, it returns the details of the error that would have been thrown. If valid, the result is null.

The pg_input_error_info() function was introduced in PostgreSQL 16, which was released on September 14th 2023. The function was initially started as pg_input_error_message(), as the initial intention was to return just the error message. But it was later decided that it should return more information, such as the sql error code, error detail (if set), and hint (if set) and so it was renamed to pg_input_error_info() to reflect this.

Syntax

The syntax goes like this:

pg_input_error_info ( string text, type text ) 

The function returns its results as a record:

record ( message text, detail text, hint text, sql_error_code text )

Example

Here’s an example to demonstrate:

SELECT * FROM pg_input_error_info('1.5', 'integer');

Result:

                   message                    | detail | hint | sql_error_code 
----------------------------------------------+--------+------+----------------
invalid input syntax for type integer: "1.5" | null | null | 22P02

Here, my first argument was 1.5, and that was validated against my second argument (integer). An integer can’t have a decimal point and so this would result in an error. The pg_input_error_info() function kindly provided information about the error that I would get if I were to try to provide that value as input to an integer.

Here are some more examples:

SELECT * FROM pg_input_error_info('dog', 'integer')
UNION ALL
SELECT * FROM pg_input_error_info('{5}', 'smallint')
UNION ALL
SELECT * FROM pg_input_error_info('7', 'integer[]')
UNION ALL
SELECT * FROM pg_input_error_info('3', 'boolean');

Result:

                    message                    |                          detail                           | hint | sql_error_code 
-----------------------------------------------+-----------------------------------------------------------+------+----------------
invalid input syntax for type integer: "dog" | null | null | 22P02
invalid input syntax for type smallint: "{5}" | null | null | 22P02
malformed array literal: "7" | Array value must start with "{" or dimension information. | null | 22P02
invalid input syntax for type boolean: "3" | null | null | 22P02

No Error

If the input value wouldn’t result in an error, then null is returned in all columns:

SELECT * FROM pg_input_error_info('7', 'integer');

Result:

 message | detail | hint | sql_error_code 
---------+--------+------+----------------
null | null | null | null

Selecting Just the Error Message or Code

We can select any of the columns returned by pg_input_error_info() simply by naming the desired column in our SELECT list:

SELECT message FROM pg_input_error_info('dog', 'integer');

Result:

                   message                    
----------------------------------------------
invalid input syntax for type integer: "dog"

And here’s the error code:

SELECT sql_error_code FROM pg_input_error_info('dog', 'integer');

Result:

 sql_error_code 
----------------
22P02

Returning the Raw Record

If we select the function without specifying the columns, we get the record as is (without it being separated into columns):

SELECT pg_input_error_info('dog', 'integer');

Result:

                    pg_input_error_info                     
------------------------------------------------------------
("invalid input syntax for type integer: ""dog""",,,22P02)

Passing the Wrong Argument Type

Passing an argument of the wrong type results in an actual error:

SELECT * FROM pg_input_error_info(7, 'integer');

Result:

ERROR:  function pg_input_error_info(integer, unknown) does not exist
LINE 1: SELECT * FROM pg_input_error_info(7, 'integer');
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Validating the Input

PostgreSQL also has a pg_input_is_valid() function that simply checks whether or not the value is valid against the data type, returning a boolean value of either true or false.