As the development of PostgreSQL moves on, more and more new features get committed. A recently commit patch added two new functions, which can be used to validate if a cast will work and what error message would be returned if the cast fails.

Before looking at the new functions in PostgreSQL 16, lets have a look at what happens in version before 16 if a cast fails:

postgres=# select 'aaaa'::int;
ERROR:  invalid input syntax for type integer: "aaaa"
LINE 1: select 'aaaa'::int;

Not really a surprise, this fails. The downside with this is, that it will also abort the transaction it is failing in:

postgres=# begin;
BEGIN
postgres=*# select 1;
 ?column? 
----------
        1
(1 row)

postgres=*# select 'aaaa'::int;
ERROR:  invalid input syntax for type integer: "aaaa"
LINE 1: select 'aaaa'::int;
               ^
postgres=!# select 1;
ERROR:  current transaction is aborted, commands ignored until end of transaction block
postgres=!# end;
ROLLBACK
postgres=# 

With PostgreSQL 16 this can be done more convenient. The first new function is called pg_input_is_valid and can be used to test if a cast will succeed or fail:

postgres=# select pg_input_is_valid('aaa','text');
 pg_input_is_valid 
-------------------
 t
(1 row)

postgres=# select pg_input_is_valid('aaa','int');
 pg_input_is_valid 
-------------------
 f
(1 row)

This gives you more control if you are in a transaction, as you now can test before you actually execute the cast:

postgres=# begin;
BEGIN
postgres=*# select 1;
 ?column? 
----------
        1
(1 row)

postgres=*# select pg_input_is_valid('aaa','int');
 pg_input_is_valid 
-------------------
 f
(1 row)

postgres=*# select pg_input_is_valid('aaa','text');
 pg_input_is_valid 
-------------------
 t
(1 row)

postgres=*# end;
COMMIT

The second new function is called pg_input_error_message and will give you the error message you would get, if a cast fails:

postgres=# select pg_input_error_message('aaaa','int');
            pg_input_error_message             
-----------------------------------------------
 invalid input syntax for type integer: "aaaa"
(1 row)

postgres=# select pg_input_error_message('22.22','int');
             pg_input_error_message             
------------------------------------------------
 invalid input syntax for type integer: "22.22"
(1 row)

postgres=# 

Nice.