-
Notifications
You must be signed in to change notification settings - Fork 1k
Fix fcoalesce Date/IDate mixing and resolve test collisions (#7463) #7557
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
base: master
Are you sure you want to change the base?
Fix fcoalesce Date/IDate mixing and resolve test collisions (#7463) #7557
Conversation
| if (TYPEOF(x)!=VECSXP) internal_error(__func__, "input is list(...) at R level"); // # nocov | ||
| if (!IS_TRUE_OR_FALSE(inplaceArg)) internal_error(__func__, "argument 'inplaceArg' must be TRUE or FALSE"); // # nocov | ||
| if (!IS_TRUE_OR_FALSE(nan_is_na_arg)) internal_error(__func__, "argument 'nan_is_na_arg' must be TRUE or FALSE"); // # nocov | ||
| if (TYPEOF(x) != VECSXP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please dont reformat existing code. This makes reviewing quite tedious.
| VDate = fifelse(VDate == as.Date("3000-01-01"), as.Date(NA), VDate), | ||
| VIDate = fifelse(VIDate == as.IDate("3000-01-01"), as.IDate(NA), VIDate), | ||
| VNumA, VNumB, Count, Y_Sum)]) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please no formatting changes.
|
|
||
| # fcoalesce Date and IDate mixing, #7463 | ||
| test(2357.1, fcoalesce(as.Date("2026-01-01"), as.IDate("2026-01-02")), as.Date("2026-01-01")) | ||
| test(2357.2, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please dont make tests super complicated. {} should only be used when you are confident that it makes the test easier to read and you necessarily need multiple state. this is probably not warranted.
|
I can review, once the formatting diffs are removed. Note that we already have a similar promoting logic in place for |
This PR addresses #7463 by allowing fcoalesce() and setcoalesce() to handle mixing of Date (double) and IDate (integer) classes, as well as general mixing of integer and double types. Previously, these combinations would throw a strict type/class mismatch error.
Technical Details The core of the change is in
src/coalesce.c
. I've updated the logic to:
Relax Type Checks: Added a promote_to_real flag that triggers when fcoalesce sees an integer vector followed by a double. This allows fcoalesce to return a REALSXP vector even if the first argument was INTSXP.
Handle Date/IDate Inheritance: Modified the class-matching check to allow any two objects that both inherit from the Date class. This handles the specific pairing of Date and IDate which were previously rejected as "different classes".
Strict In-place Rules: For setcoalesce(), I've kept the strict rule that we cannot promote an integer vector to double in-place (as that would require memory reallocation). It now throws a specific, helpful error suggesting manual coercion instead of a generic "type mismatch".
Attribute Persistence: Corrected the attribute handling so that if we promote an IDate to a double Date, the class attributes are correctly propagated to the new object.
Testing I've added six new tests to the end of
inst/tests/tests.Rraw
(numbered 2357.1–2357.6) covering:
fcoalesce(Date, IDate)
fcoalesce(IDate, Date) (promotion check)
Numeric mixing (INTSXP + REALSXP)
setcoalesce safety checks (ensuring we don't accidentally reallocate in-place).
Verified that these fail on the current master and pass with this build. I also re-ran the full local test suite to ensure no regressions in existing fcoalesce logic.
A Note to Maintainers I've tried my best to follow the data.table coding style and memory safety principles, but I'm still getting my head around some of the C-level internals. I could be wrong about how I've handled the promotion flags or if there's a more efficient way to check for the Date class inheritance at this level. I'm very much open to learning if there's a better or more "the data.table way" to implement this!