feat(core): interface types for L1 input, L3 intent algebra, L4 sketch algebra - #3
Conversation
…L4 sketch algebra Introduces the Cargo workspace skeleton and the `asap-control-core` crate with pure interface/boundary types for three pipeline layers — no logic, no I/O, no external dependencies. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exact accumulators need to be representable in
|
|
One clarification on |
…#2, #3) Locks behavior introduced by the recent fixes, +5 tests (125→130): - promql_conformance: nested unary negation propagates rejection (`a - -b`, `sum(-x)`), not just top-level; and count→Cardinality threads the AccuracyTarget (Exact stays exact, Epsilon carried) — pins review #2. - sql_lowering: a qualified WHERE on the *duplicated* join column (`WHERE hosts.service = ...`) binds to the qualified position (4), not the first `service` (1) — extends the #7 disambiguation past the join key. - error.rs: `UnsupportedFeature` Display is language-neutral (no "PromQL") — pins the #3 fix without depending on DataFusion plan shapes. - schema.rs: `Column.table` deserializes to `None` when the key is absent (the `#[serde(default)]` backward-compat contract), and a qualified column round-trips. Full workspace green (130 tests), clippy -D warnings + fmt clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… mark reserved nodes (L2 review #3/#4/#6) - #4: remove `AggItem.distinct` — a write-only field the converter never read, redundant with `AggFunc::CountDistinct` (COUNT(DISTINCT) sets the func; value DISTINCT is rejected up front). It encoded "distinct" a second way, consumed zero ways. - #6: `AggItem.alias` is now `Option<String>` (was a `""` sentinel), matching its sibling `L2ProjectItem.alias`. The converter maps `None → ""` for L3's `output_names` sentinel; PromQL emits `None`, SQL `Some(name)`. - #3: doc-mark the L2 nodes no front end produces as **Reserved** — `Ref`/`LetBinding` (CSE is L3), `Merge` (UNION→SetOp), L2 `Partition` (PromQL emits `Aggregate.keys`), and `PartitionKeys::Without` (rejected up front) — so the dead converter arms read as intentional, not oversights. No behavior change. Full suite green (133), clippy + fmt clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restructure the flat 19-section developer guide into the three-part structure the doc owner asked for: Part 1 - Code Architecture, Part 2 - Interfaces and Definitions, Part 3 - How to Add X, Y, Z (each ending in how to verify). Content is moved, not rewritten: Part 1 (Mental model first, per doc-owner follow-up, then a new whole-PR architecture diagram, then "How the current pieces fit together"): - old #1 Mental model -> Part 1 #1 - new: whole-PR architecture diagram (TargetSubDAG's two entry points through ReplacementStrategy, PlanSpace/cost_sorted, explanation.rs, to a downstream consumer) -> Part 1 #2 - old #3 How the current pieces fit together -> Part 1 #3 Part 2: - old Terminology's "Implementation" definition merged into the Glossary as one more entry (### Implementation), next to ReplacementStrategy - old #2 Glossary -> Part 2 #1 (plus the merged Implementation entry and old #10 Matcher, retitled to match glossary-entry style) - old #10 Matcher (implementation.rs) -> ### Matcher inside the Glossary; implementation.rs no longer exists, so the stale title is fixed - old #19's definitional content (ReplacementExplanation/ ExplanationKind shapes, node_hash, why there's no ExplanationRule trait, location-text ownership) -> Part 2 #2 Part 3: - old #4, #5, #6, #7, #13, #14 -> Part 3 #1, Adding a new ReplacementStrategy (ending in Testing a new strategy) - old #8, #9, #15 -> Part 3 #2, Adding or customizing a CostModel (ending in Testing a new cost model) - old #12 -> Part 3 #3, Adding a new sketch algorithm, with its stale implementation.rs/binder references fixed to replacement.rs/ construct_summary vocabulary, plus a new "Verifying a new sketch algorithm" close grounded in the existing coverage-matrix tests - old #11, #16, #17, #18 -> Part 3 #4-#7 (capstone + closing reference material); #18's extension-map table's implementation.rs row fixed to replacement.rs - old #19's "Using it"/"Adding a new kind" content -> Part 3 #8, Using and extending explanation.rs cargo build --workspace --all-targets is clean (docs-only change). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
Cargo.tomlat root,crates/core/)QueryWorkload,QueryLanguage(withSqlDialectvariants),BatchEntry,RepeatingEntry,DataCharacteristics,DataDistribution,QueryRequirementsintent_algebra):QueryExprDAG withRc<L3Node>children,L3Schema/L3DataType/L3Field,HasSchematrait,AggIntent,Source,TimeWindowKind(renamed fromWindowKind)sketch_algebra):SummaryExprDAG withRc<L4Node>children,L4Schema/L4DataType(Primitive(L3DataType) | Sketch(SketchKind, SketchParams)),SketchKind,SketchParams,SketchQueryAccuracyTargetenum (Epsilon/EpsilonDelta/Exact) intypes.rsDesign choices
L3Node { expr: QueryExpr, schema: L3Schema }andL4Node { expr: SummaryExpr, schema: L4Schema }— everyRc<*Node>pointer IS an edge, carrying the child's output schema inline. No separate Edge type.L4DataType::Primitive(L3DataType)wraps L3 types;L4DataType::Sketch(...)is L4-only. L3 nodes structurally cannot carry sketch-typed columns.AggIntentandHasSchemaaretodo!()stubs. Zero external dependencies.Test plan
cargo checkpasses with zero warnings🤖 Generated with Claude Code