use sqlparser::ast;
use crate::parser::normalize::normalize_ident;
pub(super) fn resolve_order_by_target<'a>(
expr: &'a ast::Expr,
select_items: &'a [ast::SelectItem],
) -> (&'a ast::Expr, Option<String>) {
if let ast::Expr::Identifier(ident) = expr {
let needle = normalize_ident(ident);
for item in select_items {
if let ast::SelectItem::ExprWithAlias {
expr: aliased_expr,
alias,
} = item
&& normalize_ident(alias) == needle
{
return (aliased_expr, Some(needle));
}
}
return (expr, None);
}
if let Some(name) = function_call_name(expr) {
for item in select_items {
if let ast::SelectItem::ExprWithAlias {
expr: aliased_expr,
alias,
} = item
&& let Some(other) = function_call_name(aliased_expr)
&& other.eq_ignore_ascii_case(&name)
{
return (expr, Some(normalize_ident(alias)));
}
}
}
(expr, None)
}
pub(super) fn function_call_name(expr: &ast::Expr) -> Option<String> {
let ast::Expr::Function(func) = expr else {
return None;
};
let parts: Vec<String> = func
.name
.0
.iter()
.map(|p| match p {
ast::ObjectNamePart::Identifier(ident) => normalize_ident(ident),
_ => String::new(),
})
.collect();
if parts.is_empty() {
None
} else {
Some(parts.join("."))
}
}