iridium_core 0.1.12

SQL Server-compatible Rust engine core for Iridium SQL
Documentation
use std::collections::HashMap;
use std::sync::Arc;

use parking_lot::Mutex;

use crate::error::DbError;
use crate::executor::context::{ExecutionContext, Variables};
use crate::executor::context_factory;
use crate::executor::dirty_buffer;
use crate::executor::locks;
use crate::executor::model::Group;
use crate::executor::session;
use crate::executor::tooling;
use crate::types::Value;

#[allow(dead_code)]
pub struct ScopeGuard<F: FnOnce()> {
    cleanup: Option<F>,
}

#[allow(dead_code)]
impl<F: FnOnce()> ScopeGuard<F> {
    pub fn new(cleanup: F) -> Self {
        Self {
            cleanup: Some(cleanup),
        }
    }

    pub fn dismiss(mut self) {
        self.cleanup = None;
    }
}

impl<F: FnOnce()> Drop for ScopeGuard<F> {
    fn drop(&mut self) {
        if let Some(cleanup) = self.cleanup.take() {
            cleanup();
        }
    }
}

impl<'a> ExecutionContext<'a> {
    pub fn from_session<C, S>(
        session: &'a mut crate::executor::session::SessionRuntime<C, S>,
        session_id: locks::SessionId,
        dirty_buffer: Option<Arc<Mutex<dirty_buffer::DirtyBuffer>>>,
    ) -> Self {
        context_factory::from_session(session, session_id, dirty_buffer)
    }

    #[deprecated(since = "0.2.0", note = "Use ExecutionContext::from_session() instead")]
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        variables: &'a mut Variables,
        bulk_load: &'a mut crate::executor::session::BulkLoadState,
        session_last_identity: &'a mut Option<i64>,
        scope_identity_stack: &'a mut Vec<Option<i64>>,
        temp_table_map: &'a mut HashMap<String, String>,
        session_table_var_map: &'a mut HashMap<String, String>,
        table_var_counter: &'a mut u64,
        ansi_nulls: bool,
        datefirst: i32,
        random_state: &'a mut u64,
        cursors: &'a mut HashMap<String, crate::executor::model::Cursor>,
        fetch_status: &'a mut i32,
        next_cursor_handle: &'a mut i32,
        handle_map: &'a mut HashMap<i32, String>,
        print_output: &'a mut Vec<String>,
        context_info: &'a mut Vec<u8>,
        session_context: &'a mut HashMap<String, (Value, bool)>,
        dirty_buffer: Option<Arc<Mutex<dirty_buffer::DirtyBuffer>>>,
        session_id: locks::SessionId,
        session_current_database: String,
        session_original_database: String,
        user: Option<String>,
        app_name: Option<String>,
        host_name: Option<String>,
    ) -> Self {
        context_factory::legacy_new(
            variables,
            bulk_load,
            session_last_identity,
            scope_identity_stack,
            temp_table_map,
            session_table_var_map,
            table_var_counter,
            ansi_nulls,
            datefirst,
            random_state,
            cursors,
            fetch_status,
            next_cursor_handle,
            handle_map,
            print_output,
            context_info,
            session_context,
            dirty_buffer,
            session_id,
            session_current_database,
            session_original_database,
            user,
            app_name,
            host_name,
        )
    }

    pub fn session_id(&self) -> locks::SessionId {
        self.metadata.id
    }

    pub fn depth(&self) -> usize {
        self.frame.depth
    }

    pub fn loop_depth(&self) -> usize {
        self.frame.loop_depth
    }

    pub fn trancount(&self) -> u32 {
        self.frame.trancount
    }

    pub fn xact_state(&self) -> i8 {
        self.frame.xact_state
    }

    pub fn trigger_depth(&self) -> usize {
        self.frame.trigger_depth
    }

    pub fn current_scope_identity(&self) -> Option<i64> {
        self.session.current_scope_identity()
    }

    pub fn current_procid(&self) -> Option<i32> {
        self.frame.module_stack.last().map(|frame| frame.object_id)
    }

    pub fn push_module(&mut self, frame: crate::executor::context::ModuleFrame) {
        self.frame.module_stack.push(frame);
    }

    pub fn pop_module(&mut self) {
        self.frame.module_stack.pop();
    }

    pub fn current_group(&self) -> &Option<Group> {
        &self.row.current_group
    }

    #[inline]
    pub fn current_group_mut(&mut self) -> &mut Option<Group> {
        &mut self.row.current_group
    }

    #[inline]
    pub fn ansi_nulls(&self) -> bool {
        self.metadata.ansi_nulls
    }

    #[inline]
    pub fn ansi_nulls_mut(&mut self) -> &mut bool {
        &mut self.metadata.ansi_nulls
    }

    #[inline]
    pub fn datefirst(&self) -> i32 {
        self.metadata.datefirst
    }

    #[inline]
    pub fn datefirst_mut(&mut self) -> &mut i32 {
        &mut self.metadata.datefirst
    }

    #[inline]
    pub fn dirty_buffer(&self) -> &Option<Arc<Mutex<dirty_buffer::DirtyBuffer>>> {
        self.session.dirty_buffer()
    }

    #[inline]
    pub fn identity_insert(&self) -> &std::collections::HashSet<String> {
        self.session.identity_insert()
    }

    #[inline]
    pub fn identity_insert_mut(&mut self) -> &mut std::collections::HashSet<String> {
        self.session.identity_insert_mut()
    }

    #[inline]
    pub fn last_error(&self) -> &Option<DbError> {
        &self.frame.last_error
    }

    #[inline]
    pub fn last_error_mut(&mut self) -> &mut Option<DbError> {
        &mut self.frame.last_error
    }

    pub fn set_last_identity(&mut self, val: i64) {
        self.session.set_last_identity(val);
    }

    pub fn next_table_var_id(&mut self) -> u64 {
        self.session.next_table_var_id()
    }

    pub fn set_bulk_load_active(
        &mut self,
        active: bool,
        table: crate::ast::ObjectName,
        columns: Vec<crate::ast::statements::ddl::ColumnSpec>,
    ) {
        self.session.set_bulk_load_active(active, table, columns);
    }

    pub fn create_snapshot(&self, options: &tooling::SessionOptions) -> session::SessionSnapshot {
        self.session.create_snapshot(options)
    }

    pub fn restore_snapshot(
        &mut self,
        snapshot: session::SessionSnapshot,
        options: &mut tooling::SessionOptions,
    ) {
        self.session.restore_snapshot(snapshot, options);
    }

    pub fn subquery(&mut self) -> ExecutionContext<'_> {
        ExecutionContext {
            session: self.session.fork(),
            metadata: self.metadata.clone(),
            options: self.options.clone(),
            frame: self.frame.fork(),
            row: self.row.fork(),
            subquery_cache: self.subquery_cache.clone(),
        }
    }

    pub fn with_outer_row(&mut self, row: crate::executor::model::JoinedRow) -> ExecutionContext<'_> {
        let mut sub = self.subquery();
        sub.row.outer_stack.push(row);
        sub
    }

    pub fn enter_scope(&mut self) {
        self.frame.enter_scope(&mut self.session);
    }

    pub fn leave_scope(&mut self) {
        let _ = self.leave_scope_collect_table_vars();
    }

    pub fn leave_scope_collect_table_vars(&mut self) -> Vec<String> {
        self.frame.leave_scope_collect_table_vars(&mut self.session)
    }

    pub fn register_declared_var(&mut self, name: &str) {
        self.frame.register_declared_var(name);
    }

    pub fn register_table_var(&mut self, logical_name: &str, physical_name: &str) {
        self.frame
            .register_table_var(&mut self.session, logical_name, physical_name);
    }

    pub fn mark_table_var_readonly(&mut self, logical_name: &str) {
        self.frame.mark_table_var_readonly(logical_name);
    }

    pub fn is_readonly_table_var(&self, logical_name: &str) -> bool {
        self.frame.is_readonly_table_var(logical_name)
    }

    pub fn resolve_table_name(&self, logical: &str) -> Option<String> {
        self.frame.resolve_table_name(&self.session, logical)
    }

    pub fn push_apply_row(&mut self, row: crate::executor::model::JoinedRow) {
        self.row.push_apply_row(row);
    }

    pub fn pop_apply_row(&mut self) {
        self.row.pop_apply_row();
    }

    pub fn get_window_value(&self, key: &str) -> Option<Value> {
        self.row.get_window_value(key)
    }
}