Skip to content

Commit 5e0c863

Browse files
committed
Flip interval field ordering (apache#5654)
1 parent f276528 commit 5e0c863

File tree

4 files changed

+49
-49
lines changed

4 files changed

+49
-49
lines changed

arrow-arith/src/numeric.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,8 +1346,10 @@ mod tests {
13461346
IntervalMonthDayNanoType::make_value(35, -19, 41899000000000000)
13471347
])
13481348
);
1349-
let a = IntervalMonthDayNanoArray::from(vec![i64::MAX as i128]);
1350-
let b = IntervalMonthDayNanoArray::from(vec![1]);
1349+
let max_nanos = IntervalMonthDayNanoType::make_value(0, 0, i64::MAX);
1350+
let a = IntervalMonthDayNanoArray::from(vec![max_nanos]);
1351+
let one_nanos = IntervalMonthDayNanoType::make_value(0, 0, 1);
1352+
let b = IntervalMonthDayNanoArray::from(vec![one_nanos]);
13511353
let err = add(&a, &b).unwrap_err().to_string();
13521354
assert_eq!(
13531355
err,

arrow-array/src/types.rs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,11 @@ Each field is independent (e.g. there is no constraint that the quantity of
264264
nanoseconds represents less than a day's worth of time).
265265
266266
```text
267-
┌──────────────────────────────┬───────────────────────────┐
268-
Nanos Days Months
269-
(64 bits) │ (32 bits) │ (32 bits)
270-
└──────────────────────────────┴───────────────────────────┘
271-
0 63 95 127 bit offset
267+
┌────────────────────────────┬─────────────────────────────┐
268+
Months Days Nanos
269+
(32 bits) │ (32 bits) (64 bits)
270+
└────────────────────────────┴─────────────────────────────┘
271+
0 32 64 128 bit offset
272272
```
273273
Please see the [Arrow Spec](https://github.com/apache/arrow/blob/081b4022fe6f659d8765efc82b3f4787c5039e3c/format/Schema.fbs#L409-L415) for more details
274274
@@ -290,9 +290,9 @@ representation which is fast and efficient, but leads
290290
to potentially surprising results.
291291
292292
For example a
293-
`IntervalMonthDayNano` of `1 month` will compare as **greater** than a
294-
`IntervalMonthDayNano` of `100 days` because the binary representation of `1 month`
295-
is larger than the binary representation of 100 days.
293+
`IntervalMonthDayNano` of `1 month` will compare as **less** than a
294+
`IntervalMonthDayNano` of `1 days` because the binary representation of `1 month`
295+
is smaller than the binary representation of 1 days.
296296
"#
297297
);
298298
make_type!(
@@ -928,13 +928,14 @@ impl IntervalDayTimeType {
928928
int32_t milliseconds = 0;
929929
...
930930
}
931-
64 56 48 40 32 24 16 8 0
932-
+-------+-------+-------+-------+-------+-------+-------+-------+
933-
| days | milliseconds |
934-
+-------+-------+-------+-------+-------+-------+-------+-------+
931+
┌──────────────┬──────────────┐
932+
│ Days │ Milliseconds │
933+
│ (32 bits) │ (32 bits) │
934+
└──────────────┴──────────────┘
935+
0 31 63 bit offset
935936
*/
936-
let m = millis as u64 & u32::MAX as u64;
937-
let d = (days as u64 & u32::MAX as u64) << 32;
937+
let m = (millis as u64 & u32::MAX as u64) << 32;
938+
let d = days as u64 & u32::MAX as u64;
938939
(m | d) as <IntervalDayTimeType as ArrowPrimitiveType>::Native
939940
}
940941

@@ -945,8 +946,8 @@ impl IntervalDayTimeType {
945946
/// * `i` - The IntervalDayTimeType to convert
946947
#[inline]
947948
pub fn to_parts(i: <IntervalDayTimeType as ArrowPrimitiveType>::Native) -> (i32, i32) {
948-
let days = (i >> 32) as i32;
949-
let ms = i as i32;
949+
let days = i as i32;
950+
let ms = (i >> 32) as i32;
950951
(days, ms)
951952
}
952953
}
@@ -972,14 +973,16 @@ impl IntervalMonthDayNanoType {
972973
int32_t days;
973974
int64_t nanoseconds;
974975
}
975-
128 112 96 80 64 48 32 16 0
976-
+-------+-------+-------+-------+-------+-------+-------+-------+
977-
| months | days | nanos |
978-
+-------+-------+-------+-------+-------+-------+-------+-------+
976+
┌───────────────┬─────────────┬─────────────────────────────┐
977+
│ Months │ Days │ Nanos │
978+
│ (32 bits) │ (32 bits) │ (64 bits) │
979+
└───────────────┴─────────────┴─────────────────────────────┘
980+
0 32 64 128 bit offset
981+
979982
*/
980-
let m = (months as u128 & u32::MAX as u128) << 96;
981-
let d = (days as u128 & u32::MAX as u128) << 64;
982-
let n = nanos as u128 & u64::MAX as u128;
983+
let m = months as u128 & u32::MAX as u128;
984+
let d = (days as u128 & u32::MAX as u128) << 32;
985+
let n = (nanos as u128 & u64::MAX as u128) << 64;
983986
(m | d | n) as <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native
984987
}
985988

@@ -992,9 +995,9 @@ impl IntervalMonthDayNanoType {
992995
pub fn to_parts(
993996
i: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
994997
) -> (i32, i32, i64) {
995-
let months = (i >> 96) as i32;
996-
let days = (i >> 64) as i32;
997-
let nanos = i as i64;
998+
let months = i as i32;
999+
let days = (i >> 32) as i32;
1000+
let nanos = (i >> 64) as i64;
9981001
(months, days, nanos)
9991002
}
10001003
}

arrow-ord/src/comparison.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,18 +1714,17 @@ mod tests {
17141714
IntervalDayTimeType::make_value(1, 3000),
17151715
// 90M milliseconds
17161716
IntervalDayTimeType::make_value(0, 90_000_000),
1717+
IntervalDayTimeType::make_value(4, 10),
17171718
],
17181719
vec![
17191720
IntervalDayTimeType::make_value(0, 1000),
17201721
IntervalDayTimeType::make_value(1, 0),
17211722
IntervalDayTimeType::make_value(10, 0),
17221723
IntervalDayTimeType::make_value(2, 1),
1723-
// NB even though 1 day is less than 90M milliseconds long,
1724-
// it compares as greater because the underlying type stores
1725-
// days and milliseconds as different fields
17261724
IntervalDayTimeType::make_value(0, 12),
1725+
IntervalDayTimeType::make_value(56, 10),
17271726
],
1728-
vec![false, true, true, true ,false]
1727+
vec![true, false, false, false, false, true]
17291728
);
17301729

17311730
cmp_vec!(
@@ -1771,7 +1770,7 @@ mod tests {
17711770
// 100 days (note is treated as greater than 1 month as the underlying integer representation)
17721771
IntervalMonthDayNanoType::make_value(0, 100, 0),
17731772
],
1774-
vec![false, false, true, false, false]
1773+
vec![false, true, true, true, true]
17751774
);
17761775
}
17771776

arrow-ord/src/ord.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,12 @@ pub mod tests {
227227

228228
let cmp = build_compare(&array, &array).unwrap();
229229

230-
assert_eq!(Ordering::Less, cmp(0, 1));
231-
assert_eq!(Ordering::Greater, cmp(1, 0));
232-
233-
// somewhat confusingly, while 90M milliseconds is more than 1 day,
234-
// it will compare less as the comparison is done on the underlying
235-
// values not field by field
236-
assert_eq!(Ordering::Greater, cmp(1, 2));
237-
assert_eq!(Ordering::Less, cmp(2, 1));
230+
// Ordering is based on the underlying values
231+
// leading to potentially surprising results
232+
assert_eq!(Ordering::Greater, cmp(0, 1));
233+
assert_eq!(Ordering::Less, cmp(1, 0));
234+
assert_eq!(Ordering::Less, cmp(1, 2));
235+
assert_eq!(Ordering::Greater, cmp(2, 1));
238236
}
239237

240238
#[test]
@@ -271,14 +269,12 @@ pub mod tests {
271269

272270
let cmp = build_compare(&array, &array).unwrap();
273271

274-
assert_eq!(Ordering::Less, cmp(0, 1));
275-
assert_eq!(Ordering::Greater, cmp(1, 0));
276-
277-
// somewhat confusingly, while 100 days is more than 1 month in all cases
278-
// it will compare less as the comparison is done on the underlying
279-
// values not field by field
280-
assert_eq!(Ordering::Greater, cmp(1, 2));
281-
assert_eq!(Ordering::Less, cmp(2, 1));
272+
// Ordering is based on the underlying values
273+
// leading to potentially surprising results
274+
assert_eq!(Ordering::Greater, cmp(0, 1));
275+
assert_eq!(Ordering::Less, cmp(1, 0));
276+
assert_eq!(Ordering::Less, cmp(1, 2));
277+
assert_eq!(Ordering::Greater, cmp(2, 1));
282278
}
283279

284280
#[test]

0 commit comments

Comments
 (0)