Skip to content

Commit bb5f12b

Browse files
authored
Make display of interval types more pretty (#6006)
* improve dispaly for interval. * update test in pretty, and fix display problem. * tmp * fix tests in arrow-cast. * fix tests in pretty. * fix style.
1 parent 8f76248 commit bb5f12b

File tree

3 files changed

+196
-80
lines changed

3 files changed

+196
-80
lines changed

arrow-cast/src/cast/mod.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4314,8 +4314,8 @@ mod tests {
43144314
IntervalUnit::YearMonth,
43154315
IntervalYearMonthArray,
43164316
vec![
4317-
Some("1 years 1 mons 0 days 0 hours 0 mins 0.00 secs"),
4318-
Some("2 years 7 mons 0 days 0 hours 0 mins 0.00 secs"),
4317+
Some("1 years 1 mons"),
4318+
Some("2 years 7 mons"),
43194319
None,
43204320
None,
43214321
None,
@@ -4338,9 +4338,9 @@ mod tests {
43384338
IntervalUnit::DayTime,
43394339
IntervalDayTimeArray,
43404340
vec![
4341-
Some("0 years 0 mons 390 days 0 hours 0 mins 0.000 secs"),
4342-
Some("0 years 0 mons 930 days 0 hours 0 mins 0.000 secs"),
4343-
Some("0 years 0 mons 30 days 0 hours 0 mins 0.000 secs"),
4341+
Some("390 days"),
4342+
Some("930 days"),
4343+
Some("30 days"),
43444344
None,
43454345
None,
43464346
]
@@ -4366,16 +4366,16 @@ mod tests {
43664366
IntervalUnit::MonthDayNano,
43674367
IntervalMonthDayNanoArray,
43684368
vec![
4369-
Some("0 years 13 mons 1 days 0 hours 0 mins 0.000000000 secs"),
4369+
Some("13 mons 1 days"),
43704370
None,
4371-
Some("0 years 31 mons 35 days 0 hours 0 mins 0.001400000 secs"),
4372-
Some("0 years 0 mons 3 days 0 hours 0 mins 0.000000000 secs"),
4373-
Some("0 years 0 mons 0 days 0 hours 0 mins 8.000000000 secs"),
4371+
Some("31 mons 35 days 0.001400000 secs"),
4372+
Some("3 days"),
4373+
Some("8.000000000 secs"),
43744374
None,
4375-
Some("0 years 0 mons 1 days 0 hours 0 mins 29.800000000 secs"),
4376-
Some("0 years 3 mons 0 days 0 hours 0 mins 1.000000000 secs"),
4377-
Some("0 years 0 mons 0 days 0 hours 8 mins 0.000000000 secs"),
4378-
Some("0 years 63 mons 9 days 19 hours 9 mins 2.222000000 secs"),
4375+
Some("1 days 29.800000000 secs"),
4376+
Some("3 mons 1.000000000 secs"),
4377+
Some("8 mins"),
4378+
Some("63 mons 9 days 19 hours 9 mins 2.222000000 secs"),
43794379
None,
43804380
]
43814381
);

arrow-cast/src/display.rs

Lines changed: 156 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -654,73 +654,189 @@ impl<'a> DisplayIndex for &'a PrimitiveArray<IntervalYearMonthType> {
654654
let years = (interval / 12_f64).floor();
655655
let month = interval - (years * 12_f64);
656656

657-
write!(
658-
f,
659-
"{years} years {month} mons 0 days 0 hours 0 mins 0.00 secs",
660-
)?;
657+
write!(f, "{years} years {month} mons",)?;
661658
Ok(())
662659
}
663660
}
664661

665662
impl<'a> DisplayIndex for &'a PrimitiveArray<IntervalDayTimeType> {
666663
fn write(&self, idx: usize, f: &mut dyn Write) -> FormatResult {
667664
let value = self.value(idx);
665+
let mut first_part = true;
668666

669-
let secs = value.milliseconds / 1_000;
667+
if value.days != 0 {
668+
write!(f, "{} days", value.days)?;
669+
first_part = false;
670+
}
671+
672+
if value.milliseconds != 0 {
673+
let millis_fmt = MillisecondsFormatter {
674+
milliseconds: value.milliseconds,
675+
first_part,
676+
};
677+
678+
f.write_fmt(format_args!("{millis_fmt}"))?;
679+
}
680+
681+
Ok(())
682+
}
683+
}
684+
685+
impl<'a> DisplayIndex for &'a PrimitiveArray<IntervalMonthDayNanoType> {
686+
fn write(&self, idx: usize, f: &mut dyn Write) -> FormatResult {
687+
let value = self.value(idx);
688+
let mut first_part = true;
689+
690+
if value.months != 0 {
691+
write!(f, "{} mons", value.months)?;
692+
first_part = false;
693+
}
694+
695+
if value.days != 0 {
696+
if first_part {
697+
write!(f, "{} days", value.days)?;
698+
first_part = false;
699+
} else {
700+
write!(f, " {} days", value.days)?;
701+
}
702+
}
703+
704+
if value.nanoseconds != 0 {
705+
let nano_fmt = NanosecondsFormatter {
706+
nanoseconds: value.nanoseconds,
707+
first_part,
708+
};
709+
f.write_fmt(format_args!("{nano_fmt}"))?;
710+
}
711+
712+
Ok(())
713+
}
714+
}
715+
716+
struct NanosecondsFormatter {
717+
nanoseconds: i64,
718+
first_part: bool,
719+
}
720+
721+
impl Display for NanosecondsFormatter {
722+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
723+
let mut first_part = self.first_part;
724+
725+
let secs = self.nanoseconds / 1_000_000_000;
670726
let mins = secs / 60;
671727
let hours = mins / 60;
672728

673729
let secs = secs - (mins * 60);
674730
let mins = mins - (hours * 60);
675731

676-
let milliseconds = value.milliseconds % 1_000;
732+
let nanoseconds = self.nanoseconds % 1_000_000_000;
677733

678-
let secs_sign = if secs < 0 || milliseconds < 0 {
679-
"-"
680-
} else {
681-
""
682-
};
734+
if hours != 0 {
735+
if first_part {
736+
write!(f, "{} hours", hours)?;
737+
first_part = false;
738+
} else {
739+
write!(f, " {} hours", hours)?;
740+
}
741+
}
742+
743+
if mins != 0 {
744+
if first_part {
745+
write!(f, "{} mins", mins)?;
746+
first_part = false;
747+
} else {
748+
write!(f, " {} mins", mins)?;
749+
}
750+
}
751+
752+
if secs != 0 || nanoseconds != 0 {
753+
let secs_sign = if secs < 0 || nanoseconds < 0 { "-" } else { "" };
754+
755+
if first_part {
756+
write!(
757+
f,
758+
"{}{}.{:09} secs",
759+
secs_sign,
760+
secs.abs(),
761+
nanoseconds.abs()
762+
)?;
763+
} else {
764+
write!(
765+
f,
766+
" {}{}.{:09} secs",
767+
secs_sign,
768+
secs.abs(),
769+
nanoseconds.abs()
770+
)?;
771+
}
772+
}
683773

684-
write!(
685-
f,
686-
"0 years 0 mons {} days {} hours {} mins {}{}.{:03} secs",
687-
value.days,
688-
hours,
689-
mins,
690-
secs_sign,
691-
secs.abs(),
692-
milliseconds.abs(),
693-
)?;
694774
Ok(())
695775
}
696776
}
697777

698-
impl<'a> DisplayIndex for &'a PrimitiveArray<IntervalMonthDayNanoType> {
699-
fn write(&self, idx: usize, f: &mut dyn Write) -> FormatResult {
700-
let value = self.value(idx);
778+
struct MillisecondsFormatter {
779+
milliseconds: i32,
780+
first_part: bool,
781+
}
782+
783+
impl Display for MillisecondsFormatter {
784+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
785+
let mut first_part = self.first_part;
701786

702-
let secs = value.nanoseconds / 1_000_000_000;
787+
let secs = self.milliseconds / 1_000;
703788
let mins = secs / 60;
704789
let hours = mins / 60;
705790

706791
let secs = secs - (mins * 60);
707792
let mins = mins - (hours * 60);
708793

709-
let nanoseconds = value.nanoseconds % 1_000_000_000;
710-
711-
let secs_sign = if secs < 0 || nanoseconds < 0 { "-" } else { "" };
712-
713-
write!(
714-
f,
715-
"0 years {} mons {} days {} hours {} mins {}{}.{:09} secs",
716-
value.months,
717-
value.days,
718-
hours,
719-
mins,
720-
secs_sign,
721-
secs.abs(),
722-
nanoseconds.abs(),
723-
)?;
794+
let milliseconds = self.milliseconds % 1_000;
795+
796+
if hours != 0 {
797+
if first_part {
798+
write!(f, "{} hours", hours,)?;
799+
first_part = false;
800+
} else {
801+
write!(f, " {} hours", hours,)?;
802+
}
803+
}
804+
805+
if mins != 0 {
806+
if first_part {
807+
write!(f, "{} mins", mins,)?;
808+
first_part = false;
809+
} else {
810+
write!(f, " {} mins", mins,)?;
811+
}
812+
}
813+
814+
if secs != 0 || milliseconds != 0 {
815+
let secs_sign = if secs < 0 || milliseconds < 0 {
816+
"-"
817+
} else {
818+
""
819+
};
820+
821+
if first_part {
822+
write!(
823+
f,
824+
"{}{}.{:03} secs",
825+
secs_sign,
826+
secs.abs(),
827+
milliseconds.abs()
828+
)?;
829+
} else {
830+
write!(
831+
f,
832+
" {}{}.{:03} secs",
833+
secs_sign,
834+
secs.abs(),
835+
milliseconds.abs()
836+
)?;
837+
}
838+
}
839+
724840
Ok(())
725841
}
726842
}

arrow-cast/src/pretty.rs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -986,16 +986,16 @@ mod tests {
986986
let table = pretty_format_batches(&[batch]).unwrap().to_string();
987987

988988
let expected = vec![
989-
"+----------------------------------------------------+",
990-
"| IntervalDayTime |",
991-
"+----------------------------------------------------+",
992-
"| 0 years 0 mons -1 days 0 hours -10 mins 0.000 secs |",
993-
"| 0 years 0 mons 0 days 0 hours 0 mins -1.001 secs |",
994-
"| 0 years 0 mons 0 days 0 hours 0 mins -0.001 secs |",
995-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.001 secs |",
996-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.010 secs |",
997-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.100 secs |",
998-
"+----------------------------------------------------+",
989+
"+------------------+",
990+
"| IntervalDayTime |",
991+
"+------------------+",
992+
"| -1 days -10 mins |",
993+
"| -1.001 secs |",
994+
"| -0.001 secs |",
995+
"| 0.001 secs |",
996+
"| 0.010 secs |",
997+
"| 0.100 secs |",
998+
"+------------------+",
999999
];
10001000

10011001
let actual: Vec<&str> = table.lines().collect();
@@ -1032,23 +1032,23 @@ mod tests {
10321032
let table = pretty_format_batches(&[batch]).unwrap().to_string();
10331033

10341034
let expected = vec![
1035-
"+-----------------------------------------------------------+",
1036-
"| IntervalMonthDayNano |",
1037-
"+-----------------------------------------------------------+",
1038-
"| 0 years -1 mons -1 days 0 hours -10 mins 0.000000000 secs |",
1039-
"| 0 years 0 mons 0 days 0 hours 0 mins -1.000000001 secs |",
1040-
"| 0 years 0 mons 0 days 0 hours 0 mins -0.000000001 secs |",
1041-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.000000001 secs |",
1042-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.000000010 secs |",
1043-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.000000100 secs |",
1044-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.000001000 secs |",
1045-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.000010000 secs |",
1046-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.000100000 secs |",
1047-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.001000000 secs |",
1048-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.010000000 secs |",
1049-
"| 0 years 0 mons 0 days 0 hours 0 mins 0.100000000 secs |",
1050-
"| 0 years 0 mons 0 days 0 hours 0 mins 1.000000000 secs |",
1051-
"+-----------------------------------------------------------+",
1035+
"+--------------------------+",
1036+
"| IntervalMonthDayNano |",
1037+
"+--------------------------+",
1038+
"| -1 mons -1 days -10 mins |",
1039+
"| -1.000000001 secs |",
1040+
"| -0.000000001 secs |",
1041+
"| 0.000000001 secs |",
1042+
"| 0.000000010 secs |",
1043+
"| 0.000000100 secs |",
1044+
"| 0.000001000 secs |",
1045+
"| 0.000010000 secs |",
1046+
"| 0.000100000 secs |",
1047+
"| 0.001000000 secs |",
1048+
"| 0.010000000 secs |",
1049+
"| 0.100000000 secs |",
1050+
"| 1.000000000 secs |",
1051+
"+--------------------------+",
10521052
];
10531053

10541054
let actual: Vec<&str> = table.lines().collect();

0 commit comments

Comments
 (0)