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::CompositeRow { items, .. }
24 | ScalarExpr::And(items)
25 | ScalarExpr::Or(items) => items.iter().all(expr_is_row_independent),
26 ScalarExpr::Binary { lhs, rhs, .. } => {
27 expr_is_row_independent(lhs) && expr_is_row_independent(rhs)
28 }
29 ScalarExpr::Not(inner) | ScalarExpr::UnaryMinus(inner) => expr_is_row_independent(inner),
30 ScalarExpr::IsNull { expr, .. } => expr_is_row_independent(expr),
31 ScalarExpr::Between { expr, low, high } => {
32 expr_is_row_independent(expr)
33 && expr_is_row_independent(low)
34 && expr_is_row_independent(high)
35 }
36 ScalarExpr::InList { expr, list, .. } => {
37 expr_is_row_independent(expr) && list.iter().all(expr_is_row_independent)
38 }
39 ScalarExpr::Case {
40 base,
41 when,
42 else_branch,
43 } => {
44 base.as_deref().map_or(true, expr_is_row_independent)
45 && when.iter().all(|(condition, result)| {
46 expr_is_row_independent(condition) && expr_is_row_independent(result)
47 })
48 && else_branch.as_deref().map_or(true, expr_is_row_independent)
49 }
50 ScalarExpr::Cast { expr, .. } => expr_is_row_independent(expr),
51 ScalarExpr::Default
52 | ScalarExpr::Star
53 | ScalarExpr::QualifiedStar(_)
54 | ScalarExpr::Column(_)
55 | ScalarExpr::Position(_)
56 | ScalarExpr::InternalColumn(_)
57 | ScalarExpr::QualifiedColumn { .. }
58 | ScalarExpr::Func { .. }
59 | ScalarExpr::WindowCall { .. }
60 | ScalarExpr::ScalarSubquery(_)
61 | ScalarExpr::Exists { .. }
62 | ScalarExpr::InSubquery { .. } => false,
63 }
64}