use crate::ScalarExpr;
pub fn top_level_column(expr: &ScalarExpr) -> Option<&str> {
match expr {
ScalarExpr::Column(name) => Some(name),
ScalarExpr::QualifiedColumn { column, .. } => Some(column),
_ => None,
}
}
pub fn expr_is_row_independent(expr: &ScalarExpr) -> bool {
match expr {
ScalarExpr::Literal(_) | ScalarExpr::TypedLiteral { .. } | ScalarExpr::Param(_) => true,
ScalarExpr::Array(items)
| ScalarExpr::Row(items)
| ScalarExpr::And(items)
| ScalarExpr::Or(items) => items.iter().all(expr_is_row_independent),
ScalarExpr::Binary { lhs, rhs, .. } => {
expr_is_row_independent(lhs) && expr_is_row_independent(rhs)
}
ScalarExpr::Not(inner) | ScalarExpr::UnaryMinus(inner) => expr_is_row_independent(inner),
ScalarExpr::IsNull { expr, .. } => expr_is_row_independent(expr),
ScalarExpr::Between { expr, low, high } => {
expr_is_row_independent(expr)
&& expr_is_row_independent(low)
&& expr_is_row_independent(high)
}
ScalarExpr::InList { expr, list, .. } => {
expr_is_row_independent(expr) && list.iter().all(expr_is_row_independent)
}
ScalarExpr::Case {
base,
when,
else_branch,
} => {
base.as_deref().map_or(true, expr_is_row_independent)
&& when.iter().all(|(condition, result)| {
expr_is_row_independent(condition) && expr_is_row_independent(result)
})
&& else_branch.as_deref().map_or(true, expr_is_row_independent)
}
ScalarExpr::Cast { expr, .. } => expr_is_row_independent(expr),
ScalarExpr::Default
| ScalarExpr::Star
| ScalarExpr::QualifiedStar(_)
| ScalarExpr::Column(_)
| ScalarExpr::Position(_)
| ScalarExpr::InternalColumn(_)
| ScalarExpr::QualifiedColumn { .. }
| ScalarExpr::Func { .. }
| ScalarExpr::WindowCall { .. }
| ScalarExpr::ScalarSubquery(_)
| ScalarExpr::Exists { .. }
| ScalarExpr::InSubquery { .. } => false,
}
}