#![allow(clippy::too_many_arguments)]
use std::collections::HashMap;
use super::{cte::CteResult, join::FromResult};
use crate::errors::ExecutorError;
use vibesql_catalog::TableIdentifier;
pub(crate) mod bloom_context;
mod derived;
pub(crate) mod index_scan;
mod join_scan;
mod predicates;
mod reorder;
mod table;
pub(crate) mod values;
pub(super) fn execute_from_clause<F>(
from: &vibesql_ast::FromClause,
cte_results: &HashMap<String, CteResult>,
database: &vibesql_storage::Database,
where_clause: Option<&vibesql_ast::Expression>,
order_by: Option<&[vibesql_ast::OrderByItem]>,
limit: Option<usize>,
outer_row: Option<&vibesql_storage::Row>,
outer_schema: Option<&crate::schema::CombinedSchema>,
execute_subquery: F,
) -> Result<FromResult, ExecutorError>
where
F: Fn(&vibesql_ast::SelectStmt) -> Result<super::SelectResult, ExecutorError> + Copy,
{
if matches!(from, vibesql_ast::FromClause::Join { .. }) {
let table_count = reorder::count_tables_in_from(from);
if reorder::should_apply_join_reordering(table_count) && reorder::all_joins_are_cross(from)
{
return reorder::execute_with_join_reordering(
from,
cte_results,
database,
where_clause,
outer_row,
outer_schema,
execute_subquery,
);
}
if let vibesql_ast::FromClause::Join {
left,
right,
join_type: vibesql_ast::JoinType::Semi | vibesql_ast::JoinType::Anti,
..
} = from
{
let inner_table_count = reorder::count_tables_in_from(left);
if reorder::should_apply_join_reordering(inner_table_count)
&& reorder::all_joins_are_cross(left)
{
if let vibesql_ast::FromClause::Subquery { .. } = right.as_ref() {
return reorder::execute_with_semi_join_reordering(
from,
cte_results,
database,
where_clause,
outer_row,
outer_schema,
execute_subquery,
);
}
}
}
}
match from {
vibesql_ast::FromClause::Table { index_hint: _, name, alias, column_aliases, quoted } => {
let identifier = TableIdentifier::new(name, *quoted);
table::execute_table_scan_with_identifier(
&identifier,
alias.as_ref(),
column_aliases.as_ref(),
cte_results,
database,
where_clause,
order_by,
limit,
outer_row,
outer_schema,
)
}
vibesql_ast::FromClause::Join {
left,
right,
join_type,
condition,
using_columns,
natural,
alias,
..
} => {
let result = join_scan::execute_join(
left,
right,
join_type,
condition,
using_columns,
*natural,
cte_results,
database,
where_clause,
outer_row,
outer_schema,
alias.as_deref(),
execute_subquery,
)?;
Ok(result)
}
vibesql_ast::FromClause::Subquery { query, alias, column_aliases } => {
derived::execute_derived_table(query, alias, column_aliases.as_ref(), execute_subquery)
}
vibesql_ast::FromClause::Values { rows, alias, column_aliases } => values::execute_values(
rows,
alias,
column_aliases.as_ref(),
Some(database),
Some(cte_results),
),
}
}