use rudb_seam::SeamId;
use crate::node::Node;
#[must_use]
pub fn seams_of(node: &Node) -> &'static [SeamId] {
const HASHED: &[SeamId] = &[SeamId::HashKey, SeamId::HashFunction, SeamId::HashTable];
match node {
Node::Get { .. } => &[SeamId::VectorForm, SeamId::ScanMaterialisation],
Node::Filter { .. } => &[
SeamId::ExprEval,
SeamId::KernelCompare,
SeamId::KernelFilter,
SeamId::ChunkCompaction,
],
Node::Project { .. } => &[SeamId::ExprEval],
Node::Aggregate { .. } => &[
SeamId::HashKey,
SeamId::HashFunction,
SeamId::HashTable,
SeamId::AggState,
SeamId::AggParallel,
],
Node::Distinct { .. } | Node::SetOp { .. } => HASHED,
Node::Sort { .. } => &[SeamId::Sort],
Node::TopN { .. } => &[SeamId::TopK],
Node::Join { .. } => {
&[SeamId::JoinBuild, SeamId::JoinFilter, SeamId::HashKey, SeamId::HashFunction]
}
Node::Dummy
| Node::Values { .. }
| Node::TableFunction { .. }
| Node::Fetch { .. }
| Node::Limit { .. }
| Node::CrossProduct { .. } => &[],
}
}
#[cfg(test)]
mod tests {
use rudb_seam::SeamId;
use super::seams_of;
use crate::node::Node;
#[test]
fn an_operator_with_one_way_to_do_its_job_sits_on_no_seam() {
assert!(seams_of(&Node::Limit { input: 0, count: Some(10), offset: 0 }).is_empty());
assert!(seams_of(&Node::Dummy).is_empty());
}
#[test]
fn a_filter_sits_on_the_seam_a_filter_actually_chooses_from() {
let seams = seams_of(&Node::Filter { input: 0, predicate: 0 });
assert!(seams.contains(&SeamId::ChunkCompaction), "{seams:?}");
}
}