diff --git a/.gitignore b/.gitignore index c2e4cb9e..dbcf703f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ install_manifest.txt compile_commands.json CTestTestfile.cmake _deps +_test* *.db deps/ \ No newline at end of file diff --git a/src/db/iterator.rs b/src/db/iterator.rs index 58b1f86f..d80172fc 100644 --- a/src/db/iterator.rs +++ b/src/db/iterator.rs @@ -1,3 +1,4 @@ +use crate::db::engine::Session; use crate::db::eval::{compare_tuple_by_keys, tuple_eval}; use crate::db::table::{ColId, TableId, TableInfo}; use crate::error::CozoError::LogicError; @@ -25,14 +26,20 @@ impl<'a> Debug for IteratorSlot<'a> { } } -pub enum TableRowGetter { +pub enum TableRowGetter<'a> { Dummy, + Reified { + sess: &'a Session<'a>, + key_cache: OwnTuple, + in_root: bool, + }, } -impl Debug for TableRowGetter { +impl<'a> Debug for TableRowGetter<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { TableRowGetter::Dummy => write!(f, "DummyRowGetter"), + TableRowGetter::Reified { .. } => write!(f, "TableRowGetter"), } } } @@ -81,12 +88,13 @@ pub enum ExecPlan<'a> { it: IteratorSlot<'a>, info: TableInfo, binding: Option, - getter: TableRowGetter, + getter: TableRowGetter<'a>, }, ChainJoinItPlan { left: Box>, - right: TableRowGetter, + right: TableRowGetter<'a>, right_info: TableInfo, + right_binding: Option, kind: ChainJoinKind, left_outer: bool, right_outer: bool, @@ -177,8 +185,11 @@ impl<'a> ExecPlan<'a> { ExecPlan::EdgeBwdItPlan { .. } => { todo!() } - ExecPlan::ChainJoinItPlan { .. } => { - todo!() + ExecPlan::ChainJoinItPlan { + left, right_info, .. + } => { + let (l1, l2) = left.tuple_widths(); + (l1 + 1, l2 + 1) } } } diff --git a/src/db/plan.rs b/src/db/plan.rs index 8520d462..ffbf785b 100644 --- a/src/db/plan.rs +++ b/src/db/plan.rs @@ -6,6 +6,7 @@ use crate::error::CozoError::LogicError; use crate::error::Result; use crate::parser::Rule; use crate::relation::data::DataKind; +use crate::relation::tuple::OwnTuple; use crate::relation::value::{StaticValue, Value}; use cozorocks::IteratorPtr; use pest::iterators::Pair; @@ -113,7 +114,7 @@ impl<'a> Session<'a> { let amap = match &binding { None => Default::default(), Some(binding) => { - let amap = self.edge_accessor_map(&binding, &info); + let amap = self.edge_accessor_map(binding, &info); convert_to_relative_accessor_map(amap) } }; @@ -189,8 +190,35 @@ impl<'a> Session<'a> { kind, left_outer, right_outer, + right_binding, } => { - todo!() + let (l_plan, l_map) = self.do_reify_intermediate_plan(*left)?; + let r_map = match &right_binding { + None => Default::default(), + Some(binding) => match kind { + ChainJoinKind::NodeToFwdEdge | ChainJoinKind::NodeToBwdEdge => { + self.edge_accessor_map(binding, &right_info) + } + ChainJoinKind::FwdEdgeToNode | ChainJoinKind::BwdEdgeToNode => { + self.node_accessor_map(binding, &right_info) + } + }, + }; + let r_map = shift_accessor_map(r_map, l_plan.tuple_widths()); + let plan = ExecPlan::ChainJoinItPlan { + left: l_plan.into(), + right: TableRowGetter::Reified { + sess: self, + key_cache: OwnTuple::with_prefix(right_info.table_id.id as u32), + in_root: right_info.table_id.in_root, + }, + right_info, + right_binding, + kind, + left_outer, + right_outer, + }; + (plan, merge_accessor_map(l_map, r_map)) } }; Ok(res) @@ -295,6 +323,7 @@ impl<'a> Session<'a> { }, left_outer: prev_left_outer, right_outer: el.right_outer_marker, + right_binding: el.binding, }; prev_kind = el.kind; diff --git a/src/relation/tuple.rs b/src/relation/tuple.rs index 5f8d4030..7d0da5b4 100644 --- a/src/relation/tuple.rs +++ b/src/relation/tuple.rs @@ -19,6 +19,15 @@ where idx_cache: RefCell>, } +impl Tuple +where + T: AsRef<[u8]>, +{ + pub fn clear_cache(&self) { + self.idx_cache.borrow_mut().clear() + } +} + impl AsRef<[u8]> for Tuple where T: AsRef<[u8]>, @@ -482,6 +491,11 @@ impl<'a, T: AsRef<[u8]>> Iterator for TupleIter<'a, T> { } impl OwnTuple { + #[inline] + pub fn truncate_all(&mut self) { + self.clear_cache(); + self.data.truncate(PREFIX_LEN); + } #[inline] pub fn empty_tuple() -> OwnTuple { OwnTuple::with_data_prefix(DataKind::Empty)