#![allow(unsafe_code)]
use crate::hton::{HaNotificationType, SelectExecutedIn};
use crate::panic_guard::FfiBoundary;
use crate::runtime;
use crate::runtime::FfiPtr;
use crate::sys;
fn result_to_veto(r: crate::engine::EngineResult) -> bool {
match r {
Ok(()) => false,
Err(_) => true,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__notify_after_select(thd: *const sys::THD, executed_in: bool) {
FfiBoundary::run_void(|| {
let thd_ref = unsafe { thd.as_ref() };
if let Some(h) = runtime::handlerton() {
h.notify_after_select(thd_ref, SelectExecutedIn::from_raw(executed_in));
}
});
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__notify_create_table(
db: *const u8,
db_len: usize,
table: *const u8,
table_len: usize,
) {
FfiBoundary::run_void(|| {
let db_str = match unsafe { FfiPtr::bytes_to_str(db, db_len) } {
Ok(s) => s,
Err(_) => return,
};
let table_str = match unsafe { FfiPtr::bytes_to_str(table, table_len) } {
Ok(s) => s,
Err(_) => return,
};
if let Some(h) = runtime::handlerton() {
h.notify_create_table(db_str, table_str);
}
});
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__notify_drop_table() {
FfiBoundary::run_void(|| {
if let Some(h) = runtime::handlerton() {
h.notify_drop_table();
}
});
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__notify_exclusive_mdl(
thd: *const sys::THD,
mdl_key: *const sys::MdlKey,
kind: i32,
) -> bool {
FfiBoundary::run_default(false, || {
let thd_ref = unsafe { thd.as_ref() };
let key_ref = unsafe { mdl_key.as_ref() };
match runtime::handlerton() {
Some(h) => result_to_veto(h.notify_exclusive_mdl(
thd_ref,
key_ref,
HaNotificationType::from_raw(kind),
)),
None => false,
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__notify_alter_table(
thd: *const sys::THD,
mdl_key: *const sys::MdlKey,
kind: i32,
) -> bool {
FfiBoundary::run_default(false, || {
let thd_ref = unsafe { thd.as_ref() };
let key_ref = unsafe { mdl_key.as_ref() };
match runtime::handlerton() {
Some(h) => result_to_veto(h.notify_alter_table(
thd_ref,
key_ref,
HaNotificationType::from_raw(kind),
)),
None => false,
}
})
}
#[unsafe(no_mangle)]
#[allow(clippy::too_many_arguments)]
pub unsafe extern "C" fn rust__hton__notify_rename_table(
thd: *const sys::THD,
mdl_key: *const sys::MdlKey,
kind: i32,
old_db: *const u8,
old_db_len: usize,
old_name: *const u8,
old_name_len: usize,
new_db: *const u8,
new_db_len: usize,
new_name: *const u8,
new_name_len: usize,
) -> bool {
FfiBoundary::run_default(false, || {
let decoded = unsafe {
(
FfiPtr::bytes_to_str(old_db, old_db_len),
FfiPtr::bytes_to_str(old_name, old_name_len),
FfiPtr::bytes_to_str(new_db, new_db_len),
FfiPtr::bytes_to_str(new_name, new_name_len),
)
};
let (old_db_str, old_name_str, new_db_str, new_name_str) = match decoded {
(Ok(a), Ok(b), Ok(c), Ok(d)) => (a, b, c, d),
_ => return false,
};
let thd_ref = unsafe { thd.as_ref() };
let key_ref = unsafe { mdl_key.as_ref() };
match runtime::handlerton() {
Some(h) => result_to_veto(h.notify_rename_table(
thd_ref,
key_ref,
HaNotificationType::from_raw(kind),
old_db_str,
old_name_str,
new_db_str,
new_name_str,
)),
None => false,
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__notify_truncate_table(
thd: *const sys::THD,
mdl_key: *const sys::MdlKey,
kind: i32,
) -> bool {
FfiBoundary::run_default(false, || {
let thd_ref = unsafe { thd.as_ref() };
let key_ref = unsafe { mdl_key.as_ref() };
match runtime::handlerton() {
Some(h) => result_to_veto(h.notify_truncate_table(
thd_ref,
key_ref,
HaNotificationType::from_raw(kind),
)),
None => false,
}
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::engine::EngineError;
#[test]
fn ok_maps_to_no_veto() {
assert!(!result_to_veto(Ok(())));
}
#[test]
fn err_maps_to_veto() {
assert!(result_to_veto(Err(EngineError::Unsupported)));
assert!(result_to_veto(Err(EngineError::Internal)));
}
}