use vibesql_ast::*;
use vibesql_storage::Database;
use crate::errors::ExecutorError;
pub fn execute_create_function(
stmt: &CreateFunctionStmt,
db: &mut Database,
) -> Result<(), ExecutorError> {
use vibesql_catalog::{Function, FunctionBody, FunctionParam, SqlSecurity};
let catalog_params = stmt
.parameters
.iter()
.map(|param| FunctionParam { name: param.name.clone(), data_type: param.data_type.clone() })
.collect();
let catalog_body = match &stmt.body {
vibesql_ast::ProcedureBody::BeginEnd(_) => {
FunctionBody::RawSql(format!("{:?}", stmt.body))
}
vibesql_ast::ProcedureBody::RawSql(sql) => FunctionBody::RawSql(sql.clone()),
};
let deterministic = stmt.deterministic.unwrap_or(false);
let sql_security = stmt
.sql_security
.as_ref()
.map(|sec| match sec {
vibesql_ast::SqlSecurity::Definer => SqlSecurity::Definer,
vibesql_ast::SqlSecurity::Invoker => SqlSecurity::Invoker,
})
.unwrap_or(SqlSecurity::Definer);
let function = if stmt.deterministic.is_some()
|| stmt.sql_security.is_some()
|| stmt.comment.is_some()
|| stmt.language.is_some()
{
Function::with_characteristics(
stmt.function_name.clone(),
db.catalog.get_current_schema().to_string(),
catalog_params,
stmt.return_type.clone(),
catalog_body,
deterministic,
sql_security,
stmt.comment.clone(),
stmt.language.clone().unwrap_or_else(|| "SQL".to_string()),
)
} else {
Function::new(
stmt.function_name.clone(),
db.catalog.get_current_schema().to_string(),
catalog_params,
stmt.return_type.clone(),
catalog_body,
)
};
db.catalog.create_function_with_characteristics(function)?;
Ok(())
}
pub fn execute_drop_function(
stmt: &DropFunctionStmt,
db: &mut Database,
) -> Result<(), ExecutorError> {
let function_exists = db.catalog.function_exists(&stmt.function_name);
if stmt.if_exists && !function_exists {
return Ok(());
}
db.catalog.drop_function(&stmt.function_name)?;
Ok(())
}