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.
910use mz_repr::adt::interval::{Interval, RoundBehavior};
11use mz_repr::strconv;
12use mz_sql_parser::ast::IntervalValue;
1314use crate::plan::PlanError;
1516/// Convert an [`IntervalValue`] into an [`Interval`].
17///
18/// The reverse of [`unplan_interval`].
19pub fn plan_interval(iv: &IntervalValue) -> Result<Interval, PlanError> {
20let leading_precision = parser_datetimefield_to_adt(iv.precision_high);
21let mut i = strconv::parse_interval_w_disambiguator(
22&iv.value,
23match 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 )?;
36Ok(i)
37}
3839/// Convert an [`Interval`] into an [`IntervalValue`].
40///
41/// The reverse of [`plan_interval`].
42pub fn unplan_interval(i: &Interval) -> IntervalValue {
43let mut iv = IntervalValue::default();
44 iv.value = i.to_string();
45 iv
46}
4748fn parser_datetimefield_to_adt(
49 dtf: mz_sql_parser::ast::DateTimeField,
50) -> mz_repr::adt::datetime::DateTimeField {
51use mz_sql_parser::ast::DateTimeField::*;
52match 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}