Skip to content

Commit f8149af

Browse files
authored
fix: getting resultset metadata twice could skip row (#323)
* fix: getting resultset metadata twice could skip row If the client application would call ResultSet#getMetaData() more than once **before** calling ResultSet#next(), the ResultSet would skip a row when the rows would be consumed. Fixes #322 * test: add test for getMetaData twice
1 parent 9a32100 commit f8149af

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ public InputStream getBinaryStream(String columnLabel) throws SQLException {
547547
@Override
548548
public JdbcResultSetMetaData getMetaData() throws SQLException {
549549
checkClosed();
550-
if (isBeforeFirst()) {
550+
if (isBeforeFirst() && !nextCalledForMetaData) {
551551
// do a call to next() on the underlying resultset to initialize metadata
552552
nextCalledForMetaData = true;
553553
nextCalledForMetaDataResult = spanner.next();

src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import static org.junit.Assert.assertTrue;
2626
import static org.junit.Assert.fail;
2727
import static org.mockito.Mockito.mock;
28+
import static org.mockito.Mockito.when;
2829

2930
import com.google.cloud.ByteArray;
3031
import com.google.cloud.Date;
@@ -802,6 +803,32 @@ public void testGetMetaData() throws SQLException {
802803
assertNotNull(metadata);
803804
}
804805

806+
@Test
807+
public void testGetMetaDataBeforeNext() throws SQLException {
808+
ResultSet spannerResultSet = mock(ResultSet.class);
809+
when(spannerResultSet.next()).thenReturn(true, false);
810+
811+
JdbcResultSet resultSet = JdbcResultSet.of(spannerResultSet);
812+
assertNotNull(resultSet.getMetaData());
813+
assertTrue(resultSet.next());
814+
assertFalse(resultSet.next());
815+
}
816+
817+
@Test
818+
public void testGetMetaDataTwiceBeforeNext() throws SQLException {
819+
ResultSet spannerResultSet = mock(ResultSet.class);
820+
when(spannerResultSet.next()).thenReturn(true, false);
821+
822+
JdbcResultSet resultSet = JdbcResultSet.of(spannerResultSet);
823+
assertNotNull(resultSet.getMetaData());
824+
assertNotNull(resultSet.getMetaData());
825+
826+
// This would have returned false before the fix in
827+
// https://github.com/googleapis/java-spanner-jdbc/pull/323
828+
assertTrue(resultSet.next());
829+
assertFalse(resultSet.next());
830+
}
831+
805832
@Test
806833
public void testFindColumn() throws SQLException {
807834
assertEquals(2, subject.findColumn(STRING_COL_NOT_NULL));

0 commit comments

Comments
 (0)