risingwavelabs/risingwave · error

invalid timestamp

Error message

invalid timestamp

What it means

After computing now - interval_sec for AS OF PROCESS TIME WITH INTERVAL, checked_sub guards against underflowing the Unix timestamp (huge intervals pushing below i64 seconds range). On underflow the code returns this "invalid timestamp" error via ok_or_else.

Solutions

  1. Reduce the interval to a realistic duration.
  2. Verify the unit/leading field in the interval literal matches intent.
  3. Clamp or validate interval magnitude in application code before issuing the query.

Example fix

// before
AS OF PROCESS TIME WITH INTERVAL '100000000000' DAY
// after
AS OF PROCESS TIME WITH INTERVAL '30' DAY
Defensive patterns

Strategy: validation

Validate before calling

// bound interval magnitude before issuing query
let max_days: i64 = 3650;
assert!(days <= max_days, "AS OF interval too large");

Type guard

fn interval_in_range(days: i64) -> bool { (0..=3650).contains(&days) }

Try / catch

match res {
    Err(e) if e.to_string().contains("invalid timestamp") => eprintln!("interval too large; computed AS OF time underflowed"),
    other => other?,
}

Prevention

When it happens

Trigger: AS OF PROCESS TIME WITH INTERVAL with an enormous interval (e.g. INTERVAL '999999999999' DAY) whose seconds exceed i64 range when subtracted from the current Unix timestamp.

Common situations: Accidental unit mistakes in generated SQL (microseconds treated as days), absurdly large interval literals in tests or scripts.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/70ee1af77c48a5d0. Report an issue: GitHub.

Appendix: source

Thrown at src/frontend/src/optimizer/plan_node/utils.rs:567

        }
        AsOf::VersionNum(_) | AsOf::VersionString(_) => {
            return Err(ErrorCode::NotSupported(
                "AS OF VERSION is not supported".to_owned(),
                "please use AS OF TIMESTAMP".to_owned(),
            )
            .into());
        }
        AsOf::ProcessTimeWithInterval((value, leading_field)) => {
            let interval = Interval::parse_with_fields(
                value,
                Some(crate::Binder::bind_date_time_field(*leading_field)),
            )
            .map_err(|_| anyhow!("failed to parse the interval"))?;
            let interval_sec = (interval.epoch_in_micros() / 1_000_000) as i64;
            chrono::Utc::now()
                .timestamp()
                .checked_sub(interval_sec)
                .ok_or_else(|| anyhow!("invalid timestamp"))?
        }
    };
    Ok(Some(PbBatchQueryEpoch {
        epoch: Some(batch_query_epoch::PbEpoch::TimeTravel(
            unix_timestamp_sec_to_epoch(timestamp).0,
        )),
    }))
}

pub fn to_iceberg_time_travel_as_of(
    a: &Option<AsOf>,
    timezone: &String,
) -> Result<Option<IcebergTimeTravelInfo>> {
    Ok(match a {
        Some(AsOf::VersionNum(v)) => Some(IcebergTimeTravelInfo::Version(*v)),
        Some(AsOf::TimestampNum(ts)) => Some(IcebergTimeTravelInfo::TimestampMs(ts * 1000)),
        Some(AsOf::VersionString(_)) => {
            bail!("Unsupported version string in iceberg time travel")

View on GitHub (pinned to 6469eb736d)