Skip to content

Commit e61af5a

Browse files
authored
fix(common): interval overflow panic / wrap during comparison and justify (risingwavelabs#8556)
1 parent 04a2885 commit e61af5a

File tree

3 files changed

+321
-105
lines changed

3 files changed

+321
-105
lines changed

e2e_test/batch/types/interval.slt.part

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,20 @@ SELECT INTERVAL '3 mins' * 1.5;
7474
00:04:30
7575

7676
# https://github.com/risingwavelabs/risingwave/issues/3873
77-
query TTTTT
77+
query T
7878
select distinct * from (values (interval '1' month), (interval '30' day)) as t;
7979
----
80-
30 days
80+
1 mon
8181

82-
query TTTTT
82+
query T
8383
select distinct * from (values (interval '30' day), (interval '1' month)) as t;
8484
----
85-
30 days
85+
1 mon
8686

87-
query TTTTT
87+
query T
8888
select distinct * from (values (interval '720' hour), (interval '1' month)) as t;
8989
----
90-
30 days
90+
1 mon
9191

9292
query TTTTTT
9393
select interval '1 year 1 month 1 day 1';
@@ -119,3 +119,44 @@ query T
119119
select '1 mons 1 days 00:00:00.0000001'::INTERVAL;
120120
----
121121
1 mon 1 day
122+
123+
# Tests moved from regress tests due to not matching exactly.
124+
125+
# In mixed sign intervals, PostgreSQL displays positive sign after negative
126+
# (e.g. `-1 mons +1 day`) while we display it without sign
127+
# (e.g. `-1 mons 1 day`).
128+
# But the main purpose of this test case is ordering of large values.
129+
130+
statement ok
131+
CREATE TABLE INTERVAL_TBL_OF (f1 interval);
132+
133+
statement ok
134+
INSERT INTO INTERVAL_TBL_OF (f1) VALUES
135+
('2147483647 days 2147483647 months'),
136+
('2147483647 days -2147483648 months'),
137+
('1 year'),
138+
('-2147483648 days 2147483647 months'),
139+
('-2147483648 days -2147483648 months');
140+
141+
statement ok
142+
FLUSH;
143+
144+
query TT
145+
SELECT r1.*, r2.*
146+
FROM INTERVAL_TBL_OF r1, INTERVAL_TBL_OF r2
147+
WHERE r1.f1 > r2.f1
148+
ORDER BY r1.f1, r2.f1;
149+
----
150+
-178956970 years -8 mons 2147483647 days -178956970 years -8 mons -2147483648 days
151+
1 year -178956970 years -8 mons -2147483648 days
152+
1 year -178956970 years -8 mons 2147483647 days
153+
178956970 years 7 mons -2147483648 days -178956970 years -8 mons -2147483648 days
154+
178956970 years 7 mons -2147483648 days -178956970 years -8 mons 2147483647 days
155+
178956970 years 7 mons -2147483648 days 1 year
156+
178956970 years 7 mons 2147483647 days -178956970 years -8 mons -2147483648 days
157+
178956970 years 7 mons 2147483647 days -178956970 years -8 mons 2147483647 days
158+
178956970 years 7 mons 2147483647 days 1 year
159+
178956970 years 7 mons 2147483647 days 178956970 years 7 mons -2147483648 days
160+
161+
statement ok
162+
DROP TABLE INTERVAL_TBL_OF;

src/common/src/hash/key.rs

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ use crate::collection::estimate_size::EstimateSize;
3939
use crate::hash::VirtualNode;
4040
use crate::row::{OwnedRow, RowDeserializer};
4141
use crate::types::{
42-
DataType, Decimal, IntervalUnit, NaiveDateTimeWrapper, NaiveDateWrapper, NaiveTimeWrapper,
43-
OrderedF32, OrderedF64, ScalarRef,
42+
DataType, Decimal, NaiveDateTimeWrapper, NaiveDateWrapper, NaiveTimeWrapper, OrderedF32,
43+
OrderedF64, ScalarRef,
4444
};
4545
use crate::util::hash_util::Crc32FastBuilder;
4646
use crate::util::iter_util::ZipEqFast;
@@ -357,29 +357,6 @@ impl HashKeySerDe<'_> for Decimal {
357357
}
358358
}
359359

360-
impl HashKeySerDe<'_> for IntervalUnit {
361-
type S = [u8; 16];
362-
363-
fn serialize(mut self) -> Self::S {
364-
self.justify_interval();
365-
let mut ret = [0; 16];
366-
ret[0..4].copy_from_slice(&self.get_months().to_ne_bytes());
367-
ret[4..8].copy_from_slice(&self.get_days().to_ne_bytes());
368-
ret[8..16].copy_from_slice(&self.get_usecs().to_ne_bytes());
369-
370-
ret
371-
}
372-
373-
fn deserialize<R: Read>(source: &mut R) -> Self {
374-
let value = Self::read_fixed_size_bytes::<R, 16>(source);
375-
IntervalUnit::from_month_day_usec(
376-
i32::from_ne_bytes(value[0..4].try_into().unwrap()),
377-
i32::from_ne_bytes(value[4..8].try_into().unwrap()),
378-
i64::from_ne_bytes(value[8..16].try_into().unwrap()),
379-
)
380-
}
381-
}
382-
383360
impl<'a> HashKeySerDe<'a> for &'a str {
384361
type S = Vec<u8>;
385362

0 commit comments

Comments
 (0)