use super::RoutineMutationContext;
use std::sync::Arc;
use uqa_sql::{
ast::FunctionBody,
expr::composites::constants::CompositeConstantChange,
routines::{CompiledFunctionBody, RoutineBody},
SQLError,
};
pub fn rewrite_composite_constants(
context: &RoutineMutationContext<'_>,
change: &CompositeConstantChange<'_>,
) -> Result<(), SQLError> {
let before = context.registry.routine_snapshot();
let mut next = before.clone();
let mut changed = false;
for routine in next.values_mut().flatten() {
let mut definition = routine.def.clone();
let mut revised = false;
for parameter in &mut definition.params {
if let Some(default) = &mut parameter.default {
revised |= change.expression(default)?;
}
}
if let FunctionBody::Statements(statements) = &mut definition.body {
for statement in statements {
revised |= change.statement(statement)?;
}
}
if !revised {
continue;
}
let mut body = routine.body.clone();
if let RoutineBody::Bound(compiled) = &mut body {
if let CompiledFunctionBody::SQL(plans) = Arc::make_mut(compiled) {
for plan in plans {
change.plan(plan)?;
}
}
}
*routine = super::revision::replacement(definition, body)?;
changed = true;
}
if changed {
context.publication.persist_routine_definitions(&next)?;
super::publication::record_changes(context.changes, &before, &next);
**context.registry.routines_write() = next;
context.changes.catalog_registry_changed();
}
Ok(())
}