Prevent FATAL error when non-existing prepared statement is given.
authorTatsuo Ishii <ishii@postgresql.org>
Fri, 3 Oct 2025 01:18:45 +0000 (10:18 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Fri, 3 Oct 2025 01:28:56 +0000 (10:28 +0900)
Previously Bind() raised FATAL error if non-existing prepared statement was given.
This is different from PostgreSQL's behavior.

\bind_named stmt2 'baz' \g
ERROR:  prepared statement "stmt2" does not exist

This commit let Bind() check the existence of prepared statement and
if it does not exist, send an ERROR message to frontend. Note that no
log is left in the log file. This is not preferred action but currently
it's not possible to leave log.

Backpatch-through: v4.2

src/protocol/pool_proto_modules.c

index 393292487231682b80216af4e435f46de3bfe92b..484c1516b2017a19091043ee4c2a59c506afc13a 100644 (file)
@@ -1660,9 +1660,26 @@ Bind(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend,
                parse_msg = pool_get_sent_message('P', pstmt_name, POOL_SENT_MESSAGE_CREATED);
        if (!parse_msg)
        {
-               ereport(FATAL,
-                               (errmsg("unable to bind"),
-                                errdetail("cannot get parse message \"%s\"", pstmt_name)));
+               char       *errmessage;
+
+               /* send error message to frontend */
+               errmessage = psprintf("prepared statement \"%s\" does not exist",
+                                                         pstmt_name);
+               pool_send_error_message(frontend, MAJOR(cp), "XX000", errmessage,
+                                                               "", "", __FILE__, __LINE__);
+               pfree(errmessage);
+
+               /*
+                * Since we do not receive an error response from backend, we need
+                * similar treatement in case of error response.
+                */
+               pool_set_ignore_till_sync();
+               pool_unset_query_in_progress();
+               pool_unset_suspend_reading_from_frontend();
+               if (SL_MODE)
+                       pool_discard_except_sync_and_ready_for_query(frontend, backend);
+
+               return POOL_CONTINUE;
        }
 
        bind_msg = pool_create_sent_message('B', len, contents,