1use rudb_catalog::{Catalog, QualifiedName};
15use rudb_common::Result;
16use rudb_plan::{Node, NodeRef, Plan};
17
18use crate::group::{Aggregate, Distinct};
19use crate::join::{CrossProduct, Join};
20use crate::operator::Operator;
21use crate::setop::SetOp;
22use crate::sort::Sort;
23use crate::source::{Dummy, Scan, Values};
24use crate::stream::{Filter, Limit, Project};
25
26pub fn build<'a>(plan: &'a Plan, catalog: &'a Catalog) -> Result<Box<dyn Operator + 'a>> {
33 node(plan, catalog, plan.root())
34}
35
36fn node<'a>(
37 plan: &'a Plan,
38 catalog: &'a Catalog,
39 reference: NodeRef,
40) -> Result<Box<dyn Operator + 'a>> {
41 Ok(match *plan.node(reference) {
42 Node::Get { catalog: database, schema, table, index, columns, .. } => {
43 let name =
44 QualifiedName::new(plan.string(database), plan.string(schema), plan.string(table));
45 Box::new(Scan::new(plan, catalog.table(&name)?, index, columns)?)
46 }
47 Node::Dummy => Box::new(Dummy::new()),
48 Node::Values { index, columns, rows } => Box::new(Values::new(plan, index, columns, rows)?),
49 Node::Filter { input, predicate } => {
50 Box::new(Filter::new(plan, node(plan, catalog, input)?, predicate))
51 }
52 Node::Project { input, index, exprs, names } => {
53 Box::new(Project::new(plan, node(plan, catalog, input)?, index, exprs, names)?)
54 }
55 Node::Aggregate { input, index, groups, aggregates } => {
56 Box::new(Aggregate::new(plan, node(plan, catalog, input)?, index, groups, aggregates)?)
57 }
58 Node::Sort { input, keys } => Box::new(Sort::new(plan, node(plan, catalog, input)?, keys)),
59 Node::Limit { input, count, offset } => {
60 Box::new(Limit::new(node(plan, catalog, input)?, count, offset))
61 }
62 Node::Distinct { input, on } => {
63 Box::new(Distinct::new(plan, node(plan, catalog, input)?, on))
64 }
65 Node::Join { left, right, kind, conditions } => Box::new(Join::new(
66 plan,
67 node(plan, catalog, left)?,
68 node(plan, catalog, right)?,
69 kind,
70 conditions,
71 )),
72 Node::CrossProduct { left, right } => {
73 Box::new(CrossProduct::new(node(plan, catalog, left)?, node(plan, catalog, right)?))
74 }
75 Node::SetOp { left, right, kind, all, index } => Box::new(SetOp::new(
76 node(plan, catalog, left)?,
77 node(plan, catalog, right)?,
78 kind,
79 all,
80 index,
81 )),
82 })
83}