pgpool2.git / summary / log / commit / refs

commit    3462d5e6ee12ca5fc58d446ecd62b54ac112e55e
Author:   Taiki Koshino <koshino@sraoss.co.jp>
Date:     Wed Oct 21 02:00:32 2026 +0000

    Fix extended-protocol DISCARD ALL and statement reuse after DISCARD PLANS.
    
    DISCARD ALL cleared the sent message list before CommandComplete()
    finished using the current query context, causing a "no query context"
    error and closing the frontend connection. Defer cleanup until the
    context is no longer needed.
    
    DISCARD PLANS also removed saved Query and Parse messages, although
    PostgreSQL preserves prepared statements. Keep these records so that
    subsequent Bind messages can reuse the statements without another Parse.
    
    Author: Taiki Koshino(koshino@sraoss.co.jp)
    Discussion: https://github.com/pgpool/pgpool2/issues/175
    Backpatch-through: v4.3


src/protocol/CommandComplete.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/protocol/CommandComplete.c b/src/protocol/CommandComplete.c index 5578bb10b..719a5594e 100644 --- a/src/protocol/CommandComplete.c +++ b/src/protocol/CommandComplete.c @@ -59,6 +59,7 @@ CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, bool c int i; POOL_SESSION_CONTEXT *session_context; POOL_CONNECTION *con; + bool discard_all = false; p1 = NULL; len1 = 0; @@ -66,6 +67,13 @@ CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, bool c /* Get session context */ session_context = pool_get_session_context(false); + /* Check if the current query contains DISCARD ALL. */ + if (session_context->query_context && + session_context->query_context->parse_tree && + IsA(session_context->query_context->parse_tree, DiscardStmt) && + ((DiscardStmt *) session_context->query_context->parse_tree)->target == DISCARD_ALL) + discard_all = true; + /* * Handle misc process which is necessary when query context exists. */ @@ -289,6 +297,13 @@ CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, bool c } } + /* + * DISCARD ALL removes every saved statement and portal. Do this only + * after CommandComplete has finished using the current query context. + */ + if (discard_all) + pool_clear_sent_message_list(); + return POOL_CONTINUE; } @@ -381,20 +396,6 @@ handle_query_context(POOL_CONNECTION_POOL *backend) pool_remove_sent_message('P', name); } } - else if (IsA(node, DiscardStmt)) - { - DiscardStmt *stmt = (DiscardStmt *) node; - - if (stmt->target == DISCARD_PLANS) - { - pool_remove_sent_messages('Q'); - pool_remove_sent_messages('P'); - } - else if (stmt->target == DISCARD_ALL) - { - pool_clear_sent_message_list(); - } - } /* * JDBC driver sends "BEGIN" query internally if setAutoCommit(false). But [parent: ccb1c06acd1f]