uqa_sql/semantics/
mutation_inputs.rs1use crate::ScalarExpr;
9
10pub fn top_level_column(expr: &ScalarExpr) -> Option<&str> {
11 match expr {
12 ScalarExpr::Column(name) => Some(name),
13 ScalarExpr::QualifiedColumn { column, .. } => Some(column),
14 _ => None,
15 }
16}
17
18pub fn expr_is_row_independent(expr: &ScalarExpr) -> bool {
19 match expr {
20 ScalarExpr::Literal(_) | ScalarExpr::TypedLiteral { .. } | ScalarExpr::Param(_) => true,
21 ScalarExpr::Array(items)
22 | ScalarExpr::Row(items)
23 | ScalarExpr::And(items)
24 | ScalarExpr::Or(items) => items.iter().all(expr_is_row_independent),
25 ScalarExpr::Binary { lhs, rhs, .. } => {
26 expr_is_row_independent(lhs) && expr_is_row_independent(rhs)
27 }
28 ScalarExpr::Not(inner) | ScalarExpr::UnaryMinus(inner) => expr_is_row_independent(inner),
29 ScalarExpr::IsNull { expr, .. } => expr_is_row_independent(expr),
30 ScalarExpr::Between { expr, low, high } => {
31 expr_is_row_independent(expr)
32 && expr_is_row_independent(low)
33 && expr_is_row_independent(high)
34 }
35 ScalarExpr::InList { expr, list, .. } => {
36 expr_is_row_independent(expr) && list.iter().all(expr_is_row_independent)
37 }
38 ScalarExpr::Case {
39 base,
40 when,
41 else_branch,
42 } => {
43 base.as_deref().map_or(true, expr_is_row_independent)
44 && when.iter().all(|(condition, result)| {
45 expr_is_row_independent(condition) && expr_is_row_independent(result)
46 })
47 && else_branch.as_deref().map_or(true, expr_is_row_independent)
48 }
49 ScalarExpr::Cast { expr, .. } => expr_is_row_independent(expr),
50 ScalarExpr::Default
51 | ScalarExpr::Star
52 | ScalarExpr::QualifiedStar(_)
53 | ScalarExpr::Column(_)
54 | ScalarExpr::Position(_)
55 | ScalarExpr::InternalColumn(_)
56 | ScalarExpr::QualifiedColumn { .. }
57 | ScalarExpr::Func { .. }
58 | ScalarExpr::WindowCall { .. }
59 | ScalarExpr::ScalarSubquery(_)
60 | ScalarExpr::Exists { .. }
61 | ScalarExpr::InSubquery { .. } => false,
62 }
63}