From 32a251cd91abf2f09b836163d1fcd31d60c751f9 Mon Sep 17 00:00:00 2001 From: RinChanNOWWW Date: Fri, 14 Oct 2022 19:43:05 +0800 Subject: [PATCH] Add interval arithmetic for date and timestamp. --- src/query/expression/tests/it/convert.rs | 3 +- .../functions-v2/tests/it/scalars/datetime.rs | 265 +++++++ .../functions-v2/tests/it/scalars/parser.rs | 132 +++- .../tests/it/scalars/testdata/datetime.txt | 720 ++++++++++++++++++ 4 files changed, 1078 insertions(+), 42 deletions(-) diff --git a/src/query/expression/tests/it/convert.rs b/src/query/expression/tests/it/convert.rs index 0dc6fd588644..ab604ba60e67 100644 --- a/src/query/expression/tests/it/convert.rs +++ b/src/query/expression/tests/it/convert.rs @@ -25,7 +25,7 @@ fn random_type() -> DataTypeImpl { let mut rng = rand::thread_rng(); loop { - let datatype = match rng.gen_range(0..22) { + let datatype = match rng.gen_range(0..21) { 0 => DataTypeImpl::Null(NullType {}), 1 => NullableType::new_impl(u64::to_data_type()), 2 => DataTypeImpl::Boolean(BooleanType {}), @@ -50,7 +50,6 @@ fn random_type() -> DataTypeImpl { 17 => ArrayType::new_impl(f32::to_data_type()), 18 => DataTypeImpl::VariantArray(VariantArrayType {}), 19 => DataTypeImpl::VariantObject(VariantObjectType {}), - 20 => DataTypeImpl::Interval(IntervalType::new(IntervalKind::Day)), _ => DataTypeImpl::Variant(VariantType {}), }; if can_convert(&datatype) { diff --git a/src/query/functions-v2/tests/it/scalars/datetime.rs b/src/query/functions-v2/tests/it/scalars/datetime.rs index 0ce73b99f4b1..4702af6e27c5 100644 --- a/src/query/functions-v2/tests/it/scalars/datetime.rs +++ b/src/query/functions-v2/tests/it/scalars/datetime.rs @@ -38,6 +38,9 @@ fn test_datetime() { // date_{add | sub}({year | quarter | month | week | day | hour | minute | second}, date, number) test_date_date_add_sub(file); test_timestamp_date_add_sub(file); + // date {+ | -} interval number {year | quarter | month | week | day | hour | minute | second} + test_date_arith(file); + test_timestamp_arith(file); } fn test_to_timestamp(file: &mut impl Write) { @@ -630,3 +633,265 @@ fn test_timestamp_date_add_sub(file: &mut impl Write) { ), ]); } + +fn test_date_arith(file: &mut impl Write) { + run_ast(file, "to_date(0) + interval 10000 year", &[]); // failed + run_ast(file, "to_date(0) + interval 100 year", &[]); + run_ast(file, "to_date(0) + interval 100 quarter", &[]); + run_ast(file, "to_date(0) + interval 100 month", &[]); + run_ast(file, "to_date(0) + interval 100 day", &[]); + run_ast(file, "to_date(0) - interval 100 year", &[]); + run_ast(file, "to_date(0) - interval 100 quarter", &[]); + run_ast(file, "to_date(0) - interval 100 month", &[]); + run_ast(file, "to_date(0) - interval 100 day", &[]); + run_ast(file, "a + interval b year", &[ + ("a", DataType::Date, from_date_data(vec![-100, 0, 100])), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b quarter", &[ + ("a", DataType::Date, from_date_data(vec![-100, 0, 100])), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b month", &[ + ("a", DataType::Date, from_date_data(vec![-100, 0, 100])), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b day", &[ + ("a", DataType::Date, from_date_data(vec![-100, 0, 100])), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b year", &[ + ("a", DataType::Date, from_date_data(vec![-100, 0, 100])), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b quarter", &[ + ("a", DataType::Date, from_date_data(vec![-100, 0, 100])), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b month", &[ + ("a", DataType::Date, from_date_data(vec![-100, 0, 100])), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b day", &[ + ("a", DataType::Date, from_date_data(vec![-100, 0, 100])), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); +} + +fn test_timestamp_arith(file: &mut impl Write) { + run_ast(file, "to_timestamp(0) + interval 10000 year", &[]); // failed + run_ast(file, "to_timestamp(0) + interval 100 year", &[]); + run_ast(file, "to_timestamp(0) + interval 100 quarter", &[]); + run_ast(file, "to_timestamp(0) + interval 100 month", &[]); + run_ast(file, "to_timestamp(0) + interval 100 day", &[]); + run_ast(file, "to_timestamp(0) + interval 100 hour", &[]); + run_ast(file, "to_timestamp(0) + interval 100 minute", &[]); + run_ast(file, "to_timestamp(0) + interval 100 second", &[]); + run_ast(file, "to_timestamp(0) - interval 100 year", &[]); + run_ast(file, "to_timestamp(0) - interval 100 quarter", &[]); + run_ast(file, "to_timestamp(0) - interval 100 month", &[]); + run_ast(file, "to_timestamp(0) - interval 100 day", &[]); + run_ast(file, "to_timestamp(0) - interval 100 hour", &[]); + run_ast(file, "to_timestamp(0) - interval 100 minute", &[]); + run_ast(file, "to_timestamp(0) - interval 100 second", &[]); + run_ast(file, "a + interval b year", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b quarter", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b month", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b day", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b hour", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b minute", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a + interval b second", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b year", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b quarter", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b month", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b day", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b hour", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b minute", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); + run_ast(file, "a - interval b second", &[ + ( + "a", + DataType::Timestamp, + from_timestamp_data(vec![-100, 0, 100]), + ), + ( + "b", + DataType::Number(NumberDataType::Int32), + Column::from_data(vec![1, 2, 3]), + ), + ]); +} diff --git a/src/query/functions-v2/tests/it/scalars/parser.rs b/src/query/functions-v2/tests/it/scalars/parser.rs index 87569eef13b9..19ed2027aa1a 100644 --- a/src/query/functions-v2/tests/it/scalars/parser.rs +++ b/src/query/functions-v2/tests/it/scalars/parser.rs @@ -47,6 +47,44 @@ macro_rules! with_interval_mapped_name { } } +macro_rules! transform_interval_add_sub { + ($span: expr, $columns: expr, $name: expr, $unit: expr, $date: expr, $interval: expr) => { + if $name == "plus" { + with_interval_mapped_name!(|INTERVAL| match $unit { + IntervalKind::INTERVAL => RawExpr::FunctionCall { + span: transform_span($span), + name: concat!("add_", INTERVAL).to_string(), + params: vec![], + args: vec![ + transform_expr(*$date, $columns), + transform_expr(*$interval, $columns), + ], + }, + kind => { + unimplemented!("{kind:?} is not supported for interval") + } + }) + } else if $name == "minus" { + with_interval_mapped_name!(|INTERVAL| match $unit { + IntervalKind::INTERVAL => RawExpr::FunctionCall { + span: transform_span($span), + name: concat!("substract_", INTERVAL).to_string(), + params: vec![], + args: vec![ + transform_expr(*$date, $columns), + transform_expr(*$interval, $columns), + ], + }, + kind => { + unimplemented!("{kind:?} is not supported for interval") + } + }) + } else { + unimplemented!("operator {} is not supported for interval", $name) + } + }; +} + pub fn transform_expr(ast: common_ast::ast::Expr, columns: &[(&str, DataType)]) -> RawExpr { match ast { common_ast::ast::Expr::Literal { span, lit } => RawExpr::Literal { @@ -151,48 +189,62 @@ pub fn transform_expr(ast: common_ast::ast::Expr, columns: &[(&str, DataType)]) right, } => { let name = transform_binary_op(op); - if name != "notlike" && name != "notregexp" && name != "notrlike" { - RawExpr::FunctionCall { - span: transform_span(span), - name, - params: vec![], - args: vec![ - transform_expr(*left, columns), - transform_expr(*right, columns), - ], - } - } else if name == "notlike" { - let result = RawExpr::FunctionCall { - span: transform_span(span), - name: "like".to_string(), - params: vec![], - args: vec![ - transform_expr(*left, columns), - transform_expr(*right, columns), - ], - }; - RawExpr::FunctionCall { - span: transform_span(span), - name: "not".to_string(), - params: vec![], - args: vec![result], + match name.as_str() { + "notlike" => { + let result = RawExpr::FunctionCall { + span: transform_span(span), + name: "like".to_string(), + params: vec![], + args: vec![ + transform_expr(*left, columns), + transform_expr(*right, columns), + ], + }; + RawExpr::FunctionCall { + span: transform_span(span), + name: "not".to_string(), + params: vec![], + args: vec![result], + } } - } else { - let result = RawExpr::FunctionCall { - span: transform_span(span), - name: "regexp".to_string(), - params: vec![], - args: vec![ - transform_expr(*left, columns), - transform_expr(*right, columns), - ], - }; - RawExpr::FunctionCall { - span: transform_span(span), - name: "not".to_string(), - params: vec![], - args: vec![result], + "notregexp" | "notrlike" => { + let result = RawExpr::FunctionCall { + span: transform_span(span), + name: "regexp".to_string(), + params: vec![], + args: vec![ + transform_expr(*left, columns), + transform_expr(*right, columns), + ], + }; + RawExpr::FunctionCall { + span: transform_span(span), + name: "not".to_string(), + params: vec![], + args: vec![result], + } } + _ => match (*left.clone(), *right.clone()) { + (common_ast::ast::Expr::Interval { expr, unit, .. }, _) => { + if name == "minus" { + unimplemented!("interval cannot be the minuend") + } else { + transform_interval_add_sub!(span, columns, name, unit, right, expr) + } + } + (_, common_ast::ast::Expr::Interval { expr, unit, .. }) => { + transform_interval_add_sub!(span, columns, name, unit, left, expr) + } + (_, _) => RawExpr::FunctionCall { + span: transform_span(span), + name, + params: vec![], + args: vec![ + transform_expr(*left, columns), + transform_expr(*right, columns), + ], + }, + }, } } common_ast::ast::Expr::Position { diff --git a/src/query/functions-v2/tests/it/scalars/testdata/datetime.txt b/src/query/functions-v2/tests/it/scalars/testdata/datetime.txt index 9db5a841cf4c..2f6f0f63c7f2 100644 --- a/src/query/functions-v2/tests/it/scalars/testdata/datetime.txt +++ b/src/query/functions-v2/tests/it/scalars/testdata/datetime.txt @@ -1751,3 +1751,723 @@ evaluation (internal): +--------+--------------------------------+ +error: + --> SQL:1:12 + | +1 | to_date(0) + interval 10000 year + | ^ date `+11970-01-01` is out of range + + + +ast : to_date(0) + interval 100 year +raw expr : add_years(to_date(0_u8), 100_u8) +checked expr : add_years(to_date(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 36525 +output type : Date +output domain : Unknown +output : 2070-01-01 + + +ast : to_date(0) + interval 100 quarter +raw expr : add_quarters(to_date(0_u8), 100_u8) +checked expr : add_quarters(to_date(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 9131 +output type : Date +output domain : Unknown +output : 1995-01-01 + + +ast : to_date(0) + interval 100 month +raw expr : add_months(to_date(0_u8), 100_u8) +checked expr : add_months(to_date(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 3042 +output type : Date +output domain : Unknown +output : 1978-05-01 + + +ast : to_date(0) + interval 100 day +raw expr : add_days(to_date(0_u8), 100_u8) +checked expr : add_days(to_date(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 100 +output type : Date +output domain : Unknown +output : 1970-04-11 + + +ast : to_date(0) - interval 100 year +raw expr : substract_years(to_date(0_u8), 100_u8) +checked expr : substract_years(to_date(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -36524 +output type : Date +output domain : Unknown +output : 1870-01-01 + + +ast : to_date(0) - interval 100 quarter +raw expr : substract_quarters(to_date(0_u8), 100_u8) +checked expr : substract_quarters(to_date(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -9131 +output type : Date +output domain : Unknown +output : 1945-01-01 + + +ast : to_date(0) - interval 100 month +raw expr : substract_months(to_date(0_u8), 100_u8) +checked expr : substract_months(to_date(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -3044 +output type : Date +output domain : Unknown +output : 1961-09-01 + + +ast : to_date(0) - interval 100 day +raw expr : substract_days(to_date(0_u8), 100_u8) +checked expr : substract_days(to_date(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -100 +output type : Date +output domain : Unknown +output : 1969-09-23 + + +ast : a + interval b year +raw expr : add_years(ColumnRef(0)::Date, ColumnRef(1)::Int32) +checked expr : add_years(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+--------------+---------+------------+ +| | a | b | Output | ++--------+--------------+---------+------------+ +| Type | Date | Int32 | Date | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-09-23 | 1 | 1970-09-23 | +| Row 1 | 1970-01-01 | 2 | 1972-01-01 | +| Row 2 | 1970-04-11 | 3 | 1973-04-11 | ++--------+--------------+---------+------------+ +evaluation (internal): ++--------+------------------+ +| Column | Data | ++--------+------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [265, 730, 1196] | ++--------+------------------+ + + +ast : a + interval b quarter +raw expr : add_quarters(ColumnRef(0)::Date, ColumnRef(1)::Int32) +checked expr : add_quarters(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+--------------+---------+------------+ +| | a | b | Output | ++--------+--------------+---------+------------+ +| Type | Date | Int32 | Date | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-09-23 | 1 | 1969-12-23 | +| Row 1 | 1970-01-01 | 2 | 1970-07-01 | +| Row 2 | 1970-04-11 | 3 | 1971-01-11 | ++--------+--------------+---------+------------+ +evaluation (internal): ++--------+------------------+ +| Column | Data | ++--------+------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-9, 181, 375] | ++--------+------------------+ + + +ast : a + interval b month +raw expr : add_months(ColumnRef(0)::Date, ColumnRef(1)::Int32) +checked expr : add_months(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+--------------+---------+------------+ +| | a | b | Output | ++--------+--------------+---------+------------+ +| Type | Date | Int32 | Date | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-09-23 | 1 | 1969-10-23 | +| Row 1 | 1970-01-01 | 2 | 1970-03-01 | +| Row 2 | 1970-04-11 | 3 | 1970-07-11 | ++--------+--------------+---------+------------+ +evaluation (internal): ++--------+------------------+ +| Column | Data | ++--------+------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-70, 59, 191] | ++--------+------------------+ + + +ast : a + interval b day +raw expr : add_days(ColumnRef(0)::Date, ColumnRef(1)::Int32) +checked expr : add_days(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+--------------+---------+------------+ +| | a | b | Output | ++--------+--------------+---------+------------+ +| Type | Date | Int32 | Date | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-09-23 | 1 | 1969-09-24 | +| Row 1 | 1970-01-01 | 2 | 1970-01-03 | +| Row 2 | 1970-04-11 | 3 | 1970-04-14 | ++--------+--------------+---------+------------+ +evaluation (internal): ++--------+------------------+ +| Column | Data | ++--------+------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-99, 2, 103] | ++--------+------------------+ + + +ast : a - interval b year +raw expr : substract_years(ColumnRef(0)::Date, ColumnRef(1)::Int32) +checked expr : substract_years(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+--------------+---------+------------+ +| | a | b | Output | ++--------+--------------+---------+------------+ +| Type | Date | Int32 | Date | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-09-23 | 1 | 1968-09-23 | +| Row 1 | 1970-01-01 | 2 | 1968-01-01 | +| Row 2 | 1970-04-11 | 3 | 1967-04-11 | ++--------+--------------+---------+------------+ +evaluation (internal): ++--------+--------------------+ +| Column | Data | ++--------+--------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-465, -731, -996] | ++--------+--------------------+ + + +ast : a - interval b quarter +raw expr : substract_quarters(ColumnRef(0)::Date, ColumnRef(1)::Int32) +checked expr : substract_quarters(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+--------------+---------+------------+ +| | a | b | Output | ++--------+--------------+---------+------------+ +| Type | Date | Int32 | Date | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-09-23 | 1 | 1969-06-23 | +| Row 1 | 1970-01-01 | 2 | 1969-07-01 | +| Row 2 | 1970-04-11 | 3 | 1969-07-11 | ++--------+--------------+---------+------------+ +evaluation (internal): ++--------+--------------------+ +| Column | Data | ++--------+--------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-192, -184, -174] | ++--------+--------------------+ + + +ast : a - interval b month +raw expr : substract_months(ColumnRef(0)::Date, ColumnRef(1)::Int32) +checked expr : substract_months(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+--------------+---------+------------+ +| | a | b | Output | ++--------+--------------+---------+------------+ +| Type | Date | Int32 | Date | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-09-23 | 1 | 1969-08-23 | +| Row 1 | 1970-01-01 | 2 | 1969-11-01 | +| Row 2 | 1970-04-11 | 3 | 1970-01-11 | ++--------+--------------+---------+------------+ +evaluation (internal): ++--------+------------------+ +| Column | Data | ++--------+------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-131, -61, 10] | ++--------+------------------+ + + +ast : a - interval b day +raw expr : substract_days(ColumnRef(0)::Date, ColumnRef(1)::Int32) +checked expr : substract_days(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+--------------+---------+------------+ +| | a | b | Output | ++--------+--------------+---------+------------+ +| Type | Date | Int32 | Date | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-09-23 | 1 | 1969-09-22 | +| Row 1 | 1970-01-01 | 2 | 1969-12-30 | +| Row 2 | 1970-04-11 | 3 | 1970-04-08 | ++--------+--------------+---------+------------+ +evaluation (internal): ++--------+------------------+ +| Column | Data | ++--------+------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-101, -2, 97] | ++--------+------------------+ + + +error: + --> SQL:1:17 + | +1 | to_timestamp(0) + interval 10000 year + | ^ timestamp `315569520000000000` is out of range + + + +ast : to_timestamp(0) + interval 100 year +raw expr : add_years(to_timestamp(0_u8), 100_u8) +checked expr : add_years(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 3155760000000000 +output type : Timestamp +output domain : Unknown +output : 2070-01-01 00:00:00.000000 + + +ast : to_timestamp(0) + interval 100 quarter +raw expr : add_quarters(to_timestamp(0_u8), 100_u8) +checked expr : add_quarters(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 788918400000000 +output type : Timestamp +output domain : Unknown +output : 1995-01-01 00:00:00.000000 + + +ast : to_timestamp(0) + interval 100 month +raw expr : add_months(to_timestamp(0_u8), 100_u8) +checked expr : add_months(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 262828800000000 +output type : Timestamp +output domain : Unknown +output : 1978-05-01 00:00:00.000000 + + +ast : to_timestamp(0) + interval 100 day +raw expr : add_days(to_timestamp(0_u8), 100_u8) +checked expr : add_days(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 8640000000000 +output type : Timestamp +output domain : Unknown +output : 1970-04-11 00:00:00.000000 + + +ast : to_timestamp(0) + interval 100 hour +raw expr : add_hours(to_timestamp(0_u8), 100_u8) +checked expr : add_hours(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 360000000000 +output type : Timestamp +output domain : Unknown +output : 1970-01-05 04:00:00.000000 + + +ast : to_timestamp(0) + interval 100 minute +raw expr : add_minutes(to_timestamp(0_u8), 100_u8) +checked expr : add_minutes(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 6000000000 +output type : Timestamp +output domain : Unknown +output : 1970-01-01 01:40:00.000000 + + +ast : to_timestamp(0) + interval 100 second +raw expr : add_seconds(to_timestamp(0_u8), 100_u8) +checked expr : add_seconds(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : 100000000 +output type : Timestamp +output domain : Unknown +output : 1970-01-01 00:01:40.000000 + + +ast : to_timestamp(0) - interval 100 year +raw expr : substract_years(to_timestamp(0_u8), 100_u8) +checked expr : substract_years(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -3155673600000000 +output type : Timestamp +output domain : Unknown +output : 1870-01-01 00:00:00.000000 + + +ast : to_timestamp(0) - interval 100 quarter +raw expr : substract_quarters(to_timestamp(0_u8), 100_u8) +checked expr : substract_quarters(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -788918400000000 +output type : Timestamp +output domain : Unknown +output : 1945-01-01 00:00:00.000000 + + +ast : to_timestamp(0) - interval 100 month +raw expr : substract_months(to_timestamp(0_u8), 100_u8) +checked expr : substract_months(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -263001600000000 +output type : Timestamp +output domain : Unknown +output : 1961-09-01 00:00:00.000000 + + +ast : to_timestamp(0) - interval 100 day +raw expr : substract_days(to_timestamp(0_u8), 100_u8) +checked expr : substract_days(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -8640000000000 +output type : Timestamp +output domain : Unknown +output : 1969-09-23 00:00:00.000000 + + +ast : to_timestamp(0) - interval 100 hour +raw expr : substract_hours(to_timestamp(0_u8), 100_u8) +checked expr : substract_hours(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -360000000000 +output type : Timestamp +output domain : Unknown +output : 1969-12-27 20:00:00.000000 + + +ast : to_timestamp(0) - interval 100 minute +raw expr : substract_minutes(to_timestamp(0_u8), 100_u8) +checked expr : substract_minutes(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -6000000000 +output type : Timestamp +output domain : Unknown +output : 1969-12-31 22:20:00.000000 + + +ast : to_timestamp(0) - interval 100 second +raw expr : substract_seconds(to_timestamp(0_u8), 100_u8) +checked expr : substract_seconds(to_timestamp(CAST(0_u8 AS Int64)), CAST(100_u8 AS Int64)) +optimized expr : -100000000 +output type : Timestamp +output domain : Unknown +output : 1969-12-31 23:58:20.000000 + + +ast : a + interval b year +raw expr : add_years(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : add_years(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1970-12-31 23:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1972-01-01 00:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1973-01-01 00:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+--------------------------------------------------+ +| Column | Data | ++--------+--------------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [31535999999900, 63072000000000, 94694400000100] | ++--------+--------------------------------------------------+ + + +ast : a + interval b quarter +raw expr : add_quarters(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : add_quarters(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1970-03-31 23:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1970-07-01 00:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1970-10-01 00:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+-------------------------------------------------+ +| Column | Data | ++--------+-------------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [7775999999900, 15638400000000, 23587200000100] | ++--------+-------------------------------------------------+ + + +ast : a + interval b month +raw expr : add_months(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : add_months(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1970-01-31 23:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1970-03-01 00:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1970-04-01 00:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+-----------------------------------------------+ +| Column | Data | ++--------+-----------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [2678399999900, 5097600000000, 7776000000100] | ++--------+-----------------------------------------------+ + + +ast : a + interval b day +raw expr : add_days(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : add_days(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1970-01-01 23:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1970-01-03 00:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1970-01-04 00:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+-------------------------------------------+ +| Column | Data | ++--------+-------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [86399999900, 172800000000, 259200000100] | ++--------+-------------------------------------------+ + + +ast : a + interval b hour +raw expr : add_hours(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : add_hours(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1970-01-01 00:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1970-01-01 02:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1970-01-01 03:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+---------------------------------------+ +| Column | Data | ++--------+---------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [3599999900, 7200000000, 10800000100] | ++--------+---------------------------------------+ + + +ast : a + interval b minute +raw expr : add_minutes(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : add_minutes(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1970-01-01 00:00:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1970-01-01 00:02:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1970-01-01 00:03:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+----------------------------------+ +| Column | Data | ++--------+----------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [59999900, 120000000, 180000100] | ++--------+----------------------------------+ + + +ast : a + interval b second +raw expr : add_seconds(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : add_seconds(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1970-01-01 00:00:00.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1970-01-01 00:00:02.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1970-01-01 00:00:03.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+----------------------------+ +| Column | Data | ++--------+----------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [999900, 2000000, 3000100] | ++--------+----------------------------+ + + +ast : a - interval b year +raw expr : substract_years(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : substract_years(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1968-12-31 23:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1968-01-01 00:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1967-01-01 00:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+-----------------------------------------------------+ +| Column | Data | ++--------+-----------------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-31536000000100, -63158400000000, -94694399999900] | ++--------+-----------------------------------------------------+ + + +ast : a - interval b quarter +raw expr : substract_quarters(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : substract_quarters(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1969-09-30 23:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1969-07-01 00:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1969-04-01 00:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+----------------------------------------------------+ +| Column | Data | ++--------+----------------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-7948800000100, -15897600000000, -23759999999900] | ++--------+----------------------------------------------------+ + + +ast : a - interval b month +raw expr : substract_months(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : substract_months(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1969-11-30 23:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1969-11-01 00:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1969-10-01 00:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+--------------------------------------------------+ +| Column | Data | ++--------+--------------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-2678400000100, -5270400000000, -7948799999900] | ++--------+--------------------------------------------------+ + + +ast : a - interval b day +raw expr : substract_days(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : substract_days(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1969-12-30 23:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1969-12-30 00:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1969-12-29 00:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+----------------------------------------------+ +| Column | Data | ++--------+----------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-86400000100, -172800000000, -259199999900] | ++--------+----------------------------------------------+ + + +ast : a - interval b hour +raw expr : substract_hours(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : substract_hours(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1969-12-31 22:59:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1969-12-31 22:00:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1969-12-31 21:00:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+------------------------------------------+ +| Column | Data | ++--------+------------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-3600000100, -7200000000, -10799999900] | ++--------+------------------------------------------+ + + +ast : a - interval b minute +raw expr : substract_minutes(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : substract_minutes(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1969-12-31 23:58:59.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1969-12-31 23:58:00.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1969-12-31 23:57:00.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+-------------------------------------+ +| Column | Data | ++--------+-------------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-60000100, -120000000, -179999900] | ++--------+-------------------------------------+ + + +ast : a - interval b second +raw expr : substract_seconds(ColumnRef(0)::Timestamp, ColumnRef(1)::Int32) +checked expr : substract_seconds(ColumnRef(0), CAST(ColumnRef(1) AS Int64)) +evaluation: ++--------+----------------------------+---------+----------------------------+ +| | a | b | Output | ++--------+----------------------------+---------+----------------------------+ +| Type | Timestamp | Int32 | Timestamp | +| Domain | {-100..=100} | {1..=3} | Unknown | +| Row 0 | 1969-12-31 23:59:59.999900 | 1 | 1969-12-31 23:59:58.999900 | +| Row 1 | 1970-01-01 00:00:00.000000 | 2 | 1969-12-31 23:59:58.000000 | +| Row 2 | 1970-01-01 00:00:00.000100 | 3 | 1969-12-31 23:59:57.000100 | ++--------+----------------------------+---------+----------------------------+ +evaluation (internal): ++--------+--------------------------------+ +| Column | Data | ++--------+--------------------------------+ +| a | [-100, 0, 100] | +| b | Int32([1, 2, 3]) | +| Output | [-1000100, -2000000, -2999900] | ++--------+--------------------------------+ + +