Skip to content

Commit bed61d2

Browse files
authored
fix(query): Correct sign extension handling in months_days_micros struct (#17086)
Casting days to u32 before casting to i128 to prevent sign extension. Casting microseconds to u64 before casting to i128 to prevent sign extension.
1 parent f7a4a5d commit bed61d2

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

src/common/column/src/types/native.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,10 @@ pub struct months_days_micros(pub i128);
271271
impl months_days_micros {
272272
pub fn new(months: i32, days: i32, microseconds: i64) -> Self {
273273
let months_bits = (months as i128) << 96;
274-
let days_bits = (days as i128) << 64;
275-
let micros_bits = microseconds as i128;
274+
// converting to u32 before i128 ensures we’re working with the raw, unsigned bit pattern of the i32 value,
275+
// preventing unwanted sign extension when that value is later used within the i128.
276+
let days_bits = ((days as u32) as i128) << 64;
277+
let micros_bits = (microseconds as u64) as i128;
276278

277279
Self(months_bits | days_bits | micros_bits)
278280
}

tests/sqllogictests/suites/query/functions/02_0079_function_interval.test

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ query TT
1111
select * from t order by c1;
1212
----
1313
-1 year -1 month 0:00:00.000001
14-
-1 month -1 day -1:00:00 0:00:00.001
14+
-1 month -1:00:00 0:00:00.001
1515

1616
onlyif http
1717
statement error 1006
@@ -22,3 +22,9 @@ query T
2222
select to_interval('1 month 1 hour 1 microsecond');
2323
----
2424
1 month 1:00:00.000001
25+
26+
onlyif http
27+
query T
28+
select to_interval('1 month 1 hour 1 microsecond ago');
29+
----
30+
-1 month -1:00:00.000001

0 commit comments

Comments
 (0)