Skip to content

Commit

Permalink
#762 Remove restriction to only allow calls to getResultSet if the re…
Browse files Browse the repository at this point in the history
…sult set was not returned yet

Deprecates FirebirdStatement.getCurrentResultSet.
  • Loading branch information
mrotteveel committed Oct 27, 2023
1 parent 45ad2eb commit dbaf8f9
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 60 deletions.
7 changes: 7 additions & 0 deletions src/docs/asciidoc/release_notes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,10 @@ Other drivers and tools simply send the requests for blob id `0` to the server,
For consistency, we decided to let Jaybird handle it the same.
+
This change was also backported to Jaybird 5.0.3.
* Improvement: `Statement.getResultSet` no longer throws a `SQLException` with message "`Only one result set at a time/statement`" if the current result set has already been returned by `executeQuery` or a previous call to `getResultSet` (https://github.com/FirebirdSQL/jaybird/issues/762[#762])
+
Repeated calls to `getResultSet` will now return the current result set.
As part of this change implementations of `FirebirdStatement.getCurrentResultSet` now simply call and returns `getResultSet`, and the `getCurrentResultSet` method has been deprecated for removal in Jaybird 7.
* Fixed: The implementation of `Blob.getBytes(long, int)` threw a `SQLException` if the remaining bytes of the blob where less than the requested number of bytes (https://github.com/FirebirdSQL/jaybird/issues/767[#767])
+
The JDBC API specifies _"This `byte` array contains up to `length` consecutive bytes starting at position pos."_, so the implementation was changed to return up to `length` bytes, or the remaining actual blob length, whichever is shorter.
Expand Down Expand Up @@ -1437,6 +1441,9 @@ The following methods will be removed in Jaybird 7:
It may get removed in Jaybird 7 or later.
** `getSupportedProtocols` -- use `getSupportedProtocolList()`.
It may get removed in Jaybird 7 or later.
* `FirebirdStatement`
** `getCurrentResultSet()` -- use `getResultSet()`.
Will be removed in Jaybird 7.

[#removal-of-deprecated-classes-7]
===== Removal of deprecated classes
Expand Down
43 changes: 6 additions & 37 deletions src/main/org/firebirdsql/jdbc/FBCallableStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public class FBCallableStatement extends FBPreparedStatement implements Callable
static final String NATIVE_CALL_COMMAND = "EXECUTE PROCEDURE ";
static final String NATIVE_SELECT_COMMAND = "SELECT * FROM ";

private ResultSet currentRs;
private ResultSet singletonRs;

protected boolean selectableProcedure;
Expand Down Expand Up @@ -173,10 +172,7 @@ public boolean isSelectableProcedure() {
* @throws SQLException if something went wrong.
*/
protected void setRequiredTypes() throws SQLException {
if (singletonRs != null) {
setRequiredTypesInternal((FBResultSet) singletonRs);
}
setRequiredTypesInternal((FBResultSet) getCurrentResultSet());
setRequiredTypesInternal((FBResultSet) (singletonRs != null ? singletonRs : getResultSet()));
}

private void setRequiredTypesInternal(FBResultSet resultSet) throws SQLException {
Expand Down Expand Up @@ -248,17 +244,17 @@ public boolean execute() throws SQLException {
public ResultSet executeQuery() throws SQLException {
procedureCall.checkParameters();
try (LockCloseable ignored = withLock()) {
checkValidity();
notifyStatementStarted();
prepareFixedStatement(procedureCall.getSQL(isSelectableProcedure()));

if (!internalExecute(!isSelectableProcedure())) {
throw new SQLNonTransientException("No resultset for sql", SQL_STATE_NO_RESULT_SET);
}

getResultSet();
setRequiredTypes();

return getCurrentResultSet();
ResultSet rs = getResultSet();
setRequiredTypesInternal((FBResultSet) rs);
return rs;
}
}

Expand Down Expand Up @@ -296,7 +292,6 @@ public int executeUpdate() throws SQLException {
// Execute statement internally. This method sets cached parameters. Rest of the processing is done by superclass.
@Override
protected boolean internalExecute(boolean sendOutParams) throws SQLException {
currentRs = null;
singletonRs = null;
int counter = 0;
for (FBProcedureParam param : procedureCall.getInputParams()) {
Expand Down Expand Up @@ -478,7 +473,6 @@ public double getDouble(int parameterIndex) throws SQLException {
return getAndAssertSingletonResultSet().getDouble(parameterIndex);
}

@SuppressWarnings("deprecation")
@Deprecated
@Override
public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
Expand Down Expand Up @@ -1109,14 +1103,6 @@ protected void assertHasData(ResultSet rs) throws SQLException {
}
}

// this method doesn't give an exception if it is called twice.
@Override
public ResultSet getCurrentResultSet() throws SQLException {
if (currentRs == null)
currentRs = super.getResultSet();
return currentRs;
}

/**
* Returns the result set for the singleton row of the callable statement and asserts it has data. If this is a
* selectable procedure, or there is no singleton row, it will return the normal result set.
Expand All @@ -1129,28 +1115,11 @@ public ResultSet getCurrentResultSet() throws SQLException {
* @throws SQLException For database access errors
*/
protected ResultSet getAndAssertSingletonResultSet() throws SQLException {
final ResultSet rs;
if (!isSelectableProcedure() && singletonRs != null) {
rs = singletonRs;
} else {
rs = getCurrentResultSet();
}
final ResultSet rs = !isSelectableProcedure() && singletonRs != null ? singletonRs : getResultSet();
assertHasData(rs);
return rs;
}

/**
* {@inheritDoc}
* <p>
* Calling this method twice with autocommit on and used will probably
* throw an inappropriate or uninformative exception.
* </p>
*/
@Override
public ResultSet getResultSet() throws SQLException {
return getCurrentResultSet();
}

@Override
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
procedureCall.getInputParam(parameterIndex).setValue(x);
Expand Down
30 changes: 16 additions & 14 deletions src/main/org/firebirdsql/jdbc/FBStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -537,26 +537,21 @@ public ResultSet getResultSet() throws SQLException {
public ResultSet getResultSet(boolean metaDataQuery) throws SQLException {
if (fbStatement == null) {
throw new SQLException("No statement was executed", SQL_STATE_INVALID_STATEMENT_ID);
}

if (cursorName != null) {
fbStatement.setCursorName(cursorName);
}

if (currentRs != null) {
throw new SQLException("Only one result set at a time/statement", SQL_STATE_GENERAL_ERROR);
} else if (currentRs != null) {
return currentRs;
}

// A generated keys query does not produce a normal result set (but EXECUTE PROCEDURE or INSERT ... RETURNING without Statement.RETURN_GENERATED_KEYS do)
// TODO Behavior might not be correct for callable statement implementation
if (!isGeneratedKeyQuery() && currentStatementResult.isResultSet()) {
if (!isSingletonResult) {
currentRs = new FBResultSet(connection, this, fbStatement, resultSetListener, metaDataQuery, rsType,
rsConcurrency, rsHoldability, false);
if (cursorName != null) {
fbStatement.setCursorName(cursorName);
}
return currentRs = new FBResultSet(connection, this, fbStatement, resultSetListener, metaDataQuery,
rsType, rsConcurrency, rsHoldability, false);
} else if (!specialResult.isEmpty()) {
currentRs = createSpecialResultSet(resultSetListener);
return currentRs = createSpecialResultSet(resultSetListener);
}
return currentRs;
}
return null;
}
Expand Down Expand Up @@ -832,9 +827,16 @@ void closeResultSet(boolean notifyListener, CompletionReason completionReason) t
}
}

/**
* {@inheritDoc}
*
* @deprecated Use {@link #getResultSet()} instead, will be removed in Jaybird 7
*/
@SuppressWarnings("removal")
@Deprecated(since = "6", forRemoval = true)
@Override
public ResultSet getCurrentResultSet() throws SQLException {
return currentRs;
return getResultSet();
}

@Override
Expand Down
18 changes: 9 additions & 9 deletions src/main/org/firebirdsql/jdbc/FirebirdStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,17 @@ public interface FirebirdStatement extends Statement {
* with this statement, otherwise <code>false</code>.
*/
boolean hasOpenResultSet();

/**
* Get current result set. Behaviour of this method is similar to the
* behavior of the {@link Statement#getResultSet()}, except that this method
* can be called as much as you like.
*
* @return instance of {@link ResultSet} representing current result set
* or <code>null</code> if it is not available.
*
* @throws SQLException if database access error happened.
* Get current result set. Behaviour of this method is similar to the behavior of the
* {@link Statement#getResultSet()}.
*
* @return instance of {@link ResultSet} representing current result set or {@code null} if it is not available.
* @throws SQLException
* if a database access error happens
* @deprecated Use {@link #getResultSet()} instead, will be removed in Jaybird 7
*/
@Deprecated(since = "6", forRemoval = true)
ResultSet getCurrentResultSet() throws SQLException;

/**
Expand Down
22 changes: 22 additions & 0 deletions src/test/org/firebirdsql/jdbc/FBStatementTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,28 @@ void psqlExceptionWithParametersRendering() throws Exception {
}
}

@Test
void getResultSetAfterExecuteQuery_sameResultSet() throws Exception {
try (var stmt = con.createStatement();
var rs = stmt.executeQuery("select 1 from rdb$database")) {
ResultSet sameRs = assertDoesNotThrow(stmt::getResultSet);

assertSame(rs, sameRs, "Expected ResultSet from getResultSet to be the same as from executeQuery");
}
}

@Test
void multipleGetResultSetCalls_sameResultSet() throws SQLException {
try (var stmt = con.createStatement()) {
assertTrue(stmt.execute("select 1 from rdb$database"), "Expected a result set as first result");

ResultSet rs = stmt.getResultSet();
ResultSet sameRs = assertDoesNotThrow(stmt::getResultSet);

assertSame(rs, sameRs, "Expected ResultSet from getResultSet to be the same as from previous getResultSet");
}
}

private void prepareTestData() throws SQLException {
executeCreateTable(con, CREATE_TABLE);

Expand Down

0 comments on commit dbaf8f9

Please sign in to comment.