Skip to content

Commit

Permalink
add datediff function
Browse files Browse the repository at this point in the history
  • Loading branch information
chagelo committed Oct 2, 2024
1 parent e8895e6 commit 5d67b7b
Show file tree
Hide file tree
Showing 15 changed files with 688 additions and 161 deletions.
25 changes: 25 additions & 0 deletions src/query/ast/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ pub enum Expr {
interval: Box<Expr>,
date: Box<Expr>,
},
DateDiff {
span: Span,
unit: IntervalKind,
date_start: Box<Expr>,
date_end: Box<Expr>,
},
DateSub {
span: Span,
unit: IntervalKind,
Expand Down Expand Up @@ -260,6 +266,7 @@ impl Expr {
| Expr::Map { span, .. }
| Expr::Interval { span, .. }
| Expr::DateAdd { span, .. }
| Expr::DateDiff { span, .. }
| Expr::DateSub { span, .. }
| Expr::DateTrunc { span, .. }
| Expr::Hole { span, .. } => *span,
Expand Down Expand Up @@ -388,6 +395,15 @@ impl Expr {
date,
..
} => merge_span(merge_span(*span, interval.whole_span()), date.whole_span()),
Expr::DateDiff {
span,
date_start,
date_end,
..
} => merge_span(
merge_span(*span, date_start.whole_span()),
date_end.whole_span(),
),
Expr::DateSub {
span,
interval,
Expand All @@ -409,6 +425,7 @@ impl Expr {
"SUBSTRING",
"TRIM",
"DATE_ADD",
"DATE_DIFF",
"DATE_SUB",
"DATE_TRUNC",
]
Expand Down Expand Up @@ -698,6 +715,14 @@ impl Display for Expr {
} => {
write!(f, "DATE_ADD({unit}, {interval}, {date})")?;
}
Expr::DateDiff {
unit,
date_start,
date_end,
..
} => {
write!(f, "DATE_DIFF({unit}, {date_start}, {date_end})")?;
}
Expr::DateSub {
unit,
interval,
Expand Down
14 changes: 14 additions & 0 deletions src/query/ast/src/ast/format/syntax/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,20 @@ pub(crate) fn pretty_expr(expr: Expr) -> RcDoc<'static> {
.append(RcDoc::space())
.append(pretty_expr(*date))
.append(RcDoc::text(")")),
Expr::DateDiff {
unit,
date_start,
date_end,
..
} => RcDoc::text("DATE_DIFF(")
.append(RcDoc::text(unit.to_string()))
.append(RcDoc::text(","))
.append(RcDoc::space())
.append(pretty_expr(*date_start))
.append(RcDoc::text(","))
.append(RcDoc::space())
.append(pretty_expr(*date_end))
.append(RcDoc::text(")")),
Expr::DateSub {
unit,
interval,
Expand Down
30 changes: 30 additions & 0 deletions src/query/ast/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,11 @@ pub enum ExprElement {
interval: Expr,
date: Expr,
},
DateDiff {
unit: IntervalKind,
date_start: Expr,
date_end: Expr,
},
DateSub {
unit: IntervalKind,
interval: Expr,
Expand Down Expand Up @@ -407,6 +412,7 @@ impl ExprElement {
ExprElement::Map { .. } => Affix::Nilfix,
ExprElement::Interval { .. } => Affix::Nilfix,
ExprElement::DateAdd { .. } => Affix::Nilfix,
ExprElement::DateDiff { .. } => Affix::Nilfix,
ExprElement::DateSub { .. } => Affix::Nilfix,
ExprElement::DateTrunc { .. } => Affix::Nilfix,
ExprElement::Hole { .. } => Affix::Nilfix,
Expand Down Expand Up @@ -449,6 +455,7 @@ impl Expr {
Expr::Map { .. } => Affix::Nilfix,
Expr::Interval { .. } => Affix::Nilfix,
Expr::DateAdd { .. } => Affix::Nilfix,
Expr::DateDiff { .. } => Affix::Nilfix,
Expr::DateSub { .. } => Affix::Nilfix,
Expr::DateTrunc { .. } => Affix::Nilfix,
Expr::Hole { .. } => Affix::Nilfix,
Expand Down Expand Up @@ -624,6 +631,16 @@ impl<'a, I: Iterator<Item = WithSpan<'a, ExprElement>>> PrattParser<I> for ExprP
interval: Box::new(interval),
date: Box::new(date),
},
ExprElement::DateDiff {
unit,
date_start,
date_end,
} => Expr::DateDiff {
span: transform_span(elem.span.tokens),
unit,
date_start: Box::new(date_start),
date_end: Box::new(date_end),
},
ExprElement::DateSub {
unit,
interval,
Expand Down Expand Up @@ -1176,6 +1193,18 @@ pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
date,
},
);

let date_diff = map(
rule! {
DATE_DIFF ~ "(" ~ #interval_kind ~ "," ~ #subexpr(0) ~ "," ~ #subexpr(0) ~ ")"
},
|(_, _, unit, _, date_start, _, date_end, _)| ExprElement::DateDiff {
unit,
date_start,
date_end,
},
);

let date_sub = map(
rule! {
DATE_SUB ~ "(" ~ #interval_kind ~ "," ~ #subexpr(0) ~ "," ~ #subexpr(0) ~ ")"
Expand Down Expand Up @@ -1262,6 +1291,7 @@ pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
| #unary_op : "<operator>"
| #cast : "`CAST(... AS ...)`"
| #date_add: "`DATE_ADD(..., ..., (YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | SECOND | DOY | DOW))`"
| #date_diff: "`DATE_DIFF(..., ..., (YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | SECOND | DOY | DOW))`"
| #date_sub: "`DATE_SUB(..., ..., (YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | SECOND | DOY | DOW))`"
| #date_trunc: "`DATE_TRUNC((YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | SECOND), ...)`"
| #date_expr: "`DATE <str_literal>`"
Expand Down
3 changes: 3 additions & 0 deletions src/query/ast/src/parser/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,8 @@ pub enum TokenKind {
DATE,
#[token("DATE_ADD", ignore(ascii_case))]
DATE_ADD,
#[token("DATE_DIFF", ignore(ascii_case))]
DATE_DIFF,
#[token("DATE_PART", ignore(ascii_case))]
DATE_PART,
#[token("DATE_SUB", ignore(ascii_case))]
Expand Down Expand Up @@ -1567,6 +1569,7 @@ impl TokenKind {
// | TokenKind::WINDOW
| TokenKind::WITH
| TokenKind::DATE_ADD
| TokenKind::DATE_DIFF
| TokenKind::DATE_SUB
| TokenKind::DATE_TRUNC
| TokenKind::IGNORE_RESULT
Expand Down
2 changes: 1 addition & 1 deletion src/query/ast/tests/it/testdata/expr-error.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ error:
--> SQL:1:10
|
1 | CAST(col1)
| ---- ^ unexpected `)`, expecting `AS`, `,`, `(`, `IS`, `NOT`, `IN`, `EXISTS`, `BETWEEN`, `+`, `-`, `*`, `/`, `//`, `DIV`, `%`, `||`, `<->`, `>`, `<`, `>=`, `<=`, `=`, `<>`, `!=`, `^`, `AND`, `OR`, `XOR`, `LIKE`, `REGEXP`, `RLIKE`, `SOUNDS`, <BitWiseOr>, <BitWiseAnd>, <BitWiseXor>, <ShiftLeft>, <ShiftRight>, `->`, `->>`, `#>`, `#>>`, `?`, `?|`, `?&`, `@>`, `<@`, `@?`, `@@`, `#-`, <Factorial>, <SquareRoot>, <BitWiseNot>, <CubeRoot>, <Abs>, `CAST`, `TRY_CAST`, `DATE_ADD`, `DATE_SUB`, `DATE_TRUNC`, `DATE`, or 32 more ...
| ---- ^ unexpected `)`, expecting `AS`, `,`, `(`, `IS`, `NOT`, `IN`, `EXISTS`, `BETWEEN`, `+`, `-`, `*`, `/`, `//`, `DIV`, `%`, `||`, `<->`, `>`, `<`, `>=`, `<=`, `=`, `<>`, `!=`, `^`, `AND`, `OR`, `XOR`, `LIKE`, `REGEXP`, `RLIKE`, `SOUNDS`, <BitWiseOr>, <BitWiseAnd>, <BitWiseXor>, <ShiftLeft>, <ShiftRight>, `->`, `->>`, `#>`, `#>>`, `?`, `?|`, `?&`, `@>`, `<@`, `@?`, `@@`, `#-`, <Factorial>, <SquareRoot>, <BitWiseNot>, <CubeRoot>, <Abs>, `CAST`, `TRY_CAST`, `DATE_ADD`, `DATE_DIFF`, `DATE_SUB`, `DATE_TRUNC`, or 33 more ...
| |
| while parsing `CAST(... AS ...)`
| while parsing expression
Expand Down
4 changes: 2 additions & 2 deletions src/query/ast/tests/it/testdata/stmt-error.txt
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ error:
--> SQL:1:41
|
1 | SELECT * FROM t GROUP BY GROUPING SETS ()
| ------ ^ unexpected `)`, expecting `(`, `IS`, `IN`, `EXISTS`, `BETWEEN`, `+`, `-`, `*`, `/`, `//`, `DIV`, `%`, `||`, `<->`, `>`, `<`, `>=`, `<=`, `=`, `<>`, `!=`, `^`, `AND`, `OR`, `XOR`, `LIKE`, `NOT`, `REGEXP`, `RLIKE`, `SOUNDS`, <BitWiseOr>, <BitWiseAnd>, <BitWiseXor>, <ShiftLeft>, <ShiftRight>, `->`, `->>`, `#>`, `#>>`, `?`, `?|`, `?&`, `@>`, `<@`, `@?`, `@@`, `#-`, <Factorial>, <SquareRoot>, <BitWiseNot>, <CubeRoot>, <Abs>, `CAST`, `TRY_CAST`, `DATE_ADD`, `DATE_SUB`, `DATE_TRUNC`, `DATE`, `TIMESTAMP`, `INTERVAL`, or 30 more ...
| ------ ^ unexpected `)`, expecting `(`, `IS`, `IN`, `EXISTS`, `BETWEEN`, `+`, `-`, `*`, `/`, `//`, `DIV`, `%`, `||`, `<->`, `>`, `<`, `>=`, `<=`, `=`, `<>`, `!=`, `^`, `AND`, `OR`, `XOR`, `LIKE`, `NOT`, `REGEXP`, `RLIKE`, `SOUNDS`, <BitWiseOr>, <BitWiseAnd>, <BitWiseXor>, <ShiftLeft>, <ShiftRight>, `->`, `->>`, `#>`, `#>>`, `?`, `?|`, `?&`, `@>`, `<@`, `@?`, `@@`, `#-`, <Factorial>, <SquareRoot>, <BitWiseNot>, <CubeRoot>, <Abs>, `CAST`, `TRY_CAST`, `DATE_ADD`, `DATE_DIFF`, `DATE_SUB`, `DATE_TRUNC`, `DATE`, `TIMESTAMP`, or 31 more ...
| |
| while parsing `SELECT ...`

Expand Down Expand Up @@ -865,7 +865,7 @@ error:
--> SQL:1:65
|
1 | CREATE FUNCTION IF NOT EXISTS isnotempty AS(p) -> not(is_null(p)
| ------ -- ---- ^ unexpected end of input, expecting `)`, `IGNORE`, `RESPECT`, `OVER`, `(`, `IS`, `NOT`, `IN`, `EXISTS`, `BETWEEN`, `+`, `-`, `*`, `/`, `//`, `DIV`, `%`, `||`, `<->`, `>`, `<`, `>=`, `<=`, `=`, `<>`, `!=`, `^`, `AND`, `OR`, `XOR`, `LIKE`, `REGEXP`, `RLIKE`, `SOUNDS`, <BitWiseOr>, <BitWiseAnd>, <BitWiseXor>, <ShiftLeft>, <ShiftRight>, `->`, `->>`, `#>`, `#>>`, `?`, `?|`, `?&`, `@>`, `<@`, `@?`, `@@`, `#-`, <Factorial>, <SquareRoot>, <BitWiseNot>, <CubeRoot>, <Abs>, `CAST`, `TRY_CAST`, `DATE_ADD`, `DATE_SUB`, or 35 more ...
| ------ -- ---- ^ unexpected end of input, expecting `)`, `IGNORE`, `RESPECT`, `OVER`, `(`, `IS`, `NOT`, `IN`, `EXISTS`, `BETWEEN`, `+`, `-`, `*`, `/`, `//`, `DIV`, `%`, `||`, `<->`, `>`, `<`, `>=`, `<=`, `=`, `<>`, `!=`, `^`, `AND`, `OR`, `XOR`, `LIKE`, `REGEXP`, `RLIKE`, `SOUNDS`, <BitWiseOr>, <BitWiseAnd>, <BitWiseXor>, <ShiftLeft>, <ShiftRight>, `->`, `->>`, `#>`, `#>>`, `?`, `?|`, `?&`, `@>`, `<@`, `@?`, `@@`, `#-`, <Factorial>, <SquareRoot>, <BitWiseNot>, <CubeRoot>, <Abs>, `CAST`, `TRY_CAST`, `DATE_ADD`, `DATE_DIFF`, or 36 more ...
| | | | |
| | | | while parsing `(<expr> [, ...])`
| | | while parsing expression
Expand Down
6 changes: 3 additions & 3 deletions src/query/expression/src/types/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ pub const TIMESTAMP_MIN: i64 = -30610224000000000;
/// Maximum valid timestamp `9999-12-31 23:59:59.999999`, represented by the microsecs offset from 1970-01-01.
pub const TIMESTAMP_MAX: i64 = 253402300799999999;

pub const MICROS_IN_A_SEC: i64 = 1_000_000;
pub const MICROS_IN_A_MILLI: i64 = 1_000;
pub const MICROS_PER_SEC: i64 = 1_000_000;
pub const MICROS_PER_MILLI: i64 = 1_000;

pub const PRECISION_MICRO: u8 = 6;
pub const PRECISION_MILLI: u8 = 3;
Expand Down Expand Up @@ -262,7 +262,7 @@ impl ArgType for TimestampType {
}

pub fn microseconds_to_seconds(micros: i64) -> i64 {
micros / MICROS_IN_A_SEC
micros / MICROS_PER_SEC
}

pub fn microseconds_to_days(micros: i64) -> i32 {
Expand Down
Loading

0 comments on commit 5d67b7b

Please sign in to comment.