1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Copyright Materialize, Inc. and contributors. All rights reserved.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0.

use mz_repr::adt::interval::{Interval, RoundBehavior};
use mz_repr::strconv;
use mz_sql_parser::ast::IntervalValue;

use crate::plan::PlanError;

/// Convert an [`IntervalValue`] into an [`Interval`].
///
/// The reverse of [`unplan_interval`].
pub fn plan_interval(iv: &IntervalValue) -> Result<Interval, PlanError> {
    let leading_precision = parser_datetimefield_to_adt(iv.precision_high);
    let mut i = strconv::parse_interval_w_disambiguator(
        &iv.value,
        match leading_precision {
            mz_repr::adt::datetime::DateTimeField::Hour
            | mz_repr::adt::datetime::DateTimeField::Minute => Some(leading_precision),
            _ => None,
        },
        parser_datetimefield_to_adt(iv.precision_low),
    )?;
    i.truncate_high_fields(parser_datetimefield_to_adt(iv.precision_high));
    i.truncate_low_fields(
        parser_datetimefield_to_adt(iv.precision_low),
        iv.fsec_max_precision,
        RoundBehavior::Nearest,
    )?;
    Ok(i)
}

/// Convert an [`Interval`] into an [`IntervalValue`].
///
/// The reverse of [`plan_interval`].
pub fn unplan_interval(i: &Interval) -> IntervalValue {
    let mut iv = IntervalValue::default();
    iv.value = i.to_string();
    iv
}

fn parser_datetimefield_to_adt(
    dtf: mz_sql_parser::ast::DateTimeField,
) -> mz_repr::adt::datetime::DateTimeField {
    use mz_sql_parser::ast::DateTimeField::*;
    match dtf {
        Millennium => mz_repr::adt::datetime::DateTimeField::Millennium,
        Century => mz_repr::adt::datetime::DateTimeField::Century,
        Decade => mz_repr::adt::datetime::DateTimeField::Decade,
        Year => mz_repr::adt::datetime::DateTimeField::Year,
        Month => mz_repr::adt::datetime::DateTimeField::Month,
        Day => mz_repr::adt::datetime::DateTimeField::Day,
        Hour => mz_repr::adt::datetime::DateTimeField::Hour,
        Minute => mz_repr::adt::datetime::DateTimeField::Minute,
        Second => mz_repr::adt::datetime::DateTimeField::Second,
        Milliseconds => mz_repr::adt::datetime::DateTimeField::Milliseconds,
        Microseconds => mz_repr::adt::datetime::DateTimeField::Microseconds,
    }
}