databendlabs/databend · info

epoch date is valid

Error message

epoch date is valid

What it means

date_from_days converts internal epoch-day integers to a chrono NaiveDate. The first expect — 'epoch date is valid' — builds the fixed base date 1970-01-01. This can only panic if chrono itself fails to construct the epoch date, which is impossible with a valid chrono build; it exists so the Option from from_ymd_opt is explicitly handled. In practice it is an unreachable internal invariant.

Solutions

  1. No caller action needed; treat a panic here as a chrono/dependency bug.
  2. If refactoring, keep the base date within chrono's civil range (years 0..=9999 for NaiveDate construction bounds).
Defensive patterns

Strategy: validation

Validate before calling

// Not required; this panic is unreachable. Validate SQL inputs instead:
check_date(days)?;
let d = date_from_days(days);

Prevention

When it happens

Trigger: Effectively never triggered by callers; would only fire if the chrono crate were broken or the constant 1970/1/1 were out of chrono's supported range (it is not).

Common situations: Not user-reachable; seen only when debugging chrono version mismatches or when refactoring the constants to an invalid date.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/d540308e43895698. Report an issue: GitHub.

Appendix: source

Thrown at src/query/expression/src/types/date.rs:50

use super::number::SimpleDomain;
use crate::ColumnBuilder;
use crate::ScalarRef;
use crate::property::Domain;
use crate::values::Column;
use crate::values::Scalar;

pub const DATE_FORMAT: &str = "%Y-%m-%d";
/// SQL DATE bounds, represented as days since 1970-01-01.
/// Calendar inputs and computed DATE values both use years 0001..=9999.
/// 0001-01-01
pub const DATE_MIN: i32 = -719_162;
/// 9999-12-31
pub const DATE_MAX: i32 = 2_932_896;

/// Converts internal epoch days. SQL inputs must pass `check_date` first.
pub fn date_from_days(days: impl AsPrimitive<i64>) -> NaiveDate {
    NaiveDate::from_ymd_opt(1970, 1, 1)
        .expect("epoch date is valid")
        .checked_add_signed(TimeDelta::days(days.as_()))
        .expect("date day count is inside the chrono civil range")
}

/// Preserve the legacy conversion policy: either bound overflow maps to DATE_MIN.
#[inline]
pub fn clamp_date(days: i64) -> i32 {
    if (DATE_MIN as i64..=DATE_MAX as i64).contains(&days) {
        days as i32
    } else {
        DATE_MIN
    }
}

/// Validate the SQL DATE range without silently changing the value.
#[inline]
pub fn check_date(days: i64) -> Result<i32, String> {
    if (i64::from(DATE_MIN)..=i64::from(DATE_MAX)).contains(&days) {

View on GitHub (pinned to 288d84d76e)