MCPcopy Create free account
hub / github.com/apache/datafusion / interval_to_mysql_expr

Method interval_to_mysql_expr

datafusion/sql/src/unparser/expr.rs:1529–1648  ·  view source on GitHub ↗

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,
    )

Source from the content-addressed store, hash-verified

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

Callers 1

Calls 4

newFunction · 0.85
valueFunction · 0.85
IntervalEnum · 0.50
to_stringMethod · 0.45

Tested by

no test coverage detected