fn join(rel_a: Relation, rel_b: Relation) -> Relation {
    // The join key is a vector of vars in both a and b, ordered as they are in a.
    let join_key: Vec<Var> = derive_join_key(&rel_a, &rel_b);
    let output_key = derive_output_key(&rel_a, &rel_b);

    let rel_a_vars = rel_a.0.iter().cloned().collect::<HashSet<Var>>();
    let rel_b_out_indices = rel_b.0.iter().enumerate()
        .filter(|(_idx, var)| !rel_a_vars.contains(var))
        .map(|(idx, _var)| idx)
        .collect::<Vec<usize>>();

    let rel_b_map = hash_relation(&join_key, rel_b);

    let project = |mut tuple_a: Vec<Value>, tuple_b: &Vec<Value>| {
        for idx in rel_b_out_indices.iter() {
            let val = tuple_b[*idx].clone();
            tuple_a.push(val);
        }

        tuple_a
    };

    // Join tuples in a and b on matching join key
    let rel_a_key_indices = key_indices(&join_key, &rel_a);
    let joined: Vec<Vec<Value>> = rel_a.1.iter().fold(vec![], |mut output, tuple_a| {
        if let Some(matches) = rel_b_map.get(&key_for_tuple(&rel_a_key_indices, &tuple_a)) {
            for tuple_b in matches {
                output.push(project(tuple_a.clone(), tuple_b));
            }
        }

        output
    });

    Relation(output_key, joined)
}
/// Implements the natural join between relations, outputting one
/// tuple for each combination of tuples in the two relations which
/// match on all overlapping variables.
Implements the natural join between relations, outputting one
tuple for each combination of tuples in the two relations which
match on all overlapping variables.
Implements the natural join between relations outputting one tuple for each combination of tuples in the two relations which match on all overlapping variables .
fn join(rel_a: Relation, rel_b: Relation) -> Relation {
    // The join key is a vector of vars in both a and b, ordered as they are in a.
    let join_key: Vec<Var> = derive_join_key(&rel_a, &rel_b);
    let output_key = derive_output_key(&rel_a, &rel_b);
    let rel_a_vars = rel_a.0.iter().cloned().collect::<HashSet<Var>>();
    let rel_b_out_indices = rel_b.0.iter().enumerate()
        .filter(|(_idx, var)| !rel_a_vars.contains(var))
        .map(|(idx, _var)| idx)
        .collect::<Vec<usize>>();
    let rel_b_map = hash_relation(&join_key, rel_b);
    let project = |mut tuple_a: Vec<Value>, tuple_b: &Vec<Value>| {
        for idx in rel_b_out_indices.iter() {
            let val = tuple_b[*idx].clone();
            tuple_a.push(val);
        }
        tuple_a
    };
    // Join tuples in a and b on matching join key
    let rel_a_key_indices = key_indices(&join_key, &rel_a);
    let joined: Vec<Vec<Value>> = rel_a.1.iter().fold(vec![], |mut output, tuple_a| {
        if let Some(matches) = rel_b_map.get(&key_for_tuple(&rel_a_key_indices, &tuple_a)) {
            for tuple_b in matches {
                output.push(project(tuple_a.clone(), tuple_b));
            }
        }
        output
    });
    Relation(output_key, joined)
}
fn join ( rel_a : Relation , rel_b : Relation ) -> Relation { // The join key is a vector of vars in both a and b, ordered as they are in a. let join_key : Vec < Var > = derive_join_key ( & rel_a , & rel_b ) ; let output_key = derive_output_key ( & rel_a , & rel_b ) ; let rel_a_vars = rel_a . 0 . iter ( ) . cloned ( ) . collect :: < HashSet < Var > > ( ) ; let rel_b_out_indices = rel_b . 0 . iter ( ) . enumerate ( ) . filter ( | ( _idx , var ) | ! rel_a_vars . contains ( var ) ) . map ( | ( idx , _var ) | idx ) . collect :: < Vec < usize > > ( ) ; let rel_b_map = hash_relation ( & join_key , rel_b ) ; let project = | mut tuple_a : Vec < Value > , tuple_b : & Vec < Value > | { for idx in rel_b_out_indices . iter ( ) { let val = tuple_b [ * idx ] . clone ( ) ; tuple_a . push ( val ) ; } tuple_a } ; // Join tuples in a and b on matching join key let rel_a_key_indices = key_indices ( & join_key , & rel_a ) ; let joined : Vec < Vec < Value > > = rel_a . 1 . iter ( ) . fold ( vec ! [ ] , | mut output , tuple_a | { if let Some ( matches ) = rel_b_map . get ( & key_for_tuple ( & rel_a_key_indices , & tuple_a ) ) { for tuple_b in matches { output . push ( project ( tuple_a . clone ( ) , tuple_b ) ) ; } } output } ) ; Relation ( output_key , joined ) }
Implements the natural join between relations, outputting one
tuple for each combination of tuples in the two relations which
match on all overlapping variables.
Implements the natural join between relations outputting one tuple for each combination of tuples in the two relations which match on all overlapping variables .
rel_a
Relation
rel_b
Relation
rel_a
Relation
rel_b
Relation