use super::*;
use plexus_serde::{CmpOp, ColDef, ColKind, Expr, LogicalType, Op, SortDir};
fn execute_plan(plan: Plan) -> QueryResult {
let mut engine = IndependentConsumerEngine::new(proof_fixture_graph());
engine.execute_plan(&plan).expect("execute")
}
#[test]
fn independent_consumer_executes_scan_project_sort_subset() {
let result = execute_plan(Plan {
version: version(),
ops: vec![
Op::ScanNodes {
labels: vec!["Person".to_string()],
schema: vec![ColDef {
name: "n".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
}],
must_labels: vec!["Person".to_string()],
forbidden_labels: vec![],
est_rows: -1,
selectivity: 1.0,
graph_ref: None,
},
Op::Project {
input: 0,
exprs: vec![Expr::PropAccess {
col: 0,
prop: "name".to_string(),
}],
schema: vec![ColDef {
name: "name".to_string(),
kind: ColKind::Value,
logical_type: LogicalType::Unknown,
}],
},
Op::Sort {
input: 1,
keys: vec![0],
dirs: vec![SortDir::Asc],
},
Op::Return { input: 2 },
],
root_op: 3,
});
assert_eq!(
result.rows,
vec![
vec![Value::String("Alice".to_string())],
vec![Value::String("Bob".to_string())],
]
);
}
#[test]
fn independent_consumer_executes_expand_filter_subset() {
let result = execute_plan(Plan {
version: version(),
ops: vec![
Op::ScanNodes {
labels: vec!["Person".to_string()],
schema: vec![ColDef {
name: "n".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
}],
must_labels: vec!["Person".to_string()],
forbidden_labels: vec![],
est_rows: -1,
selectivity: 1.0,
graph_ref: None,
},
Op::Expand {
input: 0,
src_col: 0,
types: vec!["KNOWS".to_string()],
dir: ExpandDir::Out,
schema: vec![
ColDef {
name: "n".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
},
ColDef {
name: "r".to_string(),
kind: ColKind::Rel,
logical_type: LogicalType::Unknown,
},
ColDef {
name: "m".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
},
],
src_var: "n".to_string(),
rel_var: "r".to_string(),
dst_var: "m".to_string(),
legal_src_labels: vec!["Person".to_string()],
legal_dst_labels: vec!["Person".to_string()],
est_degree: 1.0,
graph_ref: None,
},
Op::Filter {
input: 1,
predicate: Expr::Cmp {
op: CmpOp::Gt,
lhs: Box::new(Expr::PropAccess {
col: 2,
prop: "age".to_string(),
}),
rhs: Box::new(Expr::IntLiteral(30)),
},
},
Op::Project {
input: 2,
exprs: vec![Expr::PropAccess {
col: 0,
prop: "name".to_string(),
}],
schema: vec![ColDef {
name: "name".to_string(),
kind: ColKind::Value,
logical_type: LogicalType::Unknown,
}],
},
Op::Sort {
input: 3,
keys: vec![0],
dirs: vec![SortDir::Asc],
},
Op::Return { input: 4 },
],
root_op: 5,
});
assert_eq!(result.rows, vec![vec![Value::String("Alice".to_string())]]);
}
#[test]
fn independent_consumer_executes_optional_expand_subset() {
let result = execute_plan(Plan {
version: version(),
ops: vec![
Op::ScanNodes {
labels: vec!["Person".to_string()],
schema: vec![ColDef {
name: "n".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
}],
must_labels: vec!["Person".to_string()],
forbidden_labels: vec![],
est_rows: -1,
selectivity: 1.0,
graph_ref: None,
},
Op::OptionalExpand {
input: 0,
src_col: 0,
types: vec!["WORKS_AT".to_string()],
dir: ExpandDir::Out,
schema: vec![
ColDef {
name: "n".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
},
ColDef {
name: "r".to_string(),
kind: ColKind::Rel,
logical_type: LogicalType::Unknown,
},
ColDef {
name: "c".to_string(),
kind: ColKind::Node,
logical_type: LogicalType::Unknown,
},
],
src_var: "n".to_string(),
rel_var: "r".to_string(),
dst_var: "c".to_string(),
legal_src_labels: vec!["Person".to_string()],
legal_dst_labels: vec!["Company".to_string()],
graph_ref: None,
},
Op::Project {
input: 1,
exprs: vec![Expr::PropAccess {
col: 2,
prop: "name".to_string(),
}],
schema: vec![ColDef {
name: "name".to_string(),
kind: ColKind::Value,
logical_type: LogicalType::Unknown,
}],
},
Op::Sort {
input: 2,
keys: vec![0],
dirs: vec![SortDir::Asc],
},
Op::Return { input: 3 },
],
root_op: 4,
});
assert_eq!(
result.rows,
vec![vec![Value::Null], vec![Value::String("Acme".to_string())],]
);
}