It's possible to retrieve the desirable standard SQLSTATE errcode, but there's a trick: the query has to be sent through the asynchronous pg_send_query() instead of the synchronous pg_query(). This is because pg_query() returns false on error instead of the resource that is required to peek at the error details.
When pg_get_result() is called after pg_send_query, it will block anyway until the query is done, so it does not really complicate things compared to the synchronous case.
And it returns a result which can be fully exploited for precise error handling.
Example:
if (pg_send_query($db, $query)) {
$res=pg_get_result($db);
if ($res) {
$state = pg_result_error_field($res, PGSQL_DIAG_SQLSTATE);
if ($state==0) {
// success
}
else {
// some error happened
if ($state=="23505") { // unique_violation
// process specific error
}
else {
// process other errors
}
}
}
}
Also, if the argument passed to pg_query might contain several SQL statements (separated by semicolons), the above example should be extended to retrieve all results in a loop, as mentioned in the comment by @user1760150. Compared to pg_query which returns only the last result, pg_get_result in a loop gives access to the results of each statement of the combined query.