Skip to content

Commit 39ff806

Browse files
zzylolclaude
andcommitted
chore(types): delete the dag_export module
Nothing outside tests and comments used it once the dag_export bin was gone; the viewer reads stage_pipeline documents. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 7fc5190 commit 39ff806

11 files changed

Lines changed: 25 additions & 1863 deletions

File tree

‎.github/workflows/rust.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
- 'Cargo.toml'
99
- 'Cargo.lock'
1010
- '.github/workflows/rust.yml'
11-
# The types tests validate the viewer's exported-kind contract.
11+
# The devtools viewer_contract test validates the viewer's operator-kind contract.
1212
- 'tools/dag-viewer/**'
1313
pull_request:
1414
types: [opened, synchronize, reopened, ready_for_review]
@@ -17,7 +17,7 @@ on:
1717
- 'Cargo.toml'
1818
- 'Cargo.lock'
1919
- '.github/workflows/rust.yml'
20-
# The types tests validate the viewer's exported-kind contract.
20+
# The devtools viewer_contract test validates the viewer's operator-kind contract.
2121
- 'tools/dag-viewer/**'
2222
workflow_dispatch:
2323

‎crates/devtools/tests/viewer_contract.rs‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
//! `tools/dag-viewer` ↔ `asap_types::dag_export` contract: the viewer's
2-
//! `KIND_CATEGORY_JSON` must categorize exactly the `kind` strings
3-
//! [`asap_types::dag_export::export`] can emit — `Operator::kind_name()` of
4-
//! every `NonASAPOp` and `ASAPOp` variant — no more (a stale kind the IR no
5-
//! longer has) and no less (an exported kind the viewer would render
6-
//! uncategorized).
1+
//! `tools/dag-viewer` ↔ IR contract: the viewer's `KIND_CATEGORY_JSON` must
2+
//! categorize exactly the `Operator::kind_name()` strings of every
3+
//! `NonASAPOp` and `ASAPOp` variant — no more (a stale kind the IR no longer
4+
//! has) and no less (a kind the viewer would render uncategorized).
75
86
use std::collections::{BTreeMap, BTreeSet};
97

‎crates/integration-tests/tests/exact_composition.rs‎

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Issue #171 — composing exact operators with summary plans across
22
//! explicit update/evaluation boundaries, end to end through
33
//! `search_workload_with` → `candidate_selection::global_selection` →
4-
//! `GlobalSelection::assemble_selected_dag` → `dag_export`.
4+
//! `GlobalSelection::assemble_selected_dag`.
55
//!
66
//! Covers the issue's integration matrix: both nesting directions, grouped
77
//! fine-to-coarse and identity folds, one inner summary shared by several
@@ -13,7 +13,7 @@
1313
use std::rc::Rc;
1414

1515
use asap_integration_tests::fixtures::lower_promql;
16-
use asap_integration_tests::post_asap::{maintained, post_asap_dag, timed};
16+
use asap_integration_tests::post_asap::{maintained, timed};
1717
use asap_logical_optimizer::pass1::exact_composition::ExactOperation;
1818
use asap_logical_optimizer::pass1::replacement::{
1919
default_strategies, search_workload_with, ASAPStrategies, Replacement, ReplacementProvenance,
@@ -25,11 +25,9 @@ use asap_plan_selection::cost::cost_model::{
2525
CostProvenance, CostUnit, ExactCompositionCostInputs, ExactCompositionCostRequest,
2626
};
2727
use asap_plan_selection::{CostModel, DefaultCostModel, EvaluationRate};
28-
use asap_types::dag_export;
29-
use asap_types::ir::data_state;
30-
use asap_types::ir::operator::{default_quantile, AggIntent};
31-
use asap_types::ir::operator::{Reduction, Source};
32-
use asap_types::ir::physical_export::PhysicalASAPOperatorPayload;
28+
use asap_types::ir::operator::agg_intent::{default_quantile, AggIntent};
29+
use asap_types::ir::operator::operator_properties::{Reduction, Source};
30+
use asap_types::ir::properties::timing::data_state;
3331
use asap_types::ir::properties::{ExecutionDataState, ExecutionTiming};
3432
use asap_types::ir::schema::{DataType, Field, Schema};
3533
use asap_types::ir::schema::{ExactKind, FieldDataType, SketchAlgorithm, SummaryUpdate};
@@ -703,43 +701,6 @@ fn missing_cost_statistics_preserve_the_conservative_retain_exact() {
703701
.any(|e| e.kind == ExplanationKind::ExactComposition));
704702
}
705703

706-
// ── DAG export: explicit stage, schema, provenance ───────────────────────
707-
708-
#[test]
709-
fn dag_export_carries_explicit_stage_and_plain_schema_for_a_composed_plan() {
710-
let root = agg(vec![0], AggIntent::Max { col: None }, fine_quantile());
711-
let space = plan(vec![("q", root)]);
712-
let root = &space.roots[0].1;
713-
let composed = global_selection(&space, &StatsModel)
714-
.assemble_selected_dag(root)
715-
.unwrap()
716-
.unwrap();
717-
let dag = dag_export::export_summary(&composed);
718-
let node = &dag.nodes[dag.root as usize];
719-
assert_eq!(node.kind, "aggregate");
720-
assert!(node.detail["measures"].is_array());
721-
// Timing is explicit in the wire-6 DAG: the root is a relational
722-
// aggregate placed at query time.
723-
let wire = post_asap_dag(&composed);
724-
let wire_root = wire.nodes.iter().find(|n| n.id == wire.roots[0]).unwrap();
725-
assert!(matches!(
726-
wire_root.payload,
727-
PhysicalASAPOperatorPayload::NonASAP(NonASAPOp::Aggregate { .. })
728-
));
729-
assert_eq!(wire_root.output_state.timing, ExecutionTiming::QueryTime);
730-
731-
// Pre-ASAP export of the same target still describes the same columns.
732-
let pre = dag_export::export(root);
733-
let pre_root = &pre.nodes[pre.root as usize];
734-
let pre_cols: Vec<String> = pre_root.schema.as_ref().unwrap()["fields"]
735-
.as_array()
736-
.unwrap()
737-
.iter()
738-
.map(|c| c["name"].as_str().unwrap().to_string())
739-
.collect();
740-
assert_eq!(pre_cols, names(&composed));
741-
}
742-
743704
/// The PromQL front end produces the exact issue shape and it composes.
744705
#[test]
745706
fn promql_max_by_zone_over_quantile_over_time_composes() {

‎crates/logical-optimizer/src/pass1/explanation.rs‎

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,10 @@ pub enum ExplanationKind {
232232
/// [`crate::pass1::replacement::ReplacementSubDAG::rationale`]).
233233
///
234234
/// `node_hash` is [`structural_hash`](asap_types::ir::cse::structural_hash)
235-
/// of the `TargetSubDAG`'s own `target` sub-DAG — the same function, on the
236-
/// same `Rc<OperatorNode>` shape, that [`asap_types::dag_export::DAGNode::hash`]
237-
/// is computed with. A downstream consumer that independently exported the
238-
/// same node (e.g. via `asap_types::dag_export::export`) can match
239-
/// this explanation to a `DAGNode` by first comparing hashes and then
240-
/// confirming structural equality with [`ReplacementExplanation::target`].
235+
/// of the `TargetSubDAG`'s own `target` sub-DAG. A downstream consumer that
236+
/// hashed the same node can match this explanation by first comparing hashes
237+
/// and then confirming structural equality with
238+
/// [`ReplacementExplanation::target`].
241239
#[derive(Debug, Clone, PartialEq)]
242240
pub struct ReplacementExplanation {
243241
pub kind: ExplanationKind,
@@ -300,10 +298,9 @@ fn findings_from_candidate_logical_asap_dags(
300298
space: &CandidateLogicalASAPDAGs<String>,
301299
) -> Vec<ReplacementExplanation> {
302300
let locations = collect_locations(&space.roots);
303-
// One cache for the whole pass, mirroring `dag_export::export`'s own
304-
// `HashCache` reuse — this is a bottom-up pass over every discovered
305-
// group, so amortizing the cache across groups (rather than resetting it
306-
// per group) is real, not just a micro-optimization.
301+
// One cache for the whole pass — this is a bottom-up pass over every
302+
// discovered group, so amortizing the cache across groups (rather than
303+
// resetting it per group) is real, not just a micro-optimization.
307304
let mut hash_cache = HashCache::new();
308305
let mut findings = Vec::new();
309306
for group in space.target_subdag_candidates() {
@@ -581,30 +578,6 @@ mod tests {
581578
assert!(sketch[0].reason.to_lowercase().contains("kll"));
582579
}
583580

584-
/// `node_hash` must be the literal `structural_hash` a downstream
585-
/// consumer would compute over the *same* `OperatorNode` sub-DAG via
586-
/// `asap_types::dag_export::export` — the whole point of carrying it is
587-
/// that two independent exports of the same DAG agree, with no
588-
/// string-matching against `location` required.
589-
#[test]
590-
fn node_hash_matches_dag_export_hash_for_the_same_sub_dag() {
591-
let q = agg(vec![2], default_quantile(0.99), metric_scan(&["job"]));
592-
let dag = asap_types::dag_export::export(&q);
593-
let expected_hash = dag.nodes[dag.root as usize].hash;
594-
595-
let findings = explain_replacements(vec![("dashboard_p99", q)]);
596-
let sketch = findings
597-
.iter()
598-
.find(|f| f.kind == ExplanationKind::SketchApproximation)
599-
.expect("expected a sketch finding");
600-
assert_eq!(
601-
Some(sketch.node_hash),
602-
expected_hash,
603-
"ReplacementExplanation::node_hash must match dag_export's DAGNode::hash \
604-
for the same OperatorNode sub_dag"
605-
);
606-
}
607-
608581
#[test]
609582
fn exact_quantile_is_not_a_sketch_applicability_finding() {
610583
let q = agg(

‎crates/logical-optimizer/src/pass1/replacement.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8192,8 +8192,7 @@ mod tests {
81928192
let Replacement::SubDAG(node) = &candidate.replacement else {
81938193
unreachable!()
81948194
};
8195-
let exported = asap_types::dag_export::export_summary(node);
8196-
assert!(exported.nodes[exported.root as usize]
8195+
assert!(node
81978196
.guarantee
81988197
.as_ref()
81998198
.is_some_and(ResultGuarantee::has_unknown));

‎crates/types/Cargo.toml‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ edition = "2021"
1010
[dependencies]
1111
# "rc" — OperatorNode child fields are Rc<OperatorNode> (issue #212, #222:
1212
# shared sub-expressions), and Rc<T>'s Serialize/Deserialize impls live behind
13-
# this feature flag. dag_export.rs / DAGNode already flatten the DAG to a
14-
# node+edge list for JSON export, so this does not change wire format — a
15-
# shared Rc still (de)serializes as an ordinary inline value, once per
16-
# reference, exactly like the old Box.
13+
# this feature flag. A shared Rc still (de)serializes as an ordinary inline
14+
# value, once per reference, exactly like the old Box.
1715
serde = { version = "1", features = ["derive", "rc"] }
1816
serde_json = "1"
1917
thiserror = "2"

‎crates/types/src/cost.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,7 @@ where
420420
/// Whole-selected-workload cost/benefit — one query's (or one workload
421421
/// batch's) aggregate baseline, selected, and benefit, built from
422422
/// [`sum_workload_costs`] over that scope's own per-decision node
423-
/// annotations. See [`crate::dag_export::NamedDAG::workload_cost`] /
424-
/// [`crate::dag_export::WorkloadDAG::workload_cost`].
423+
/// annotations.
425424
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
426425
pub struct WorkloadCostSummary {
427426
pub baseline_cost: CostAnnotation,

0 commit comments

Comments
 (0)