Skip to content

Commit

Permalink
fix: getting resultset metadata twice could skip row (#323)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
olavloite committed Jan 17, 2021
1 parent 9a32100 commit f8149af
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
Expand Up @@ -547,7 +547,7 @@ public InputStream getBinaryStream(String columnLabel) throws SQLException {
@Override
public JdbcResultSetMetaData getMetaData() throws SQLException {
checkClosed();
if (isBeforeFirst()) {
if (isBeforeFirst() && !nextCalledForMetaData) {
// do a call to next() on the underlying resultset to initialize metadata
nextCalledForMetaData = true;
nextCalledForMetaDataResult = spanner.next();
Expand Down
27 changes: 27 additions & 0 deletions src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetTest.java
Expand Up @@ -25,6 +25,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.cloud.ByteArray;
import com.google.cloud.Date;
Expand Down Expand Up @@ -802,6 +803,32 @@ public void testGetMetaData() throws SQLException {
assertNotNull(metadata);
}

@Test
public void testGetMetaDataBeforeNext() throws SQLException {
ResultSet spannerResultSet = mock(ResultSet.class);
when(spannerResultSet.next()).thenReturn(true, false);

JdbcResultSet resultSet = JdbcResultSet.of(spannerResultSet);
assertNotNull(resultSet.getMetaData());
assertTrue(resultSet.next());
assertFalse(resultSet.next());
}

@Test
public void testGetMetaDataTwiceBeforeNext() throws SQLException {
ResultSet spannerResultSet = mock(ResultSet.class);
when(spannerResultSet.next()).thenReturn(true, false);

JdbcResultSet resultSet = JdbcResultSet.of(spannerResultSet);
assertNotNull(resultSet.getMetaData());
assertNotNull(resultSet.getMetaData());

// This would have returned false before the fix in
// https://github.com/googleapis/java-spanner-jdbc/pull/323
assertTrue(resultSet.next());
assertFalse(resultSet.next());
}

@Test
public void testFindColumn() throws SQLException {
assertEquals(2, subject.findColumn(STRING_COL_NOT_NULL));
Expand Down

0 comments on commit f8149af

Please sign in to comment.