use super::*;
fn assert_aggregate_terminal_public_contract(
plan: &ExplainAggregateTerminalPlan,
expected_node_type: ExplainExecutionNodeType,
expected_layer: &str,
expected_execution_mode_detail: &str,
) {
let execution = plan.execution();
let node = plan.execution_node_descriptor();
let text = node.render_text_tree();
let json = node.render_json_canonical();
assert_eq!(
node.node_type(),
expected_node_type,
"aggregate terminal explain must keep the high-level execution node family stable",
);
assert!(
text.contains(&format!("layer={expected_layer}")),
"aggregate terminal text explain must keep the node layer stable",
);
assert!(
json.contains(&format!("\"layer\":\"{expected_layer}\"")),
"aggregate terminal JSON explain must keep the node layer stable",
);
assert!(
text.contains(&format!(
"execution_mode_detail={expected_execution_mode_detail}"
)),
"aggregate terminal text explain must keep execution mode detail stable",
);
assert!(
json.contains(&format!(
"\"execution_mode_detail\":\"{expected_execution_mode_detail}\""
)),
"aggregate terminal JSON explain must keep execution mode detail stable",
);
assert!(
json.contains("\"predicate_pushdown_mode\":\"none\""),
"aggregate terminal JSON explain must keep the pushdown classification stable",
);
assert_eq!(
execution.aggregation(),
plan.terminal(),
"aggregate terminal execution payload must stay aligned with the terminal kind",
);
}
#[test]
fn explain_aggregate_terminal_seek_route_public_contract_is_stable() {
let mut plan: AccessPlannedQuery = AccessPlannedQuery::new(
AccessPath::IndexPrefix {
index: PUSHDOWN_INDEX,
values: vec![Value::Text("alpha".to_string())],
},
MissingRowPolicy::Ignore,
);
plan.scalar_plan_mut().order = Some(OrderSpec {
fields: vec![
("tag".to_string(), OrderDirection::Asc),
("id".to_string(), OrderDirection::Asc),
],
});
let query_explain = plan.explain();
let mut node_properties = ExplainPropertyMap::new();
node_properties.insert("fetch", Value::from(1_u64));
let terminal_plan = ExplainAggregateTerminalPlan::new(
query_explain,
AggregateKind::Min,
ExplainExecutionDescriptor {
access_strategy: ExplainAccessPath::IndexPrefix {
name: "explain::pushdown_tag",
fields: vec!["tag"],
prefix_len: 1,
values: vec![Value::Text("alpha".to_string())],
},
covering_projection: false,
aggregation: AggregateKind::Min,
execution_mode: ExplainExecutionMode::Materialized,
ordering_source: ExplainExecutionOrderingSource::IndexSeekFirst { fetch: 1 },
limit: None,
cursor: false,
node_properties,
},
);
assert_eq!(terminal_plan.terminal(), AggregateKind::Min);
assert!(matches!(
terminal_plan.query().access(),
ExplainAccessPath::IndexPrefix { name, fields, prefix_len, values }
if *name == "explain::pushdown_tag"
&& fields == &vec!["tag"]
&& *prefix_len == 1
&& values == &vec![Value::Text("alpha".to_string())]
));
assert!(matches!(
terminal_plan.query().order_by(),
ExplainOrderBy::Fields(fields)
if fields.len() == 2
&& fields[0].field == "tag"
&& fields[0].direction == OrderDirection::Asc
&& fields[1].field == "id"
&& fields[1].direction == OrderDirection::Asc
));
assert_eq!(terminal_plan.query().page(), &ExplainPagination::None);
assert_eq!(terminal_plan.query().grouping(), &ExplainGrouping::None);
assert_eq!(
terminal_plan.execution().ordering_source(),
ExplainExecutionOrderingSource::IndexSeekFirst { fetch: 1 },
);
assert_eq!(terminal_plan.execution().limit(), None);
assert!(!terminal_plan.execution().cursor());
assert!(!terminal_plan.execution().covering_projection());
assert_aggregate_terminal_public_contract(
&terminal_plan,
ExplainExecutionNodeType::AggregateSeekFirst,
"aggregate",
"materialized",
);
}
#[test]
fn explain_aggregate_terminal_standard_route_public_contract_is_stable() {
let mut plan: AccessPlannedQuery =
AccessPlannedQuery::new(AccessPath::<Value>::FullScan, MissingRowPolicy::Ignore);
plan.scalar_plan_mut().order = Some(OrderSpec {
fields: vec![("id".to_string(), OrderDirection::Asc)],
});
plan.scalar_plan_mut().page = Some(crate::db::query::plan::PageSpec {
limit: Some(3),
offset: 1,
});
let query_explain = plan.explain();
let terminal_plan = ExplainAggregateTerminalPlan::new(
query_explain,
AggregateKind::Exists,
ExplainExecutionDescriptor {
access_strategy: ExplainAccessPath::FullScan,
covering_projection: false,
aggregation: AggregateKind::Exists,
execution_mode: ExplainExecutionMode::Streaming,
ordering_source: ExplainExecutionOrderingSource::AccessOrder,
limit: Some(3),
cursor: true,
node_properties: ExplainPropertyMap::new(),
},
);
assert_eq!(terminal_plan.terminal(), AggregateKind::Exists);
assert_eq!(terminal_plan.query().access(), &ExplainAccessPath::FullScan);
assert!(matches!(
terminal_plan.query().order_by(),
ExplainOrderBy::Fields(fields)
if fields.len() == 1
&& fields[0].field == "id"
&& fields[0].direction == OrderDirection::Asc
));
assert_eq!(
terminal_plan.query().page(),
&ExplainPagination::Page {
limit: Some(3),
offset: 1,
},
);
assert_eq!(terminal_plan.query().grouping(), &ExplainGrouping::None);
assert_eq!(
terminal_plan.execution().ordering_source(),
ExplainExecutionOrderingSource::AccessOrder,
);
assert_eq!(terminal_plan.execution().limit(), Some(3));
assert!(terminal_plan.execution().cursor());
assert!(!terminal_plan.execution().covering_projection());
assert_aggregate_terminal_public_contract(
&terminal_plan,
ExplainExecutionNodeType::AggregateExists,
"aggregate",
"streaming",
);
}