Skip to content

Commit 76f23d2

Browse files
authored
Remove petgraph from logical plan dependency (#207)
1 parent 87ba5be commit 76f23d2

File tree

4 files changed

+96
-20
lines changed

4 files changed

+96
-20
lines changed

partiql-eval/src/lib.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ mod tests {
4141
}
4242

4343
// TODO: rename once we move to DAG model completely
44-
fn evaluate_dag(logical: LogicalPlan, bindings: MapBindings<Value>) -> Value {
44+
fn evaluate_dag(logical: LogicalPlan<BindingsExpr>, bindings: MapBindings<Value>) -> Value {
4545
// TODO remove once we agree on using evaluate output in the following PR:
4646
// https://github.com/partiql/partiql-lang-rust/pull/202
4747
let output = Rc::new(RefCell::new(EvalOutputAccumulator::default()));
@@ -256,15 +256,15 @@ mod tests {
256256

257257
#[test]
258258
fn select_dag() {
259-
// Plan for `select a as b from data`
260-
let mut logical = LogicalPlan::new();
261-
let from = logical.0.add_node(BindingsExpr::Scan(logical::Scan {
259+
let mut lg = LogicalPlan::new();
260+
261+
let from = lg.add_operator(BindingsExpr::Scan(logical::Scan {
262262
expr: ValueExpr::VarRef(BindingsName::CaseInsensitive("data".into())),
263263
as_key: "data".to_string(),
264264
at_key: None,
265265
}));
266266

267-
let project = logical.0.add_node(BindingsExpr::Project(logical::Project {
267+
let project = lg.add_operator(BindingsExpr::Project(logical::Project {
268268
exprs: HashMap::from([(
269269
"b".to_string(),
270270
ValueExpr::Path(
@@ -276,13 +276,12 @@ mod tests {
276276
)]),
277277
}));
278278

279-
let sink = logical.0.add_node(BindingsExpr::Output);
279+
let sink = lg.add_operator(BindingsExpr::Output);
280280

281-
logical
282-
.0
283-
.extend_with_edges(&[(from, project), (project, sink)]);
281+
lg.add_flow(from, project);
282+
lg.add_flow(project, sink);
284283

285-
if let Value::Bag(b) = evaluate_dag(logical, data_3_tuple()) {
284+
if let Value::Bag(b) = evaluate_dag(lg, data_3_tuple()) {
286285
assert_eq!(b.len(), 3);
287286
} else {
288287
panic!("Wrong output")

partiql-eval/src/plan.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,36 @@ impl EvaluatorPlanner {
3939
}
4040
}
4141

42-
pub fn compile_dag(&self, plan: LogicalPlan) -> EvalPlan {
42+
pub fn compile_dag(&self, plan: LogicalPlan<BindingsExpr>) -> EvalPlan {
4343
self.plan_eval_dag(plan)
4444
}
4545

4646
#[inline]
47-
fn plan_eval_dag(&self, lg: LogicalPlan) -> EvalPlan {
48-
let plan = lg.0;
47+
fn plan_eval_dag(&self, lg: LogicalPlan<BindingsExpr>) -> EvalPlan {
4948
let mut eval_plan = EvalPlan::default();
50-
eval_plan.0 = plan.map(|_, n| self.get_eval_node(n), |_, e| e.clone());
49+
let ops = lg.operators();
50+
let flows = lg.flows();
51+
52+
let mut seen = HashMap::new();
53+
54+
flows.into_iter().for_each(|r| {
55+
let (s, d) = r;
56+
57+
let mut nodes = vec![];
58+
for op_id in vec![s, d] {
59+
let logical_op = &ops[op_id.index() - 1];
60+
let eval_op = if let Some(op) = seen.get(op_id) {
61+
*op
62+
} else {
63+
let id = eval_plan.0.add_node(self.get_eval_node(logical_op));
64+
seen.insert(op_id, id);
65+
id
66+
};
67+
nodes.push(eval_op)
68+
}
69+
70+
eval_plan.0.add_edge(nodes[0], nodes[1], ());
71+
});
5172

5273
eval_plan
5374
}

partiql-logical/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ edition.workspace = true
2121

2222
[dependencies]
2323
partiql-value = { path = "../partiql-value" }
24-
petgraph = "0.6.*"
2524
ordered-float = "3.*"
2625
itertools = "0.10.*"
2726
unicase = "2.*"

partiql-logical/src/lib.rs

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,53 @@
11
use partiql_value::{BindingsName, Value};
2-
use petgraph::prelude::StableGraph;
3-
use petgraph::Directed;
42
use std::collections::HashMap;
53

4+
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
5+
pub struct OpId(usize);
6+
7+
impl OpId {
8+
pub fn index(&self) -> usize {
9+
self.0
10+
}
11+
}
12+
613
#[derive(Debug)]
7-
pub struct LogicalPlan(pub StableGraph<BindingsExpr, (), Directed>);
14+
pub struct LogicalPlan<T> {
15+
nodes: Vec<T>,
16+
edges: Vec<(OpId, OpId)>,
17+
}
818

9-
impl LogicalPlan {
19+
impl<T> LogicalPlan<T> {
1020
pub fn new() -> Self {
11-
LogicalPlan(StableGraph::<BindingsExpr, (), Directed>::new())
21+
LogicalPlan {
22+
nodes: vec![],
23+
edges: vec![],
24+
}
25+
}
26+
27+
pub fn add_operator(&mut self, op: T) -> OpId {
28+
self.nodes.push(op);
29+
OpId(self.operator_count())
30+
}
31+
32+
pub fn add_flow(&mut self, src: OpId, dst: OpId) {
33+
let src_idx = src.index() - 1;
34+
let dst_idx = dst.index() - 1;
35+
assert!(src_idx <= self.operator_count());
36+
assert!(dst_idx <= self.operator_count());
37+
38+
self.edges.push((src, dst));
39+
}
40+
41+
pub fn operator_count(&self) -> usize {
42+
self.nodes.len()
43+
}
44+
45+
pub fn operators(&self) -> &Vec<T> {
46+
&self.nodes
47+
}
48+
49+
pub fn flows(&self) -> &Vec<(OpId, OpId)> {
50+
&self.edges
1251
}
1352
}
1453

@@ -133,3 +172,21 @@ pub struct SelectValue {
133172
pub struct Distinct {
134173
pub out: Box<BindingsExpr>,
135174
}
175+
176+
#[cfg(test)]
177+
mod tests {
178+
use super::*;
179+
180+
#[test]
181+
fn test_plan() {
182+
let mut p: LogicalPlan<BindingsExpr> = LogicalPlan::new();
183+
let a = p.add_operator(BindingsExpr::OrderBy);
184+
let b = p.add_operator(BindingsExpr::Output);
185+
let c = p.add_operator(BindingsExpr::Limit);
186+
p.add_flow(a, b);
187+
p.add_flow(a, c);
188+
p.add_flow(b, c);
189+
assert_eq!(3, p.operators().len());
190+
assert_eq!(3, p.flows().len());
191+
}
192+
}

0 commit comments

Comments
 (0)