diff --git a/src/algebra/op/assoc.rs b/src/algebra/op/assoc.rs index 105a4c6b..639db64f 100644 --- a/src/algebra/op/assoc.rs +++ b/src/algebra/op/assoc.rs @@ -1,9 +1,10 @@ -use crate::algebra::op::RelationalAlgebra; +use crate::algebra::op::{InterpretContext, RelationalAlgebra}; use crate::algebra::parser::RaBox; use crate::context::TempDbContext; -use crate::data::expr::StaticExpr; +use crate::data::expr::{Expr, StaticExpr}; use crate::data::tuple::{OwnTuple, Tuple}; use crate::data::tuple_set::{next_tset_indices, BindingMap, TupleSet, TupleSetIdx}; +use crate::data::value::Value; use crate::ddl::reify::{AssocInfo, TableInfo}; use crate::runtime::options::default_read_options; use anyhow::Result; @@ -19,6 +20,62 @@ pub(crate) struct AssocOp<'a> { pub(crate) binding: String, } +impl<'a> AssocOp<'a> { + pub(crate) fn build( + ctx: &'a TempDbContext<'a>, + source: RaBox<'a>, + binding: &str, + table_info: &TableInfo, + assoc_infos: Vec, + ) -> Result { + let mut key_extractors = vec![]; + match table_info { + TableInfo::Node(info) => { + for col in &info.keys { + key_extractors.push(Expr::FieldAcc( + col.name.clone(), + Expr::Variable(binding.to_string()).into(), + )) + } + } + TableInfo::Edge(info) => { + let src = ctx.get_table_info(info.src_id)?; + let src = src.as_node()?; + let dst = ctx.get_table_info(info.dst_id)?; + let dst = dst.as_node()?; + key_extractors.push(Expr::Const(Value::Int(info.src_id.int_for_storage()))); + for col in &src.keys { + key_extractors.push(Expr::FieldAcc( + "_src_".to_string() + &col.name, + Expr::Variable(binding.to_string()).into(), + )); + } + key_extractors.push(Expr::Const(Value::Bool(true))); + for col in &dst.keys { + key_extractors.push(Expr::FieldAcc( + "_dst_".to_string() + &col.name, + Expr::Variable(binding.to_string()).into(), + )); + } + for col in &info.keys { + key_extractors.push(Expr::FieldAcc( + col.name.clone(), + Expr::Variable(binding.to_string()).into(), + )); + } + } + _ => unreachable!(), + } + Ok(AssocOp { + ctx, + source, + assoc_infos, + key_extractors, + binding: binding.to_string(), + }) + } +} + impl<'b> RelationalAlgebra for AssocOp<'b> { fn name(&self) -> &str { NAME_ASSOC diff --git a/src/algebra/op/scan.rs b/src/algebra/op/scan.rs index 79748126..e94f3d3c 100644 --- a/src/algebra/op/scan.rs +++ b/src/algebra/op/scan.rs @@ -61,54 +61,15 @@ impl<'a> TableScan<'a> { ctx, binding: el.binding.clone(), table_info: table_info.clone(), - // assoc_infos, })); if !assoc_infos.is_empty() { - let mut key_extractors = vec![]; - match &table_info { - TableInfo::Node(info) => { - for col in &info.keys { - key_extractors.push(Expr::FieldAcc( - col.name.clone(), - Expr::Variable(el.binding.clone()).into(), - )) - } - } - TableInfo::Edge(info) => { - let src = ctx.get_table_info(info.src_id)?; - let src = src.as_node()?; - let dst = ctx.get_table_info(info.dst_id)?; - let dst = dst.as_node()?; - key_extractors.push(Expr::Const(Value::Int(info.src_id.int_for_storage()))); - for col in &src.keys { - key_extractors.push(Expr::FieldAcc( - "_src_".to_string() + &col.name, - Expr::Variable(el.binding.clone()).into(), - )); - } - key_extractors.push(Expr::Const(Value::Bool(true))); - for col in &dst.keys { - key_extractors.push(Expr::FieldAcc( - "_dst_".to_string() + &col.name, - Expr::Variable(el.binding.clone()).into(), - )); - } - for col in &info.keys { - key_extractors.push(Expr::FieldAcc( - col.name.clone(), - Expr::Variable(el.binding.clone()).into(), - )); - } - } - _ => unreachable!(), - } - ret = RaBox::AssocOp(Box::new(AssocOp { + ret = RaBox::AssocOp(Box::new(AssocOp::build( ctx, - source: ret, + ret, + &el.binding, + &table_info, assoc_infos, - key_extractors, - binding: el.binding.clone(), - })) + )?)) } Ok(ret) }