MySQL requires INTERVAL sql to be in the format: INTERVAL 1 YEAR + INTERVAL 1 MONTH + INTERVAL 1 DAY etc ` ` Interval sequence can't be wrapped in brackets - (INTERVAL 1 YEAR + INTERVAL 1 MONTH ...) so we need to generate a single INTERVAL expression so it works correct for interval subtraction cases MySQL supports the DAY
(
&self,
months: i32,
days: i32,
microseconds: i64,
)
| 1527 | /// MySQL supports the DAY_MICROSECOND unit type (format is DAYS HOURS:MINUTES:SECONDS.MICROSECONDS), but it is not supported by sqlparser |
| 1528 | /// so we calculate the best single interval to represent the provided duration |
| 1529 | fn interval_to_mysql_expr( |
| 1530 | &self, |
| 1531 | months: i32, |
| 1532 | days: i32, |
| 1533 | microseconds: i64, |
| 1534 | ) -> Result<ast::Expr> { |
| 1535 | // MONTH only |
| 1536 | if months != 0 && days == 0 && microseconds == 0 { |
| 1537 | let interval = Interval { |
| 1538 | value: Box::new(ast::Expr::value(ast::Value::Number( |
| 1539 | months.to_string(), |
| 1540 | false, |
| 1541 | ))), |
| 1542 | leading_field: Some(ast::DateTimeField::Month), |
| 1543 | leading_precision: None, |
| 1544 | last_field: None, |
| 1545 | fractional_seconds_precision: None, |
| 1546 | }; |
| 1547 | return Ok(ast::Expr::Interval(interval)); |
| 1548 | } else if months != 0 { |
| 1549 | return not_impl_err!( |
| 1550 | "Unsupported Interval scalar with both Month and DayTime for IntervalStyle::MySQL" |
| 1551 | ); |
| 1552 | } |
| 1553 | |
| 1554 | // DAY only |
| 1555 | if microseconds == 0 { |
| 1556 | let interval = Interval { |
| 1557 | value: Box::new(ast::Expr::value(ast::Value::Number( |
| 1558 | days.to_string(), |
| 1559 | false, |
| 1560 | ))), |
| 1561 | leading_field: Some(ast::DateTimeField::Day), |
| 1562 | leading_precision: None, |
| 1563 | last_field: None, |
| 1564 | fractional_seconds_precision: None, |
| 1565 | }; |
| 1566 | return Ok(ast::Expr::Interval(interval)); |
| 1567 | } |
| 1568 | |
| 1569 | // Calculate the best single interval to represent the provided days and microseconds |
| 1570 | |
| 1571 | let microseconds = microseconds + (days as i64 * 24 * 60 * 60 * 1_000_000); |
| 1572 | |
| 1573 | if microseconds % 1_000_000 != 0 { |
| 1574 | let interval = Interval { |
| 1575 | value: Box::new(ast::Expr::value(ast::Value::Number( |
| 1576 | microseconds.to_string(), |
| 1577 | false, |
| 1578 | ))), |
| 1579 | leading_field: Some(ast::DateTimeField::Microsecond), |
| 1580 | leading_precision: None, |
| 1581 | last_field: None, |
| 1582 | fractional_seconds_precision: None, |
| 1583 | }; |
| 1584 | return Ok(ast::Expr::Interval(interval)); |
| 1585 | } |
| 1586 |
no test coverage detected