Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,58 @@ public void testAggregateWithMultipleGroupingLevels(String dataStoreName) throws
testCountApi(dataStoreName, query, "query/multi_level_grouping_response.json");
}

@ParameterizedTest
@ArgumentsSource(MongoProvider.class)
public void testSortByListSizeWithMissingField(String dataStoreName) throws IOException {
Datastore datastore = datastoreMap.get(dataStoreName);
String collectionName = "list_size_sort_collection";
Comment on lines +922 to +926

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The integration test runs against nested collections (the standard document store pattern) which exercises the jsonb_array_length path. The flat collection path (ARRAY_LENGTH) is covered by the existing unit tests in PostgresQueryParserTest which validate SQL generation for LENGTH on aggregation aliases. The flat collection LENGTH on a direct column field follows the same ARRAY_LENGTH codepath and is validated by the existing tests that assert correct SQL output.

datastore.deleteCollection(collectionName);
datastore.createCollection(collectionName, null);
Collection collection = datastore.getCollection(collectionName);
Comment on lines +924 to +929

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Wrapped the test body in try-finally in be9514a so deleteCollection runs regardless of assertion failures.


try {
collection.upsert(
new SingleValueKey(TENANT_ID, "three"),
new JSONDocument("{\"item\":\"three\",\"tags\":[\"a\",\"b\",\"c\"]}"));
collection.upsert(
new SingleValueKey(TENANT_ID, "one"),
new JSONDocument("{\"item\":\"one\",\"tags\":[\"x\"]}"));
// Document intentionally missing the "tags" field; LENGTH must resolve to 0 instead of
// failing
collection.upsert(
new SingleValueKey(TENANT_ID, "none"), new JSONDocument("{\"item\":\"none\"}"));

Query query =
Query.builder()
.addSelection(IdentifierExpression.of("item"))
.addSelection(
FunctionExpression.builder()
.operator(LENGTH)
.operand(IdentifierExpression.of("tags"))
.build(),
"tag_count")
.addSort(IdentifierExpression.of("tag_count"), ASC)
.build();

Iterator<Document> resultDocs = collection.aggregate(query);
List<Map<String, Object>> results = new ArrayList<>();
while (resultDocs.hasNext()) {
results.add(Utils.convertDocumentToMap(resultDocs.next()));
}

assertEquals(3, results.size());
// Document without the "tags" field counts as 0 and sorts first in ascending order
assertEquals("none", results.get(0).get("item"));
assertEquals(0, ((Number) results.get(0).get("tag_count")).intValue());
assertEquals("one", results.get(1).get("item"));
assertEquals(1, ((Number) results.get(1).get("tag_count")).intValue());
assertEquals("three", results.get(2).get("item"));
assertEquals(3, ((Number) results.get(2).get("tag_count")).intValue());
} finally {
datastore.deleteCollection(collectionName);
}
}

@ParameterizedTest
@ArgumentsSource(AllProvider.class)
public void testAggregateWithFunctionalLeftHandSideFilter(final String dataStoreName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ Map<String, Object> parse(final FunctionExpression expression) {

if (numArgs == 1) {
Object value = expression.getOperands().get(0).accept(parser);
// $size fails when the operand resolves to a missing/absent (or null) field. Default such a
// value to an empty array so that LENGTH of an absent field is 0 instead of throwing an
// error.
if (operator == LENGTH) {
value = Map.of("$ifNull", List.of(value, List.of()));
}
return Map.of(key, value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
{
"$project": {
"section_count": {
"$size": "$section_count"
"$size": {
"$ifNull": [
"$section_count",
[]
]
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
{
"$project": {
"total": {
"$size": "$total"
"$size": {
"$ifNull": [
"$total",
[]
]
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
{
"$project": {
"total": {
"$size": "$total"
"$size": {
"$ifNull": [
"$total",
[]
]
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
{
"$project": {
"total": {
"$size": "$total"
"$size": {
"$ifNull": [
"$total",
[]
]
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
"$project": {
"name": 1,
"total": {
"$size": "$total"
"$size": {
"$ifNull": [
"$total",
[]
]
}
}
}
}
Expand Down
Loading