|
|
|
@ -25,8 +25,8 @@ use crate::data::symb::Symbol;
|
|
|
|
|
use crate::data::tuple::{Tuple, TupleIter};
|
|
|
|
|
use crate::data::value::DataValue;
|
|
|
|
|
use crate::parse::SourceSpan;
|
|
|
|
|
use crate::runtime::in_mem::{InMemRelation, StoredRelationId};
|
|
|
|
|
use crate::runtime::relation::RelationHandle;
|
|
|
|
|
use crate::runtime::temp_store::EpochStore;
|
|
|
|
|
use crate::runtime::transact::SessionTx;
|
|
|
|
|
use crate::utils::swap_option_result;
|
|
|
|
|
|
|
|
|
@ -113,9 +113,8 @@ impl UnificationRA {
|
|
|
|
|
fn iter<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
tx: &'a SessionTx<'_>,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let mut bindings = self.parent.bindings_after_eliminate();
|
|
|
|
|
bindings.push(self.binding.clone());
|
|
|
|
@ -123,7 +122,7 @@ impl UnificationRA {
|
|
|
|
|
Ok(if self.is_multi {
|
|
|
|
|
let it = self
|
|
|
|
|
.parent
|
|
|
|
|
.iter(tx, epoch, use_delta, stores)?
|
|
|
|
|
.iter(tx, delta_rule, stores)?
|
|
|
|
|
.map_ok(move |tuple| -> Result<Vec<Tuple>> {
|
|
|
|
|
let result_list = self.expr.eval(&tuple)?;
|
|
|
|
|
let result_list = result_list.get_list().ok_or_else(|| {
|
|
|
|
@ -151,7 +150,7 @@ impl UnificationRA {
|
|
|
|
|
} else {
|
|
|
|
|
Box::new(
|
|
|
|
|
self.parent
|
|
|
|
|
.iter(tx, epoch, use_delta, stores)?
|
|
|
|
|
.iter(tx, delta_rule, stores)?
|
|
|
|
|
.map_ok(move |tuple| -> Result<Tuple> {
|
|
|
|
|
let result = self.expr.eval(&tuple)?;
|
|
|
|
|
let mut ret = tuple;
|
|
|
|
@ -204,15 +203,14 @@ impl FilteredRA {
|
|
|
|
|
fn iter<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
tx: &'a SessionTx<'_>,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let bindings = self.parent.bindings_after_eliminate();
|
|
|
|
|
let eliminate_indices = get_eliminate_indices(&bindings, &self.to_eliminate);
|
|
|
|
|
Ok(Box::new(
|
|
|
|
|
self.parent
|
|
|
|
|
.iter(tx, epoch, use_delta, stores)?
|
|
|
|
|
.iter(tx, delta_rule, stores)?
|
|
|
|
|
.filter_map(move |tuple| match tuple {
|
|
|
|
|
Ok(t) => {
|
|
|
|
|
for p in self.pred.iter() {
|
|
|
|
@ -260,13 +258,13 @@ impl Debug for RelAlgebra {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RelAlgebra::TempStore(r) => f
|
|
|
|
|
.debug_tuple("Derived")
|
|
|
|
|
.debug_tuple("TempStore")
|
|
|
|
|
.field(&bindings)
|
|
|
|
|
.field(&r.storage_key)
|
|
|
|
|
.field(&r.filters)
|
|
|
|
|
.finish(),
|
|
|
|
|
RelAlgebra::Stored(r) => f
|
|
|
|
|
.debug_tuple("Derived")
|
|
|
|
|
.debug_tuple("Stored")
|
|
|
|
|
.field(&bindings)
|
|
|
|
|
.field(&r.storage.name)
|
|
|
|
|
.field(&r.filters)
|
|
|
|
@ -356,7 +354,11 @@ impl RelAlgebra {
|
|
|
|
|
pub(crate) fn cartesian_join(self, right: RelAlgebra, span: SourceSpan) -> Self {
|
|
|
|
|
self.join(right, vec![], vec![], span)
|
|
|
|
|
}
|
|
|
|
|
pub(crate) fn derived(bindings: Vec<Symbol>, storage_key: MagicSymbol, span: SourceSpan) -> Self {
|
|
|
|
|
pub(crate) fn derived(
|
|
|
|
|
bindings: Vec<Symbol>,
|
|
|
|
|
storage_key: MagicSymbol,
|
|
|
|
|
span: SourceSpan,
|
|
|
|
|
) -> Self {
|
|
|
|
|
Self::TempStore(TempStoreRA {
|
|
|
|
|
bindings,
|
|
|
|
|
storage_key,
|
|
|
|
@ -556,9 +558,8 @@ impl ReorderRA {
|
|
|
|
|
fn iter<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
tx: &'a SessionTx<'_>,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let old_order = self.relation.bindings_after_eliminate();
|
|
|
|
|
let old_order_indices: BTreeMap<_, _> = old_order
|
|
|
|
@ -575,16 +576,18 @@ impl ReorderRA {
|
|
|
|
|
.expect("program logic error: reorder indices mismatch")
|
|
|
|
|
})
|
|
|
|
|
.collect_vec();
|
|
|
|
|
Ok(Box::new(self.relation.iter(tx, epoch, use_delta, stores)?.map_ok(
|
|
|
|
|
move |tuple| {
|
|
|
|
|
let old = tuple;
|
|
|
|
|
let new = reorder_indices
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|i| old[*i].clone())
|
|
|
|
|
.collect_vec();
|
|
|
|
|
new
|
|
|
|
|
},
|
|
|
|
|
)))
|
|
|
|
|
Ok(Box::new(
|
|
|
|
|
self.relation
|
|
|
|
|
.iter(tx, delta_rule, stores)?
|
|
|
|
|
.map_ok(move |tuple| {
|
|
|
|
|
let old = tuple;
|
|
|
|
|
let new = reorder_indices
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|i| old[*i].clone())
|
|
|
|
|
.collect_vec();
|
|
|
|
|
new
|
|
|
|
|
}),
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1069,26 +1072,20 @@ impl TempStoreRA {
|
|
|
|
|
|
|
|
|
|
fn iter<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let storage = stores.get(&self.storage_key).unwrap();
|
|
|
|
|
if epoch == Some(0) && use_delta.contains(&storage.id) {
|
|
|
|
|
return Ok(Box::new(iter::empty()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let scan_epoch = match epoch {
|
|
|
|
|
None => 0,
|
|
|
|
|
Some(ep) => {
|
|
|
|
|
if use_delta.contains(&storage.id) {
|
|
|
|
|
ep - 1
|
|
|
|
|
} else {
|
|
|
|
|
0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let scan_epoch = match delta_rule {
|
|
|
|
|
None => false,
|
|
|
|
|
Some(name) => *name == self.storage_key,
|
|
|
|
|
};
|
|
|
|
|
let it = if scan_epoch {
|
|
|
|
|
Left(storage.delta_all_iter().map(|t| Ok(t.into_tuple())))
|
|
|
|
|
} else {
|
|
|
|
|
Right(storage.all_iter().map(|t| Ok(t.into_tuple())))
|
|
|
|
|
};
|
|
|
|
|
let it = storage.scan_all_for_epoch(scan_epoch);
|
|
|
|
|
Ok(if self.filters.is_empty() {
|
|
|
|
|
Box::new(it)
|
|
|
|
|
} else {
|
|
|
|
@ -1100,7 +1097,7 @@ impl TempStoreRA {
|
|
|
|
|
left_iter: TupleIter<'a>,
|
|
|
|
|
(left_join_indices, right_join_indices): (Vec<usize>, Vec<usize>),
|
|
|
|
|
eliminate_indices: BTreeSet<usize>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let storage = stores.get(&self.storage_key).unwrap();
|
|
|
|
|
debug_assert!(!right_join_indices.is_empty());
|
|
|
|
@ -1122,12 +1119,11 @@ impl TempStoreRA {
|
|
|
|
|
.map(|i| tuple[*i].clone())
|
|
|
|
|
.collect_vec();
|
|
|
|
|
|
|
|
|
|
'outer: for found in storage.scan_prefix(&prefix) {
|
|
|
|
|
let found = found?;
|
|
|
|
|
'outer: for found in storage.prefix_iter(&prefix) {
|
|
|
|
|
for (left_idx, right_idx) in
|
|
|
|
|
left_join_indices.iter().zip(right_join_indices.iter())
|
|
|
|
|
{
|
|
|
|
|
if tuple[*left_idx] != found[*right_idx] {
|
|
|
|
|
if tuple[*left_idx] != *found.get(*right_idx) {
|
|
|
|
|
continue 'outer;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1155,11 +1151,10 @@ impl TempStoreRA {
|
|
|
|
|
))
|
|
|
|
|
} else {
|
|
|
|
|
let mut right_join_vals = BTreeSet::new();
|
|
|
|
|
for tuple in storage.scan_all() {
|
|
|
|
|
let tuple = tuple?;
|
|
|
|
|
for tuple in storage.all_iter() {
|
|
|
|
|
let to_join: Box<[DataValue]> = right_join_indices
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|i| tuple[*i].clone())
|
|
|
|
|
.map(|i| tuple.get(*i).clone())
|
|
|
|
|
.collect();
|
|
|
|
|
right_join_vals.insert(to_join);
|
|
|
|
|
}
|
|
|
|
@ -1200,29 +1195,20 @@ impl TempStoreRA {
|
|
|
|
|
left_iter: TupleIter<'a>,
|
|
|
|
|
(left_join_indices, right_join_indices): (Vec<usize>, Vec<usize>),
|
|
|
|
|
eliminate_indices: BTreeSet<usize>,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let storage = stores.get(&self.storage_key).unwrap();
|
|
|
|
|
if epoch == Some(0) && use_delta.contains(&storage.id) {
|
|
|
|
|
return Ok(Box::new(iter::empty()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut right_invert_indices = right_join_indices.iter().enumerate().collect_vec();
|
|
|
|
|
right_invert_indices.sort_by_key(|(_, b)| **b);
|
|
|
|
|
let left_to_prefix_indices = right_invert_indices
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|(a, _)| left_join_indices[a])
|
|
|
|
|
.collect_vec();
|
|
|
|
|
let scan_epoch = match epoch {
|
|
|
|
|
None => 0,
|
|
|
|
|
Some(ep) => {
|
|
|
|
|
if use_delta.contains(&storage.id) {
|
|
|
|
|
ep - 1
|
|
|
|
|
} else {
|
|
|
|
|
0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let scan_epoch = match delta_rule {
|
|
|
|
|
None => false,
|
|
|
|
|
Some(name) => *name == self.storage_key,
|
|
|
|
|
};
|
|
|
|
|
let mut skip_range_check = false;
|
|
|
|
|
let it = left_iter
|
|
|
|
@ -1241,13 +1227,23 @@ impl TempStoreRA {
|
|
|
|
|
if !l_bound.iter().all(|v| *v == DataValue::Null)
|
|
|
|
|
|| !u_bound.iter().all(|v| *v == DataValue::Bot)
|
|
|
|
|
{
|
|
|
|
|
let mut lower_bound = prefix.clone();
|
|
|
|
|
lower_bound.extend(l_bound);
|
|
|
|
|
let mut upper_bound = prefix.clone();
|
|
|
|
|
upper_bound.extend(u_bound);
|
|
|
|
|
let it = if scan_epoch {
|
|
|
|
|
Left(storage.delta_range_iter(&lower_bound, &upper_bound, true))
|
|
|
|
|
} else {
|
|
|
|
|
Right(storage.range_iter(&lower_bound, &upper_bound, true))
|
|
|
|
|
};
|
|
|
|
|
return Left(
|
|
|
|
|
storage
|
|
|
|
|
.scan_bounded_prefix_for_epoch(
|
|
|
|
|
&prefix, &l_bound, &u_bound, scan_epoch,
|
|
|
|
|
)
|
|
|
|
|
.map(move |res_found| -> Result<Option<Tuple>> {
|
|
|
|
|
let found = res_found?;
|
|
|
|
|
it.map(move |res_found| -> Result<Option<Tuple>> {
|
|
|
|
|
if self.filters.is_empty() {
|
|
|
|
|
let mut ret = tuple.clone();
|
|
|
|
|
ret.extend(res_found.into_iter().cloned());
|
|
|
|
|
Ok(Some(ret))
|
|
|
|
|
} else {
|
|
|
|
|
let found = res_found.into_tuple();
|
|
|
|
|
for p in self.filters.iter() {
|
|
|
|
|
if !p.eval_pred(&found)? {
|
|
|
|
|
return Ok(None);
|
|
|
|
@ -1256,17 +1252,28 @@ impl TempStoreRA {
|
|
|
|
|
let mut ret = tuple.clone();
|
|
|
|
|
ret.extend(found);
|
|
|
|
|
Ok(Some(ret))
|
|
|
|
|
})
|
|
|
|
|
.filter_map(swap_option_result),
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.filter_map(swap_option_result),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
skip_range_check = true;
|
|
|
|
|
|
|
|
|
|
let it = if scan_epoch {
|
|
|
|
|
Left(storage.delta_prefix_iter(&prefix))
|
|
|
|
|
} else {
|
|
|
|
|
Right(storage.prefix_iter(&prefix))
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Right(
|
|
|
|
|
storage
|
|
|
|
|
.scan_prefix_for_epoch(&prefix, scan_epoch)
|
|
|
|
|
.map(move |res_found| -> Result<Option<Tuple>> {
|
|
|
|
|
let found = res_found?;
|
|
|
|
|
it.map(move |res_found| -> Result<Option<Tuple>> {
|
|
|
|
|
if self.filters.is_empty() {
|
|
|
|
|
let mut ret = tuple.clone();
|
|
|
|
|
ret.extend(res_found.into_iter().cloned());
|
|
|
|
|
Ok(Some(ret))
|
|
|
|
|
} else {
|
|
|
|
|
let found = res_found.into_tuple();
|
|
|
|
|
for p in self.filters.iter() {
|
|
|
|
|
if !p.eval_pred(&found)? {
|
|
|
|
|
return Ok(None);
|
|
|
|
@ -1275,8 +1282,9 @@ impl TempStoreRA {
|
|
|
|
|
let mut ret = tuple.clone();
|
|
|
|
|
ret.extend(found);
|
|
|
|
|
Ok(Some(ret))
|
|
|
|
|
})
|
|
|
|
|
.filter_map(swap_option_result),
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.filter_map(swap_option_result),
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
.flatten_ok()
|
|
|
|
@ -1395,19 +1403,18 @@ impl RelAlgebra {
|
|
|
|
|
pub(crate) fn iter<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
tx: &'a SessionTx<'_>,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
match self {
|
|
|
|
|
RelAlgebra::Fixed(f) => Ok(Box::new(f.data.iter().map(|t| Ok(t.clone())))),
|
|
|
|
|
RelAlgebra::TempStore(r) => r.iter(epoch, use_delta, stores),
|
|
|
|
|
RelAlgebra::TempStore(r) => r.iter(delta_rule, stores),
|
|
|
|
|
RelAlgebra::Stored(v) => v.iter(tx),
|
|
|
|
|
RelAlgebra::Join(j) => j.iter(tx, epoch, use_delta, stores),
|
|
|
|
|
RelAlgebra::Reorder(r) => r.iter(tx, epoch, use_delta, stores),
|
|
|
|
|
RelAlgebra::Filter(r) => r.iter(tx, epoch, use_delta, stores),
|
|
|
|
|
RelAlgebra::NegJoin(r) => r.iter(tx, epoch, use_delta, stores),
|
|
|
|
|
RelAlgebra::Unification(r) => r.iter(tx, epoch, use_delta, stores),
|
|
|
|
|
RelAlgebra::Join(j) => j.iter(tx, delta_rule, stores),
|
|
|
|
|
RelAlgebra::Reorder(r) => r.iter(tx, delta_rule, stores),
|
|
|
|
|
RelAlgebra::Filter(r) => r.iter(tx, delta_rule, stores),
|
|
|
|
|
RelAlgebra::NegJoin(r) => r.iter(tx, delta_rule, stores),
|
|
|
|
|
RelAlgebra::Unification(r) => r.iter(tx, delta_rule, stores),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1474,9 +1481,8 @@ impl NegJoin {
|
|
|
|
|
pub(crate) fn iter<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
tx: &'a SessionTx<'_>,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let bindings = self.left.bindings_after_eliminate();
|
|
|
|
|
let eliminate_indices = get_eliminate_indices(&bindings, &self.to_eliminate);
|
|
|
|
@ -1490,10 +1496,10 @@ impl NegJoin {
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
r.neg_join(
|
|
|
|
|
self.left.iter(tx, epoch, use_delta, stores)?,
|
|
|
|
|
self.left.iter(tx, delta_rule, stores)?,
|
|
|
|
|
join_indices,
|
|
|
|
|
eliminate_indices,
|
|
|
|
|
stores
|
|
|
|
|
stores,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
RelAlgebra::Stored(v) => {
|
|
|
|
@ -1506,7 +1512,7 @@ impl NegJoin {
|
|
|
|
|
.unwrap();
|
|
|
|
|
v.neg_join(
|
|
|
|
|
tx,
|
|
|
|
|
self.left.iter(tx, epoch, use_delta, stores)?,
|
|
|
|
|
self.left.iter(tx, delta_rule, stores)?,
|
|
|
|
|
join_indices,
|
|
|
|
|
eliminate_indices,
|
|
|
|
|
)
|
|
|
|
@ -1604,9 +1610,8 @@ impl InnerJoin {
|
|
|
|
|
pub(crate) fn iter<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
tx: &'a SessionTx<'_>,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let bindings = self.bindings();
|
|
|
|
|
let eliminate_indices = get_eliminate_indices(&bindings, &self.to_eliminate);
|
|
|
|
@ -1620,7 +1625,7 @@ impl InnerJoin {
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
f.join(
|
|
|
|
|
self.left.iter(tx, epoch, use_delta, stores)?,
|
|
|
|
|
self.left.iter(tx, delta_rule, stores)?,
|
|
|
|
|
join_indices,
|
|
|
|
|
eliminate_indices,
|
|
|
|
|
)
|
|
|
|
@ -1635,15 +1640,14 @@ impl InnerJoin {
|
|
|
|
|
.unwrap();
|
|
|
|
|
if join_is_prefix(&join_indices.1) {
|
|
|
|
|
r.prefix_join(
|
|
|
|
|
self.left.iter(tx, epoch, use_delta, stores)?,
|
|
|
|
|
self.left.iter(tx, delta_rule, stores)?,
|
|
|
|
|
join_indices,
|
|
|
|
|
eliminate_indices,
|
|
|
|
|
epoch,
|
|
|
|
|
use_delta,
|
|
|
|
|
stores
|
|
|
|
|
delta_rule,
|
|
|
|
|
stores,
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
self.materialized_join(tx, eliminate_indices, epoch, use_delta, stores)
|
|
|
|
|
self.materialized_join(tx, eliminate_indices, delta_rule, stores)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RelAlgebra::Stored(r) => {
|
|
|
|
@ -1658,17 +1662,17 @@ impl InnerJoin {
|
|
|
|
|
let left_len = self.left.bindings_after_eliminate().len();
|
|
|
|
|
r.prefix_join(
|
|
|
|
|
tx,
|
|
|
|
|
self.left.iter(tx, epoch, use_delta, stores)?,
|
|
|
|
|
self.left.iter(tx, delta_rule, stores)?,
|
|
|
|
|
join_indices,
|
|
|
|
|
eliminate_indices,
|
|
|
|
|
left_len,
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
self.materialized_join(tx, eliminate_indices, epoch, use_delta, stores)
|
|
|
|
|
self.materialized_join(tx, eliminate_indices, delta_rule, stores)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RelAlgebra::Join(_) | RelAlgebra::Filter(_) | RelAlgebra::Unification(_) => {
|
|
|
|
|
self.materialized_join(tx, eliminate_indices, epoch, use_delta, stores)
|
|
|
|
|
self.materialized_join(tx, eliminate_indices, delta_rule, stores)
|
|
|
|
|
}
|
|
|
|
|
RelAlgebra::Reorder(_) => {
|
|
|
|
|
panic!("joining on reordered")
|
|
|
|
@ -1682,9 +1686,8 @@ impl InnerJoin {
|
|
|
|
|
&'a self,
|
|
|
|
|
tx: &'a SessionTx<'_>,
|
|
|
|
|
eliminate_indices: BTreeSet<usize>,
|
|
|
|
|
epoch: Option<u32>,
|
|
|
|
|
use_delta: &BTreeSet<StoredRelationId>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, InMemRelation>
|
|
|
|
|
delta_rule: Option<&MagicSymbol>,
|
|
|
|
|
stores: &'a BTreeMap<MagicSymbol, EpochStore>,
|
|
|
|
|
) -> Result<TupleIter<'a>> {
|
|
|
|
|
let right_bindings = self.right.bindings_after_eliminate();
|
|
|
|
|
let (left_join_indices, right_join_indices) = self
|
|
|
|
@ -1692,7 +1695,7 @@ impl InnerJoin {
|
|
|
|
|
.join_indices(&self.left.bindings_after_eliminate(), &right_bindings)
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
let mut left_iter = self.left.iter(tx, epoch, use_delta, stores)?;
|
|
|
|
|
let mut left_iter = self.left.iter(tx, delta_rule, stores)?;
|
|
|
|
|
let left_cache = match left_iter.next() {
|
|
|
|
|
None => return Ok(Box::new(iter::empty())),
|
|
|
|
|
Some(Err(err)) => return Err(err),
|
|
|
|
@ -1717,7 +1720,7 @@ impl InnerJoin {
|
|
|
|
|
self.mat_right_cache.borrow().clone()
|
|
|
|
|
} else {
|
|
|
|
|
let mut cache = BTreeSet::new();
|
|
|
|
|
for item in self.right.iter(tx, epoch, use_delta, stores)? {
|
|
|
|
|
for item in self.right.iter(tx, delta_rule, stores)? {
|
|
|
|
|
match item {
|
|
|
|
|
Ok(tuple) => {
|
|
|
|
|
let stored_tuple = right_store_indices
|
|
|
|
|