mod constraints;
mod executor;
mod fast_path;
mod foreign_keys;
mod from_clause;
mod index_sync;
mod row_selector;
#[cfg(test)]
mod tests;
mod triggers;
mod value_updater;
use std::collections::HashSet;
use vibesql_ast::UpdateStmt;
use vibesql_storage::{Database, Row};
use crate::errors::ExecutorError;
#[derive(Debug, Clone)]
pub(super) struct PendingUpdate {
pub row_index: usize,
pub old_row: Row,
pub new_row: Row,
pub changed_columns: HashSet<usize>,
pub updates_pk: bool,
}
pub use triggers::execute_update_with_trigger_context;
pub struct UpdateExecutor;
impl UpdateExecutor {
pub fn execute(stmt: &UpdateStmt, database: &mut Database) -> Result<usize, ExecutorError> {
let may_fire = crate::raise_scope::table_may_fire_trigger(database, &stmt.table_name);
crate::raise_scope::run_top_level_dml(database, may_fire, |database| {
executor::execute_internal(stmt, database, None, None, None).map(|(count, _)| count)
})
}
pub fn execute_returning(
stmt: &UpdateStmt,
database: &mut Database,
) -> Result<(usize, Option<crate::select::SelectResult>), ExecutorError> {
let may_fire = crate::raise_scope::table_may_fire_trigger(database, &stmt.table_name);
crate::raise_scope::run_top_level_dml(database, may_fire, |database| {
executor::execute_internal(stmt, database, None, None, None)
})
}
pub fn execute_with_procedural_context(
stmt: &UpdateStmt,
database: &mut Database,
procedural_context: &crate::procedural::ExecutionContext,
) -> Result<usize, ExecutorError> {
let may_fire = crate::raise_scope::table_may_fire_trigger(database, &stmt.table_name);
crate::raise_scope::run_top_level_dml(database, may_fire, |database| {
executor::execute_internal(stmt, database, None, Some(procedural_context), None)
.map(|(count, _)| count)
})
}
pub fn execute_with_trigger_context(
stmt: &UpdateStmt,
database: &mut Database,
trigger_context: &crate::trigger_execution::TriggerContext,
) -> Result<usize, ExecutorError> {
executor::execute_internal(stmt, database, None, None, Some(trigger_context))
.map(|(count, _)| count)
}
pub fn execute_with_schema(
stmt: &UpdateStmt,
database: &mut Database,
schema: Option<&vibesql_catalog::TableSchema>,
) -> Result<usize, ExecutorError> {
executor::execute_internal(stmt, database, schema, None, None).map(|(count, _)| count)
}
}