Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(common): interval overflow panic / wrap during comparison and justify #8556

Merged
merged 11 commits into from
Mar 16, 2023
51 changes: 45 additions & 6 deletions e2e_test/batch/types/interval.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,20 @@ SELECT INTERVAL '3 mins' * 1.5;
00:04:30

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

query TTTTT
query T
select distinct * from (values (interval '30' day), (interval '1' month)) as t;
----
30 days
1 mon

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

query TTTTTT
select interval '1 year 1 month 1 day 1';
Expand Down Expand Up @@ -119,3 +119,42 @@ query T
select '1 mons 1 days 00:00:00.0000001'::INTERVAL;
----
1 mon 1 day

# Tests moved from regress tests due to not matching exactly.

# PostgreSQL outputs `-1 mons +1 day` while we output `-1 mons 1 day`.
xiangjinwu marked this conversation as resolved.
Show resolved Hide resolved
# But the main purpose of this test case is ordering of large values.

statement ok
CREATE TABLE INTERVAL_TBL_OF (f1 interval);

statement ok
INSERT INTO INTERVAL_TBL_OF (f1) VALUES
('2147483647 days 2147483647 months'),
('2147483647 days -2147483648 months'),
('1 year'),
('-2147483648 days 2147483647 months'),
('-2147483648 days -2147483648 months');

statement ok
FLUSH;

query TT
SELECT r1.*, r2.*
FROM INTERVAL_TBL_OF r1, INTERVAL_TBL_OF r2
WHERE r1.f1 > r2.f1
ORDER BY r1.f1, r2.f1;
----
-178956970 years -8 mons 2147483647 days -178956970 years -8 mons -2147483648 days
1 year -178956970 years -8 mons -2147483648 days
1 year -178956970 years -8 mons 2147483647 days
178956970 years 7 mons -2147483648 days -178956970 years -8 mons -2147483648 days
178956970 years 7 mons -2147483648 days -178956970 years -8 mons 2147483647 days
178956970 years 7 mons -2147483648 days 1 year
178956970 years 7 mons 2147483647 days -178956970 years -8 mons -2147483648 days
178956970 years 7 mons 2147483647 days -178956970 years -8 mons 2147483647 days
178956970 years 7 mons 2147483647 days 1 year
178956970 years 7 mons 2147483647 days 178956970 years 7 mons -2147483648 days

statement ok
DROP TABLE INTERVAL_TBL_OF;
27 changes: 2 additions & 25 deletions src/common/src/hash/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ use crate::collection::estimate_size::EstimateSize;
use crate::hash::VirtualNode;
use crate::row::{OwnedRow, RowDeserializer};
use crate::types::{
DataType, Decimal, IntervalUnit, NaiveDateTimeWrapper, NaiveDateWrapper, NaiveTimeWrapper,
OrderedF32, OrderedF64, ScalarRef,
DataType, Decimal, NaiveDateTimeWrapper, NaiveDateWrapper, NaiveTimeWrapper, OrderedF32,
OrderedF64, ScalarRef,
};
use crate::util::hash_util::Crc32FastBuilder;
use crate::util::iter_util::ZipEqFast;
Expand Down Expand Up @@ -357,29 +357,6 @@ impl HashKeySerDe<'_> for Decimal {
}
}

impl HashKeySerDe<'_> for IntervalUnit {
type S = [u8; 16];

fn serialize(mut self) -> Self::S {
self.justify_interval();
let mut ret = [0; 16];
ret[0..4].copy_from_slice(&self.get_months().to_ne_bytes());
ret[4..8].copy_from_slice(&self.get_days().to_ne_bytes());
ret[8..16].copy_from_slice(&self.get_usecs().to_ne_bytes());

ret
}

fn deserialize<R: Read>(source: &mut R) -> Self {
let value = Self::read_fixed_size_bytes::<R, 16>(source);
IntervalUnit::from_month_day_usec(
i32::from_ne_bytes(value[0..4].try_into().unwrap()),
i32::from_ne_bytes(value[4..8].try_into().unwrap()),
i64::from_ne_bytes(value[8..16].try_into().unwrap()),
)
}
}

impl<'a> HashKeySerDe<'a> for &'a str {
type S = Vec<u8>;

Expand Down
Loading