use vibesql_executor::SelectExecutor;
fn parse_select(sql: &str) -> vibesql_ast::SelectStmt {
match vibesql_parser::Parser::parse_sql(sql) {
Ok(vibesql_ast::Statement::Select(select_stmt)) => *select_stmt,
_ => panic!("Failed to parse SELECT statement: {}", sql),
}
}
#[test]
fn test_phase_2_table_local_pushdown() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::new(
"T1".to_string(),
vec![
vibesql_catalog::ColumnSchema {
name: "a".to_string(),
data_type: vibesql_types::DataType::Integer,
nullable: false,
default_value: None,
generated_expr: None,
is_exact_integer_type: false,
collation: None,
},
vibesql_catalog::ColumnSchema {
name: "b".to_string(),
data_type: vibesql_types::DataType::Integer,
nullable: false,
default_value: None,
generated_expr: None,
is_exact_integer_type: false,
collation: None,
},
],
);
db.create_table(schema).unwrap();
for i in 1..=1000 {
db.insert_row(
"T1",
vibesql_storage::Row::new(vec![
vibesql_types::SqlValue::Integer(i),
vibesql_types::SqlValue::Integer(i * 10),
]),
)
.unwrap();
}
let sql = "SELECT COUNT(*) FROM T1 WHERE a > 990";
let stmt = parse_select(sql);
let executor = SelectExecutor::new(&db);
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
let count = match &result[0].values[0] {
vibesql_types::SqlValue::Integer(n) => *n,
_ => panic!("Expected integer count"),
};
assert_eq!(count, 10); }
#[test]
fn test_phase_3_equijoin_hash_join() {
let mut db = vibesql_storage::Database::new();
for table_num in 1..=2 {
let table_name = format!("T{}", table_num);
let schema = vibesql_catalog::TableSchema::new(
table_name.clone(),
vec![vibesql_catalog::ColumnSchema {
name: "a".to_string(),
data_type: vibesql_types::DataType::Integer,
nullable: false,
default_value: None,
generated_expr: None,
is_exact_integer_type: false,
collation: None,
}],
);
db.create_table(schema).unwrap();
for i in 1..=100 {
db.insert_row(
&table_name,
vibesql_storage::Row::new(vec![vibesql_types::SqlValue::Integer(i)]),
)
.unwrap();
}
}
let sql = "SELECT COUNT(*) FROM T1, T2 WHERE T1.a = T2.a";
let stmt = parse_select(sql);
let executor = SelectExecutor::new(&db);
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
let count = match &result[0].values[0] {
vibesql_types::SqlValue::Integer(n) => *n,
_ => panic!("Expected integer count"),
};
assert_eq!(count, 100); }
#[test]
fn test_phases_2_and_3_combined() {
let mut db = vibesql_storage::Database::new();
for table_num in 1..=3 {
let table_name = format!("T{}", table_num);
let schema = vibesql_catalog::TableSchema::new(
table_name.clone(),
vec![
vibesql_catalog::ColumnSchema {
name: "a".to_string(),
data_type: vibesql_types::DataType::Integer,
nullable: false,
default_value: None,
generated_expr: None,
is_exact_integer_type: false,
collation: None,
},
vibesql_catalog::ColumnSchema {
name: "b".to_string(),
data_type: vibesql_types::DataType::Integer,
nullable: false,
default_value: None,
generated_expr: None,
is_exact_integer_type: false,
collation: None,
},
],
);
db.create_table(schema).unwrap();
for i in 1..=50 {
db.insert_row(
&table_name,
vibesql_storage::Row::new(vec![
vibesql_types::SqlValue::Integer(i),
vibesql_types::SqlValue::Integer(i * 10),
]),
)
.unwrap();
}
}
let sql = "SELECT COUNT(*) FROM T1, T2, T3 WHERE T1.a > 40 AND T1.a = T2.a AND T2.a = T3.a";
let stmt = parse_select(sql);
let executor = SelectExecutor::new(&db);
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
let count = match &result[0].values[0] {
vibesql_types::SqlValue::Integer(n) => *n,
_ => panic!("Expected integer count"),
};
assert_eq!(count, 10); }