mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-03 11:52:54 +00:00
fix: interval rewrite rule that messes up show create flow function (#5642)
* fix/interval-cast-rewrite: ### Enhance Interval Parsing and Casting - **`create_parser.rs`**: Added a test case `test_parse_interval_cast` to verify the parsing of interval casts. - **`expand_interval.rs`**: Refactored interval casting logic to handle `CastKind` and `format` attributes. Removed the `create_interval` function and integrated its logic directly into the casting process. - **`interval.result`**: Updated test results to reflect changes in interval representation, switching from `IntervalMonthDayNano` to `Utf8` format for interval operations. * reformat code
This commit is contained in:
@@ -2475,4 +2475,13 @@ CREATE TABLE log (
|
||||
assert!(extensions.fulltext_index_options.is_some());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_interval_cast() {
|
||||
let s = "select '10s'::INTERVAL";
|
||||
let stmts =
|
||||
ParserContext::create_with_dialect(s, &GreptimeDbDialect {}, ParseOptions::default())
|
||||
.unwrap();
|
||||
assert_eq!("SELECT '10 seconds'::INTERVAL", &stmts[0].to_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,15 +99,21 @@ impl TransformRule for ExpandIntervalTransformRule {
|
||||
Expr::Cast {
|
||||
expr: cast_exp,
|
||||
data_type,
|
||||
..
|
||||
kind,
|
||||
format,
|
||||
} => {
|
||||
if DataType::Interval == *data_type {
|
||||
match &**cast_exp {
|
||||
Expr::Value(Value::SingleQuotedString(value))
|
||||
| Expr::Value(Value::DoubleQuotedString(value)) => {
|
||||
let interval_name =
|
||||
let interval_value =
|
||||
normalize_interval_name(value).unwrap_or_else(|| value.to_string());
|
||||
*expr = create_interval(single_quoted_string_expr(interval_name));
|
||||
*expr = Expr::Cast {
|
||||
kind: kind.clone(),
|
||||
expr: single_quoted_string_expr(interval_value),
|
||||
data_type: DataType::Interval,
|
||||
format: std::mem::take(format),
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -123,16 +129,6 @@ fn single_quoted_string_expr(string: String) -> Box<Expr> {
|
||||
Box::new(Expr::Value(Value::SingleQuotedString(string)))
|
||||
}
|
||||
|
||||
fn create_interval(value: Box<Expr>) -> Expr {
|
||||
Expr::Interval(Interval {
|
||||
value,
|
||||
leading_field: None,
|
||||
leading_precision: None,
|
||||
last_field: None,
|
||||
fractional_seconds_precision: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn update_existing_interval_with_value(interval: &Interval, value: Box<Expr>) -> Expr {
|
||||
Expr::Interval(Interval {
|
||||
value,
|
||||
@@ -199,14 +195,23 @@ fn expand_interval_abbreviation(interval_str: &str) -> Option<String> {
|
||||
mod tests {
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use sqlparser::ast::{BinaryOperator, DataType, Expr, Interval, Value};
|
||||
use sqlparser::ast::{BinaryOperator, CastKind, DataType, Expr, Interval, Value};
|
||||
|
||||
use crate::statements::transform::expand_interval::{
|
||||
create_interval, normalize_interval_name, single_quoted_string_expr,
|
||||
ExpandIntervalTransformRule,
|
||||
normalize_interval_name, single_quoted_string_expr, ExpandIntervalTransformRule,
|
||||
};
|
||||
use crate::statements::transform::TransformRule;
|
||||
|
||||
fn create_interval(value: Box<Expr>) -> Expr {
|
||||
Expr::Interval(Interval {
|
||||
value,
|
||||
leading_field: None,
|
||||
leading_precision: None,
|
||||
last_field: None,
|
||||
fractional_seconds_precision: None,
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transform_interval_basic_conversions() {
|
||||
let test_cases = vec![
|
||||
@@ -379,15 +384,14 @@ mod tests {
|
||||
assert_eq!(control_flow, ControlFlow::Continue(()));
|
||||
assert_eq!(
|
||||
cast_to_interval_expr,
|
||||
Expr::Interval(Interval {
|
||||
value: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
Expr::Cast {
|
||||
kind: CastKind::Cast,
|
||||
expr: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"3 years 2 months".to_string()
|
||||
))),
|
||||
leading_field: None,
|
||||
leading_precision: None,
|
||||
last_field: None,
|
||||
fractional_seconds_precision: None,
|
||||
})
|
||||
data_type: DataType::Interval,
|
||||
format: None,
|
||||
}
|
||||
);
|
||||
|
||||
let mut cast_to_i64_expr = Expr::Cast {
|
||||
|
||||
@@ -25,11 +25,11 @@ SELECT INTERVAL '-2 months';
|
||||
|
||||
SELECT '3 hours'::INTERVAL;
|
||||
|
||||
+--------------------------------------------------------------------------------------------------+
|
||||
| IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 0, nanoseconds: 10800000000000 }") |
|
||||
+--------------------------------------------------------------------------------------------------+
|
||||
| 3 hours |
|
||||
+--------------------------------------------------------------------------------------------------+
|
||||
+-----------------+
|
||||
| Utf8("3 hours") |
|
||||
+-----------------+
|
||||
| 3 hours |
|
||||
+-----------------+
|
||||
|
||||
SELECT INTERVAL '1 year 2 months 3 days 4 hours' + INTERVAL '1 year';
|
||||
|
||||
@@ -128,11 +128,11 @@ SELECT INTERVAL '1y2w3d4h';
|
||||
|
||||
SELECT '3y2mon'::INTERVAL;
|
||||
|
||||
+--------------------------------------------------------------------------------------+
|
||||
| IntervalMonthDayNano("IntervalMonthDayNano { months: 38, days: 0, nanoseconds: 0 }") |
|
||||
+--------------------------------------------------------------------------------------+
|
||||
| 38 mons |
|
||||
+--------------------------------------------------------------------------------------+
|
||||
+--------------------------+
|
||||
| Utf8("3 years 2 months") |
|
||||
+--------------------------+
|
||||
| 38 mons |
|
||||
+--------------------------+
|
||||
|
||||
SELECT INTERVAL '7 days' - INTERVAL '1d';
|
||||
|
||||
@@ -169,11 +169,11 @@ SELECT INTERVAL '-P3Y3M700DT133H17M36.789S';
|
||||
|
||||
SELECT 'P3Y3M700DT133H17M36.789S'::INTERVAL;
|
||||
|
||||
+------------------------------------------------------------------------------------------------------+
|
||||
| IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 0, nanoseconds: 163343856789000000 }") |
|
||||
+------------------------------------------------------------------------------------------------------+
|
||||
| 45373 hours 17 mins 36.789000000 secs |
|
||||
+------------------------------------------------------------------------------------------------------+
|
||||
+---------------------------------------+
|
||||
| Utf8("163343856789 milliseconds") |
|
||||
+---------------------------------------+
|
||||
| 45373 hours 17 mins 36.789000000 secs |
|
||||
+---------------------------------------+
|
||||
|
||||
SELECT INTERVAL '2h' + INTERVAL 'P3Y3M700DT133H17M36.789S';
|
||||
|
||||
@@ -185,115 +185,115 @@ SELECT INTERVAL '2h' + INTERVAL 'P3Y3M700DT133H17M36.789S';
|
||||
|
||||
select '2022-01-01T00:00:01'::timestamp + '1 days'::interval;
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 1, nanoseconds: 0 }") |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2022-01-02T00:00:01 |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + Utf8("1 days") |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| 2022-01-02T00:00:01 |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
|
||||
select '2022-01-01T00:00:01'::timestamp + '2 days'::interval;
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 2, nanoseconds: 0 }") |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2022-01-03T00:00:01 |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + Utf8("2 days") |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| 2022-01-03T00:00:01 |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
|
||||
select '2022-01-01T00:00:01'::timestamp - '1 days'::interval;
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) - IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 1, nanoseconds: 0 }") |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2021-12-31T00:00:01 |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) - Utf8("1 days") |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| 2021-12-31T00:00:01 |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
|
||||
select '2022-01-01T00:00:01'::timestamp - '2 days'::interval;
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) - IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 2, nanoseconds: 0 }") |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2021-12-30T00:00:01 |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) - Utf8("2 days") |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| 2021-12-30T00:00:01 |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
|
||||
select '2022-01-01T00:00:01'::timestamp + '1 month'::interval;
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + IntervalMonthDayNano("IntervalMonthDayNano { months: 1, days: 0, nanoseconds: 0 }") |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2022-02-01T00:00:01 |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + Utf8("1 month") |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| 2022-02-01T00:00:01 |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
|
||||
select '2022-01-01T00:00:01'::timestamp + '2 months'::interval;
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + IntervalMonthDayNano("IntervalMonthDayNano { months: 2, days: 0, nanoseconds: 0 }") |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2022-03-01T00:00:01 |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+-------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + Utf8("2 months") |
|
||||
+-------------------------------------------------------------------------------------------------+
|
||||
| 2022-03-01T00:00:01 |
|
||||
+-------------------------------------------------------------------------------------------------+
|
||||
|
||||
select '2022-01-01T00:00:01'::timestamp + '1 year'::interval;
|
||||
|
||||
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + IntervalMonthDayNano("IntervalMonthDayNano { months: 12, days: 0, nanoseconds: 0 }") |
|
||||
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2023-01-01T00:00:01 |
|
||||
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2022-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + Utf8("1 year") |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
| 2023-01-01T00:00:01 |
|
||||
+-----------------------------------------------------------------------------------------------+
|
||||
|
||||
select '2023-01-01T00:00:01'::timestamp + '2 years'::interval;
|
||||
|
||||
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2023-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + IntervalMonthDayNano("IntervalMonthDayNano { months: 24, days: 0, nanoseconds: 0 }") |
|
||||
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2025-01-01T00:00:01 |
|
||||
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| arrow_cast(Utf8("2023-01-01T00:00:01"),Utf8("Timestamp(Millisecond, None)")) + Utf8("2 years") |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
| 2025-01-01T00:00:01 |
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
|
||||
-- DATE + INTERVAL
|
||||
SELECT DATE '2000-10-30' + '1 days'::interval;
|
||||
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
| Utf8("2000-10-30") + IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 1, nanoseconds: 0 }") |
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
| 2000-10-31 |
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
+-------------------------------------+
|
||||
| Utf8("2000-10-30") + Utf8("1 days") |
|
||||
+-------------------------------------+
|
||||
| 2000-10-31 |
|
||||
+-------------------------------------+
|
||||
|
||||
SELECT DATE '2000-10-30' + '2 months'::interval;
|
||||
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
| Utf8("2000-10-30") + IntervalMonthDayNano("IntervalMonthDayNano { months: 2, days: 0, nanoseconds: 0 }") |
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
| 2000-12-30 |
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
+---------------------------------------+
|
||||
| Utf8("2000-10-30") + Utf8("2 months") |
|
||||
+---------------------------------------+
|
||||
| 2000-12-30 |
|
||||
+---------------------------------------+
|
||||
|
||||
SELECT DATE '2000-10-30' + '2 years'::interval;
|
||||
|
||||
+-----------------------------------------------------------------------------------------------------------+
|
||||
| Utf8("2000-10-30") + IntervalMonthDayNano("IntervalMonthDayNano { months: 24, days: 0, nanoseconds: 0 }") |
|
||||
+-----------------------------------------------------------------------------------------------------------+
|
||||
| 2002-10-30 |
|
||||
+-----------------------------------------------------------------------------------------------------------+
|
||||
+--------------------------------------+
|
||||
| Utf8("2000-10-30") + Utf8("2 years") |
|
||||
+--------------------------------------+
|
||||
| 2002-10-30 |
|
||||
+--------------------------------------+
|
||||
|
||||
-- DATE - INTERVAL
|
||||
SELECT DATE '2000-10-30' - '1 days'::interval;
|
||||
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
| Utf8("2000-10-30") - IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 1, nanoseconds: 0 }") |
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
| 2000-10-29 |
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
+-------------------------------------+
|
||||
| Utf8("2000-10-30") - Utf8("1 days") |
|
||||
+-------------------------------------+
|
||||
| 2000-10-29 |
|
||||
+-------------------------------------+
|
||||
|
||||
SELECT DATE '2000-10-30' - '2 months'::interval;
|
||||
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
| Utf8("2000-10-30") - IntervalMonthDayNano("IntervalMonthDayNano { months: 2, days: 0, nanoseconds: 0 }") |
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
| 2000-08-30 |
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
+---------------------------------------+
|
||||
| Utf8("2000-10-30") - Utf8("2 months") |
|
||||
+---------------------------------------+
|
||||
| 2000-08-30 |
|
||||
+---------------------------------------+
|
||||
|
||||
SELECT DATE '2000-10-30' - '2 years'::interval;
|
||||
|
||||
+-----------------------------------------------------------------------------------------------------------+
|
||||
| Utf8("2000-10-30") - IntervalMonthDayNano("IntervalMonthDayNano { months: 24, days: 0, nanoseconds: 0 }") |
|
||||
+-----------------------------------------------------------------------------------------------------------+
|
||||
| 1998-10-30 |
|
||||
+-----------------------------------------------------------------------------------------------------------+
|
||||
+--------------------------------------+
|
||||
| Utf8("2000-10-30") - Utf8("2 years") |
|
||||
+--------------------------------------+
|
||||
| 1998-10-30 |
|
||||
+--------------------------------------+
|
||||
|
||||
|
||||
Reference in New Issue
Block a user