From de1acb3e83bea37530d71b14e065d450f4dc1fdd Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Thu, 17 Sep 2026 11:16:54 -0400 Subject: [PATCH 1/5] feat(control-plane): inspect compiled physical plans --- .../examples/compile_workload_artifact.rs | 51 ++--- control_plane/src/physical/compiler.rs | 6 +- control_plane/src/physical/mod.rs | 1 + control_plane/src/physical/plan_dot.rs | 215 ++++++++++++++++++ 4 files changed, 236 insertions(+), 37 deletions(-) create mode 100644 control_plane/src/physical/plan_dot.rs diff --git a/control_plane/examples/compile_workload_artifact.rs b/control_plane/examples/compile_workload_artifact.rs index 392ba029..0513ea1e 100644 --- a/control_plane/examples/compile_workload_artifact.rs +++ b/control_plane/examples/compile_workload_artifact.rs @@ -1,52 +1,31 @@ //! Control-plane entry point: cost-select a workload and emit its atomic install request. use control_plane::physical::compiler::BackendLocalPlanningInput; -use serde_json::json; fn main() -> Result<(), Box> { let mut args = std::env::args().skip(1); let path = args .next() - .ok_or("usage: compile_workload_artifact SNAPSHOT.json [--metricsql]")?; - let metricsql = match args.next().as_deref() { - None => false, - Some("--metricsql") => true, - Some(_) => return Err("expected optional --metricsql".into()), - }; - if args.next().is_some() { - return Err("unexpected arguments".into()); + .ok_or("usage: compile_workload_artifact SNAPSHOT.json [--metricsql] [--dot OUTPUT.dot]")?; + let mut metricsql = false; + let mut dot_path = None; + while let Some(argument) = args.next() { + match argument.as_str() { + "--metricsql" => metricsql = true, + "--dot" => { + dot_path = Some(args.next().ok_or("--dot requires an output path")?); + } + _ => return Err(format!("unexpected argument `{argument}`").into()), + } } let snapshot: BackendLocalPlanningInput = serde_json::from_slice(&std::fs::read(path)?)?; - let start = std::time::Instant::now(); let plan = if metricsql { snapshot.compile_metricsql()? } else { snapshot.compile_promql()? }; - let elapsed = start.elapsed().as_nanos(); - let comparison = plan - .cost_comparison - .ok_or("missing complete-plan comparison")?; - println!( - "{}", - serde_json::to_string_pretty(&json!({ - "schema_version": 1, - "planning_elapsed_ns": elapsed, - "envelope": plan.envelope, - "cost_comparison": comparison, - "logical_selection": plan.planner_selection_trace, - "backend_revision": control_plane::physical::compiler::BACKEND_REVISION, - "planner_revision": control_plane::physical::compiler::PLANNER_REVISION, - "lifecycle_estimates": plan.lifecycle_estimates, - "install_request": { - "summary_catalog": plan.summary_catalog, - "collector_plans": plan.collector_plans, - "precompute_plan": plan.precompute_plan, - "transmission_plan": plan.transmission_plan, - "query_plan": plan.query_plan, - "storage_routing": null, - "adaptation_evidence": [] - } - }))? - ); + if let Some(path) = dot_path { + std::fs::write(path, control_plane::physical::plan_dot::render(&plan))?; + } + println!("{}", serde_json::to_string_pretty(&plan)?); Ok(()) } diff --git a/control_plane/src/physical/compiler.rs b/control_plane/src/physical/compiler.rs index c55d2a8c..909f6f1c 100644 --- a/control_plane/src/physical/compiler.rs +++ b/control_plane/src/physical/compiler.rs @@ -450,7 +450,11 @@ pub fn build_transmission_plan( /// Complete physical projection of one post-ASAP planning decision. /// All three child plans share the same envelope and are compiled together. -#[derive(Debug, Clone)] +/// Complete selected physical plan, serializable for developer inspection. +/// +/// The serialized form is an inspection artifact emitted by +/// `compile_workload_artifact`; it is not an input accepted by the compiler. +#[derive(Debug, Clone, Serialize)] pub struct CompiledPhysicalPlan { pub envelope: PlanEnvelope, pub summary_catalog: super::summary_catalog::SummaryCatalog, diff --git a/control_plane/src/physical/mod.rs b/control_plane/src/physical/mod.rs index a31de4e5..fb61d2c4 100644 --- a/control_plane/src/physical/mod.rs +++ b/control_plane/src/physical/mod.rs @@ -13,6 +13,7 @@ pub mod sketch_catalog; pub mod summary_catalog; pub mod workload_cost; +pub mod plan_dot; pub mod publication; pub(crate) mod maintained_population; diff --git a/control_plane/src/physical/plan_dot.rs b/control_plane/src/physical/plan_dot.rs new file mode 100644 index 00000000..3a5135a7 --- /dev/null +++ b/control_plane/src/physical/plan_dot.rs @@ -0,0 +1,215 @@ +//! Graphviz inspection rendering for one selected physical plan. +//! +//! This is intentionally a developer-facing view: JSON remains the complete +//! representation, while DOT keeps labels compact enough to follow execution. + +use super::compiler::CompiledPhysicalPlan; +use crate::query_plan::QueryPlanNode; +use asap_types::query_plan::residual::ResidualQueryOperator; + +/// Render the selected precompute and query execution DAGs as deterministic DOT. +pub fn render(plan: &CompiledPhysicalPlan) -> String { + let mut dot = String::from( + "digraph compiled_physical_plan {\n rankdir=LR;\n node [shape=box, fontname=Helvetica];\n", + ); + + dot.push_str(" subgraph cluster_precompute {\n label=\"PrecomputePlan\";\n"); + for materialization in &plan.precompute_plan.materializations { + let id = materialization.policy_fingerprint(); + let node = materialization_node(id.as_u64()); + let label = format!( + "materialization\\n{}\\nmetric={}\\nwindow={}s / {}s", + id, materialization.metric, materialization.window_size, materialization.slide_interval, + ); + emit_node(&mut dot, &node, &label, "shape=component"); + } + for (dag_index, (query_id, installed)) in + plan.precompute_plan.executable_dags.iter().enumerate() + { + dot.push_str(&format!( + " subgraph cluster_precompute_dag_{dag_index} {{\n label=\"{}\";\n", + escape(query_id) + )); + for node in &installed.document.nodes { + let id = precompute_node(dag_index, node.id.0); + let binding = installed + .binding + .nodes + .get(&node.id) + .map(|binding| format!("\\n{:?}", binding)) + .unwrap_or_default(); + emit_node( + &mut dot, + &id, + &format!("{:?} #{}{}", node.operator, node.id.0, binding), + "", + ); + } + for edge in &installed.document.edges { + dot.push_str(&format!( + " {} -> {} [label=\"{:?}\"];\n", + precompute_node(dag_index, edge.producer.0), + precompute_node(dag_index, edge.consumer.0), + edge.role + )); + } + dot.push_str(" }\n"); + } + dot.push_str(" }\n"); + + for (query_index, (query_key, entry)) in plan.query_plan.entries.iter().enumerate() { + dot.push_str(&format!( + " subgraph cluster_query_{query_index} {{\n label=\"QueryPlan: {}\";\n", + escape(query_key) + )); + for (id, node) in &entry.nodes { + let attributes = if *id == entry.root { + "shape=doubleoctagon" + } else { + "" + }; + emit_node( + &mut dot, + &query_node(query_index, id.0), + &query_node_label(node), + attributes, + ); + if let QueryPlanNode::ReadMaterialization { binding } = node { + dot.push_str(&format!( + " {} -> {} [style=dashed, color=gray40, label=\"reads\"];\n", + materialization_node(binding.materialization.as_u64()), + query_node(query_index, id.0), + )); + } + } + for (id, node) in &entry.nodes { + for input in node.inputs() { + dot.push_str(&format!( + " {} -> {};\n", + query_node(query_index, input.0), + query_node(query_index, id.0), + )); + } + } + dot.push_str(" }\n"); + } + dot.push_str("}\n"); + dot +} + +fn materialization_node(id: u64) -> String { + format!("materialization_{id:016x}") +} + +fn precompute_node(dag: usize, id: u32) -> String { + format!("precompute_{dag}_{id}") +} + +fn query_node(query: usize, id: u64) -> String { + format!("query_{query}_{id}") +} + +fn emit_node(dot: &mut String, id: &str, label: &str, attributes: &str) { + dot.push_str(&format!(" {id} [label=\"{}\"", escape(label))); + if !attributes.is_empty() { + dot.push_str(&format!(", {attributes}")); + } + dot.push_str("];\n"); +} + +fn escape(value: &str) -> String { + value + .replace('\\', "\\\\") + .replace('"', "\\\"") + .replace('\n', "\\n") +} + +fn query_node_label(node: &QueryPlanNode) -> String { + match node { + QueryPlanNode::RelationalJoin { .. } => "RelationalJoin".into(), + QueryPlanNode::Relational { .. } => "Relational".into(), + QueryPlanNode::Logical { operator, .. } => { + format!("Logical\\n{}", residual_label(operator)) + } + QueryPlanNode::Scalar { value } => format!("Scalar\\n{value}"), + QueryPlanNode::Binary { operator, .. } => format!("Binary\\n{operator:?}"), + QueryPlanNode::ReduceSum { .. } => "ReduceSum".into(), + QueryPlanNode::ReadMaterialization { binding } => format!( + "ReadMaterialization\\n{}\\nwindow={}ms\\nlookback={:?}", + binding.materialization.fingerprint(), + binding.window_ms, + binding.readout_lookback_ms + ), + QueryPlanNode::SummaryEstimate { query, .. } => format!("SummaryEstimate\\n{query:?}"), + QueryPlanNode::ExactReadout { readout, .. } => format!("ExactReadout\\n{readout:?}"), + QueryPlanNode::SummaryMerge { .. } => "SummaryMerge".into(), + QueryPlanNode::CandidateTopK { k, .. } => format!("CandidateTopK\\nk={k}"), + QueryPlanNode::ExternalExact { .. } => "ExternalExact".into(), + QueryPlanNode::ExactFallback { reason } => format!("ExactFallback\\n{reason}"), + } +} + +fn residual_label(operator: &ResidualQueryOperator) -> &'static str { + match operator { + ResidualQueryOperator::CurrentSeries { .. } => "CurrentSeries", + ResidualQueryOperator::ExactSubquery { .. } => "ExactSubquery", + ResidualQueryOperator::CandidateExactSubquery { .. } => "CandidateExactSubquery", + ResidualQueryOperator::Scan { .. } => "Scan", + ResidualQueryOperator::UnaryNegate => "UnaryNegate", + ResidualQueryOperator::VectorToScalar => "VectorToScalar", + ResidualQueryOperator::Aggregate { .. } => "Aggregate", + ResidualQueryOperator::TopKSelection { .. } => "TopKSelection", + ResidualQueryOperator::Binary { .. } => "Binary", + ResidualQueryOperator::Temporal { .. } => "Temporal", + ResidualQueryOperator::Sort { .. } => "Sort", + ResidualQueryOperator::HistogramQuantile => "HistogramQuantile", + ResidualQueryOperator::Subquery { .. } => "Subquery", + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::physical::compiler::{BackendLocalPlanningInput, QueryFrontend}; + + fn fixture() -> CompiledPhysicalPlan { + let snapshot: BackendLocalPlanningInput = serde_json::from_str(include_str!( + "../../../docs/examples/asapquery-planning-snapshot.json" + )) + .unwrap(); + crate::physical::compiler::tests::quoted_snapshot(snapshot, QueryFrontend::PromQl) + .compile_promql() + .unwrap() + } + + #[test] + fn render_links_query_reads_to_precompute_materializations() { + let dot = render(&fixture()); + assert!(dot.contains("cluster_precompute"), "{dot}"); + assert!(dot.contains("cluster_query_"), "{dot}"); + assert!(dot.contains("style=dashed"), "{dot}"); + assert!(dot.contains("ReadMaterialization"), "{dot}"); + } + + #[test] + fn compiled_physical_plan_serializes_each_projection() { + let artifact = serde_json::to_value(fixture()).unwrap(); + for field in [ + "envelope", + "summary_catalog", + "collector_plans", + "precompute_plan", + "transmission_plan", + "query_plan", + "storage_routing", + "lifecycle_estimates", + "cost_comparison", + "planner_selection_trace", + ] { + assert!( + artifact.get(field).is_some(), + "missing `{field}`: {artifact}" + ); + } + } +} From cb4909450bc2a9f74eba73cddc5b84df260e30e6 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Thu, 17 Sep 2026 11:34:07 -0400 Subject: [PATCH 2/5] docs: describe compiled plan inspection output --- README.md | 15 +++++++++------ control_plane/docs/candidate-physical-explain.md | 2 +- docs/evaluation/e2e-physical-dag.md | 11 +++++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 102e1783..3293c7f8 100644 --- a/README.md +++ b/README.md @@ -289,14 +289,17 @@ jq '.candidates[] | {candidate_index, unavailable_reason}' \ target/debug/examples/compile_workload_artifact \ "$ASAPQUERY_PLANNING_SNAPSHOT" \ + --dot target/readme-evidence/selected.dot \ > target/readme-evidence/selected.json jq '.cost_comparison' target/readme-evidence/selected.json -jq '.install_request.summary_catalog' target/readme-evidence/selected.json -jq '.install_request.precompute_plan | {materializations, executable_dags}' \ +jq '.summary_catalog' target/readme-evidence/selected.json +jq '.precompute_plan | {materializations, executable_dags}' \ target/readme-evidence/selected.json -jq '.install_request.query_plan.entries' target/readme-evidence/selected.json -jq '.install_request.precompute_plan.schemas[] | {materialization, schema_id}' \ +jq '.query_plan.entries' target/readme-evidence/selected.json +jq '.precompute_plan.schemas[] | {materialization, schema_id}' \ target/readme-evidence/selected.json +dot -Tsvg target/readme-evidence/selected.dot \ + -o target/readme-evidence/selected.svg ``` Candidate discovery accepts the checked-in unquoted templates. Deployment and @@ -471,7 +474,7 @@ To inspect supported MetricsQL planning independently: target/debug/examples/compile_workload_artifact \ "$ASAPQUERY_PLANNING_SNAPSHOT" --metricsql \ > target/readme-evidence/victoriametrics/selected.json -jq '.install_request.query_plan.entries' \ +jq '.query_plan.entries' \ target/readme-evidence/victoriametrics/selected.json ``` @@ -522,7 +525,7 @@ python3 - <<'PY' import json from pathlib import Path root = Path('target/readme-evidence') -envelope = json.loads((root / 'selected.json').read_text())['install_request']['precompute_plan']['envelope'] +envelope = json.loads((root / 'selected.json').read_text())['precompute_plan']['envelope'] envelope['plan_id'] = 9001 envelope['plan_version'] = 1 workload = { diff --git a/control_plane/docs/candidate-physical-explain.md b/control_plane/docs/candidate-physical-explain.md index fded1a0a..f6c0dddf 100644 --- a/control_plane/docs/candidate-physical-explain.md +++ b/control_plane/docs/candidate-physical-explain.md @@ -18,7 +18,7 @@ Physical identity combines the logical/mask alternative with existing materializ The read-only `/api/v1/physical-plan/cost-manifests` and MetricsQL equivalent retain their default manifest-array response. Add `"explain": true` to the existing request to receive `{ "manifests": [...], "alternatives": [...], "logical_selection": [...] }`. Failed alternatives remain alongside usable manifests. When none can bind or be completely priced, the error retains an `all_infeasible` report and every accumulated alternative rather than only a generic message. -Snapshot compilation exposes the same logical trace on `PhysicalPlan`; `compile_workload_artifact` prints it outside the install request. Compile-and-publish returns the trace without adding it to executable wire DTOs. SQL's existing selection trace gains the same semantic candidate/root identities. +Snapshot compilation exposes the same logical trace on `CompiledPhysicalPlan`; `compile_workload_artifact` serializes it as `planner_selection_trace`. Compile-and-publish returns the trace without adding it to executable wire DTOs. SQL's existing selection trace gains the same semantic candidate/root identities. These are bounded explanations: they cover the actual Planner search and the existing physical materialization/exact inventory, not every possible placement or resource-constrained cluster assignment. Missing numeric measurements remain missing. The next provider integration must occur before logical commitment and reuse Planner's provider/resource contracts. diff --git a/docs/evaluation/e2e-physical-dag.md b/docs/evaluation/e2e-physical-dag.md index 1a3c2807..a9cbfe10 100644 --- a/docs/evaluation/e2e-physical-dag.md +++ b/docs/evaluation/e2e-physical-dag.md @@ -63,11 +63,14 @@ substituting a preferred sketch family: ```bash cargo run --locked -p control_plane --example compile_workload_artifact -- \ "$ASAPQUERY_PLANNING_SNAPSHOT" \ + --dot target/physical-dag-inspection/selected.dot \ > target/physical-dag-inspection/selected.json -jq '.install_request' target/physical-dag-inspection/selected.json \ +jq '{summary_catalog, precompute_plan, query_plan}' target/physical-dag-inspection/selected.json \ > target/physical-dag-inspection/physical-plan.json -jq '.install_request | {summary_catalog, precompute_plan, query_plan}' \ +jq '{summary_catalog, precompute_plan, query_plan}' \ target/physical-dag-inspection/selected.json +dot -Tsvg target/physical-dag-inspection/selected.dot \ + -o target/physical-dag-inspection/selected.svg ``` `compile_workload_artifact` calls the same evidence-required snapshot compiler @@ -150,7 +153,7 @@ outer state's version or assume new routing has been activated by this guide. ## d. Precompute subDAG and completion ```bash -jq '.install_request.precompute_plan | {materializations, executable_dags}' \ +jq '.precompute_plan | {materializations, executable_dags}' \ target/physical-dag-inspection/selected.json ``` @@ -184,7 +187,7 @@ remote-write automatically supplies this proof. ## e. QueryPlan → physical DAG → SID-bound readout ```bash -jq '.install_request.query_plan.entries' target/physical-dag-inspection/selected.json +jq '.query_plan.entries' target/physical-dag-inspection/selected.json curl -sS -D target/physical-dag-inspection/query.headers --get \ http://127.0.0.1:9091/api/v1/query \ --data-urlencode 'query=sum(sum_over_time(asap_demo_gauge[5s]))' \ From 3a849e2811961ed9a4d2930e03411162f1c0eb7e Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Thu, 17 Sep 2026 12:12:46 -0400 Subject: [PATCH 3/5] fix(control-plane): render plan diagram line breaks --- control_plane/src/physical/plan_dot.rs | 35 +++++++++++++++++--------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/control_plane/src/physical/plan_dot.rs b/control_plane/src/physical/plan_dot.rs index 3a5135a7..308d23a6 100644 --- a/control_plane/src/physical/plan_dot.rs +++ b/control_plane/src/physical/plan_dot.rs @@ -18,7 +18,7 @@ pub fn render(plan: &CompiledPhysicalPlan) -> String { let id = materialization.policy_fingerprint(); let node = materialization_node(id.as_u64()); let label = format!( - "materialization\\n{}\\nmetric={}\\nwindow={}s / {}s", + "materialization\n{}\nmetric={}\nwindow={}s / {}s", id, materialization.metric, materialization.window_size, materialization.slide_interval, ); emit_node(&mut dot, &node, &label, "shape=component"); @@ -36,7 +36,7 @@ pub fn render(plan: &CompiledPhysicalPlan) -> String { .binding .nodes .get(&node.id) - .map(|binding| format!("\\n{:?}", binding)) + .map(|binding| format!("\n{:?}", binding)) .unwrap_or_default(); emit_node( &mut dot, @@ -128,24 +128,22 @@ fn query_node_label(node: &QueryPlanNode) -> String { match node { QueryPlanNode::RelationalJoin { .. } => "RelationalJoin".into(), QueryPlanNode::Relational { .. } => "Relational".into(), - QueryPlanNode::Logical { operator, .. } => { - format!("Logical\\n{}", residual_label(operator)) - } - QueryPlanNode::Scalar { value } => format!("Scalar\\n{value}"), - QueryPlanNode::Binary { operator, .. } => format!("Binary\\n{operator:?}"), + QueryPlanNode::Logical { operator, .. } => format!("Logical\n{}", residual_label(operator)), + QueryPlanNode::Scalar { value } => format!("Scalar\n{value}"), + QueryPlanNode::Binary { operator, .. } => format!("Binary\n{operator:?}"), QueryPlanNode::ReduceSum { .. } => "ReduceSum".into(), QueryPlanNode::ReadMaterialization { binding } => format!( - "ReadMaterialization\\n{}\\nwindow={}ms\\nlookback={:?}", + "ReadMaterialization\n{}\nwindow={}ms\nlookback={:?}", binding.materialization.fingerprint(), binding.window_ms, binding.readout_lookback_ms ), - QueryPlanNode::SummaryEstimate { query, .. } => format!("SummaryEstimate\\n{query:?}"), - QueryPlanNode::ExactReadout { readout, .. } => format!("ExactReadout\\n{readout:?}"), + QueryPlanNode::SummaryEstimate { query, .. } => format!("SummaryEstimate\n{query:?}"), + QueryPlanNode::ExactReadout { readout, .. } => format!("ExactReadout\n{readout:?}"), QueryPlanNode::SummaryMerge { .. } => "SummaryMerge".into(), - QueryPlanNode::CandidateTopK { k, .. } => format!("CandidateTopK\\nk={k}"), + QueryPlanNode::CandidateTopK { k, .. } => format!("CandidateTopK\nk={k}"), QueryPlanNode::ExternalExact { .. } => "ExternalExact".into(), - QueryPlanNode::ExactFallback { reason } => format!("ExactFallback\\n{reason}"), + QueryPlanNode::ExactFallback { reason } => format!("ExactFallback\n{reason}"), } } @@ -191,6 +189,19 @@ mod tests { assert!(dot.contains("ReadMaterialization"), "{dot}"); } + #[test] + fn render_uses_graphviz_line_breaks_in_labels() { + let dot = render(&fixture()); + assert!( + dot.contains("materialization\\npolicy_fp:"), + "expected a Graphviz line break, not a literal backslash-n: {dot}" + ); + assert!( + !dot.contains("materialization\\\\npolicy_fp:"), + "label double-escaped its Graphviz line break: {dot}" + ); + } + #[test] fn compiled_physical_plan_serializes_each_projection() { let artifact = serde_json::to_value(fixture()).unwrap(); From d074887f9b62436792fb0cc1078119a2163fae33 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Thu, 17 Sep 2026 12:40:40 -0400 Subject: [PATCH 4/5] feat(control-plane): show materialization window layout --- control_plane/src/physical/plan_dot.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/control_plane/src/physical/plan_dot.rs b/control_plane/src/physical/plan_dot.rs index 308d23a6..d6ced46e 100644 --- a/control_plane/src/physical/plan_dot.rs +++ b/control_plane/src/physical/plan_dot.rs @@ -18,8 +18,13 @@ pub fn render(plan: &CompiledPhysicalPlan) -> String { let id = materialization.policy_fingerprint(); let node = materialization_node(id.as_u64()); let label = format!( - "materialization\n{}\nmetric={}\nwindow={}s / {}s", - id, materialization.metric, materialization.window_size, materialization.slide_interval, + "materialization\n{}\nmetric={}\nwindow_type={}\nwindow={}s / {}s\nlayout={:?}", + id, + materialization.metric, + materialization.window_type, + materialization.window_size, + materialization.slide_interval, + materialization.window_layout, ); emit_node(&mut dot, &node, &label, "shape=component"); } @@ -187,6 +192,8 @@ mod tests { assert!(dot.contains("cluster_query_"), "{dot}"); assert!(dot.contains("style=dashed"), "{dot}"); assert!(dot.contains("ReadMaterialization"), "{dot}"); + assert!(dot.contains("window_type="), "{dot}"); + assert!(dot.contains("layout="), "{dot}"); } #[test] From 98041ca1d2db7a5dc3415d9031a0fb02b50380c6 Mon Sep 17 00:00:00 2001 From: Milind Srivastava Date: Thu, 17 Sep 2026 13:41:27 -0400 Subject: [PATCH 5/5] docs: add compiled plan diagram example --- .../compiled-plan-inspection-example.svg | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 docs/evaluation/compiled-plan-inspection-example.svg diff --git a/docs/evaluation/compiled-plan-inspection-example.svg b/docs/evaluation/compiled-plan-inspection-example.svg new file mode 100644 index 00000000..e27e742f --- /dev/null +++ b/docs/evaluation/compiled-plan-inspection-example.svg @@ -0,0 +1,106 @@ + + + + + + +compiled_physical_plan + + +cluster_precompute + +PrecomputePlan + + +cluster_precompute_dag_0 + +compat-query-0 + + +cluster_query_0 + +QueryPlan: quantile_over_time(0.99, m[1m]) + + + +materialization_dbbce066175e12e0 + + + +materialization +policy_fp:dbbce066175e12e0 +metric=m +window_type=sliding +window=60s / 10s +layout=Pane { pane_secs: 10 } + + + +query_0_1 + +ReadMaterialization +policy_fp:dbbce066175e12e0 +window=10000ms +lookback=Some(60000) + + + +materialization_dbbce066175e12e0->query_0_1 + + +reads + + + +precompute_0_0 + +Fallback #0 +MaintenanceInput + + + +precompute_0_1 + +SummaryAgg #1 +Materialization { summary_definition: SummaryDefinitionId(PolicyFingerprint(15833777119011148512)) } + + + +precompute_0_0->precompute_0_1 + + +Input + + + +precompute_0_2 + +SummaryEstimate #2 +Query { query_node: QueryNodeId(0) } + + + +precompute_0_1->precompute_0_2 + + +Input + + + +query_0_0 + + +SummaryEstimate +Quantile { q: 0.99 } + + + +query_0_1->query_0_0 + + + + +