Skip to content

Commit 0167f7a

Browse files
committed
fix: validate physical row identity and preserve missing grouping labels
1 parent db50523 commit 0167f7a

2 files changed

Lines changed: 82 additions & 1 deletion

File tree

‎crates/asap_types/src/query_plan.rs‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,12 @@ impl QueryPlanEntry {
520520
));
521521
}
522522
} else {
523+
if compiled.row_source(compiled.roots()[0]).is_some() {
524+
return Err(QueryPlanError::Invalid(
525+
"row-preserving physical output requires its input identity binding"
526+
.into(),
527+
));
528+
}
523529
let output = compiled
524530
.output_contract(compiled.roots()[0])
525531
.map_err(|e| QueryPlanError::Invalid(e.to_string()))?;
@@ -957,6 +963,77 @@ mod contract_tests {
957963

958964
#[cfg(test)]
959965
mod retired_plan_tests {
966+
// Row-preserving operators cannot opt out of the original vector identity.
967+
#[test]
968+
fn row_preserving_graph_requires_its_identity_binding() {
969+
use super::*;
970+
use asap_physical_operators::{
971+
operators::Operator,
972+
physical_planner::{CompiledPhysicalDag, InputContract},
973+
};
974+
use planner_types::{
975+
post_asap::{SummaryFamilyType, SummaryField, SummarySchema},
976+
pre_asap::DataType,
977+
};
978+
let schema = std::sync::Arc::new(SummarySchema {
979+
fields: vec![SummaryField {
980+
name: "value".into(),
981+
dtype: SummaryFamilyType::Plain(DataType::Float64),
982+
nullable: false,
983+
}],
984+
time_index: None,
985+
});
986+
let program = CompiledPhysicalDag::from_operators(
987+
[(0, InputContract::bounded(schema.clone()))].into(),
988+
[(1, (vec![0], Operator::limit(schema, 1, 0, vec![]).unwrap()))].into(),
989+
vec![1],
990+
)
991+
.unwrap();
992+
let mut entry = QueryPlanEntry {
993+
language: QueryLanguage::PromQl,
994+
query_id: "identity".into(),
995+
canonical_query: "m".into(),
996+
fixed_evaluation: None,
997+
physical_dag: None,
998+
root: QueryNodeId(1),
999+
nodes: [
1000+
(
1001+
QueryNodeId(0),
1002+
QueryPlanNode::ExactFallback {
1003+
reason: "bound vector".into(),
1004+
},
1005+
),
1006+
(
1007+
QueryNodeId(1),
1008+
QueryPlanNode::PhysicalFragment {
1009+
inputs: vec![QueryNodeId(0)],
1010+
dag: program.encode().unwrap(),
1011+
row_input: None,
1012+
pruning: None,
1013+
},
1014+
),
1015+
]
1016+
.into(),
1017+
instant: InstantExecution {
1018+
lookback_ms: 0,
1019+
full_history: false,
1020+
cumulative_readout: false,
1021+
},
1022+
fallback: FallbackPolicy::Reject,
1023+
};
1024+
assert!(entry
1025+
.validate(&BTreeSet::new())
1026+
.unwrap_err()
1027+
.to_string()
1028+
.contains("identity binding"));
1029+
if let QueryPlanNode::PhysicalFragment { row_input, .. } =
1030+
entry.nodes.get_mut(&QueryNodeId(1)).unwrap()
1031+
{
1032+
*row_input = Some(0);
1033+
}
1034+
entry.validate(&BTreeSet::new()).unwrap();
1035+
}
1036+
9601037
#[test]
9611038
fn uncompiled_relation_variants_are_not_accepted() {
9621039
for kind in ["relational", "relational_join"] {

‎data_plane/src/query_engines/asap_query_engine/logical_dag/native_values.rs‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,9 @@ pub(super) fn physical(
273273
for (field, cell) in output_schema.fields.iter().zip(row) {
274274
match cell {
275275
Value::Utf8(value) => {
276-
labels.insert(field.name.clone(), value.to_string());
276+
if !value.is_empty() {
277+
labels.insert(field.name.clone(), value.to_string());
278+
}
277279
}
278280
Value::Float64(value) => sample = Some(*value),
279281
Value::Int64(value) if value.unsigned_abs() <= (1u64 << 53) => {
@@ -616,6 +618,7 @@ mod tests {
616618
)
617619
.unwrap();
618620
let values = vec![
621+
(Labels::from([("instance".into(), "c".into())]), 5.),
619622
(
620623
Labels::from([
621624
("job".into(), "api".into()),
@@ -650,6 +653,7 @@ mod tests {
650653
assert_eq!(
651654
output,
652655
vec![
656+
(Labels::new(), 5.),
653657
(Labels::from([("job".into(), "api".into())]), 3.),
654658
(Labels::from([("job".into(), "worker".into())]), 4.),
655659
]

0 commit comments

Comments
 (0)