Message-ID: From: "ShenFeng312 (@ShenFeng312)" To: "pgjdbc/pgjdbc" Date: Fri, 22 Aug 2025 04:40:35 +0000 Subject: [pgjdbc/pgjdbc] issue #3781: Performance Optimization: PgPreparedStatement.getMetaData Should Not Use QUERY_ONESHOT List-Id: X-GitHub-Author-Id: 49786112 X-GitHub-Author-Login: ShenFeng312 X-GitHub-Issue: 3781 X-GitHub-Repo: pgjdbc/pgjdbc X-GitHub-State: closed X-GitHub-Type: issue X-GitHub-Url: https://github.com/pgjdbc/pgjdbc/issues/3781 Content-Type: text/plain; charset=utf-8 Description: Currently, `PgPreparedStatement.getMetaData` uses `QUERY_ONESHOT` before `execute` is invoked, which results in `query.setStatementName(statementName, deallocateEpoch)` not being executed. Consequently, the binary protocol cannot be used to receive the result set. ```java if (!oneShot) { // Generate a statement name to use. statementName = "S_" + (nextUniqueID++); // And prepare the new statement. // NB: Must clone the OID array, as it's a direct reference to // the SimpleParameterList's internal array that might be modified // under us. query.setStatementName(statementName, deallocateEpoch); query.setPrepareTypes(typeOIDs); registerParsedQuery(query, statementName); } ``` ```java public @Nullable ResultSetMetaData getMetaData() throws SQLException { checkClosed(); ResultSet rs = getResultSet(); if (rs == null || ((PgResultSet) rs).isResultSetClosed()) { // OK, we haven't executed it yet, or it was closed // we've got to go to the backend // for more info. We send the full query, but just don't // execute it. int flags = QueryExecutor.QUERY_ONESHOT | QueryExecutor.QUERY_DESCRIBE_ONLY | QueryExecutor.QUERY_SUPPRESS_BEGIN; StatementResultHandler handler = new StatementResultHandler(); connection.getQueryExecutor().execute(preparedQuery.query, preparedParameters, handler, 0, 0, flags); ResultWrapper wrapper = handler.getResults(); if (wrapper != null) { rs = wrapper.getResultSet(); } } if (rs != null) { return rs.getMetaData(); } return null; } ```