Skip to content

refactor: PathQuery::classify() — one shared shape decision for query dispatch - #795

Merged
QuantumExplorer merged 1 commit into
developfrom
claude/pathquery-classify-shape
Aug 14, 2026
Merged

refactor: PathQuery::classify() — one shared shape decision for query dispatch#795
QuantumExplorer merged 1 commit into
developfrom
claude/pathquery-classify-shape

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Aug 13, 2026

Copy link
Copy Markdown
Member

Context

This is PR 1 of the unified PathQuery effort: making PathQuery express and serve every query shape (key selection, aggregates, count-offset pagination, and — in upcoming PRs — indexed-axis reads and sum-budget reads) through one classification shared by reader, prover, and verifier.

Today each entry point re-discovers the shape of the query it was handed by calling the has_* / validate_* helpers in its own order. Since prover and verifier must agree on what a query means (the proof does not carry the query), that discovery is consensus-relevant — and it currently exists in several copies.

What this does

  • PathQuery::classify() -> Result<PathQueryShape, Error> (new grovedb/src/query/shape.rs): pure (no DB access — a verifier holding only the query classifies identically to the prover), total (every query maps to exactly one shape or a typed InvalidQuery), and mirrors prove_query_non_serialized's exact gate order (aggregate-count → aggregate-sum → combined → count-offset → key selection) so future call-site migrations keep their error surface byte-for-byte.
  • Shapes: KeySelection, CountOffsetPaginated, AggregateLeaf/AggregateCarrier × AggregateKind::{Count, Sum, CountAndSum}. Axis and sum-budget shapes arrive with the vocabulary PR.
  • Behavior-preserving: implemented entirely over the existing validators; nothing dispatches through it yet. The LOCKED V0/V1 prover internals are untouched.
  • grovedbg drift fix: the debugger's mirrored Query lacked add_parent_tree_on_subquery and the converter hardcoded false, so debugger-issued queries could never exercise the flag. Added with serde(default) so older frontend payloads keep decoding.

Tests

  • Error-surface equality tests: for malformed aggregate / count-offset queries, classify() must return the exact error the corresponding validator returns.
  • Shape tests for every family (leaf + carrier × 3 kinds), the limit/offset size-constraint split, offset == Some(0) treated as no offset, and mixed-aggregate rejection.
  • Totality grid: item sets × subqueries × limits × offsets × path emptiness — classify never panics and only fails with InvalidQuery.
  • Full grovedb + grovedb-query suites green; --no-default-features --features verify build green.

Noted in passing (not fixed here)

While writing tests: Query::insert_item collision-merges an aggregate wrapper with an overlapping plain item and silently degrades it to a plain range (AggregateCountAndSumOnRange(Range(a..z)) + insert_key("extra")items == [Range(a..z)]). Pre-existing; will be filed/fixed separately.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added query shape classification for key selection, pagination, and count, sum, or combined aggregate queries.
    • Exposed query shape and aggregate type information for broader query tooling support.
  • Bug Fixes
    • Subqueries now correctly preserve the option to include parent tree data.
  • Compatibility
    • Query payloads from older versions remain supported when the new option is absent.

…uery dispatch

Every prove/verify/read entry point currently re-discovers what kind of
query it was handed by calling the has_*/validate_* helpers in its own
order. This adds PathQueryShape and PathQuery::classify() as the single
named version of that decision — pure (no DB, so a verifier classifies
identically to the prover), total (every query maps to one shape or a
typed InvalidQuery), and mirroring prove_query_non_serialized's exact
gate order so migrating call sites keep their error surface. Behavior-
preserving: classify() is implemented entirely over the existing
validators and nothing dispatches through it yet; it is the foundation
for the unified-PathQuery work (axis reads, sum-budget reads) that
follows.

Also fixes a grovedbg drift: the debugger's mirrored Query type lacked
add_parent_tree_on_subquery and the converter hardcoded it to false, so
debugger-issued queries could never exercise the flag. The field is
serde(default) so payloads from older frontends keep decoding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 00c15032-92fc-4bbf-a361-c346da3d6b01

📥 Commits

Reviewing files that changed from the base of the PR and between a2791bb and f5c2875.

📒 Files selected for processing (5)
  • grovedb/src/debugger.rs
  • grovedb/src/lib.rs
  • grovedb/src/query/mod.rs
  • grovedb/src/query/shape.rs
  • grovedbg-types/src/lib.rs

📝 Walkthrough

Walkthrough

The change adds pure PathQuery shape classification with public shape types and feature-gated exports. It also adds backward-compatible serialization for add_parent_tree_on_subquery and preserves that value during debugger query conversion.

Changes

Query Shape Classification

Layer / File(s) Summary
PathQuery shape classifier
grovedb/src/query/shape.rs
Adds AggregateKind, PathQueryShape, and PathQuery::classify. Tests cover pagination, aggregate forms, validation errors, precedence, and totality.
Public shape exports
grovedb/src/query/mod.rs, grovedb/src/lib.rs
Declares the shape module and re-exports AggregateKind and PathQueryShape under the supported feature gates.

Query Flag Propagation

Layer / File(s) Summary
Parent-tree query flag propagation
grovedbg-types/src/lib.rs, grovedb/src/debugger.rs
Adds add_parent_tree_on_subquery with a default of false and forwards the source value during query conversion.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Mergeability Score: ⚪ Minimal · up to f5c28

This change adds query-shape classification and preserves existing behavior, with no actionable merge-blocking risk remaining after normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a shared PathQuery::classify() decision for query dispatch.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/pathquery-classify-shape

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

@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.28814% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.24%. Comparing base (a2791bb) to head (f5c2875).

Files with missing lines Patch % Lines
grovedb/src/query/shape.rs 97.28% 8 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #795      +/-   ##
===========================================
+ Coverage    92.21%   92.24%   +0.02%     
===========================================
  Files          257      258       +1     
  Lines        78176    78471     +295     
===========================================
+ Hits         72091    72382     +291     
- Misses        6085     6089       +4     
Components Coverage Δ
grovedb-core 90.45% <97.28%> (+0.05%) ⬆️
merk 93.13% <ø> (ø)
storage 87.00% <ø> (ø)
commitment-tree 96.05% <ø> (ø)
mmr 96.79% <ø> (ø)
bulk-append-tree 89.82% <ø> (ø)
element 97.95% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@QuantumExplorer QuantumExplorer left a comment

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.

Reviewed

@QuantumExplorer
QuantumExplorer merged commit 90c1f68 into develop Aug 14, 2026
11 checks passed
@QuantumExplorer
QuantumExplorer deleted the claude/pathquery-classify-shape branch August 14, 2026 01:34
QuantumExplorer added a commit that referenced this pull request Aug 14, 2026
…uery stack)

Brings the branch across #795-#809: the aggregate_over_value_range
rename, GroveVersion params on the indexed-axis family, the
AggregateFold grammar, and the dual-aggregate (PCPS) count secondary.

Adaptations beyond conflict resolution:
- run_path_query's RankedPage dispatch consumes the new
  IndexedTopKPage return shape (.entries); surfacing the true
  'skipped' through PathQueryRun is left as a unified-API follow-up.
- lib.rs re-export conflict: both re-exports kept.

Zero changes to the counted-descent core: its generic already handled
ProvableCountAndSum aggregates (sum/avg secondaries were PCPS since
its base, #791), so #809's count-axis flip lands on an
already-supported flavor — the full workspace suite passes unmodified.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant