Skip to content

docs(engine): pin the sketch-vs-precompute query gap with file:line citations - #252

Merged
zzylol merged 1 commit into
mainfrom
engine-path-debug
May 15, 2026
Merged

zzylol merged 1 commit into
mainfrom
engine-path-debug

Conversation

@zzylol

@zzylol zzylol commented May 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Engine-path debug session result. Diagnoses precisely why the e2e tests' query path returns bad_data / "No result for query" even after #247#250 fixed the wire-format and L5-walk gaps.

Root cause

query_precomputes_by_agg (storage_engines/sketch_db/index/mod.rs:432, called unconditionally by engine.rs::execute_store_query) filters its candidate-sid scan with:

matches!(&m.agg_kind, AggKind::ExactAgg { agg_type: t, .. } if *t == agg_type)

It NEVER matches AggKind::Sketch. OTLP-arriving DDSketch / KLL / HLL / CountSketch / CountMinSketch DPs register with AggKind::Sketch { kind, config, .. } (per route_modified_otlp_sketches_to_precompute at otel.rs:1081), so this lookup always returns empty for them.

Sketches DO reach SketchStore — they're readable via the sid-keyed query_range(sid, ...) path (filters by payload.as_sketch()). The agg-keyed precompute lookup is the gap.

What this PR delivers

Doc-comment blocks at both:

  • the call site (engine.rs::execute_store_query) — explains why the call returns empty for sketch-backed aggs
  • the function definition (mod.rs::query_precomputes_by_agg) — explains why the filter excludes sketches

Both citations include file:line pointers + the diagnosis trail (#247#248#249#250 → engine-path debug session).

Two fix paths flagged for the next PR

  1. Teach query_precomputes_by_agg to also collect sketch payloads (assemble Box<dyn AggregateCore> from payload.as_sketch()). Non-trivial because the existing pipeline expects precompute payload shapes.

  2. Route handle_query through ASAPQueryEngine::execute(&str) trait dispatcher (engine.rs:3430) which already does idx.sids_for_policy(fp) + reducer dispatch and handles sketches natively via SketchReducer::evaluate.

Test plan

  • cargo check clean (no behaviour change)
  • cargo test --lib --tests: 690 + 27 + 62 + 768 passed; 0 failed

🤖 Generated with Claude Code

…itations

Engine-path debug session diagnosis (post-#247#248#249#250).

The query layer's "No result for query" symptom for sketch-backed
metrics has a precise root cause: `query_precomputes_by_agg` (called
unconditionally by `execute_store_query`) filters its candidate-sid
scan with `matches!(&m.agg_kind, AggKind::ExactAgg { … })` — never
matching `AggKind::Sketch`. Since OTLP-arriving DDSketch / KLL / HLL /
CountSketch / CountMinSketch DPs are registered with
`AggKind::Sketch { kind, config, .. }`, the lookup always returns an
empty map for them, the engine bubbles up "No precomputed outputs
found", and `handle_query` returns `None` → HTTP responds
`errorType: bad_data` / `error: "No result for query"`.

Sketches DO reach `SketchStore` — they're readable via the sid-keyed
`query_range(sid, ...)` path which filters on `payload.as_sketch()`.
The agg-keyed precompute lookup is the gap.

This PR adds doc-comment blocks at both the call site
(`engine.rs::execute_store_query`) and the function definition
(`mod.rs::query_precomputes_by_agg`) flagging the gap with
file:line citations and pointing at the two viable fixes:
  * teach `query_precomputes_by_agg` to also collect sketch
    payloads (assemble `Box<dyn AggregateCore>` from
    `payload.as_sketch()`) — non-trivial; payload shapes diverge.
  * route the legacy `handle_query` path through the newer
    `ASAPQueryEngine::execute(&str)` trait dispatcher (around
    engine.rs:3430) which already handles sketches via
    `idx.sids_for_policy(fp)` + reducer dispatch.

No behaviour change. 690 lib + 27 binary tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zzylol
zzylol merged commit 3155fe0 into main May 15, 2026
zzylol added a commit that referenced this pull request May 15, 2026
…path (#253)

Closes the gap pinned in #252: the legacy ASAPQueryEngine::handle_query
path can't read sketch-backed sids (`query_precomputes_by_agg` only
matches `AggKind::ExactAgg`), but the modern `execute(&str)` trait
path (engine.rs:3430) DOES — it dispatches via
`find_matching_policies` → `idx.sids_for_policy(fp)` →
`SketchReducer::evaluate` and handles sketches natively.

`process_via_simple_engine` (the HTTP handler for SketchStore-routed
queries) now falls back to `execute(&str)` when `handle_query`
returns None. Trait dispatch loses `KeyByLabelNames`; we surface
`KeyByLabelNames::default()` (mirroring `process_via_router`'s
identical handling on line 1171) — the Prometheus adapter renders
the empty `metric: {}` shape, valid PromQL response.

## Setup-side fix (the actual bug Test 3 surfaced)

The diagnostic also caught a missing `.with_sketch_index(idx)` call in
the test harness — without it, the engine's `sketch_index` is `None`
and EVERY fast path (`execute_store_query`, `execute(&str)`,
`query_range`, …) is silently skipped because they all guard with
`let Some(idx) = self.sketch_index.as_ref() else { return … };`.
This is a load-bearing wiring step that production `data_plane/main.rs`
gets right but `start_test_server` callers were missing.

Both `start_backend_http_server` and `start_full_stack` now thread
`with_sketch_index(sketch_index.clone())` so the engine's reads see
the same store the OTLP receiver / precompute engine writes to.

## Test 3 strict assertion now active

`controller_plan_to_query_full_roundtrip_ddsketch` previously
soft-checked the response had a `status` field. After this PR it
asserts `status == "success"` — the FULL e2e path
(controller plan → POST /api/v1/streaming-config → OTLP DDSketch DPs
→ window close → GET /api/v1/query) now works end-to-end.

This is the first time we have a green-bar e2e test for the
gateway-less data path.

## Tests

- `cargo test --test e2e_controller_plans_and_backend_serves`:
  3 passed, 0 failed (was 2/3 with Test 3 soft-checked).
- Full sweep: lib 690 + bins 27 + integration tests across the
  workspace all green.

## Out of scope

The legacy `query_precomputes_by_agg` filter still doesn't include
`AggKind::Sketch` (per #252's diagnostic comment). Closing that fully
— so `handle_query` itself works for sketches — would let us delete
this fallback. Not blocking; the fallback is a stable bridge.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zzylol
zzylol deleted the engine-path-debug branch July 17, 2026 20:05
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