ARROW-12011: [C++] Fix crashes and incorrect results when printing extreme date values#10988
ARROW-12011: [C++] Fix crashes and incorrect results when printing extreme date values#10988pitrou wants to merge 4 commits intoapache:masterfrom
Conversation
59361cf to
4e6020b
Compare
|
@jorisvandenbossche Would you like to review some C++ code? |
bkietz
left a comment
There was a problem hiding this comment.
Some nits, otherwise this looks good
cpp/src/arrow/pretty_print.cc
Outdated
There was a problem hiding this comment.
Nit: please extract named constants like
| if (v >= -12687428 && v <= 11248737) { | |
| if (v >= kMinimumDay && v <= kMaximumDay) { |
cpp/src/arrow/pretty_print.cc
Outdated
There was a problem hiding this comment.
The range check could possibly even just be here:
| (*sink_) << arrow_vendored::date::format(fmt, epoch_ + Unit{value}); | |
| constexpr Unit kMin = duration_cast<Unit>(kMinDay); | |
| constexpr Unit kMax = duration_cast<Unit>(kMaxDay); | |
| if (Unit{value} >= kMin && Unit{value} <= kMax) { | |
| (*sink_) << arrow_vendored::date::format(fmt, epoch_ + Unit{value}); | |
| } else { | |
| WriteOutOfRange(value); | |
| } |
There was a problem hiding this comment.
Hmm... nice idea, but it unfortunately overflows for nanoseconds.
/home/antoine/arrow/dev/cpp/src/arrow/pretty_print.cc: In instantiation of 'void arrow::{anonymous}::ArrayPrinter::FormatDateTime(const char*, int64_t, bool) [with Unit = std::chrono::duration<long int, std::ratio<1, 1000000000> >; int64_t = long int]':
/home/antoine/arrow/dev/cpp/src/arrow/pretty_print.cc:505:71: required from here
/home/antoine/arrow/dev/cpp/src/arrow/pretty_print.cc:483:59: in 'constexpr' expansion of 'std::chrono::duration_cast<std::chrono::duration<long int, std::ratio<1, 1000000000> >, int, std::ratio<86400, 1> >(std::chrono::duration<int, std::ratio<86400, 1> >(-12687428))'
/usr/include/c++/9/chrono:200:21: in 'constexpr' expansion of 'std::chrono::__duration_cast_impl<std::chrono::duration<long int, std::ratio<1, 1000000000> >, std::ratio<86400000000000, 1>, long int, false, true>::__cast<int, std::ratio<86400, 1> >((* & __d))'
/home/antoine/arrow/dev/cpp/src/arrow/pretty_print.cc:483:20: error: overflow in constant expression [-fpermissive]
483 | constexpr Unit kMin = std::chrono::duration_cast<Unit>(arrow_vendored::date::days{-12687428});
| ^~~~
There was a problem hiding this comment.
Ok, it works by templating a bit differently.
4e6020b to
3917ed1
Compare
|
I didn't yet look at the code, but one note: the That can certainly be for another JIRA, but wondering a bit if it might be possible to share some of those checks (the printing should also work if compute is not available I suppose, so cannot directly rely on it) |
…treme date values The `arrow_vendored::date` library represents year numbers as a C short and may silently wraparound its value (but also throw an exception if the year has the value -32768).
f7b8f97 to
4c6b981
Compare
|
I will merge this, feel free to post any comments afterwards, though. |
…treme date values The `arrow_vendored::date` library represents year numbers as a C short and may silently wraparound its value (but also throw an exception if the year has the value -32768). Closes apache#10988 from pitrou/ARROW-12011-date-formatting Authored-by: Antoine Pitrou <antoine@python.org> Signed-off-by: Antoine Pitrou <antoine@python.org>
The
arrow_vendored::datelibrary represents year numbers as a C shortand may silently wraparound its value
(but also throw an exception if the year has the value -32768).