Pgpool-II version
4.8devel (1a873669), backend_clustering_mode = raw, connection_cache = on, one configured PostgreSQL node.
Description
In raw mode, an extended-protocol DISCARD ALL succeeds on direct PostgreSQL but causes Pgpool to close the frontend connection.
The same failure is reachable from an ordinary PgJDBC 42.7.7 Statement.execute("DISCARD ALL") call: its default preferQueryMode=extended selects this path. No PreparedStatement or pipeline is required; preferQueryMode=simple avoids the failure.
CommandComplete() processes the command before forwarding its completion. Its DISCARD ALL branch calls pool_clear_sent_message_list(). Clearing the final sent message destroys its query context through pool_sent_message_destroy(), and pool_query_context_destroy() sets the session query context to NULL. CommandComplete() then calls pool_set_query_state(), whose null-context check (CHECK_QUERY_CONTEXT_IS_VALID) raises the local error.
Reproduce
Start PostgreSQL 16 and Pgpool-II in the configuration above, download postgresql-42.7.7.jar, and run:
javac -cp postgresql-42.7.7.jar reproduce.java
java -cp .:postgresql-42.7.7.jar Reproduce <direct-jdbc-url> <pgpool-jdbc-url>
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
class Reproduce {
static void run(String label, String url) {
Connection c = null;
try {
c = DriverManager.getConnection(url);
try (Statement s = c.createStatement()) {
s.execute("DISCARD ALL");
try (ResultSet r = s.executeQuery("SELECT 99")) {
r.next();
System.out.println(label + ": " + r.getInt(1));
}
}
} catch (SQLException e) {
boolean closed = false;
if (c != null) {
try { closed = c.isClosed(); } catch (SQLException ignored) { closed = true; }
}
System.out.println(label + ": " + e.getClass().getSimpleName() + ": "
+ e.getMessage().split("\\R", 2)[0] + "; closed=" + closed);
} finally {
if (c != null) {
try { c.close(); } catch (SQLException ignored) { }
}
}
}
public static void main(String[] args) {
run("direct", args[0]);
run("pgpool", args[1]);
}
}
Expected behavior
Both endpoints should complete DISCARD ALL, remain usable, and print:
Actual behavior
The reproducer prints:
direct: 99
pgpool: PSQLException: ERROR: setting db node for query to be sent, no query context; closed=true
Pgpool-II version
4.8devel(1a873669),backend_clustering_mode = raw,connection_cache = on, one configured PostgreSQL node.Description
In raw mode, an extended-protocol
DISCARD ALLsucceeds on direct PostgreSQL but causes Pgpool to close the frontend connection.The same failure is reachable from an ordinary PgJDBC 42.7.7
Statement.execute("DISCARD ALL")call: its defaultpreferQueryMode=extendedselects this path. NoPreparedStatementor pipeline is required;preferQueryMode=simpleavoids the failure.CommandComplete()processes the command before forwarding its completion. ItsDISCARD ALLbranch callspool_clear_sent_message_list(). Clearing the final sent message destroys its query context throughpool_sent_message_destroy(), andpool_query_context_destroy()sets the session query context toNULL.CommandComplete()then callspool_set_query_state(), whose null-context check (CHECK_QUERY_CONTEXT_IS_VALID) raises the local error.Reproduce
Start PostgreSQL 16 and Pgpool-II in the configuration above, download
postgresql-42.7.7.jar, and run:Expected behavior
Both endpoints should complete
DISCARD ALL, remain usable, and print:Actual behavior
The reproducer prints: