use super::*;
#[test]
fn test_lazy_nested_loop_join_cross() {
let (left_schema, right_schema) = test_join_schemas();
let left_rows = vec![
Row::from_vec(vec![SqlValue::Integer(1), SqlValue::Integer(10)]),
Row::from_vec(vec![SqlValue::Integer(2), SqlValue::Integer(20)]),
];
let right_rows = vec![
Row::from_vec(vec![SqlValue::Integer(1), SqlValue::Integer(100)]),
Row::from_vec(vec![SqlValue::Integer(2), SqlValue::Integer(200)]),
];
let left_iter = TableScanIterator::new(left_schema.clone(), left_rows);
let mut join = LazyNestedLoopJoin::new(
left_iter,
right_schema,
right_rows,
vibesql_ast::JoinType::Cross,
None, None, );
let results: Vec<_> = join.by_ref().collect::<Result<Vec<_>, _>>().unwrap();
assert_eq!(results.len(), 4);
assert_eq!(
results[0].values.to_vec(),
vec![
SqlValue::Integer(1),
SqlValue::Integer(10),
SqlValue::Integer(1),
SqlValue::Integer(100)
]
);
assert_eq!(
results[3].values.to_vec(),
vec![
SqlValue::Integer(2),
SqlValue::Integer(20),
SqlValue::Integer(2),
SqlValue::Integer(200)
]
);
}
#[test]
fn test_lazy_nested_loop_join_inner_with_condition() {
let (left_schema, right_schema) = test_join_schemas();
let left_rows = vec![
Row::from_vec(vec![SqlValue::Integer(1), SqlValue::Integer(10)]),
Row::from_vec(vec![SqlValue::Integer(2), SqlValue::Integer(20)]),
Row::from_vec(vec![SqlValue::Integer(3), SqlValue::Integer(30)]),
];
let right_rows = vec![
Row::from_vec(vec![SqlValue::Integer(1), SqlValue::Integer(100)]),
Row::from_vec(vec![SqlValue::Integer(2), SqlValue::Integer(200)]),
];
let left_iter = TableScanIterator::new(left_schema.clone(), left_rows);
let condition = vibesql_ast::Expression::BinaryOp {
left: Box::new(vibesql_ast::Expression::ColumnRef(
vibesql_ast::ColumnIdentifier::qualified("t1", false, "id", false),
)),
op: vibesql_ast::BinaryOperator::Equal,
right: Box::new(vibesql_ast::Expression::ColumnRef(
vibesql_ast::ColumnIdentifier::qualified("t2", false, "id", false),
)),
};
let mut join = LazyNestedLoopJoin::new(
left_iter,
right_schema,
right_rows,
vibesql_ast::JoinType::Inner,
Some(condition),
None, );
let results: Vec<_> = join.by_ref().collect::<Result<Vec<_>, _>>().unwrap();
assert_eq!(results.len(), 2);
assert_eq!(
results[0].values.to_vec(),
vec![
SqlValue::Integer(1),
SqlValue::Integer(10),
SqlValue::Integer(1),
SqlValue::Integer(100)
]
);
assert_eq!(
results[1].values.to_vec(),
vec![
SqlValue::Integer(2),
SqlValue::Integer(20),
SqlValue::Integer(2),
SqlValue::Integer(200)
]
);
}
#[test]
fn test_lazy_nested_loop_join_left_outer() {
let (left_schema, right_schema) = test_join_schemas();
let left_rows = vec![
Row::from_vec(vec![SqlValue::Integer(1), SqlValue::Integer(10)]),
Row::from_vec(vec![SqlValue::Integer(3), SqlValue::Integer(30)]), ];
let right_rows = vec![Row::from_vec(vec![SqlValue::Integer(1), SqlValue::Integer(100)])];
let left_iter = TableScanIterator::new(left_schema.clone(), left_rows);
let condition = vibesql_ast::Expression::BinaryOp {
left: Box::new(vibesql_ast::Expression::ColumnRef(
vibesql_ast::ColumnIdentifier::qualified("t1", false, "id", false),
)),
op: vibesql_ast::BinaryOperator::Equal,
right: Box::new(vibesql_ast::Expression::ColumnRef(
vibesql_ast::ColumnIdentifier::qualified("t2", false, "id", false),
)),
};
let mut join = LazyNestedLoopJoin::new(
left_iter,
right_schema,
right_rows,
vibesql_ast::JoinType::LeftOuter,
Some(condition),
None, );
let results: Vec<_> = join.by_ref().collect::<Result<Vec<_>, _>>().unwrap();
assert_eq!(results.len(), 2);
assert_eq!(
results[0].values.to_vec(),
vec![
SqlValue::Integer(1),
SqlValue::Integer(10),
SqlValue::Integer(1),
SqlValue::Integer(100)
]
);
assert_eq!(
results[1].values.to_vec(),
vec![SqlValue::Integer(3), SqlValue::Integer(30), SqlValue::Null, SqlValue::Null]
);
}
#[test]
fn test_lazy_nested_loop_join_early_termination() {
let (left_schema, right_schema) = test_join_schemas();
let left_rows: Vec<_> = (1..=1000)
.map(|i| Row::from_vec(vec![SqlValue::Integer(i), SqlValue::Integer(i * 10)]))
.collect();
let right_rows: Vec<_> = (1..=10)
.map(|i| Row::from_vec(vec![SqlValue::Integer(i), SqlValue::Integer(i * 100)]))
.collect();
let left_iter = TableScanIterator::new(left_schema.clone(), left_rows);
let join = LazyNestedLoopJoin::new(
left_iter,
right_schema,
right_rows,
vibesql_ast::JoinType::Cross,
None,
None, );
let results: Vec<_> = join.take(5).collect::<Result<Vec<_>, _>>().unwrap();
assert_eq!(results.len(), 5);
for result in &results {
assert_eq!(result.values[0], SqlValue::Integer(1)); assert_eq!(result.values[1], SqlValue::Integer(10)); }
}