Skip to content

Commit 42ddd4e

Browse files
Addressed review comments by using PaginationHelper class.
1 parent 6a36d72 commit 42ddd4e

File tree

3 files changed

+33
-40
lines changed

3 files changed

+33
-40
lines changed

athena-db2/src/main/java/com/amazonaws/athena/connectors/db2/Db2Constants.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ public class Db2Constants
3838
public static final String LIST_PAGINATED_TABLES_QUERY = "select tabschema AS \"TABLE_SCHEM\", tabname AS \"TABLE_NAME\" " +
3939
"from syscat.tables where type in ('T', 'U', 'V', 'W') and tabschema = ? " +
4040
"ORDER BY tabname OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
41-
public static final String ALL_TABLES_COUNT_QUERY = "select count(*) AS \"ALL_TABLES_COUNT\" " +
42-
"from syscat.tables where type in ('T', 'U', 'V', 'W') and tabschema = ? ";
4341

4442
static final String PARTITION_QUERY = "SELECT DATAPARTITIONID FROM SYSCAT.DATAPARTITIONS WHERE TABSCHEMA = ? AND TABNAME = ? AND SEQNO > 0";
4543
static final String COLUMN_INFO_QUERY = "select colname, typename from syscat.columns where tabschema = ? AND tabname = ?";

athena-db2/src/main/java/com/amazonaws/athena/connectors/db2/Db2MetadataHandler.java

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.amazonaws.athena.connector.lambda.metadata.optimizations.pushdown.FilterPushdownSubType;
4646
import com.amazonaws.athena.connector.lambda.metadata.optimizations.pushdown.LimitPushdownSubType;
4747
import com.amazonaws.athena.connector.lambda.metadata.optimizations.pushdown.TopNPushdownSubType;
48+
import com.amazonaws.athena.connector.util.PaginationHelper;
4849
import com.amazonaws.athena.connectors.jdbc.connection.DatabaseConnectionConfig;
4950
import com.amazonaws.athena.connectors.jdbc.connection.DatabaseConnectionInfo;
5051
import com.amazonaws.athena.connectors.jdbc.connection.GenericJdbcConnectionFactory;
@@ -184,41 +185,21 @@ public ListTablesResponse doListTables(final BlockAllocator blockAllocator, fina
184185
public ListTablesResponse listPaginatedTables(final Connection connection, final ListTablesRequest listTablesRequest) throws SQLException
185186
{
186187
LOGGER.debug("Starting listPaginatedTables for Db2.");
187-
String token = listTablesRequest.getNextToken();
188188
int pageSize = listTablesRequest.getPageSize();
189+
int token = PaginationHelper.validateAndParsePaginationArguments(listTablesRequest.getNextToken(), pageSize);
189190

190191
if (pageSize == UNLIMITED_PAGE_SIZE_VALUE) {
191-
LOGGER.debug("listPaginatedTables - pagination with UNLIMITED_PAGE_SIZE_VALUE");
192-
pageSize = getAllTablesCount(connection, listTablesRequest.getSchemaName());
192+
pageSize = Integer.MAX_VALUE;
193193
}
194194

195-
int t = token != null ? Integer.parseInt(token) : 0;
195+
LOGGER.info("Starting pagination at {} with page size {}", token, pageSize);
196+
List<TableName> paginatedTables = getPaginatedTables(connection, listTablesRequest.getSchemaName(), token, pageSize);
197+
String nextToken = PaginationHelper.calculateNextToken(token, pageSize, paginatedTables);
198+
LOGGER.info("{} tables returned. Next token is {}", paginatedTables.size(), nextToken);
196199

197-
LOGGER.info("Starting pagination at {} with page size {}", t, pageSize);
198-
List<TableName> paginatedTables = getPaginatedTables(connection, listTablesRequest.getSchemaName(), t, pageSize);
199-
LOGGER.info("{} tables returned. Next token is {}", paginatedTables.size(), t + pageSize);
200-
201-
String nextToken = paginatedTables.isEmpty() || paginatedTables.size() < pageSize || listTablesRequest.getPageSize() == UNLIMITED_PAGE_SIZE_VALUE ? null : Integer.toString(t + pageSize);
202-
// return next token is null when reaching end of files
203200
return new ListTablesResponse(listTablesRequest.getCatalogName(), paginatedTables, nextToken);
204201
}
205202

206-
private int getAllTablesCount(Connection connection, String schemaName) throws SQLException
207-
{
208-
PreparedStatement preparedStatement = connection.prepareStatement(Db2Constants.ALL_TABLES_COUNT_QUERY);
209-
preparedStatement.setString(1, schemaName);
210-
int allTablesCount = 0;
211-
try (ResultSet resultSet = preparedStatement.executeQuery()) {
212-
while (resultSet.next()) {
213-
allTablesCount = resultSet.getInt(1);
214-
}
215-
}
216-
catch (SQLException sqlException) {
217-
throw new RuntimeException(sqlException.getErrorCode() + ": " + sqlException);
218-
}
219-
return allTablesCount;
220-
}
221-
222203
@VisibleForTesting
223204
protected List<TableName> getPaginatedTables(Connection connection, String databaseName, int offset, int limit) throws SQLException
224205
{

athena-db2/src/test/java/com/amazonaws/athena/connectors/db2/Db2MetadataHandlerTest.java

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.amazonaws.athena.connector.lambda.domain.Split;
2727
import com.amazonaws.athena.connector.lambda.domain.TableName;
2828
import com.amazonaws.athena.connector.lambda.domain.predicate.Constraints;
29+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
2930
import com.amazonaws.athena.connector.lambda.metadata.GetSplitsRequest;
3031
import com.amazonaws.athena.connector.lambda.metadata.GetSplitsResponse;
3132
import com.amazonaws.athena.connector.lambda.metadata.GetTableLayoutRequest;
@@ -401,28 +402,41 @@ blockAllocator, new ListTablesRequest(this.federatedIdentity, "testQueryId",
401402
Assert.assertNull(listTablesResponse.getNextToken());
402403
Assert.assertArrayEquals(expected, listTablesResponse.getTables().toArray());
403404

404-
// Test 4: Testing when requesting pageSize UNLIMITED_PAGE_SIZE_VALUE(-1) and nextToken is 2.
405+
// Test 4: nextToken is 2 and pageSize is UNLIMITED. Return all tables starting from index 2.
405406
preparedStatement = Mockito.mock(PreparedStatement.class);
406407
Mockito.when(this.connection.prepareStatement(Db2Constants.LIST_PAGINATED_TABLES_QUERY)).thenReturn(preparedStatement);
407-
values = new Object[][]{{"testSchema", "testTable2"}};
408-
expected = new TableName[]{new TableName("testSchema", "testTable2")};
408+
values = new Object[][]{{"testSchema", "testTable3"}, {"testSchema", "testTable4"}};
409+
expected = new TableName[]{new TableName("testSchema", "testTable3"), new TableName("testSchema", "testTable4")};
409410
resultSet = mockResultSet(schema, values, new AtomicInteger(-1));
410411
Mockito.when(preparedStatement.executeQuery()).thenReturn(resultSet);
411412

412-
PreparedStatement preparedStatement1 = Mockito.mock(PreparedStatement.class);
413-
Mockito.when(this.connection.prepareStatement(Db2Constants.ALL_TABLES_COUNT_QUERY)).thenReturn(preparedStatement1);
414-
schema = new String[]{"ALL_TABLES_COUNT"};
415-
values = new Object[][] {{5}};
416-
resultSet = mockResultSet(schema, values, new AtomicInteger(1));
417-
Mockito.when(preparedStatement1.executeQuery()).thenReturn(resultSet);
418-
Mockito.when(resultSet.next()).thenReturn(true).thenReturn(false);
419-
Mockito.when(resultSet.getInt(1)).thenReturn(5);
420-
421413
listTablesResponse = this.db2MetadataHandler.doListTables(
422414
blockAllocator, new ListTablesRequest(this.federatedIdentity, "testQueryId",
423415
"testCatalog", "testSchema", "2", ListTablesRequest.UNLIMITED_PAGE_SIZE_VALUE));
424416
Assert.assertNull(listTablesResponse.getNextToken());
425417
Assert.assertArrayEquals(expected, listTablesResponse.getTables().toArray());
418+
419+
// Test 5: AthenaConnectorException with negative nextToken value
420+
preparedStatement = Mockito.mock(PreparedStatement.class);
421+
Mockito.when(this.connection.prepareStatement(Db2Constants.LIST_PAGINATED_TABLES_QUERY)).thenReturn(preparedStatement);
422+
values = new Object[][]{{"testSchema", "testTable3"}, {"testSchema", "testTable4"}};
423+
resultSet = mockResultSet(schema, values, new AtomicInteger(-1));
424+
Mockito.when(preparedStatement.executeQuery()).thenReturn(resultSet);
425+
426+
Assert.assertThrows(AthenaConnectorException.class, () -> this.db2MetadataHandler.doListTables(
427+
blockAllocator, new ListTablesRequest(this.federatedIdentity, "testQueryId",
428+
"testCatalog", "testSchema", "-1", 3)));
429+
430+
// Test 6: AthenaConnectorException with negative pageSize value
431+
preparedStatement = Mockito.mock(PreparedStatement.class);
432+
Mockito.when(this.connection.prepareStatement(Db2Constants.LIST_PAGINATED_TABLES_QUERY)).thenReturn(preparedStatement);
433+
values = new Object[][]{{"testSchema", "testTable3"}, {"testSchema", "testTable4"}};
434+
resultSet = mockResultSet(schema, values, new AtomicInteger(-1));
435+
Mockito.when(preparedStatement.executeQuery()).thenReturn(resultSet);
436+
437+
Assert.assertThrows(AthenaConnectorException.class, () -> this.db2MetadataHandler.doListTables(
438+
blockAllocator, new ListTablesRequest(this.federatedIdentity, "testQueryId",
439+
"testCatalog", "testSchema", "0", -3)));
426440
}
427441
}
428442

0 commit comments

Comments
 (0)