Skip to content

Commit eee9215

Browse files
Bruce Irschickbirschick-bq
Bruce Irschick
andauthored
[AD-216] Investigate statement.setMaxRows() and see if this needs to be incorporated ins some way during query execution (#66)
### Summary [AD-216] Investigate statement.setMaxRows() and see if this needs to be incorporated ins some way during query execution ### Description - Push-down a `$limit` command. ### Related Issue https://bitquill.atlassian.net/browse/AD-216 * [AD-216] Investigate statement.setMaxRows() and see if this needs to be incorporated ins some way during query execution https://bitquill.atlassian.net/browse/AD-216 - Push-down a `$limit` command. * [AD-216] Investigate statement.setMaxRows() and see if this needs to be incorporated ins some way during query execution https://bitquill.atlassian.net/browse/AD-216 - Fix flaky test. * Commit Code Coverage Badge Co-authored-by: birschick-bq <[email protected]>
1 parent d6cc1ec commit eee9215

File tree

4 files changed

+91
-9
lines changed

4 files changed

+91
-9
lines changed

src/main/java/software/amazon/documentdb/jdbc/DocumentDbQueryExecutor.java

+15-6
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
import com.mongodb.client.MongoClient;
2525
import com.mongodb.client.MongoClients;
2626
import com.mongodb.client.MongoCollection;
27-
import com.mongodb.client.MongoCursor;
2827
import com.mongodb.client.MongoDatabase;
28+
import org.bson.BsonDocument;
2929
import org.bson.Document;
30+
import org.bson.conversions.Bson;
3031
import org.slf4j.Logger;
3132
import org.slf4j.LoggerFactory;
3233
import software.amazon.documentdb.jdbc.common.utilities.JdbcColumnMetaData;
@@ -170,21 +171,29 @@ protected java.sql.ResultSet runQuery(final String sql) throws SQLException {
170171
final MongoDatabase database = client.getDatabase(properties.getDatabase());
171172
final MongoCollection<Document> collection = database
172173
.getCollection(queryContext.getCollectionName());
173-
AggregateIterable<Document> iterable = collection
174-
.aggregate(queryContext.getAggregateOperations());
174+
175+
// Only add limit if maxRows is non-zero.
176+
final List<Bson> aggregateOperations = queryContext.getAggregateOperations();
177+
final long maxRows = statement.getLargeMaxRows();
178+
if (maxRows > 0) {
179+
// Use push-down to apply maxRows limit.
180+
aggregateOperations.add(BsonDocument.parse(
181+
String.format("{\"$limit\": {\"$numberLong\": \"%d\"}}", maxRows)));
182+
}
183+
184+
AggregateIterable<Document> iterable = collection.aggregate(aggregateOperations);
175185
if (getQueryTimeout() > 0) {
176186
iterable = iterable.maxTime(getQueryTimeout(), TimeUnit.SECONDS);
177187
}
178188
if (getFetchSize() > 0) {
179189
iterable = iterable.batchSize(getFetchSize());
180190
}
181-
final MongoCursor<Document> iterator = iterable.iterator();
182191

183192
final ImmutableList<JdbcColumnMetaData> columnMetaData = ImmutableList
184193
.copyOf(queryContext.getColumnMetaData());
185194
return new DocumentDbResultSet(
186195
this.statement,
187-
iterator,
196+
iterable.iterator(),
188197
columnMetaData,
189198
queryContext.getPaths());
190199
}
@@ -219,7 +228,7 @@ private void performCancel() throws SQLException {
219228
SqlError.QUERY_NOT_STARTED_OR_COMPLETE);
220229
}
221230

222-
// If there is more than 1 result then more than 1 operations have been given same id
231+
// If there is more than 1 result then more than 1 operations have been given same id,
223232
// and we do not know which to cancel.
224233
if (ops.size() != 1) {
225234
throw SqlError.createSQLException(

src/test/java/software/amazon/documentdb/jdbc/DocumentDbResultSetTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ public class DocumentDbResultSetTest extends DocumentDbFlapDoodleTest {
8383

8484
@BeforeAll
8585
@SuppressFBWarnings(value = "HARD_CODE_PASSWORD", justification = "Hardcoded for test purposes only")
86-
static void initialize() throws SQLException {
86+
static void initialize() {
8787
// Add a valid users to the local MongoDB instance.
8888
client = createMongoClient("admin", "admin", "admin");
8989
createUser(DATABASE_NAME, TEST_USER, TEST_PASSWORD);
9090
}
9191

9292
@BeforeEach
9393
void init() throws SQLException {
94-
MockitoAnnotations.initMocks(this);
94+
MockitoAnnotations.openMocks(this);
9595
Mockito.when(mockStatement.getFetchSize()).thenReturn(MOCK_FETCH_SIZE);
9696
}
9797

src/test/java/software/amazon/documentdb/jdbc/DocumentDbStatementBasicTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,8 @@ void testCurrentTimestamp() throws SQLException {
10731073
final OffsetDateTime currentDateTime = Instant.now().atOffset(ZoneOffset.UTC);
10741074
final long diffInMilliSeconds = actualDateTime
10751075
.until(currentDateTime, ChronoUnit.MILLIS);
1076-
Assertions.assertTrue(diffInMilliSeconds > 0 && diffInMilliSeconds < 2000);
1076+
Assertions.assertTrue(diffInMilliSeconds >= 0);
1077+
Assertions.assertTrue(diffInMilliSeconds < 1000);
10771078
Assertions.assertFalse(testResultSet.next());
10781079
return null;
10791080
} catch (SQLException e) {

src/test/java/software/amazon/documentdb/jdbc/DocumentDbStatementFilterTest.java

+72
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.bson.BsonDouble;
2323
import org.bson.BsonInt64;
2424
import org.bson.BsonMinKey;
25+
import org.bson.BsonString;
2526
import org.junit.jupiter.api.Assertions;
2627
import org.junit.jupiter.api.Disabled;
2728
import org.junit.jupiter.api.DisplayName;
@@ -1399,4 +1400,75 @@ void testDateMinus() throws SQLException {
13991400
Assertions.assertEquals("101", resultSet.getString(1));
14001401
Assertions.assertFalse(resultSet.next());
14011402
}
1403+
1404+
@Test
1405+
@DisplayName("Tests that setMaxRows limits the number of rows returned in result set.")
1406+
void testSetMaxRows() throws SQLException {
1407+
final String collection = "testSetMaxRows";
1408+
final BsonDocument[] documents = new BsonDocument[10];
1409+
final int totalNumberDocuments = 10;
1410+
final int maxRows = 5;
1411+
for (int i = 0; i < totalNumberDocuments; i++) {
1412+
documents[i] = new BsonDocument("field", new BsonString("value"));
1413+
}
1414+
insertBsonDocuments(collection, DATABASE_NAME, USER, PASSWORD, documents);
1415+
final Statement statement = getDocumentDbStatement();
1416+
1417+
// Don't set max rows
1418+
ResultSet resultSet = statement.executeQuery(
1419+
String.format("SELECT * FROM \"%s\".\"%s\"", DATABASE_NAME, collection));
1420+
int actualRowCount = 0;
1421+
while (resultSet.next()) {
1422+
actualRowCount++;
1423+
}
1424+
Assertions.assertEquals(0, statement.getMaxRows());
1425+
Assertions.assertEquals(totalNumberDocuments, actualRowCount);
1426+
1427+
// Set max rows < actual
1428+
statement.setMaxRows(maxRows);
1429+
resultSet = statement.executeQuery(
1430+
String.format("SELECT * FROM \"%s\".\"%s\"", DATABASE_NAME, collection));
1431+
actualRowCount = 0;
1432+
while (resultSet.next()) {
1433+
actualRowCount++;
1434+
}
1435+
Assertions.assertEquals(maxRows, statement.getMaxRows());
1436+
Assertions.assertEquals(maxRows, actualRowCount);
1437+
1438+
// Set unlimited
1439+
statement.setMaxRows(0);
1440+
resultSet = statement.executeQuery(
1441+
String.format("SELECT * FROM \"%s\".\"%s\"", DATABASE_NAME, collection));
1442+
actualRowCount = 0;
1443+
while (resultSet.next()) {
1444+
actualRowCount++;
1445+
}
1446+
Assertions.assertEquals(0, statement.getMaxRows());
1447+
Assertions.assertEquals(totalNumberDocuments, actualRowCount);
1448+
1449+
// Set max rows > SQL LIMIT
1450+
int limit = maxRows - 1;
1451+
statement.setMaxRows(maxRows);
1452+
resultSet = statement.executeQuery(
1453+
String.format("SELECT * FROM \"%s\".\"%s\" LIMIT %d", DATABASE_NAME, collection, limit));
1454+
actualRowCount = 0;
1455+
while (resultSet.next()) {
1456+
actualRowCount++;
1457+
}
1458+
Assertions.assertEquals(maxRows, statement.getMaxRows());
1459+
Assertions.assertEquals(limit, actualRowCount);
1460+
1461+
// Set max rows < SQL LIMIT
1462+
limit = maxRows + 1;
1463+
statement.setMaxRows(maxRows);
1464+
resultSet = statement.executeQuery(
1465+
String.format("SELECT * FROM \"%s\".\"%s\" LIMIT %d", DATABASE_NAME, collection, limit));
1466+
actualRowCount = 0;
1467+
while (resultSet.next()) {
1468+
actualRowCount++;
1469+
}
1470+
Assertions.assertEquals(maxRows, statement.getMaxRows());
1471+
Assertions.assertEquals(maxRows, actualRowCount);
1472+
1473+
}
14021474
}

0 commit comments

Comments
 (0)