{"record":{"id":"70ee1af77c48a5d0","repo":"risingwavelabs/risingwave","slug":"invalid-timestamp","errorCode":null,"errorMessage":"invalid timestamp","messagePattern":"invalid timestamp","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/plan_node/utils.rs","lineNumber":567,"sourceCode":"        }\n        AsOf::VersionNum(_) | AsOf::VersionString(_) => {\n            return Err(ErrorCode::NotSupported(\n                \"AS OF VERSION is not supported\".to_owned(),\n                \"please use AS OF TIMESTAMP\".to_owned(),\n            )\n            .into());\n        }\n        AsOf::ProcessTimeWithInterval((value, leading_field)) => {\n            let interval = Interval::parse_with_fields(\n                value,\n                Some(crate::Binder::bind_date_time_field(*leading_field)),\n            )\n            .map_err(|_| anyhow!(\"failed to parse the interval\"))?;\n            let interval_sec = (interval.epoch_in_micros() / 1_000_000) as i64;\n            chrono::Utc::now()\n                .timestamp()\n                .checked_sub(interval_sec)\n                .ok_or_else(|| anyhow!(\"invalid timestamp\"))?\n        }\n    };\n    Ok(Some(PbBatchQueryEpoch {\n        epoch: Some(batch_query_epoch::PbEpoch::TimeTravel(\n            unix_timestamp_sec_to_epoch(timestamp).0,\n        )),\n    }))\n}\n\npub fn to_iceberg_time_travel_as_of(\n    a: &Option<AsOf>,\n    timezone: &String,\n) -> Result<Option<IcebergTimeTravelInfo>> {\n    Ok(match a {\n        Some(AsOf::VersionNum(v)) => Some(IcebergTimeTravelInfo::Version(*v)),\n        Some(AsOf::TimestampNum(ts)) => Some(IcebergTimeTravelInfo::TimestampMs(ts * 1000)),\n        Some(AsOf::VersionString(_)) => {\n            bail!(\"Unsupported version string in iceberg time travel\")","sourceCodeStart":549,"sourceCodeEnd":585,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/plan_node/utils.rs#L549-L585","documentation":"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.","triggerScenarios":"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.","commonSituations":"Accidental unit mistakes in generated SQL (microseconds treated as days), absurdly large interval literals in tests or scripts.","solutions":["Reduce the interval to a realistic duration.","Verify the unit/leading field in the interval literal matches intent.","Clamp or validate interval magnitude in application code before issuing the query."],"exampleFix":"// before\nAS OF PROCESS TIME WITH INTERVAL '100000000000' DAY\n// after\nAS OF PROCESS TIME WITH INTERVAL '30' DAY","handlingStrategy":"validation","validationCode":"// bound interval magnitude before issuing query\nlet max_days: i64 = 3650;\nassert!(days <= max_days, \"AS OF interval too large\");","typeGuard":"fn interval_in_range(days: i64) -> bool { (0..=3650).contains(&days) }","tryCatchPattern":"match res {\n    Err(e) if e.to_string().contains(\"invalid timestamp\") => eprintln!(\"interval too large; computed AS OF time underflowed\"),\n    other => other?,\n}","preventionTips":["Clamp process-time lookback intervals to sane ranges (minutes to weeks).","Double-check unit conversions in generated SQL (never pass micros where days are expected).","Add load-time validation of configured lookback durations."],"tags":["sql","time-travel","overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}