use crate::{session::StatementReadSnapshot, Engine};
use uqa_execution::schema::{
columns::removal::{ColumnRemovalContext, ColumnRemovalViews},
table_alteration::{
binding::TableAlterBindingContext,
entry::{
RelationEventAlterContext, RelationEventAlterTransactions, RelationEventAlterWrite,
TableAlterEntryContext, TableAlterSession, TableAlterTransactions, TableAlterWrite,
},
TableAlterContext, TableEventLifecycle, TableLifecycle,
},
};
use uqa_sql::{ast::EventEnableMode, SQLError, SQLResult};
use uqa_storage::StorageBackendResult;
impl uqa_execution::schema::columns::rows::changes::RewriteRowChanges for Engine {
fn storage_generation(&self, table: &str) -> Result<[u8; 16], SQLError> {
Ok(self.require_table(table)?.storage_generation())
}
fn visit_changes(
&self,
visit: &mut dyn FnMut(
&[uqa_execution::row_locks::publication::TransactionRowChange],
) -> Result<(), SQLError>,
) -> Result<(), SQLError> {
let frames = self.session.transactions.lock();
for frame in frames.iter() {
visit(&frame.row_changes)?;
}
Ok(())
}
}
impl Engine {
pub(crate) fn table_alter_binding_context(&self) -> TableAlterBindingContext<'_> {
TableAlterBindingContext {
names: self,
catalog: self,
authority: self.table_privilege_context(),
creation: self.relation_creation_context(),
locks: self,
notices: self.query_runtime_view().notices,
}
}
pub(crate) fn table_alter_entry_context(
&self,
) -> TableAlterEntryContext<'_, StatementReadSnapshot> {
TableAlterEntryContext {
session: self,
binding: self.table_alter_binding_context(),
tables: self,
events: self,
views: self,
foreign_tables: self,
sequences: self,
indexes: self,
notices: self.query_runtime_view().notices,
}
}
pub(crate) fn table_alter_context(&self) -> TableAlterContext<'_, StatementReadSnapshot> {
TableAlterContext {
schema_moves: self.relation_schema_context(),
row_changes: self,
binding: self.table_alter_binding_context(),
ownership: self.table_ownership_context(),
hierarchy: self.hierarchy_execution_context(),
constraints: self.constraint_alter_context(),
addition: self.column_addition_context(),
columns: self.column_alter_context(),
plan_type_transform: |expression| {
uqa_planner::optimizer::optimize_scalar_expression(
expression,
&uqa_planner::OptimizerConfig::new(uqa_execution::scalar::eval_constant_scalar),
)
},
removal: self.column_removal_context(),
identities: uqa_execution::schema::table_alteration::identity::IdentityAlterContext {
definitions: self.sequence_definition_context(),
catalog: self,
},
lifecycle: self,
events: self,
}
}
pub(crate) fn column_removal_context(&self) -> ColumnRemovalContext<'_> {
ColumnRemovalContext { deletion: self }
}
}
impl TableAlterSession for Engine {
fn in_transaction_block(&self) -> bool {
Engine::in_transaction_block(self)
}
}
impl TableAlterTransactions<StatementReadSnapshot> for Engine {
fn with_table_write(
&self,
write: TableAlterWrite<'_, StatementReadSnapshot>,
) -> Result<SQLResult, SQLError> {
self.with_implicit_definition_transaction(|engine| write(&engine.table_alter_context()))
}
}
impl RelationEventAlterTransactions for Engine {
fn with_event_write(&self, write: RelationEventAlterWrite<'_>) -> Result<SQLResult, SQLError> {
self.with_implicit_transaction(|engine| {
write(&RelationEventAlterContext {
events: engine,
foreign_access: engine,
})
})
}
}
impl TableLifecycle for Engine {
fn rename_table(&self, from: &str, to: &str) -> StorageBackendResult<bool> {
self.try_rename_table_inner(from, to)
}
fn rename_column(&self, table: &str, from: &str, to: &str) -> StorageBackendResult<bool> {
self.try_rename_column(table, from, to)
}
}
impl TableEventLifecycle for Engine {
fn rename_trigger(&self, table: &str, from: &str, to: &str) -> Result<(), SQLError> {
self.event_lifecycle_context()
.rename_trigger(table, from, to)
}
fn rename_trigger_constraint(&self, table: &str, from: &str, to: &str) -> Result<(), SQLError> {
self.event_lifecycle_context()
.rename_trigger_constraint(table, from, to)
}
fn rename_rule(&self, table: &str, from: &str, to: &str) -> Result<(), SQLError> {
self.event_lifecycle_context().rename_rule(table, from, to)
}
fn set_trigger_enable_mode(
&self,
table: &str,
name: Option<&str>,
mode: EventEnableMode,
) -> Result<(), SQLError> {
self.event_lifecycle_context()
.set_trigger_enable_mode(table, name, mode)
}
fn set_rule_enable_mode(
&self,
table: &str,
name: &str,
mode: EventEnableMode,
) -> Result<(), SQLError> {
self.event_lifecycle_context()
.set_rule_enable_mode(table, name, mode)
}
}
impl ColumnRemovalViews for Engine {
fn dependents(&self, table: &str, column: &str) -> StorageBackendResult<Vec<String>> {
self.views_depending_on_column(table, column)
}
}