Skip to main content

uqa_sql/semantics/
windows.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Window expression classification.
8
9use crate::ScalarExpr;
10
11pub fn expr_has_window(expr: &ScalarExpr) -> bool {
12    match expr {
13        ScalarExpr::WindowCall { .. } => true,
14        ScalarExpr::Func {
15            args,
16            order_by,
17            filter,
18            ..
19        } => {
20            args.iter().any(expr_has_window)
21                || order_by.iter().any(|order| expr_has_window(&order.expr))
22                || filter.as_ref().is_some_and(|expr| expr_has_window(expr))
23        }
24        ScalarExpr::Array(items)
25        | ScalarExpr::Row(items)
26        | ScalarExpr::And(items)
27        | ScalarExpr::Or(items) => items.iter().any(expr_has_window),
28        ScalarExpr::Binary { lhs, rhs, .. } => expr_has_window(lhs) || expr_has_window(rhs),
29        ScalarExpr::Not(inner)
30        | ScalarExpr::UnaryMinus(inner)
31        | ScalarExpr::IsNull { expr: inner, .. }
32        | ScalarExpr::Cast { expr: inner, .. } => expr_has_window(inner),
33        ScalarExpr::Between { expr, low, high } => {
34            expr_has_window(expr) || expr_has_window(low) || expr_has_window(high)
35        }
36        ScalarExpr::InList { expr, list, .. } => {
37            expr_has_window(expr) || list.iter().any(expr_has_window)
38        }
39        ScalarExpr::Case {
40            base,
41            when,
42            else_branch,
43        } => {
44            base.as_ref().is_some_and(|expr| expr_has_window(expr))
45                || when
46                    .iter()
47                    .any(|(cond, result)| expr_has_window(cond) || expr_has_window(result))
48                || else_branch
49                    .as_ref()
50                    .is_some_and(|expr| expr_has_window(expr))
51        }
52        ScalarExpr::Default
53        | ScalarExpr::Star
54        | ScalarExpr::QualifiedStar(_)
55        | ScalarExpr::Column(_)
56        | ScalarExpr::Position(_)
57        | ScalarExpr::InternalColumn(_)
58        | ScalarExpr::QualifiedColumn { .. }
59        | ScalarExpr::Literal(_)
60        | ScalarExpr::TypedLiteral { .. }
61        | ScalarExpr::Param(_)
62        | ScalarExpr::ScalarSubquery(_)
63        | ScalarExpr::Exists { .. }
64        | ScalarExpr::InSubquery { .. } => false,
65    }
66}