mz_sql/plan/
literal.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use mz_repr::adt::interval::{Interval, RoundBehavior};
11use mz_repr::strconv;
12use mz_sql_parser::ast::IntervalValue;
13
14use crate::plan::PlanError;
15
16/// Convert an [`IntervalValue`] into an [`Interval`].
17///
18/// The reverse of [`unplan_interval`].
19pub fn plan_interval(iv: &IntervalValue) -> Result<Interval, PlanError> {
20    let leading_precision = parser_datetimefield_to_adt(iv.precision_high);
21    let mut i = strconv::parse_interval_w_disambiguator(
22        &iv.value,
23        match leading_precision {
24            mz_repr::adt::datetime::DateTimeField::Hour
25            | mz_repr::adt::datetime::DateTimeField::Minute => Some(leading_precision),
26            _ => None,
27        },
28        parser_datetimefield_to_adt(iv.precision_low),
29    )?;
30    i.truncate_high_fields(parser_datetimefield_to_adt(iv.precision_high));
31    i.truncate_low_fields(
32        parser_datetimefield_to_adt(iv.precision_low),
33        iv.fsec_max_precision,
34        RoundBehavior::Nearest,
35    )?;
36    Ok(i)
37}
38
39/// Convert an [`Interval`] into an [`IntervalValue`].
40///
41/// The reverse of [`plan_interval`].
42pub fn unplan_interval(i: &Interval) -> IntervalValue {
43    let mut iv = IntervalValue::default();
44    iv.value = i.to_string();
45    iv
46}
47
48fn parser_datetimefield_to_adt(
49    dtf: mz_sql_parser::ast::DateTimeField,
50) -> mz_repr::adt::datetime::DateTimeField {
51    use mz_sql_parser::ast::DateTimeField::*;
52    match dtf {
53        Millennium => mz_repr::adt::datetime::DateTimeField::Millennium,
54        Century => mz_repr::adt::datetime::DateTimeField::Century,
55        Decade => mz_repr::adt::datetime::DateTimeField::Decade,
56        Year => mz_repr::adt::datetime::DateTimeField::Year,
57        Month => mz_repr::adt::datetime::DateTimeField::Month,
58        Day => mz_repr::adt::datetime::DateTimeField::Day,
59        Hour => mz_repr::adt::datetime::DateTimeField::Hour,
60        Minute => mz_repr::adt::datetime::DateTimeField::Minute,
61        Second => mz_repr::adt::datetime::DateTimeField::Second,
62        Milliseconds => mz_repr::adt::datetime::DateTimeField::Milliseconds,
63        Microseconds => mz_repr::adt::datetime::DateTimeField::Microseconds,
64    }
65}