use alloc::vec::Vec;
use qusql_parse::{Delete, OptSpanned, Spanned};
use crate::{
SelectTypeColumn,
type_expression::{ExpressionFlags, type_expression},
type_reference::type_reference,
type_select::{SelectType, type_select_exprs},
typer::{ReferenceType, Typer, typer_stack, unqualified_name},
};
pub(crate) fn type_delete<'a>(
typer: &mut Typer<'a, '_>,
delete: &Delete<'a>,
) -> Option<SelectType<'a>> {
let mut guard = typer_stack(
typer,
|t| core::mem::take(&mut t.reference_types),
|t, v| t.reference_types = v,
);
let typer = &mut guard.typer;
for flag in &delete.flags {
match flag {
qusql_parse::DeleteFlag::LowPriority(_)
| qusql_parse::DeleteFlag::Quick(_)
| qusql_parse::DeleteFlag::Ignore(_) => (),
}
}
if !delete.using.is_empty() && typer.dialect().is_maria() {
for reference in &delete.using {
type_reference(typer, reference, false);
}
for table in &delete.tables {
let identifier = unqualified_name(typer.issues, table);
if typer.get_schema(identifier.value).is_none() {
typer.err("Unknown table or view", identifier);
}
}
} else {
if delete.tables.len() > 1 {
typer.err(
"Expected only one table here",
&delete.tables.opt_span().unwrap(),
);
}
let identifier = unqualified_name(typer.issues, &delete.tables[0]);
if let Some(s) = typer.get_schema(identifier.value) {
let mut columns = Vec::new();
for col in &s.columns {
columns.push((col.identifier.clone(), col.type_.clone()));
}
typer.reference_types.push(ReferenceType {
name: Some(identifier.clone()),
span: identifier.span(),
columns,
});
} else {
typer.err("", identifier);
}
for reference in &delete.using {
type_reference(typer, reference, false);
}
}
if let Some((where_, _)) = &delete.where_ {
let t = type_expression(
typer,
where_,
ExpressionFlags::default(),
crate::BaseType::Bool,
);
typer.ensure_base(where_, &t, crate::type_::BaseType::Bool);
}
match &delete.returning {
Some((returning_span, returning_exprs)) => {
let columns = type_select_exprs(typer, returning_exprs, true)
.into_iter()
.map(|(name, type_, span)| SelectTypeColumn { name, type_, span })
.collect();
Some(SelectType {
columns,
select_span: returning_span.join_span(returning_exprs),
})
}
None => None,
}
}