Skip to content

Commit 48219f2

Browse files
committed
Fix for Bug#105197 (33461744), Statement.executeQuery() may return non-navigable ResultSet.
1 parent 24cf7e2 commit 48219f2

File tree

4 files changed

+128
-19
lines changed

4 files changed

+128
-19
lines changed

CHANGES

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
Version 8.0.28
55

6+
- Fix for Bug#105197 (33461744), Statement.executeQuery() may return non-navigable ResultSet.
7+
68
- Fix for Bug#105323 (33507321), README.md contains broken links.
79

810
- Fix for Bug#96900 (30355150), STATEMENT.CANCEL()CREATE A DATABASE CONNECTION BUT DOES NOT CLOSE THE CONNECTION.

src/main/resources/com/mysql/cj/LocalizedErrorMessages.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ ResultSet.Operation_not_allowed_after_ResultSet_closed_144=Operation not allowed
449449
ResultSet.Before_start_of_result_set_146=Before start of result set
450450
ResultSet.After_end_of_result_set_148=After end of result set
451451
ResultSet.Query_generated_no_fields_for_ResultSet_133=Query generated no fields for ResultSet
452-
ResultSet.ResultSet_is_from_UPDATE._No_Data_115=ResultSet is from UPDATE. No Data.
452+
ResultSet.ResultSet_is_from_UPDATE._No_Data_115=Not a navigable ResultSet.
453453

454454
ResultSet.Invalid_value_for_getFloat()_-____68=Invalid value for getFloat() - ''
455455
ResultSet.Invalid_value_for_getInt()_-____74=Invalid value for getInt() - ''

src/main/user-impl/java/com/mysql/cj/jdbc/result/ResultSetImpl.java

+62-18
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,11 @@ public void initializeWithMetadata() throws SQLException {
371371
@Override
372372
public boolean absolute(int row) throws SQLException {
373373
synchronized (checkClosed().getConnectionMutex()) {
374+
if (!hasRows()) {
375+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
376+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
377+
}
378+
374379
if (isStrictlyForwardOnly()) {
375380
throw ExceptionFactory.createException(Messages.getString("ResultSet.ForwardOnly"));
376381
}
@@ -419,6 +424,11 @@ public boolean absolute(int row) throws SQLException {
419424
@Override
420425
public void afterLast() throws SQLException {
421426
synchronized (checkClosed().getConnectionMutex()) {
427+
if (!hasRows()) {
428+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
429+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
430+
}
431+
422432
if (isStrictlyForwardOnly()) {
423433
throw ExceptionFactory.createException(Messages.getString("ResultSet.ForwardOnly"));
424434
}
@@ -435,6 +445,11 @@ public void afterLast() throws SQLException {
435445
@Override
436446
public void beforeFirst() throws SQLException {
437447
synchronized (checkClosed().getConnectionMutex()) {
448+
if (!hasRows()) {
449+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
450+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
451+
}
452+
438453
if (isStrictlyForwardOnly()) {
439454
throw ExceptionFactory.createException(Messages.getString("ResultSet.ForwardOnly"));
440455
}
@@ -560,18 +575,6 @@ public void deleteRow() throws SQLException {
560575
throw new NotUpdatable(Messages.getString("NotUpdatable.0"));
561576
}
562577

563-
/*
564-
* /**
565-
* TODO: Required by JDBC spec
566-
*/
567-
/*
568-
* protected void finalize() throws Throwable {
569-
* if (!this.isClosed) {
570-
* realClose(false);
571-
* }
572-
* }
573-
*/
574-
575578
@Override
576579
public int findColumn(String columnName) throws SQLException {
577580
synchronized (checkClosed().getConnectionMutex()) {
@@ -590,6 +593,11 @@ public int findColumn(String columnName) throws SQLException {
590593
@Override
591594
public boolean first() throws SQLException {
592595
synchronized (checkClosed().getConnectionMutex()) {
596+
if (!hasRows()) {
597+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
598+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
599+
}
600+
593601
if (isStrictlyForwardOnly()) {
594602
throw ExceptionFactory.createException(Messages.getString("ResultSet.ForwardOnly"));
595603
}
@@ -1590,6 +1598,11 @@ public java.sql.Ref getRef(String colName) throws SQLException {
15901598
public int getRow() throws SQLException {
15911599
checkClosed();
15921600

1601+
if (!hasRows()) {
1602+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"), MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR,
1603+
getExceptionInterceptor());
1604+
}
1605+
15931606
int currentRowNumber = this.rowData.getPosition();
15941607
int row = 0;
15951608

@@ -1692,29 +1705,46 @@ public void insertRow() throws SQLException {
16921705
@Override
16931706
public boolean isAfterLast() throws SQLException {
16941707
synchronized (checkClosed().getConnectionMutex()) {
1695-
boolean b = this.rowData.isAfterLast();
1696-
1697-
return b;
1708+
if (!hasRows()) {
1709+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
1710+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
1711+
}
1712+
return this.rowData.isAfterLast();
16981713
}
16991714
}
17001715

17011716
@Override
17021717
public boolean isBeforeFirst() throws SQLException {
17031718
synchronized (checkClosed().getConnectionMutex()) {
1719+
if (!hasRows()) {
1720+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
1721+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
1722+
}
1723+
17041724
return this.rowData.isBeforeFirst();
17051725
}
17061726
}
17071727

17081728
@Override
17091729
public boolean isFirst() throws SQLException {
17101730
synchronized (checkClosed().getConnectionMutex()) {
1731+
if (!hasRows()) {
1732+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
1733+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
1734+
}
1735+
17111736
return this.rowData.isFirst();
17121737
}
17131738
}
17141739

17151740
@Override
17161741
public boolean isLast() throws SQLException {
17171742
synchronized (checkClosed().getConnectionMutex()) {
1743+
if (!hasRows()) {
1744+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
1745+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
1746+
}
1747+
17181748
return this.rowData.isLast();
17191749
}
17201750
}
@@ -1733,6 +1763,11 @@ protected boolean isStrictlyForwardOnly() {
17331763
@Override
17341764
public boolean last() throws SQLException {
17351765
synchronized (checkClosed().getConnectionMutex()) {
1766+
if (!hasRows()) {
1767+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
1768+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
1769+
}
1770+
17361771
if (isStrictlyForwardOnly()) {
17371772
throw ExceptionFactory.createException(Messages.getString("ResultSet.ForwardOnly"));
17381773
}
@@ -1765,14 +1800,13 @@ public void moveToInsertRow() throws SQLException {
17651800
@Override
17661801
public boolean next() throws SQLException {
17671802
synchronized (checkClosed().getConnectionMutex()) {
1768-
1769-
boolean b;
1770-
17711803
if (!hasRows()) {
17721804
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
17731805
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
17741806
}
17751807

1808+
boolean b;
1809+
17761810
if (this.rowData.size() == 0) {
17771811
b = false;
17781812
} else {
@@ -1839,6 +1873,11 @@ public boolean prev() throws java.sql.SQLException {
18391873
@Override
18401874
public boolean previous() throws SQLException {
18411875
synchronized (checkClosed().getConnectionMutex()) {
1876+
if (!hasRows()) {
1877+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
1878+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
1879+
}
1880+
18421881
if (isStrictlyForwardOnly()) {
18431882
throw ExceptionFactory.createException(Messages.getString("ResultSet.ForwardOnly"));
18441883
}
@@ -1961,6 +2000,11 @@ public void refreshRow() throws SQLException {
19612000
@Override
19622001
public boolean relative(int rows) throws SQLException {
19632002
synchronized (checkClosed().getConnectionMutex()) {
2003+
if (!hasRows()) {
2004+
throw SQLError.createSQLException(Messages.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
2005+
MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
2006+
}
2007+
19642008
if (isStrictlyForwardOnly()) {
19652009
throw ExceptionFactory.createException(Messages.getString("ResultSet.ForwardOnly"));
19662010
}

src/test/java/testsuite/regression/ResultSetRegressionTest.java

+63
Original file line numberDiff line numberDiff line change
@@ -8058,4 +8058,67 @@ public void testBug33185116() throws Exception {
80588058
assertEquals(boolValues[i], this.rs.getBoolean(2));
80598059
}
80608060
}
8061+
8062+
/**
8063+
* Tests for Bug#105197 (33461744), Statement.executeQuery() may return non-navigable ResultSet.
8064+
*
8065+
* @throws Exception
8066+
*/
8067+
@Test
8068+
public void testBug105197() throws Exception {
8069+
createProcedure("testBug105197Proc", "() BEGIN END");
8070+
this.rs = this.stmt.executeQuery("CALL testBug105197Proc()");
8071+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8072+
this.rs.absolute(1);
8073+
return null;
8074+
});
8075+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8076+
this.rs.relative(1);
8077+
return null;
8078+
});
8079+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8080+
this.rs.getRow();
8081+
return null;
8082+
});
8083+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8084+
this.rs.beforeFirst();
8085+
return null;
8086+
});
8087+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8088+
this.rs.isBeforeFirst();
8089+
return null;
8090+
});
8091+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8092+
this.rs.first();
8093+
return null;
8094+
});
8095+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8096+
this.rs.isFirst();
8097+
return null;
8098+
});
8099+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8100+
this.rs.previous();
8101+
return null;
8102+
});
8103+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8104+
this.rs.next();
8105+
return null;
8106+
});
8107+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8108+
this.rs.last();
8109+
return null;
8110+
});
8111+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8112+
this.rs.isLast();
8113+
return null;
8114+
});
8115+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8116+
this.rs.afterLast();
8117+
return null;
8118+
});
8119+
assertThrows(SQLException.class, "Not a navigable ResultSet\\.", () -> {
8120+
this.rs.isAfterLast();
8121+
return null;
8122+
});
8123+
}
80618124
}

0 commit comments

Comments
 (0)