use crate::Engine;
use std::collections::BTreeSet;
use uqa_sql::{
ast::{ColumnDef, ColumnType, CreateFunction},
binding::{snapshot::BindingSnapshot, stored_relations::StoredQueryNamespace},
plpgsql::PlpgsqlCatalog,
routines::{
compilation::{RoutineCompilationCatalog, RoutineCompilationContext, RoutineParserCatalog},
declaration::RoutineTypeCatalog,
merge_columns::StoredMergeColumnCatalog,
regclass::RoutineRegclassCatalog,
},
SQLError,
};
impl Engine {
pub(crate) fn routine_compilation_context(&self) -> RoutineCompilationContext<'_> {
RoutineCompilationContext {
types: self,
parsers: self,
catalog: self,
routines: self,
relations: self,
sequences: self,
merge: self,
regroles: self,
}
}
}
impl RoutineTypeCatalog for Engine {
fn try_describe_table(&self, name: &str) -> Result<Option<Vec<ColumnDef>>, String> {
Engine::try_describe_table(self, name).map_err(|error| error.to_string())
}
fn resolve_catalog_column_type(&self, name: &str) -> Option<ColumnType> {
uqa_execution::catalog::projection::resolve_catalog_column_type(
&self.catalog_execution(),
name,
)
}
fn resolve_catalog_column_type_name(&self, name: &str) -> Result<ColumnType, SQLError> {
uqa_execution::catalog::projection::resolve_catalog_column_type_name(
&self.catalog_execution(),
name,
)
}
fn resolve_catalog_domain_type_by_oid(&self, oid: u32) -> Option<ColumnType> {
uqa_execution::catalog::projection::resolve_catalog_domain_type_by_oid(
&self.catalog_execution(),
oid,
)
}
}
impl StoredMergeColumnCatalog for Engine {
fn stored_merge_target_definitions(&self, table: &str) -> Option<Vec<ColumnDef>> {
self.table_entries()
.into_iter()
.find(|(name, _)| name == table)
.map(|(_, table)| table.columns.read().clone())
}
}
impl RoutineParserCatalog for Engine {
fn plpgsql_catalog(&self) -> Result<PlpgsqlCatalog, SQLError> {
uqa_execution::catalog::projection::plpgsql_catalog(&self.catalog_execution())
}
}
impl RoutineCompilationCatalog for Engine {
fn has_registered_aggregate_function(&self, name: &str) -> bool {
Engine::has_registered_aggregate_function(self, name)
}
fn binding_snapshot(&self) -> Result<BindingSnapshot, SQLError> {
let scope = super::query_scope::new_for_catalog_binding(self);
uqa_execution::query::binding::binding_context(&scope).map(Into::into)
}
fn stored_query_namespace(&self) -> StoredQueryNamespace {
StoredQueryNamespace {
temporary_schema: self.temporary_schema_name(),
transition_relations:
uqa_execution::mutation::triggers::current_transition_relation_names(),
}
}
}
impl RoutineRegclassCatalog for Engine {
fn resolve_routine_regclass(&self, reference: &str) -> Result<Option<i64>, SQLError> {
uqa_execution::catalog::projection::resolve_regclass_oid(
&self.catalog_execution(),
reference,
)
}
}
use uqa_core::RelationIdentity;
use uqa_execution::routines::{
compilation::{RoutineCompilationSession, StoredRoutineCompilationContext},
definition::RoutineDefinitionContext,
rewrites::{self, RoutineRewriteContext},
};
use uqa_sql::ast::FunctionBinding;
impl Engine {
pub(crate) fn routine_definition_context(&self) -> RoutineDefinitionContext<'_> {
RoutineDefinitionContext {
compilation: self.stored_routine_compilation_context(),
sources: self,
regclasses: self,
}
}
pub(crate) fn stored_routine_compilation_context(&self) -> StoredRoutineCompilationContext<'_> {
StoredRoutineCompilationContext {
analysis: self.routine_compilation_context(),
session: self,
}
}
pub(crate) fn routine_rewrite_context(&self) -> RoutineRewriteContext<'_> {
RoutineRewriteContext {
registry: self,
publication: self,
compilation: self.stored_routine_compilation_context(),
columns: self.stored_column_binding_context(),
changes: self,
}
}
pub(crate) fn rewrite_routine_relation_references(
&self,
from: &RelationIdentity,
to: &RelationIdentity,
) -> Result<(), SQLError> {
rewrites::rewrite_routine_relation_references(&self.routine_rewrite_context(), from, to)
}
pub(crate) fn rewrite_routine_column_references(
&self,
relation: &RelationIdentity,
from: &str,
to: &str,
) -> Result<(), SQLError> {
rewrites::rewrite_routine_column_references(
&self.routine_rewrite_context(),
relation,
from,
to,
)
}
pub(crate) fn publish_stored_routine_body_rewrites(
&self,
definitions: Vec<CreateFunction>,
) -> Result<(), SQLError> {
rewrites::publish_stored_routine_body_rewrites(&self.routine_rewrite_context(), definitions)
}
pub(crate) fn refresh_stored_merge_target_plans(&self) -> Result<(), SQLError> {
rewrites::refresh_stored_merge_target_plans(&self.routine_rewrite_context())
}
pub(crate) fn prepare_routine_column_alias_drop(
&self,
columns: BTreeSet<(String, String)>,
removed: &[FunctionBinding],
) -> Result<Vec<CreateFunction>, SQLError> {
uqa_execution::routines::removal::prepare_routine_column_alias_drop(
&self.routine_removal_context(),
columns,
removed,
)
}
}
impl RoutineCompilationSession for Engine {
fn routine_search_path(&self) -> Vec<String> {
self.session.state.read().search_path.clone()
}
fn replace_routine_search_path(&self, path: Vec<String>) -> Vec<String> {
std::mem::replace(&mut self.session.state.write().search_path, path)
}
fn restore_routine_search_path(&self, path: Vec<String>) {
self.session.state.write().search_path = path;
}
}
use uqa_execution::routines::{
catalog::RoutineMutationContext,
configuration::{RoutineConfigurationGuard, RoutineConfigurationSession},
registration::RoutineRegistrationContext,
};
use uqa_sql::routines::registration::RoutineSupportAuthority;
impl RoutineSupportAuthority for Engine {
fn current_user_is_superuser(&self) -> bool {
Engine::current_user_is_superuser(self)
}
}
impl RoutineConfigurationGuard for crate::roles::RoutineSessionStateGuard<'_> {}
impl RoutineConfigurationSession for Engine {
fn routine_configuration_guard(&self) -> Box<dyn RoutineConfigurationGuard + '_> {
Box::new(self.routine_config_state_guard())
}
fn set_routine_variable(&self, name: &str, value: &str) -> Result<(), SQLError> {
self.set_variable(name, value)
}
fn show_routine_variable(&self, name: &str) -> Result<String, SQLError> {
self.show_variable(name)
}
}
impl Engine {
pub(crate) fn routine_mutation_context(&self) -> RoutineMutationContext<'_> {
RoutineMutationContext {
writer: self,
names: self,
roles: self,
registry: self,
publication: self,
changes: self,
}
}
pub(crate) fn routine_registration_context(&self) -> RoutineRegistrationContext<'_> {
RoutineRegistrationContext {
catalog: self.routine_mutation_context(),
namespace: self.relation_creation_context(),
definition: self.routine_definition_context(),
support: self,
configuration: self,
}
}
#[cfg(test)]
pub(crate) fn register_sql_function(&self, def: CreateFunction) -> Result<(), SQLError> {
uqa_execution::routines::registration::register_sql_function(
&self.routine_registration_context(),
def,
)
}
}