Skip to content

Commit 65c7b4e

Browse files
authored
Merge pull request #64 from VibeEngineeringAI/fix/timestamp-literal-overflow-panic
fix(query): don't panic on out-of-range timestamp literals
2 parents fd6216c + 49d133f commit 65c7b4e

1 file changed

Lines changed: 41 additions & 4 deletions

File tree

‎src/query/stream_schema_provider.rs‎

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,10 +1251,11 @@ pub fn extract_timestamp_bound(
12511251
};
12521252

12531253
match value {
1254-
ScalarValue::TimestampMillisecond(Some(value), _) => Some((
1255-
binexpr.op,
1256-
DateTime::from_timestamp_millis(*value).unwrap().naive_utc(),
1257-
)),
1254+
// Out-of-range literals (reachable from SQL, e.g.
1255+
// `to_timestamp_millis(9223372036854775807)`) yield no bound.
1256+
ScalarValue::TimestampMillisecond(Some(value), _) => {
1257+
DateTime::from_timestamp_millis(*value).map(|time| (binexpr.op, time.naive_utc()))
1258+
}
12581259
ScalarValue::TimestampNanosecond(Some(value), _) => Some((
12591260
binexpr.op,
12601261
DateTime::from_timestamp_nanos(*value).naive_utc(),
@@ -1969,6 +1970,42 @@ mod tests {
19691970
assert!(!res)
19701971
}
19711972

1973+
#[test]
1974+
fn out_of_range_millisecond_literal_yields_no_bound() {
1975+
let binexpr = BinaryExpr {
1976+
left: Box::new(Expr::Column("p_timestamp".into())),
1977+
op: Operator::GtEq,
1978+
right: Box::new(Expr::Literal(
1979+
ScalarValue::TimestampMillisecond(Some(i64::MAX), None),
1980+
None,
1981+
)),
1982+
};
1983+
1984+
assert_eq!(extract_timestamp_bound(&binexpr, &None), None);
1985+
assert!(!super::expr_in_boundary(&Expr::BinaryExpr(binexpr)));
1986+
}
1987+
1988+
#[tokio::test]
1989+
async fn out_of_range_millisecond_literal_in_sql_does_not_panic() {
1990+
let schema = Arc::new(Schema::new(vec![Field::new(
1991+
"p_timestamp",
1992+
DataType::Timestamp(arrow_schema::TimeUnit::Millisecond, None),
1993+
false,
1994+
)]));
1995+
let context = SessionContext::new();
1996+
context
1997+
.register_table("logs", Arc::new(TestParquetProvider { schema }))
1998+
.unwrap();
1999+
2000+
context
2001+
.sql("SELECT * FROM logs WHERE p_timestamp >= to_timestamp_millis(9223372036854775807)")
2002+
.await
2003+
.unwrap()
2004+
.create_physical_plan()
2005+
.await
2006+
.unwrap();
2007+
}
2008+
19722009
#[test]
19732010
fn timestamp_in_milliseconds() {
19742011
let binexpr = BinaryExpr {

0 commit comments

Comments
 (0)