Skip to content

Commit ee76e18

Browse files
Fix MIN/MAX aggregation for empty partitions and add regression test (#36177)
### Packages impacted by this PR @azure/cosmos ### Issues associated with this PR ### Describe the problem that is addressed by this PR Fixed MIN/MAX aggregate queries randomly returning incorrect results in multi-partition collections. Empty partitions (count:0) were incorrectly overwriting valid aggregate values with undefined, causing MIN or MAX values to be missing from query results. ### What are the possible designs available to address the problem? If there are more than one possible design, why was the one in this PR chosen? ### Are there test cases added in this PR? _(If not, why?)_ yes ### Provide a list of related PRs _(if any)_ ### Command used to generate this PR:**_(Applicable only to SDK release request PRs)_ ### Checklists - [ ] Added impacted package name to the issue description - [ ] Does this PR needs any fixes in the SDK Generator?** _(If so, create an Issue in the [Autorest/typescript](https://github.com/Azure/autorest.typescript) repository and link it here)_ - [ ] Added a changelog (if necessary) --------- Co-authored-by: Manik Khandelwal <[email protected]>
1 parent be39eaf commit ee76e18

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

sdk/cosmosdb/cosmos/src/queryExecutionContext/Aggregators/MaxAggregator.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ export class MaxAggregator implements Aggregator {
2424
* Add the provided item to aggregation result.
2525
*/
2626
public aggregate(other: MaxAggregateResult): void {
27+
// Skip aggregation if other.max is undefined (empty partition with count:0)
28+
if (other.max === undefined) {
29+
return;
30+
}
31+
2732
if (this.value === undefined) {
2833
this.value = other.max;
2934
} else if (

sdk/cosmosdb/cosmos/src/queryExecutionContext/Aggregators/MinAggregator.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ export class MinAggregator implements Aggregator {
2424
* Add the provided item to aggregation result.
2525
*/
2626
public aggregate(other: MinAggregateResult): void {
27+
// Skip aggregation if other.min is undefined (empty partition with count:0)
28+
if (other.min === undefined) {
29+
return;
30+
}
31+
2732
if (this.value === undefined) {
2833
// || typeof this.value === "object"
2934
this.value = other.min;

sdk/cosmosdb/cosmos/test/public/integration/aggregateQuery.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,4 +404,32 @@ describe("Aggregate Query", { timeout: 20000 }, () => {
404404
}
405405
}
406406
});
407+
408+
it("should return both MIN and MAX values with empty partitions", async () => {
409+
// Regression test: MIN aggregate was incorrectly overwritten to undefined
410+
// when processing empty partitions (count:0) due to missing guard clause
411+
const multiPartitionContainer = await getTestContainer(
412+
"MIN MAX aggregate with empty partitions",
413+
undefined,
414+
{
415+
id: "minmaxemptypartitions",
416+
partitionKey: { paths: ["/pk"] },
417+
},
418+
{ offerThroughput: 12000 }, // Force multiple physical partitions
419+
);
420+
421+
// Create documents distributed across partitions (some partitions will be empty)
422+
await multiPartitionContainer.items.create({ id: "1", pk: "partition1", date: "2025-01-15" });
423+
await multiPartitionContainer.items.create({ id: "2", pk: "partition2", date: "2025-09-25" });
424+
425+
const queryIterator = multiPartitionContainer.items.query(
426+
"SELECT MIN(c.date) AS minDate, MAX(c.date) AS maxDate FROM c",
427+
{ maxItemCount: 1 },
428+
);
429+
const { resources } = await queryIterator.fetchAll();
430+
431+
assert.equal(resources.length, 1, "Should return exactly one aggregate result");
432+
assert.equal(resources[0].minDate, "2025-01-15", "MIN value should not be lost");
433+
assert.equal(resources[0].maxDate, "2025-09-25", "MAX value should be present");
434+
});
407435
});

0 commit comments

Comments
 (0)