Skip to content

feat: aggregate sum path query#364

Merged
QuantumExplorer merged 11 commits into
developfrom
feat/SumUpToQuery
Mar 5, 2026
Merged

feat: aggregate sum path query#364
QuantumExplorer merged 11 commits into
developfrom
feat/SumUpToQuery

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

@QuantumExplorer QuantumExplorer commented Mar 26, 2025

Issue being fixed or feature implemented

We needed a new type of query that would get Sum Items from a tree up to a cumulative aggregate value. For example, if a SumTree has items with values 5, 10, 3, 8, and we want all items until the running total reaches 15, the query would return items summing up to that limit.

What was done?

New types

  • AggregateSumQuery (merk level): A query type similar to Query but with a sum_limit field that specifies when to stop traversing. Supports directional iteration (left-to-right or right-to-left), item count limits, and all existing QueryItem types (keys, ranges, etc.).
  • AggregateSumPathQuery (grovedb level): The path-level equivalent of AggregateSumQuery, wrapping it with a path to target a specific subtree. Supports merging multiple queries together.

New operations

  • GroveDb::aggregate_sum_path_query: Executes an aggregate sum query on a SumTree, returning elements until the cumulative sum reaches the specified limit.
  • Insert/merge logic for AggregateSumQuery: Supports inserting new query items and merging overlapping ranges, mirroring the existing Query insert/merge infrastructure.

Extension trait pattern

Since the Element type now lives in the grovedb-element crate, the query execution logic uses the ElementAggregateSumQueryExtensions trait to add aggregate sum query methods to Element.

Merge with develop

Resolved merge conflicts from significant develop refactoring:

  • Element system moved to grovedb-element crate (adapted with extension trait pattern)
  • Op/Node/encoding moved to grovedb-query crate
  • Dependency versions updated (bincode 2.0.1, blake3 1.8.1)
  • Query modules restructured into separate files

How Has This Been Tested?

  • test_aggregate_sum_path_query_basic — basic sum limit query on a SumTree
  • test_aggregate_sum_path_query_with_limit — sum limit + item count limit
  • test_aggregate_sum_path_query_descending — right-to-left traversal
  • test_aggregate_sum_path_query_key_not_found — querying a non-existent key
  • Full test suite passes (1134 tests)
  • Clippy passes with -D warnings

Breaking Changes

None — this is purely additive. QueryItem::merge_assign was made pub (previously pub(crate)) to support cross-crate usage.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 26, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR expands GroveDB and Merk functionalities by integrating new aggregate sum query capabilities. It introduces additional versioning fields, new structs, and methods across multiple modules to support aggregate sum operations. Key changes include the addition of aggregate sum path query methods in version constants, enhanced Element query operations, new error handling, and modifications in iterator validations. The Merk side now supports query insertion and merging logic for aggregate sum queries, and test utilities have been extended to handle new sum tree structures.

Changes

File(s) Change Summary
grovedb-version/src/version/grovedb_versions.rs, .../v1.rs, .../v2.rs Added new fields and structs (e.g., aggregate_sum_path_query_methods, get_aggregate_sum_query, query_aggregate_sums) to expand aggregate sum query support in versioning.
grovedb/src/element/aggregate_sum_query.rs Introduced aggregate sum query functionality via new query option structs and methods (get_aggregate_sum_query, get_aggregate_sum_query_apply_function) in the Element implementation.
grovedb/src/element/mod.rs, grovedb/src/element/query.rs Added a new module for aggregate sum queries and updated method calls by adding an extra parameter in iterator validation.
grovedb/src/error.rs, grovedb/src/lib.rs Added new error variant Overflow and a new public export for AggregateSumPathQuery.
grovedb/src/operations/get/query.rs Added the public method query_aggregate_sums in GroveDb to retrieve SumItem elements using aggregate sum queries.
grovedb/src/query/aggregate_sum_path_query.rs, grovedb/src/query/mod.rs, grovedb/src/query_result_type.rs Introduced a new module for aggregate sum path queries with the AggregateSumPathQuery struct and a new type alias KeySumValuePair; removed conditional compilation for query types.
grovedb/src/tests/mod.rs Added new helper functions to create and populate test sum trees for aggregate sum query testing.
merk/src/lib.rs, merk/src/merk/mod.rs, merk/src/proofs/aggregate_sum_query/*, merk/src/proofs/mod.rs, merk/src/proofs/query/query_item/mod.rs Removed license comment block, updated iterator method parameters, and added extensive aggregate sum query support (insertion, merging, new constructors, and removal of compile-time conditions) in Merk’s proofs modules.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant DB as GroveDb
    participant Elem as Element
    participant Query as AggregateSumQueryOptions

    Client->>DB: query_aggregate_sums(aggregate_sum_path_query, options...)
    DB->>DB: Perform version check
    DB->>Elem: Call get_aggregate_sum_query(QueryOptions)
    Elem->>Elem: Process aggregate sum query logic
    Elem-->>DB: Return SumItem results
    DB-->>Client: Return aggregated query results
Loading

Possibly related PRs

Suggested reviewers

  • fominok
  • lklimek

Poem

I'm a happy rabbit, hopping along in code,
New features bloom like carrots in a row.
Aggregate sums now add up with ease,
In every module, they flow like a breeze.
I nibble on bugs and hop past the overflow woes—
Here's to clean queries and code that always grows! 🐰✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/SumUpToQuery

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (13)
grovedb/src/tests/mod.rs (1)

125-146: Indentation inconsistency detected

The indentation for the .unwrap() and .expect() calls in this function differs from the indentation style used in the similar function add_test_leaves (lines 102-123).

-        .unwrap()
-        .expect("successful root tree leaf insert");
+    .unwrap()
+    .expect("successful root tree leaf insert");
-        .unwrap()
-        .expect("successful root tree leaf 2 insert");
+    .unwrap()
+    .expect("successful root tree leaf 2 insert");
merk/src/proofs/aggregate_sum_query/insert.rs (5)

1-5: Use consistent feature guards for clarity.
While feature gating is helpful, consider clarifying the relationship between "minimal" and "verify" features. If further down the line you add more complex logic that also depends on these features, it may be beneficial to centralize shared code under a single, more descriptive feature gate or utilize separate ones for clarity.


27-32: Method insert_keys: Optimize for large input sets if necessary.
Repeatedly calling self.insert_item() in a loop is fine for smaller key sets. However, consider using a more efficient approach (like sorting and merging) if this is used with a large collection of keys.


127-135: Method insert_all: Discarding existing items.
Using QueryItem::RangeFull to discard pre-existing items is straightforward, but ensure that downstream consumers understand that calling insert_all will reset all prior constraints. This can otherwise lead to confusion if the caller is unaware of the discard.


137-169: Method insert_item: Potential performance bottleneck.
The current approach recreates self.items via an iterator/filter for every insertion, which could be costly with very large queries. While likely fine for moderate usage, consider a more efficient data structure (e.g., a balanced tree or interval tree) if performance becomes critical.

Additionally, the unreachable!() branch might be triggered in unexpected corner cases if new collision logic is introduced. It's fine short term, but keep in mind it might lead to app crashes without graceful handling of unexpected states.


172-176: Method insert_items: Avoid partial insert states if an insertion fails.
If a future insertion can fail (e.g., memory issues, data validation, or advanced logic), consider whether you want a partial set of items inserted or an atomic approach that reverts the entire insertion. Right now, an error partway won't revert earlier successful insertions.

merk/src/proofs/aggregate_sum_query/mod.rs (7)

1-2: Organize module imports.
These submodules (merge, insert) are a sizable part of the query logic. If their size grows, consider moving them into a dedicated folder-like structure to keep them logically grouped and more discoverable.


9-11: Clarify doc comment for AggregateSumQuery.
The doc line states “resolve a proof which will include all the requested values.” Consider clarifying it also includes partial sums up to sum_limit if relevant. Right now, the mention of sum_limit is in the struct fields but not in the doc comment.


26-36: Display trait implementation: Provide optional new lines or indentation.
Your current implementation prints new lines between items, which is helpful for debugging, but you might want to ensure the output remains consistent even if the query is large. For instance, you could truncate the printed items if the list is too long.


38-58: Constructors new & new_range_full: Possible confusion with direction.
Both methods default left_to_right: true. If a user explicitly wants a reverse-ordered query, they might accidentally pick new and get the wrong behavior. Consider grouping or naming them more distinctly (like new_ascending_range_full, new_descending_range_full) for clarity.


81-89: Multiple constructor variants: Potential duplication of logic.
You have many constructors that differ slightly only by initial items or the direction. To reduce code duplication, consider using a helper function that sets the shared fields, then focusing each constructor on key or range specifics. This approach can simplify maintenance.

Also applies to: 91-99, 101-109, 111-119, 121-135


137-140: Method len: Evaluate naming.
len is short and direct. If you foresee adding more comprehensive query info (like distinct range counts vs. key counts), you might rename it or add specialized methods (e.g., total_items() or range_count()).


164-168: Method has_only_keys: Edge case for an empty query.
An empty query trivially satisfies has_only_keys because there are no range items, though logically it has zero keys. If you expect an empty query scenario, confirm it aligns with your usage patterns.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f89e03e and ed09592.

📒 Files selected for processing (20)
  • grovedb-version/src/version/grovedb_versions.rs (3 hunks)
  • grovedb-version/src/version/v1.rs (4 hunks)
  • grovedb-version/src/version/v2.rs (4 hunks)
  • grovedb/src/element/aggregate_sum_query.rs (1 hunks)
  • grovedb/src/element/mod.rs (1 hunks)
  • grovedb/src/element/query.rs (1 hunks)
  • grovedb/src/error.rs (1 hunks)
  • grovedb/src/lib.rs (1 hunks)
  • grovedb/src/operations/get/query.rs (2 hunks)
  • grovedb/src/query/aggregate_sum_path_query.rs (1 hunks)
  • grovedb/src/query/mod.rs (4 hunks)
  • grovedb/src/query_result_type.rs (2 hunks)
  • grovedb/src/tests/mod.rs (2 hunks)
  • merk/src/lib.rs (0 hunks)
  • merk/src/merk/mod.rs (1 hunks)
  • merk/src/proofs/aggregate_sum_query/insert.rs (1 hunks)
  • merk/src/proofs/aggregate_sum_query/merge.rs (1 hunks)
  • merk/src/proofs/aggregate_sum_query/mod.rs (1 hunks)
  • merk/src/proofs/mod.rs (1 hunks)
  • merk/src/proofs/query/query_item/mod.rs (1 hunks)
💤 Files with no reviewable changes (1)
  • merk/src/lib.rs
🧰 Additional context used
🧬 Code Definitions (3)
grovedb/src/query/mod.rs (2)
grovedb/src/operations/get/query.rs (1)
  • query (239-279)
grovedb/src/operations/proof/util.rs (1)
  • hex_to_ascii (284-299)
merk/src/proofs/aggregate_sum_query/merge.rs (3)
grovedb/src/query/aggregate_sum_path_query.rs (1)
  • new (38-40)
grovedb/src/query/mod.rs (2)
  • new (80-86)
  • new (109-111)
merk/src/proofs/aggregate_sum_query/mod.rs (1)
  • new (40-42)
grovedb/src/element/aggregate_sum_query.rs (7)
grovedb/src/query/aggregate_sum_path_query.rs (2)
  • fmt (24-33)
  • new (38-40)
grovedb/src/element/mod.rs (2)
  • fmt (147-236)
  • fmt (265-270)
grovedb/src/element/query.rs (5)
  • fmt (62-77)
  • fmt (176-228)
  • default (82-89)
  • format_query (114-147)
  • new (1708-1710)
grovedb/src/query/mod.rs (6)
  • fmt (40-49)
  • fmt (66-75)
  • fmt (464-476)
  • fmt (509-523)
  • new (80-86)
  • new (109-111)
grovedb/src/query_result_type.rs (7)
  • fmt (32-42)
  • fmt (53-59)
  • fmt (75-84)
  • fmt (88-92)
  • fmt (440-463)
  • default (423-425)
  • new (143-145)
grovedb/src/operations/get/query.rs (1)
  • query (239-279)
merk/src/proofs/mod.rs (1)
  • hex_to_ascii (120-126)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Compilation errors
  • GitHub Check: Tests
  • GitHub Check: Linting
  • GitHub Check: Code Coverage
🔇 Additional comments (69)
grovedb-version/src/version/grovedb_versions.rs (4)

8-8: Well-structured addition of aggregate sum path query support

The addition of aggregate_sum_path_query_methods to the GroveDBVersions struct properly integrates the new feature into the versioning system, ensuring backward compatibility.


14-17: Good structure for versioning the new feature

The new GroveDBAggregateSumPathQueryMethodVersions struct follows the established pattern for versioning feature capabilities, with the merge field allowing for proper version handling.


98-98: Consistent versioning for query operations

Adding query_aggregate_sums to GroveDBOperationsQueryVersions maintains consistency with the existing versioning pattern for query operations.


220-220: Complete versioning for element methods

All necessary method versions for the aggregate sum functionality have been added to GroveDBElementMethodVersions, covering the full range of operations: querying, applying functions, pushing to path queries, and handling items.

Also applies to: 225-225, 227-227, 230-230, 234-234

grovedb/src/query_result_type.rs (2)

18-18: Good import organization

Clean import of SumValue from the element module, keeping it separate for clarity.


495-497: Consistent type alias pattern

The KeySumValuePair type alias follows the established pattern for key-value relationships in the codebase, maintaining consistency with other similar type aliases like KeyElementPair.

grovedb/src/error.rs (1)

162-164: Well-defined error handling for aggregate operations

The addition of the Overflow error variant is appropriate for handling arithmetic overflow scenarios that might occur during aggregate sum operations. The error includes a descriptive string parameter for context, consistent with other error variants.

grovedb/src/lib.rs (1)

210-210: Clean public export of the new query type

Exporting AggregateSumPathQuery alongside existing query types makes the new functionality accessible to users while maintaining the established pattern.

grovedb/src/element/mod.rs (1)

23-24: LGTM - New module added for aggregate sum query functionality

The addition of the new aggregate_sum_query module is properly configured with the correct feature flags, consistent with other modules in this file. This module will contain the implementation for the AggregateSumPathQuery functionality described in the PR.

merk/src/merk/mod.rs (1)

147-149: Adding parameter to support new aggregate sum functionality

The method call has been correctly updated to pass an additional None parameter to the iter_is_valid_for_type method, aligning with the modified method signature in the QueryItem implementation.

merk/src/proofs/query/query_item/mod.rs (2)

793-797: LGTM - New parameter added to support aggregate sum querying

The addition of the aggregate_limit parameter of type Option<i64> is appropriate for implementing the aggregate sum path query functionality.


804-804: LGTM - Valid logic for aggregate limit validation

The validation logic for the new aggregate_limit parameter follows the same pattern as the existing limit parameter validation, ensuring consistency in how different types of limits are handled.

grovedb/src/tests/mod.rs (1)

87-100: Looks good: New utility method for creating GroveDB with sum trees

This new helper method follows the established pattern for test utility functions in GroveDB and properly creates a test database with sum trees, which will be useful for testing the new aggregate sum path query functionality.

grovedb/src/element/query.rs (1)

836-837: Method call updated with new parameter

The iter_is_valid_for_type method now takes an additional parameter (None) which is likely related to the new aggregate sum functionality being introduced. This change ensures compatibility with the updated method signature while maintaining backward compatibility by passing None for existing query types.

grovedb-version/src/version/v2.rs (8)

14-14: Added import for new aggregate sum path query methods

This import provides access to the GroveDBAggregateSumPathQueryMethodVersions struct, which is necessary for defining version information for the new aggregate sum functionality.


59-59: Added version field for aggregate sum query method

This new version field properly tracks the implementation version of the get_aggregate_sum_query method, aligning with the PR's objective to introduce aggregate sum query functionality.


64-64: Added version field for aggregate sum query apply function

This version field tracks the implementation version of the function that applies aggregate sum queries, consistent with the overall feature addition.


66-66: Added version field for aggregate sum path query push method

This tracks the version of the method that handles pushing aggregate sum path queries, which is a key component of the new functionality.


69-69: Added version field for basic aggregate sum push method

This tracks the version of the basic implementation for pushing aggregate sum values, maintaining versioning consistency across all related methods.


75-75: Added version field for aggregate sum query item method

This field tracks the implementation version of the method that processes individual items in aggregate sum queries.


136-136: Added version field for query_aggregate_sums operation

This field tracks the version of the operation that executes aggregate sum queries at the GroveDB level, properly integrating with the versioning system.


185-185: Added aggregate sum path query methods version struct

This field incorporates all aggregate sum path query-related methods into the versioning system with initial version 0, ensuring proper version tracking for the new functionality.

grovedb/src/operations/get/query.rs (4)

11-12: Added import for AggregateSumQuery

This import provides access to the necessary aggregate sum query structures from the Merk proofs module, supporting the new functionality.


14-14: Extended imports for aggregate sum related types

Additional element types like BigSumValue and CountValue are now imported to support the new aggregate sum functionality.


21-22: Added imports for aggregate sum query options and result types

These imports provide the specialized options and return types needed for the new aggregate sum query functionality.


492-516:

Details

✅ Verification successful

Added new method to query aggregate sums

The query_aggregate_sums method enables retrieving sum items that match an aggregate sum path query, implementing the core functionality described in the PR objectives. The method properly integrates with the cost tracking system and versioning checks.


🏁 Script executed:

#!/bin/bash
# Check if the referenced Element::get_aggregate_sum_query method has been implemented

# Search for the get_aggregate_sum_query method implementation
echo "Searching for get_aggregate_sum_query implementation..."
rg "fn get_aggregate_sum_query" -A 5

Length of output: 1174


Verified aggregate sums query implementation – Approved

The implementation of query_aggregate_sums in grovedb/src/operations/get/query.rs has been verified to correctly call Element::get_aggregate_sum_query, which is implemented in grovedb/src/element/aggregate_sum_query.rs. The method appropriately integrates cost tracking and version checks as intended.

No further changes are required.

grovedb/src/query/mod.rs (9)

3-4: Add new module for aggregate sum path query
Introducing pub mod aggregate_sum_path_query; is a clear way to encapsulate new functionality for aggregate sum path queries. No issues found here.


12-12: Unconditional bincode usage
Removing any gating attributes for bincode usage aligns with having a more unified codebase. Your unconditional import is fine.


15-15: Unconditional import of Key and SubqueryBranch
Allowing Key and SubqueryBranch to be used without conditional compilation is consistent with the rest of this file’s approach.


21-21: Expose hex_to_ascii utility unconditionally
Removing the feature gate for hex_to_ascii is consistent with the code’s broader usage.


23-23: Unconditional import of crate::Error
This is in line with the remainder of the file, ensuring errors are always accessible.


454-461: Make HasSubquery always available
Unconditionally deriving and exposing HasSubquery looks good. This helps keep the code straightforward and feature-flag free in this region.


462-462: Unconditional impl fmt::Display for HasSubquery
The display implementation is simple, and removing conditional compilation here is consistent with the newly unified approach.


495-495: Make SinglePathSubquery always available
This struct is now consistently exposed. Looks good.


507-507: Unconditional impl fmt::Display for SinglePathSubquery
Similarly, no issues with removing the feature gate. The display logic remains readable.

merk/src/proofs/aggregate_sum_query/merge.rs (3)

1-2: New imports for Error and AggregateSumQuery
Bringing these types in is straightforward. No issues here.


4-42: merge_multiple method logic
Merging multiple queries while enforcing the same left_to_right value and performing overflow checks on sum_limit and limit_of_items_to_check is carefully handled. Returning an error for mismatches or overflow scenarios is appropriate. The approach of producing None for limit_of_items_to_check when any input is None also appears reasonable for an unbounded stance.


44-66: merge_with method considerations
Similarly merges sum limits with proper overflow checks and merges item limits. Inserting items from the other query is neatly placed. No concurrency or logical pitfalls stand out.

merk/src/proofs/mod.rs (1)

9-10: Add aggregate_sum_query module
This supports the new aggregate sum functionality. Looks consistent with the broader effort in this PR.

grovedb-version/src/version/v1.rs (4)

14-14: New import usage is aligned with introduced functionality.

Importing GroveDBAggregateSumPathQueryMethodVersions looks consistent with the new methods introduced below and doesn't present any immediate issues.


59-75: New version fields align well with existing naming conventions.

These added version references:

  • get_aggregate_sum_query
  • get_aggregate_sum_query_apply_function
  • aggregate_sum_path_query_push
  • basic_aggregate_sum_push
  • aggregate_sum_query_item

are consistent with the established field naming scheme in GroveDBElementMethodVersions. This appears to be the correct approach for integrating new query-related methods into the versioning system, ensuring version compatibility checks can properly handle them.


136-136: Field name is consistent with existing query operations.

Adding query_aggregate_sums in GroveDBOperationsQueryVersions follows the same naming style as other query operations. This helps maintain clarity and consistency across the codebase.


185-185: New aggregate sum path query method version entry is coherent.

Including aggregate_sum_path_query_methods in GroveDBVersions is the appropriate way to keep the new merge logic encapsulated and version-controlled. The naming is succinct and mirrors existing patterns.

grovedb/src/query/aggregate_sum_path_query.rs (7)

1-9: Imports appear necessary and well-scoped.

All imported crates, modules, and traits (e.g., Decode, Encode, AggregateSumQuery, QueryItem, etc.) align with the file’s functionality. No redundancy is apparent, and the usage of version checks is consistent with the approach in the rest of GroveDB code.


10-21: Struct definition is clear and well-documented.

  • The public fields path and aggregate_sum_query are descriptive.
  • Documentation comments adequately explain purpose and usage.

23-34: fmt::Display implementation is straightforward and beneficial for debugging.

  • Using hex_to_ascii to render path elements is consistent with other parts of the code.
  • The format string is well-structured; errors are properly handled.

36-41: new constructor is concise and clear.

Returning Self { path, aggregate_sum_query } is idiomatic. No issues found.


42-48: new_single_key convenience constructor is helpful.

Use of AggregateSumQuery::new_single_key aligns well with the design, simplifying single-key usage.


50-56: new_single_query_item constructor extends functionality for more complex queries.

Provides an easy interface for adding one QueryItem and optional limit. Implementation looks correct.


58-99: merge method logic is robust and well-validated.

  • Checking for empty input and ensuring all paths match is good defensive programming.
  • Merging multiple AggregateSumQuery objects cleanly delegates logic to merge_multiple.
  • Error handling for mismatched paths or empty queries is consistent with GroveDB’s approach.
grovedb/src/element/aggregate_sum_query.rs (14)

1-9: Module-level comments and imports are logically grouped.

The doc comments effectively explain that this file implements aggregate sum querying in the Element struct. The imported modules (e.g., grovedb_merk, grovedb_storage) are appropriate for the sum query functionality.


32-37: AggregateSumQueryOptions struct encapsulates query behavior well.

Storing flags for raw retrieval, cache, and intermediate path-tree behavior helps ensure flexible query execution.


39-51: fmt::Display for AggregateSumQueryOptions is coherent.

  • The additional indentation and labeled fields make debugging more transparent.
  • No performance concerns for debug usage.

53-61: Default implementation sets cautious and safe behavior.

  • allow_cache: true is usually beneficial for performance.
  • error_if_intermediate_path_tree_not_present: true ensures explicit control over absent subtrees.

63-80: AggregateSumPathQueryPushArgs struct is straightforward.

  • Captures transaction, storage context, and limiting parameters for sum queries.
  • The 'db: 'ctx lifetime constraints align with typical Rust usage in DB contexts.

81-97: Helper function format_query aids debugging.

The structured formatting of items in AggregateSumQuery provides clarity for logs or error messages.


99-135: Display implementation for AggregateSumPathQueryPushArgs is consistent with GroveDB’s approach.

  • Renders all struct fields in a thorough, human-readable format.
  • Hex-encoding for keys is consistent across the codebase.

137-166: get_aggregate_sum_query method integrates version checks and delegated logic.

  • Good structure for bridging path-based queries to the generic apply function.
  • No immediate correctness issues identified.

168-250: get_aggregate_sum_query_apply_function handles iteration logic effectively.

  • Splitting the ascending and descending iteration via left_to_right is clean.
  • Properly breaks early if sum_limit or limit_of_items_to_check are reached, preventing unnecessary overhead.
  • The use of CostResult for error handling is consistent with GroveDB code.

252-282: aggregate_sum_path_query_push ensures sum items are handled properly.

  • Early check for SumItem elements avoids type mismatches.
  • The delegation to basic_aggregate_sum_push is logically separate, improving maintainability.

284-290: Inline documentation clarifies the performance-related rationale.

  • Explanation of expensive queries without limit reduction is relevant for sum-based workloads.

291-463: aggregate_sum_query_item merges iteration approach with robust error handling.

  • Distinguishes between key-based queries and range queries.
  • Skips or short-circuits gracefully depending on error_if_intermediate_path_tree_not_present.
  • Thorough checks to avoid partial or inconsistent results.

465-499: basic_aggregate_sum_push finalizes item insertion logic.

  • Correctly decrements limit and sum_limit_left.
  • Ensures references are converted if needed (convert_if_reference_to_absolute_reference).

503-1197: Extensive test coverage is commendable.

  • Multiple test scenarios (keys, ranges, single items, descending, sub-ranges) confirm correctness.
  • The variety of sum limits tested helps minimize regressions.
  • Test naming is intuitive and clarifies the expected behavior.
merk/src/proofs/aggregate_sum_query/insert.rs (2)

15-18: Method insert_key: Confirm fallback behavior for duplicates.
When adding an individual key that already belongs to an existing range, the code effectively becomes a no-op. This is correct for avoiding duplicates, but ensure your unit tests or usage patterns confirm this is the desired behavior (i.e., new calls won't silently mask other concerns if the key was already covered by a range).


40-43: Insertion of various range types: Validate range overlaps in tests.
All these methods rely on self.insert_item for merge logic when overlaps occur. Although the doc comments mention correct behaviors, ensure you have test coverage for scenarios like partially overlapping ranges, adjacent ranges, and identical ranges. Confirmation via robust unit tests will avoid subtle off-by-one or boundary misinterpretations.

Also applies to: 51-54, 63-66, 75-78, 87-90, 99-101, 111-113, 123-125

merk/src/proofs/aggregate_sum_query/mod.rs (3)

19-23: sum_limit & limit_of_items_to_check: Confirm protective boundaries.
Consider verifying that sum_limit remains within valid ranges (e.g., non-negative, or within an upper bound) and that limit_of_items_to_check doesn't exceed feasible memory constraints. Input validation or checks can help mitigate potential edge cases.


70-79: Method new_single_key: Potential edge case with no limit_of_items_to_check.
Currently it sets limit_of_items_to_check to Some(1). If the single key does not exist or is out of range, no records are found, and summing might be trivially zero. Ensure that’s indeed the intended fallback.


142-162: Iterators: Confirm consistent iteration order.
You offer standard .iter(), .rev_iter(), and .directional_iter(). Ensure that the logic for reversing is thoroughly tested, especially when mixing single keys and multiple ranges. Some boundary conditions might appear reversed in partial results.

Copy link
Copy Markdown
Contributor

@shumkov shumkov left a comment

Choose a reason for hiding this comment

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

👍 utACK

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
grovedb/Cargo.toml (1)

23-23: Enforce Exact Version for bincode Dependency
Changing the version constraint to =2.0.0-rc.3 ensures that only this exact version is used across builds. This change improves consistency in dependency resolution and minimizes unexpected updates from version ranges.

merk/Cargo.toml (1)

20-20: Consistent bincode Version Specification
The update to bincode = { version = "=2.0.0-rc.3" } aligns the dependency version with the configuration in grovedb. This consistency minimizes potential compatibility issues across components. Ensure that this strict version requirement is in line with overall dependency management and that it does not restrict future patch updates that might include necessary fixes.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed09592 and ac61efa.

📒 Files selected for processing (2)
  • grovedb/Cargo.toml (1 hunks)
  • merk/Cargo.toml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Compilation errors
  • GitHub Check: Linting
  • GitHub Check: Tests
  • GitHub Check: Code Coverage

Resolve merge conflicts from develop refactoring:
- Element system moved to grovedb-element crate (use extension trait pattern)
- Op/Node/encoding moved to grovedb-query crate
- Dependency versions updated (bincode 2.0.1, blake3 1.8.1)
- Query modules restructured into separate files

Additional fixes for AggregateSumPathQuery compatibility:
- Convert impl Element to ElementAggregateSumQueryExtensions trait
- Fix raw_decode import (helpers module removed, use ElementDecodeExtensions)
- Fix Error::WrongElementType -> Error::InvalidInput
- Make QueryItem::merge_assign public (needed cross-crate)
- Add MerkErrorExt import for error conversion
- Remove unused format_query and len methods

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@QuantumExplorer QuantumExplorer marked this pull request as ready for review March 3, 2026 18:31
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 3, 2026

Coverage Diff Report

Note: No baseline coverage data available for comparison. This is expected on the first run or after cache expiry. Showing PR coverage summary only.

PR coverage: 42397/49255 lines (86.08%)

New test functions detected: 44

44 new test functions (click to expand)
  • grovedb-query/tests/aggregate_sum_query_tests.rs: new_and_new_range_full_are_equivalent
  • grovedb-query/tests/aggregate_sum_query_tests.rs: new_descending_and_new_range_full_descending_are_equivalent
  • grovedb-query/tests/aggregate_sum_query_tests.rs: new_single_key
  • grovedb-query/tests/aggregate_sum_query_tests.rs: new_single_query_item
  • grovedb-query/tests/aggregate_sum_query_tests.rs: new_with_query_items
  • grovedb-query/tests/aggregate_sum_query_tests.rs: new_with_keys
  • grovedb-query/tests/aggregate_sum_query_tests.rs: new_with_keys_reversed
  • grovedb-query/tests/aggregate_sum_query_tests.rs: new_single_query_item_with_direction
  • grovedb-query/tests/aggregate_sum_query_tests.rs: iter_forward
  • grovedb-query/tests/aggregate_sum_query_tests.rs: rev_iter_reverse
  • grovedb-query/tests/aggregate_sum_query_tests.rs: directional_iter_delegates_correctly
  • grovedb-query/tests/aggregate_sum_query_tests.rs: has_only_keys_true_for_keys
  • grovedb-query/tests/aggregate_sum_query_tests.rs: has_only_keys_false_with_range
  • grovedb-query/tests/aggregate_sum_query_tests.rs: display_includes_direction_and_sum_limit
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_key
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_keys
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_range
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_range_inclusive
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_range_from
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_range_to
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_range_to_inclusive
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_range_after
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_range_after_to
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_range_after_to_inclusive
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_all_replaces_items_with_range_full
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_item_merges_overlapping_ranges
  • grovedb-query/tests/aggregate_sum_query_tests.rs: insert_items_batch
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_multiple_empty_returns_noop
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_multiple_single_returns_equivalent
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_multiple_two_queries
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_multiple_differing_left_to_right_errors
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_multiple_sum_limit_overflow_errors
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_multiple_none_limit_plus_some_limit_gives_none
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_multiple_limit_overflow_errors
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_with_adds_items_and_limits
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_with_differing_direction_errors
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_with_sum_limit_overflow_errors
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_with_limit_overflow_errors
  • grovedb-query/tests/aggregate_sum_query_tests.rs: merge_with_none_limit_gives_none
  • grovedb-query/tests/aggregate_sum_query_tests.rs: encode_decode_round_trip
  • src/element/aggregate_sum_query.rs b/grovedb/src/element/aggregate_sum_query.rs: test_get_aggregate_sum_query_full_range
  • src/element/aggregate_sum_query.rs b/grovedb/src/element/aggregate_sum_query.rs: test_get_aggregate_sum_query_full_range_descending
  • src/element/aggregate_sum_query.rs b/grovedb/src/element/aggregate_sum_query.rs: test_get_aggregate_sum_query_sub_ranges
  • src/element/aggregate_sum_query.rs b/grovedb/src/element/aggregate_sum_query.rs: test_get_aggregate_sum_query_on_keys

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 3, 2026

Codecov Report

❌ Patch coverage is 91.70931% with 81 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.60%. Comparing base (50f86b0) to head (c4440df).
⚠️ Report is 24 commits behind head on develop.

Files with missing lines Patch % Lines
grovedb/src/element/aggregate_sum_query/mod.rs 88.06% 55 Missing ⚠️
grovedb/src/operations/get/query.rs 91.17% 12 Missing ⚠️
grovedb/src/query/aggregate_sum_path_query.rs 95.48% 6 Missing ⚠️
grovedb/src/error.rs 0.00% 3 Missing ⚠️
grovedb-query/src/aggregate_sum_query/insert.rs 97.01% 2 Missing ⚠️
grovedb-query/src/aggregate_sum_query/mod.rs 98.31% 2 Missing ⚠️
merk/src/error.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #364      +/-   ##
===========================================
+ Coverage    86.90%   88.60%   +1.70%     
===========================================
  Files          176      189      +13     
  Lines        47133    49300    +2167     
===========================================
+ Hits         40959    43681    +2722     
+ Misses        6174     5619     -555     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

QuantumExplorer and others added 7 commits March 4, 2026 08:14
Introduces AggregateSumQuery struct with constructors, insert helpers,
merge operations, iterators, Display impl, and bincode serialization.
Adds Overflow variant to query Error enum. Includes 40 tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The new Overflow variant added to grovedb_query::error::Error was not
covered in the From conversion, causing a non-exhaustive match error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover all merge branches in QueryItem::merge, AggregateSumQuery merge
methods, AggregateSumPathQuery::merge, and Display impls to satisfy
the codecov/patch 80% threshold.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove 10 tests from grovedb-query/src/query_item/merge.rs that tested
pre-existing merge() code (not new in this PR, doesn't help patch
coverage). Add 5 new tests in grovedb/src/element/aggregate_sum_query.rs
targeting uncovered production paths: PathKeyNotFound handling, limit
break in ascending/descending loops, and missing key tolerance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Deduplicate AggregateSumQuery by removing merk copy, re-exporting from grovedb-query
- Fix u64→i64 silent truncation of sum_limit with try_into + Overflow error
- Fix sum_limit_left subtraction overflow with saturating_sub
- Fix limit underflow with saturating_sub
- Add early-return guard for exhausted limits (sum_limit <= 0 or limit == 0)
- Replace expect() panics on iterator with Error::CorruptedData propagation
- Add From<grovedb_query::error::Error> impl for grovedb Error
- Add test for zero sum_limit with key query

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… following to AggregateSumQuery

- Add skip_items/skip_references options to AggregateSumQueryOptions for
  silently skipping non-SumItem elements (skipped items still decrement limit)
- Add version-gated hard scan limit (GroveDBQueryLimits) to prevent unbounded
  iteration, returning partial results when reached
- Follow references up to 3 hops to resolve target elements instead of erroring
- Add GroveDBQueryLimits struct to grovedb-version with max_aggregate_sum_query_elements_scanned
- Handle ItemWithSumItem in basic_aggregate_sum_push alongside SumItem
- Add comprehensive tests for all new behaviors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…etadata

- Rename error_if_non_sum_item_or_reference_found to error_if_non_sum_item_found
  (remove misleading "or_reference" suffix — references handled by ignore_references)
- Expose AggregateSumQueryOptions in public API via query_aggregate_sums_with_options()
- Add AggregateSumQueryResult struct with hard_limit_reached flag for truncation detection
- Split aggregate_sum_query.rs into module directory (mod.rs + tests.rs)
- Rename skip_items/skip_references to error_if_non_sum_item_found/ignore_references
- Fix reference hop off-by-one (MAX=3 now allows 3 intermediate hops)
- Skipped elements no longer decrement user limit, only system elements_scanned
- Remove unused allow_get_raw field
- Add coverage gap tests (descending hard limit, descending skip, key query skip with limit)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Member Author

@QuantumExplorer QuantumExplorer left a comment

Choose a reason for hiding this comment

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

Self Reviewed

- Add tests for query_aggregate_sums and query_aggregate_sums_with_options
- Add Display test for AggregateSumPathQueryPushArgs
- Remove unused AggregateSumQueryResult import from tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@QuantumExplorer QuantumExplorer merged commit 539dfa4 into develop Mar 5, 2026
10 checks passed
@QuantumExplorer QuantumExplorer deleted the feat/SumUpToQuery branch March 5, 2026 04:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants