Skip to main content

uqa_sql/semantics/
mutation_inputs.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Row-independent mutation input shapes.
8use 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}