mz_expr/scalar/func/impls/
range.rs1use mz_expr_derive::sqlfunc;
11use mz_repr::adt::range::Range;
12use mz_repr::{Datum, ExcludeNull, SqlScalarType};
13use serde::{Deserialize, Serialize};
14
15use crate::EvalError;
16use crate::scalar::func::stringify_datum;
17
18#[derive(
19 Ord,
20 PartialOrd,
21 Clone,
22 Debug,
23 Eq,
24 PartialEq,
25 Serialize,
26 Deserialize,
27 Hash
28)]
29pub struct CastRangeToString {
30 pub ty: SqlScalarType,
31}
32
33#[sqlfunc(CastRangeToString, sqlname = "rangetostr", preserves_uniqueness = true)]
35fn cast_range_to_string<'a>(&self, a: ExcludeNull<Datum<'a>>) -> Result<String, EvalError> {
36 let mut buf = String::new();
37 stringify_datum(&mut buf, *a, &self.ty)?;
38 Ok(buf)
39}
40
41#[sqlfunc(sqlname = "rangelower", is_monotone = true)]
51fn range_lower<T>(a: Range<T>) -> Option<T> {
52 a.inner.map(|inner| inner.lower.bound).flatten()
53}
54
55#[sqlfunc(sqlname = "rangeupper")]
56fn range_upper<T>(a: Range<T>) -> Option<T> {
57 a.inner.map(|inner| inner.upper.bound).flatten()
58}
59
60#[sqlfunc(sqlname = "range_empty")]
61fn range_empty<T>(a: Range<T>) -> bool {
62 a.inner.is_none()
63}
64
65#[sqlfunc(sqlname = "range_lower_inc")]
66fn range_lower_inc<T>(a: Range<T>) -> bool {
67 match a.inner {
68 None => false,
69 Some(inner) => inner.lower.inclusive,
70 }
71}
72
73#[sqlfunc(sqlname = "range_upper_inc")]
74fn range_upper_inc<T>(a: Range<T>) -> bool {
75 match a.inner {
76 None => false,
77 Some(inner) => inner.upper.inclusive,
78 }
79}
80
81#[sqlfunc(sqlname = "range_lower_inf")]
82fn range_lower_inf<T>(a: Range<T>) -> bool {
83 match a.inner {
84 None => false,
85 Some(inner) => inner.lower.bound.is_none(),
86 }
87}
88
89#[sqlfunc(sqlname = "range_upper_inf")]
90fn range_upper_inf<T>(a: Range<T>) -> bool {
91 match a.inner {
92 None => false,
93 Some(inner) => inner.upper.bound.is_none(),
94 }
95}