risingwavelabs/risingwave · error

failed to parse the interval

Error message

failed to parse the interval

What it means

For AS OF PROCESS TIME WITH INTERVAL clauses, to_batch_query_epoch parses the interval string with Interval::parse_with_fields using the declared leading field. If the string is not a valid interval for that field, the error is masked with this generic "failed to parse the interval" message.

Solutions

  1. Use a valid interval literal compatible with the leading field, e.g. INTERVAL '1' DAY.
  2. Match the leading field to the unit in the value (e.g. WITH INTERVAL '2' HOUR for hours).
  3. Escape/quote the interval correctly in the SQL-generating code.

Example fix

// before
AS OF PROCESS TIME WITH INTERVAL 'yesterday' DAY
// after
AS OF PROCESS TIME WITH INTERVAL '1' DAY
Defensive patterns

Strategy: validation

Validate before calling

// validate interval literal against leading field before query
let (value, field) = ("1", "DAY");
assert!(value.chars().all(|c| c.is_ascii_digit() || c == ' '), "interval value must be numeric");

Type guard

fn is_numeric_interval(v: &str) -> bool { !v.trim().is_empty() && v.trim().chars().all(|c| c.is_ascii_digit() || c == '.' ) }

Try / catch

match res {
    Err(e) if e.to_string().contains("failed to parse the interval") => eprintln!("use a numeric interval literal matching the leading field, e.g. INTERVAL '1' DAY"),
    other => other?,
}

Prevention

When it happens

Trigger: A time travel query like `... AS OF PROCESS TIME WITH INTERVAL 'xyz' DAY` where the interval literal fails Interval::parse_with_fields for the given leading field.

Common situations: Malformed interval literals (non-numeric text, wrong units for the leading field, e.g. '1 hour' when the leading field is DAY), quotes or whitespace issues in generated SQL.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

                    }
                })??
            } else {
                date_time.timestamp_tz()
            }
        }
        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>> {

View on GitHub (pinned to 6469eb736d)