|
|
@ -240,6 +240,8 @@ impl<'a> SessionTx<'a> {
|
|
|
|
let mut right_joiner_vars = vec![];
|
|
|
|
let mut right_joiner_vars = vec![];
|
|
|
|
// used to split in case we need to join again
|
|
|
|
// used to split in case we need to join again
|
|
|
|
let mut right_joiner_vars_pos = vec![];
|
|
|
|
let mut right_joiner_vars_pos = vec![];
|
|
|
|
|
|
|
|
// used to find the right joiner var with the tuple position
|
|
|
|
|
|
|
|
let mut right_joiner_vars_pos_rev = vec![None; rel_app.args.len()];
|
|
|
|
// vars introduced by right, regardless of joining
|
|
|
|
// vars introduced by right, regardless of joining
|
|
|
|
let mut right_vars = vec![];
|
|
|
|
let mut right_vars = vec![];
|
|
|
|
// used for choosing indices
|
|
|
|
// used for choosing indices
|
|
|
@ -252,6 +254,7 @@ impl<'a> SessionTx<'a> {
|
|
|
|
right_vars.push(rk.clone());
|
|
|
|
right_vars.push(rk.clone());
|
|
|
|
right_joiner_vars.push(rk);
|
|
|
|
right_joiner_vars.push(rk);
|
|
|
|
right_joiner_vars_pos.push(i);
|
|
|
|
right_joiner_vars_pos.push(i);
|
|
|
|
|
|
|
|
right_joiner_vars_pos_rev[i] = Some(right_joiner_vars.len()-1);
|
|
|
|
join_indices.push(IndexPositionUse::Join)
|
|
|
|
join_indices.push(IndexPositionUse::Join)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
seen_variables.insert(var.clone());
|
|
|
|
seen_variables.insert(var.clone());
|
|
|
@ -298,57 +301,77 @@ impl<'a> SessionTx<'a> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some((chosen_index, mapper, true)) => {
|
|
|
|
Some((chosen_index, mapper, true)) => {
|
|
|
|
// index-with-join
|
|
|
|
// index-with-join
|
|
|
|
let mut prev_joiner_first_vars = vec![];
|
|
|
|
let mut not_bound = vec![true; prev_joiner_vars.len()];
|
|
|
|
let mut middle_joiner_left_vars = vec![];
|
|
|
|
let mut index_vars = vec![];
|
|
|
|
let mut middle_vars = vec![];
|
|
|
|
// Get the index and its keys
|
|
|
|
for i in mapper.iter() {
|
|
|
|
|
|
|
|
let tv = gen_symb(right_vars[*i].span);
|
|
|
|
|
|
|
|
if let Some(j) = right_joiner_vars_pos.iter().position(|el| el == i)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
prev_joiner_first_vars.push(prev_joiner_vars[j].clone());
|
|
|
|
let mut left_keys = vec![];
|
|
|
|
middle_joiner_left_vars.push(tv.clone());
|
|
|
|
let mut right_keys = vec![];
|
|
|
|
}
|
|
|
|
for &orig_idx in mapper.iter() {
|
|
|
|
middle_vars.push(tv);
|
|
|
|
// Create a new symbol for the column in the index relation
|
|
|
|
}
|
|
|
|
let tv = gen_symb(right_vars[orig_idx].span);
|
|
|
|
let mut final_joiner_vars = vec![];
|
|
|
|
// Check for the existance of this column among the joiner columns
|
|
|
|
let middle_joiner_right_vars = mapper
|
|
|
|
if let Some(join_idx) = right_joiner_vars_pos_rev[orig_idx] {
|
|
|
|
.iter()
|
|
|
|
// Mark the field as bound, since it is used in the join
|
|
|
|
.enumerate()
|
|
|
|
not_bound[join_idx] = false;
|
|
|
|
.filter_map(|(idx, orig_idx)| {
|
|
|
|
// Push the index symbol to the left side
|
|
|
|
if *orig_idx < store.metadata.keys.len() {
|
|
|
|
left_keys.push(prev_joiner_vars[join_idx].clone());
|
|
|
|
final_joiner_vars.push(right_vars[*orig_idx].clone());
|
|
|
|
// Push the joiner symbol to the right side
|
|
|
|
Some(middle_vars[idx].clone())
|
|
|
|
right_keys.push(tv.clone());
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
None
|
|
|
|
index_vars.push(tv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
let index = RelAlgebra::relation(
|
|
|
|
.collect_vec();
|
|
|
|
index_vars.clone(),
|
|
|
|
|
|
|
|
|
|
|
|
let middle = RelAlgebra::relation(
|
|
|
|
|
|
|
|
middle_vars,
|
|
|
|
|
|
|
|
chosen_index,
|
|
|
|
chosen_index,
|
|
|
|
rel_app.span,
|
|
|
|
rel_app.span,
|
|
|
|
rel_app.valid_at,
|
|
|
|
rel_app.valid_at,
|
|
|
|
)?;
|
|
|
|
)?;
|
|
|
|
ret = ret.join(
|
|
|
|
ret = ret.join(
|
|
|
|
middle,
|
|
|
|
index,
|
|
|
|
prev_joiner_first_vars,
|
|
|
|
left_keys,
|
|
|
|
middle_joiner_left_vars,
|
|
|
|
right_keys,
|
|
|
|
rel_app.span,
|
|
|
|
rel_app.span,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
let final_alg = RelAlgebra::relation(
|
|
|
|
}
|
|
|
|
|
|
|
|
// Join the index with the original relation
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let mut left_keys = Vec::with_capacity(store.metadata.keys.len());
|
|
|
|
|
|
|
|
let mut right_keys = Vec::with_capacity(store.metadata.keys.len());
|
|
|
|
|
|
|
|
for (index_idx, &orig_idx) in mapper.iter().enumerate() {
|
|
|
|
|
|
|
|
if orig_idx < store.metadata.keys.len() {
|
|
|
|
|
|
|
|
// Push the index symbol to the left side
|
|
|
|
|
|
|
|
left_keys.push(index_vars[index_idx].clone());
|
|
|
|
|
|
|
|
// Push the relation symbol to the right side
|
|
|
|
|
|
|
|
right_keys.push(right_vars[orig_idx].clone());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let relation = RelAlgebra::relation(
|
|
|
|
right_vars,
|
|
|
|
right_vars,
|
|
|
|
store,
|
|
|
|
store,
|
|
|
|
rel_app.span,
|
|
|
|
rel_app.span,
|
|
|
|
rel_app.valid_at,
|
|
|
|
rel_app.valid_at,
|
|
|
|
)?;
|
|
|
|
)?;
|
|
|
|
ret = ret.join(
|
|
|
|
ret = ret.join(
|
|
|
|
final_alg,
|
|
|
|
relation,
|
|
|
|
middle_joiner_right_vars,
|
|
|
|
left_keys,
|
|
|
|
final_joiner_vars,
|
|
|
|
right_keys,
|
|
|
|
rel_app.span,
|
|
|
|
rel_app.span,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use the binds that were not used in the join
|
|
|
|
|
|
|
|
for (i, nb) in not_bound.into_iter().enumerate() {
|
|
|
|
|
|
|
|
if !nb { continue };
|
|
|
|
|
|
|
|
let (left, right) = (prev_joiner_vars[i].clone(), right_joiner_vars[i].clone());
|
|
|
|
|
|
|
|
ret = ret.filter(Expr::build_equate(
|
|
|
|
|
|
|
|
vec![
|
|
|
|
|
|
|
|
Expr::Binding { var: left, tuple_pos: None },
|
|
|
|
|
|
|
|
Expr::Binding { var: right, tuple_pos: None },
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
rel_app.span,
|
|
|
|
|
|
|
|
))?;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MagicAtom::NegatedRule(rule_app) => {
|
|
|
|
MagicAtom::NegatedRule(rule_app) => {
|
|
|
|