use super::{Binder, BoundResultColumn};
use crate::ast::{self, Expr, ExprId, SelectBody};
impl Binder<'_> {
pub(super) fn order_aliases(
&self,
select: &ast::Select,
columns: &[BoundResultColumn],
) -> Vec<(Vec<u8>, usize)> {
let Some(SelectBody::Select {
columns: written, ..
}) = self.ast.core(select.first).map(|core| &core.body)
else {
return Vec::new();
};
let starred = written
.iter()
.any(|column| matches!(self.ast.expr(column.expr), Some(Expr::Star { .. })));
let mut named = Vec::new();
for (position, column) in written.iter().enumerate() {
let Some(alias) = column.alias else {
continue;
};
let folded = self.ast.folded(alias).to_vec();
let at = match starred {
false => Some(position),
true => columns
.iter()
.position(|bound| bound.name.eq_ignore_ascii_case(&folded)),
};
if let Some(at) = at.filter(|at| *at < columns.len()) {
named.push((folded, at));
}
}
named
}
pub(super) fn ordered_by_alias(
&self,
term: ExprId,
aliases: &[(Vec<u8>, usize)],
) -> Option<usize> {
let Some(Expr::Column {
database: None,
table: None,
column,
}) = self.ast.expr(term)
else {
return None;
};
let folded = self.ast.folded(*column);
aliases
.iter()
.find(|(name, _)| name.as_slice() == folded)
.map(|(_, at)| *at)
}
}