ARROW-13561: [C++] Implement week kernel that accepts WeekOptions - #11026

Closed
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561
Closed

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions#11026
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561

Conversation

@rok

@rokrok commented Aug 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13561.

@github-actions

Copy link
Copy Markdown

@rok

rok commented Aug 28, 2021

Copy link
Copy Markdown
MemberAuthor

Shall we also change DayOfWeekOptions to WeekOptions? It would be a better fit overall if this PR is merged.

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from f8d1e4c to 6997246CompareAugust 29, 2021 11:38
@rok
rokforce-pushed the ARROW-13561 branch 4 times, most recently from 33b27e7 to 4a1b8a7CompareAugust 30, 2021 10:59

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

@lidavidm

Copy link
Copy Markdown
Member

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

I'm just trying to understand if it does :)

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

This evaluates to true in MySQL on sqlfiddle:

SELECT WEEK('2008-1-6', 1) != WEEK('2008-1-6', 4)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from 18a2b49 to 69eed89CompareAugust 30, 2021 22:09
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given ISOWeek is a special case of Week now, maybe we should just have one kernel (and perhaps some conveniences, e.g. DayOfWeekOptions::IsoWeek())?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a nice idea.
I'm still trying to exactly match WEEK from MySQL and once I do I'll look into this. Sorry for the WIP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no worries. I can hold off looking at this until you're ready.

@rokrokAug 31, 2021

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early feedback is great though! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this? Since it seems the two kernels are very similar.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

@ianmcook This now covers MySQL WEEK modes 1, 3, 4 and 6 (week 1 is the first week with 4 or more days this year).
If we want to cover modes 0, 2, 5, and 7 (week 1 is the first week with a Monday/Sunday in this year) we could add another parameter e.g.: DayOfWeekOptions.week_start_in_year. Do you think we should?

Another thing to note here is that DayOfWeekOptions.one_based_numbering doesn't exactly mean we count from 0 or 1 but rather that a date from iso week 52 of previous year that is in this year will be counted as 0 instead of 52. It's a MySQL convention.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

we could to add another parameter e.g.: DayOfWeekOptions.week_start_in_year.

Perhaps DayOfWeekOptions.count_full_weeks is more idiomatic.

@lidavidm

Copy link
Copy Markdown
Member

If the option doesn't apply to DayOfWeek, maybe it should be a separate WeekOptions in that case.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

So then we now have:
DayOfWeekOptions with week_start and one_based_numbering

We would need to add three binary parameters to match the 8 modes of MySQL:

  • WeekOptions with week_start (first day of week),count_from_zero (range), count_full_weeks (week 1 is ..)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

I tried adding WeekOptions with the following parameters:

 /// What day does the week start with (Monday=true, Sunday=false)
bool week_starts_monday;
/// Days in current year that fall into last years ISO week return week 0 if true
bool count_from_zero;
/// Is the first week fully in the the year or only its 4 or more days
bool first_week_in_year;

I've also added tests with all the MySQL modes. Docs and the logic need some more work, but first: do we go this way or stick to iso week only?

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from ef87424 to 062e5f2CompareSeptember 2, 2021 10:02
@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

@lidavidm@pitrou I've removed the ISOWeek kernel and added iso_week and us_week functions that use week with specific options.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

R CI is reporting:

── Error (test-dplyr-lubridate.R:80:3): extract isoweek from timestamp ─────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions
Backtrace:
█
1. ├─arrow:::expect_dplyr_equal(...) test-dplyr-lubridate.R:80:2
2. │ ├─testthat::expect_warning(...) helper-expectation.R:101:4
3. │ │ └─testthat:::quasi_capture(enquo(object), label, capture_warnings)
4. │ │ ├─testthat:::.capture(...)
5. │ │ │ └─base::withCallingHandlers(...)
6. │ │ └─rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
7. │ └─rlang::eval_tidy(expr, rlang::new_data_mask(rlang::env(input = record_batch(tbl))))
8. ├─input %>% mutate(x = isoweek(datetime)) %>% collect()
9. ├─dplyr::collect(.)
10. └─arrow:::collect.arrow_dplyr_query(.)
11. └─arrow:::do_exec_plan(x)
12. └─plan$Build(.data)
13. └─node$Project(projection)
14. ├─self$preserve_sort(ExecNode_Project(self, cols, names(cols)))
15. └─arrow:::ExecNode_Project(self, cols, names(cols))
── Error (test-dplyr-lubridate.R:205:3): extract isoweek from date ─────────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions

I suppose we then need ISOWeek and USWeek declared with options in the API.

@lidavidm

Copy link
Copy Markdown
Member

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@lidavidm oh, didn't realize it had to be there.
Maybe would be good to add R tests as well then?

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits on style/wording.

If you're up to add R tests, I think that would be appreciated, but otherwise we can put that in a follow-up JIRA (since there might be other work to bind the new kernels to dplyr features or whatnot).

Comment threadr/src/compute.cpp Outdated
Comment threaddocs/source/cpp/compute.rst Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, can we put comments for the parameter literals? Or actually, it might be nice to define WeekOptions::IsoDefaults and WeekOptions::UsDefaults which could then be used here and in the R bindings.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added WeekOptions::ISODefaults and WeekOptions::USDefaults.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a helper for USWeek?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to be missing its counterpart in api_scalar.cc.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13561 branch 3 times, most recently from 1d4a49c to 4f68c1cCompareSeptember 23, 2021 14:49

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @lidavidm ! :)

@rok
rok requested a review from pitrouSeptember 23, 2021 16:04

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased, will merge

@rok

rok commented Sep 27, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
This is to resolve [ARROW-13561](https://issues.apache.org/jira/browse/ARROW-13561`).
Closesapache#11026 from rok/ARROW-13561
Lead-authored-by: Rok <rok@mihevc.org>
Co-authored-by: Rok Mihevc <rok@mihevc.org>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@rok@lidavidm@ianmcook@nealrichardson@pitrou@jorisvandenbossche
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions - #11026

Closed
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561
Closed

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions#11026
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561

Conversation

@rok

@rokrok commented Aug 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13561.

@github-actions

Copy link
Copy Markdown

@rok

rok commented Aug 28, 2021

Copy link
Copy Markdown
MemberAuthor

Shall we also change DayOfWeekOptions to WeekOptions? It would be a better fit overall if this PR is merged.

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from f8d1e4c to 6997246CompareAugust 29, 2021 11:38
@rok
rokforce-pushed the ARROW-13561 branch 4 times, most recently from 33b27e7 to 4a1b8a7CompareAugust 30, 2021 10:59

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

@lidavidm

Copy link
Copy Markdown
Member

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

I'm just trying to understand if it does :)

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

This evaluates to true in MySQL on sqlfiddle:

SELECT WEEK('2008-1-6', 1) != WEEK('2008-1-6', 4)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from 18a2b49 to 69eed89CompareAugust 30, 2021 22:09
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given ISOWeek is a special case of Week now, maybe we should just have one kernel (and perhaps some conveniences, e.g. DayOfWeekOptions::IsoWeek())?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a nice idea.
I'm still trying to exactly match WEEK from MySQL and once I do I'll look into this. Sorry for the WIP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no worries. I can hold off looking at this until you're ready.

@rokrokAug 31, 2021

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early feedback is great though! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this? Since it seems the two kernels are very similar.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

@ianmcook This now covers MySQL WEEK modes 1, 3, 4 and 6 (week 1 is the first week with 4 or more days this year).
If we want to cover modes 0, 2, 5, and 7 (week 1 is the first week with a Monday/Sunday in this year) we could add another parameter e.g.: DayOfWeekOptions.week_start_in_year. Do you think we should?

Another thing to note here is that DayOfWeekOptions.one_based_numbering doesn't exactly mean we count from 0 or 1 but rather that a date from iso week 52 of previous year that is in this year will be counted as 0 instead of 52. It's a MySQL convention.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

we could to add another parameter e.g.: DayOfWeekOptions.week_start_in_year.

Perhaps DayOfWeekOptions.count_full_weeks is more idiomatic.

@lidavidm

Copy link
Copy Markdown
Member

If the option doesn't apply to DayOfWeek, maybe it should be a separate WeekOptions in that case.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

So then we now have:
DayOfWeekOptions with week_start and one_based_numbering

We would need to add three binary parameters to match the 8 modes of MySQL:

  • WeekOptions with week_start (first day of week),count_from_zero (range), count_full_weeks (week 1 is ..)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

I tried adding WeekOptions with the following parameters:

 /// What day does the week start with (Monday=true, Sunday=false)
bool week_starts_monday;
/// Days in current year that fall into last years ISO week return week 0 if true
bool count_from_zero;
/// Is the first week fully in the the year or only its 4 or more days
bool first_week_in_year;

I've also added tests with all the MySQL modes. Docs and the logic need some more work, but first: do we go this way or stick to iso week only?

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from ef87424 to 062e5f2CompareSeptember 2, 2021 10:02
@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

@lidavidm@pitrou I've removed the ISOWeek kernel and added iso_week and us_week functions that use week with specific options.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

R CI is reporting:

── Error (test-dplyr-lubridate.R:80:3): extract isoweek from timestamp ─────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions
Backtrace:
█
1. ├─arrow:::expect_dplyr_equal(...) test-dplyr-lubridate.R:80:2
2. │ ├─testthat::expect_warning(...) helper-expectation.R:101:4
3. │ │ └─testthat:::quasi_capture(enquo(object), label, capture_warnings)
4. │ │ ├─testthat:::.capture(...)
5. │ │ │ └─base::withCallingHandlers(...)
6. │ │ └─rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
7. │ └─rlang::eval_tidy(expr, rlang::new_data_mask(rlang::env(input = record_batch(tbl))))
8. ├─input %>% mutate(x = isoweek(datetime)) %>% collect()
9. ├─dplyr::collect(.)
10. └─arrow:::collect.arrow_dplyr_query(.)
11. └─arrow:::do_exec_plan(x)
12. └─plan$Build(.data)
13. └─node$Project(projection)
14. ├─self$preserve_sort(ExecNode_Project(self, cols, names(cols)))
15. └─arrow:::ExecNode_Project(self, cols, names(cols))
── Error (test-dplyr-lubridate.R:205:3): extract isoweek from date ─────────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions

I suppose we then need ISOWeek and USWeek declared with options in the API.

@lidavidm

Copy link
Copy Markdown
Member

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@lidavidm oh, didn't realize it had to be there.
Maybe would be good to add R tests as well then?

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits on style/wording.

If you're up to add R tests, I think that would be appreciated, but otherwise we can put that in a follow-up JIRA (since there might be other work to bind the new kernels to dplyr features or whatnot).

Comment threadr/src/compute.cpp Outdated
Comment threaddocs/source/cpp/compute.rst Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, can we put comments for the parameter literals? Or actually, it might be nice to define WeekOptions::IsoDefaults and WeekOptions::UsDefaults which could then be used here and in the R bindings.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added WeekOptions::ISODefaults and WeekOptions::USDefaults.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a helper for USWeek?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to be missing its counterpart in api_scalar.cc.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13561 branch 3 times, most recently from 1d4a49c to 4f68c1cCompareSeptember 23, 2021 14:49

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @lidavidm ! :)

@rok
rok requested a review from pitrouSeptember 23, 2021 16:04

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased, will merge

@rok

rok commented Sep 27, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
This is to resolve [ARROW-13561](https://issues.apache.org/jira/browse/ARROW-13561`).
Closesapache#11026 from rok/ARROW-13561
Lead-authored-by: Rok <rok@mihevc.org>
Co-authored-by: Rok Mihevc <rok@mihevc.org>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@rok@lidavidm@ianmcook@nealrichardson@pitrou@jorisvandenbossche
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions - #11026

Closed
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561
Closed

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions#11026
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561

Conversation

@rok

@rokrok commented Aug 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13561.

@github-actions

Copy link
Copy Markdown

@rok

rok commented Aug 28, 2021

Copy link
Copy Markdown
MemberAuthor

Shall we also change DayOfWeekOptions to WeekOptions? It would be a better fit overall if this PR is merged.

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from f8d1e4c to 6997246CompareAugust 29, 2021 11:38
@rok
rokforce-pushed the ARROW-13561 branch 4 times, most recently from 33b27e7 to 4a1b8a7CompareAugust 30, 2021 10:59

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

@lidavidm

Copy link
Copy Markdown
Member

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

I'm just trying to understand if it does :)

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

This evaluates to true in MySQL on sqlfiddle:

SELECT WEEK('2008-1-6', 1) != WEEK('2008-1-6', 4)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from 18a2b49 to 69eed89CompareAugust 30, 2021 22:09
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given ISOWeek is a special case of Week now, maybe we should just have one kernel (and perhaps some conveniences, e.g. DayOfWeekOptions::IsoWeek())?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a nice idea.
I'm still trying to exactly match WEEK from MySQL and once I do I'll look into this. Sorry for the WIP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no worries. I can hold off looking at this until you're ready.

@rokrokAug 31, 2021

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early feedback is great though! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this? Since it seems the two kernels are very similar.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

@ianmcook This now covers MySQL WEEK modes 1, 3, 4 and 6 (week 1 is the first week with 4 or more days this year).
If we want to cover modes 0, 2, 5, and 7 (week 1 is the first week with a Monday/Sunday in this year) we could add another parameter e.g.: DayOfWeekOptions.week_start_in_year. Do you think we should?

Another thing to note here is that DayOfWeekOptions.one_based_numbering doesn't exactly mean we count from 0 or 1 but rather that a date from iso week 52 of previous year that is in this year will be counted as 0 instead of 52. It's a MySQL convention.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

we could to add another parameter e.g.: DayOfWeekOptions.week_start_in_year.

Perhaps DayOfWeekOptions.count_full_weeks is more idiomatic.

@lidavidm

Copy link
Copy Markdown
Member

If the option doesn't apply to DayOfWeek, maybe it should be a separate WeekOptions in that case.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

So then we now have:
DayOfWeekOptions with week_start and one_based_numbering

We would need to add three binary parameters to match the 8 modes of MySQL:

  • WeekOptions with week_start (first day of week),count_from_zero (range), count_full_weeks (week 1 is ..)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

I tried adding WeekOptions with the following parameters:

 /// What day does the week start with (Monday=true, Sunday=false)
bool week_starts_monday;
/// Days in current year that fall into last years ISO week return week 0 if true
bool count_from_zero;
/// Is the first week fully in the the year or only its 4 or more days
bool first_week_in_year;

I've also added tests with all the MySQL modes. Docs and the logic need some more work, but first: do we go this way or stick to iso week only?

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from ef87424 to 062e5f2CompareSeptember 2, 2021 10:02
@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

@lidavidm@pitrou I've removed the ISOWeek kernel and added iso_week and us_week functions that use week with specific options.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

R CI is reporting:

── Error (test-dplyr-lubridate.R:80:3): extract isoweek from timestamp ─────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions
Backtrace:
█
1. ├─arrow:::expect_dplyr_equal(...) test-dplyr-lubridate.R:80:2
2. │ ├─testthat::expect_warning(...) helper-expectation.R:101:4
3. │ │ └─testthat:::quasi_capture(enquo(object), label, capture_warnings)
4. │ │ ├─testthat:::.capture(...)
5. │ │ │ └─base::withCallingHandlers(...)
6. │ │ └─rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
7. │ └─rlang::eval_tidy(expr, rlang::new_data_mask(rlang::env(input = record_batch(tbl))))
8. ├─input %>% mutate(x = isoweek(datetime)) %>% collect()
9. ├─dplyr::collect(.)
10. └─arrow:::collect.arrow_dplyr_query(.)
11. └─arrow:::do_exec_plan(x)
12. └─plan$Build(.data)
13. └─node$Project(projection)
14. ├─self$preserve_sort(ExecNode_Project(self, cols, names(cols)))
15. └─arrow:::ExecNode_Project(self, cols, names(cols))
── Error (test-dplyr-lubridate.R:205:3): extract isoweek from date ─────────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions

I suppose we then need ISOWeek and USWeek declared with options in the API.

@lidavidm

Copy link
Copy Markdown
Member

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@lidavidm oh, didn't realize it had to be there.
Maybe would be good to add R tests as well then?

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits on style/wording.

If you're up to add R tests, I think that would be appreciated, but otherwise we can put that in a follow-up JIRA (since there might be other work to bind the new kernels to dplyr features or whatnot).

Comment threadr/src/compute.cpp Outdated
Comment threaddocs/source/cpp/compute.rst Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, can we put comments for the parameter literals? Or actually, it might be nice to define WeekOptions::IsoDefaults and WeekOptions::UsDefaults which could then be used here and in the R bindings.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added WeekOptions::ISODefaults and WeekOptions::USDefaults.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a helper for USWeek?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to be missing its counterpart in api_scalar.cc.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13561 branch 3 times, most recently from 1d4a49c to 4f68c1cCompareSeptember 23, 2021 14:49

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @lidavidm ! :)

@rok
rok requested a review from pitrouSeptember 23, 2021 16:04

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased, will merge

@rok

rok commented Sep 27, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
This is to resolve [ARROW-13561](https://issues.apache.org/jira/browse/ARROW-13561`).
Closesapache#11026 from rok/ARROW-13561
Lead-authored-by: Rok <rok@mihevc.org>
Co-authored-by: Rok Mihevc <rok@mihevc.org>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@rok@lidavidm@ianmcook@nealrichardson@pitrou@jorisvandenbossche
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions - #11026

Closed
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561
Closed

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions#11026
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561

Conversation

@rok

@rokrok commented Aug 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13561.

@github-actions

Copy link
Copy Markdown

@rok

rok commented Aug 28, 2021

Copy link
Copy Markdown
MemberAuthor

Shall we also change DayOfWeekOptions to WeekOptions? It would be a better fit overall if this PR is merged.

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from f8d1e4c to 6997246CompareAugust 29, 2021 11:38
@rok
rokforce-pushed the ARROW-13561 branch 4 times, most recently from 33b27e7 to 4a1b8a7CompareAugust 30, 2021 10:59

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

@lidavidm

Copy link
Copy Markdown
Member

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

I'm just trying to understand if it does :)

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

This evaluates to true in MySQL on sqlfiddle:

SELECT WEEK('2008-1-6', 1) != WEEK('2008-1-6', 4)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from 18a2b49 to 69eed89CompareAugust 30, 2021 22:09
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given ISOWeek is a special case of Week now, maybe we should just have one kernel (and perhaps some conveniences, e.g. DayOfWeekOptions::IsoWeek())?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a nice idea.
I'm still trying to exactly match WEEK from MySQL and once I do I'll look into this. Sorry for the WIP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no worries. I can hold off looking at this until you're ready.

@rokrokAug 31, 2021

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early feedback is great though! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this? Since it seems the two kernels are very similar.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

@ianmcook This now covers MySQL WEEK modes 1, 3, 4 and 6 (week 1 is the first week with 4 or more days this year).
If we want to cover modes 0, 2, 5, and 7 (week 1 is the first week with a Monday/Sunday in this year) we could add another parameter e.g.: DayOfWeekOptions.week_start_in_year. Do you think we should?

Another thing to note here is that DayOfWeekOptions.one_based_numbering doesn't exactly mean we count from 0 or 1 but rather that a date from iso week 52 of previous year that is in this year will be counted as 0 instead of 52. It's a MySQL convention.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

we could to add another parameter e.g.: DayOfWeekOptions.week_start_in_year.

Perhaps DayOfWeekOptions.count_full_weeks is more idiomatic.

@lidavidm

Copy link
Copy Markdown
Member

If the option doesn't apply to DayOfWeek, maybe it should be a separate WeekOptions in that case.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

So then we now have:
DayOfWeekOptions with week_start and one_based_numbering

We would need to add three binary parameters to match the 8 modes of MySQL:

  • WeekOptions with week_start (first day of week),count_from_zero (range), count_full_weeks (week 1 is ..)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

I tried adding WeekOptions with the following parameters:

 /// What day does the week start with (Monday=true, Sunday=false)
bool week_starts_monday;
/// Days in current year that fall into last years ISO week return week 0 if true
bool count_from_zero;
/// Is the first week fully in the the year or only its 4 or more days
bool first_week_in_year;

I've also added tests with all the MySQL modes. Docs and the logic need some more work, but first: do we go this way or stick to iso week only?

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from ef87424 to 062e5f2CompareSeptember 2, 2021 10:02
@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

@lidavidm@pitrou I've removed the ISOWeek kernel and added iso_week and us_week functions that use week with specific options.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

R CI is reporting:

── Error (test-dplyr-lubridate.R:80:3): extract isoweek from timestamp ─────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions
Backtrace:
█
1. ├─arrow:::expect_dplyr_equal(...) test-dplyr-lubridate.R:80:2
2. │ ├─testthat::expect_warning(...) helper-expectation.R:101:4
3. │ │ └─testthat:::quasi_capture(enquo(object), label, capture_warnings)
4. │ │ ├─testthat:::.capture(...)
5. │ │ │ └─base::withCallingHandlers(...)
6. │ │ └─rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
7. │ └─rlang::eval_tidy(expr, rlang::new_data_mask(rlang::env(input = record_batch(tbl))))
8. ├─input %>% mutate(x = isoweek(datetime)) %>% collect()
9. ├─dplyr::collect(.)
10. └─arrow:::collect.arrow_dplyr_query(.)
11. └─arrow:::do_exec_plan(x)
12. └─plan$Build(.data)
13. └─node$Project(projection)
14. ├─self$preserve_sort(ExecNode_Project(self, cols, names(cols)))
15. └─arrow:::ExecNode_Project(self, cols, names(cols))
── Error (test-dplyr-lubridate.R:205:3): extract isoweek from date ─────────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions

I suppose we then need ISOWeek and USWeek declared with options in the API.

@lidavidm

Copy link
Copy Markdown
Member

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@lidavidm oh, didn't realize it had to be there.
Maybe would be good to add R tests as well then?

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits on style/wording.

If you're up to add R tests, I think that would be appreciated, but otherwise we can put that in a follow-up JIRA (since there might be other work to bind the new kernels to dplyr features or whatnot).

Comment threadr/src/compute.cpp Outdated
Comment threaddocs/source/cpp/compute.rst Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, can we put comments for the parameter literals? Or actually, it might be nice to define WeekOptions::IsoDefaults and WeekOptions::UsDefaults which could then be used here and in the R bindings.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added WeekOptions::ISODefaults and WeekOptions::USDefaults.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a helper for USWeek?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to be missing its counterpart in api_scalar.cc.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13561 branch 3 times, most recently from 1d4a49c to 4f68c1cCompareSeptember 23, 2021 14:49

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @lidavidm ! :)

@rok
rok requested a review from pitrouSeptember 23, 2021 16:04

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased, will merge

@rok

rok commented Sep 27, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
This is to resolve [ARROW-13561](https://issues.apache.org/jira/browse/ARROW-13561`).
Closesapache#11026 from rok/ARROW-13561
Lead-authored-by: Rok <rok@mihevc.org>
Co-authored-by: Rok Mihevc <rok@mihevc.org>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@rok@lidavidm@ianmcook@nealrichardson@pitrou@jorisvandenbossche
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions - #11026

Closed
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561
Closed

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions#11026
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561

Conversation

@rok

@rokrok commented Aug 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13561.

@github-actions

Copy link
Copy Markdown

@rok

rok commented Aug 28, 2021

Copy link
Copy Markdown
MemberAuthor

Shall we also change DayOfWeekOptions to WeekOptions? It would be a better fit overall if this PR is merged.

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from f8d1e4c to 6997246CompareAugust 29, 2021 11:38
@rok
rokforce-pushed the ARROW-13561 branch 4 times, most recently from 33b27e7 to 4a1b8a7CompareAugust 30, 2021 10:59

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

@lidavidm

Copy link
Copy Markdown
Member

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

I'm just trying to understand if it does :)

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

This evaluates to true in MySQL on sqlfiddle:

SELECT WEEK('2008-1-6', 1) != WEEK('2008-1-6', 4)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from 18a2b49 to 69eed89CompareAugust 30, 2021 22:09
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given ISOWeek is a special case of Week now, maybe we should just have one kernel (and perhaps some conveniences, e.g. DayOfWeekOptions::IsoWeek())?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a nice idea.
I'm still trying to exactly match WEEK from MySQL and once I do I'll look into this. Sorry for the WIP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no worries. I can hold off looking at this until you're ready.

@rokrokAug 31, 2021

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early feedback is great though! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this? Since it seems the two kernels are very similar.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

@ianmcook This now covers MySQL WEEK modes 1, 3, 4 and 6 (week 1 is the first week with 4 or more days this year).
If we want to cover modes 0, 2, 5, and 7 (week 1 is the first week with a Monday/Sunday in this year) we could add another parameter e.g.: DayOfWeekOptions.week_start_in_year. Do you think we should?

Another thing to note here is that DayOfWeekOptions.one_based_numbering doesn't exactly mean we count from 0 or 1 but rather that a date from iso week 52 of previous year that is in this year will be counted as 0 instead of 52. It's a MySQL convention.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

we could to add another parameter e.g.: DayOfWeekOptions.week_start_in_year.

Perhaps DayOfWeekOptions.count_full_weeks is more idiomatic.

@lidavidm

Copy link
Copy Markdown
Member

If the option doesn't apply to DayOfWeek, maybe it should be a separate WeekOptions in that case.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

So then we now have:
DayOfWeekOptions with week_start and one_based_numbering

We would need to add three binary parameters to match the 8 modes of MySQL:

  • WeekOptions with week_start (first day of week),count_from_zero (range), count_full_weeks (week 1 is ..)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

I tried adding WeekOptions with the following parameters:

 /// What day does the week start with (Monday=true, Sunday=false)
bool week_starts_monday;
/// Days in current year that fall into last years ISO week return week 0 if true
bool count_from_zero;
/// Is the first week fully in the the year or only its 4 or more days
bool first_week_in_year;

I've also added tests with all the MySQL modes. Docs and the logic need some more work, but first: do we go this way or stick to iso week only?

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from ef87424 to 062e5f2CompareSeptember 2, 2021 10:02
@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

@lidavidm@pitrou I've removed the ISOWeek kernel and added iso_week and us_week functions that use week with specific options.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

R CI is reporting:

── Error (test-dplyr-lubridate.R:80:3): extract isoweek from timestamp ─────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions
Backtrace:
█
1. ├─arrow:::expect_dplyr_equal(...) test-dplyr-lubridate.R:80:2
2. │ ├─testthat::expect_warning(...) helper-expectation.R:101:4
3. │ │ └─testthat:::quasi_capture(enquo(object), label, capture_warnings)
4. │ │ ├─testthat:::.capture(...)
5. │ │ │ └─base::withCallingHandlers(...)
6. │ │ └─rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
7. │ └─rlang::eval_tidy(expr, rlang::new_data_mask(rlang::env(input = record_batch(tbl))))
8. ├─input %>% mutate(x = isoweek(datetime)) %>% collect()
9. ├─dplyr::collect(.)
10. └─arrow:::collect.arrow_dplyr_query(.)
11. └─arrow:::do_exec_plan(x)
12. └─plan$Build(.data)
13. └─node$Project(projection)
14. ├─self$preserve_sort(ExecNode_Project(self, cols, names(cols)))
15. └─arrow:::ExecNode_Project(self, cols, names(cols))
── Error (test-dplyr-lubridate.R:205:3): extract isoweek from date ─────────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions

I suppose we then need ISOWeek and USWeek declared with options in the API.

@lidavidm

Copy link
Copy Markdown
Member

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@lidavidm oh, didn't realize it had to be there.
Maybe would be good to add R tests as well then?

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits on style/wording.

If you're up to add R tests, I think that would be appreciated, but otherwise we can put that in a follow-up JIRA (since there might be other work to bind the new kernels to dplyr features or whatnot).

Comment threadr/src/compute.cpp Outdated
Comment threaddocs/source/cpp/compute.rst Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, can we put comments for the parameter literals? Or actually, it might be nice to define WeekOptions::IsoDefaults and WeekOptions::UsDefaults which could then be used here and in the R bindings.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added WeekOptions::ISODefaults and WeekOptions::USDefaults.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a helper for USWeek?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to be missing its counterpart in api_scalar.cc.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13561 branch 3 times, most recently from 1d4a49c to 4f68c1cCompareSeptember 23, 2021 14:49

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @lidavidm ! :)

@rok
rok requested a review from pitrouSeptember 23, 2021 16:04

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased, will merge

@rok

rok commented Sep 27, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
This is to resolve [ARROW-13561](https://issues.apache.org/jira/browse/ARROW-13561`).
Closesapache#11026 from rok/ARROW-13561
Lead-authored-by: Rok <rok@mihevc.org>
Co-authored-by: Rok Mihevc <rok@mihevc.org>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@rok@lidavidm@ianmcook@nealrichardson@pitrou@jorisvandenbossche
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions - #11026

Closed
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561
Closed

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions#11026
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561

Conversation

@rok

@rokrok commented Aug 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13561.

@github-actions

Copy link
Copy Markdown

@rok

rok commented Aug 28, 2021

Copy link
Copy Markdown
MemberAuthor

Shall we also change DayOfWeekOptions to WeekOptions? It would be a better fit overall if this PR is merged.

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from f8d1e4c to 6997246CompareAugust 29, 2021 11:38
@rok
rokforce-pushed the ARROW-13561 branch 4 times, most recently from 33b27e7 to 4a1b8a7CompareAugust 30, 2021 10:59

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

@lidavidm

Copy link
Copy Markdown
Member

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

I'm just trying to understand if it does :)

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

This evaluates to true in MySQL on sqlfiddle:

SELECT WEEK('2008-1-6', 1) != WEEK('2008-1-6', 4)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from 18a2b49 to 69eed89CompareAugust 30, 2021 22:09
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given ISOWeek is a special case of Week now, maybe we should just have one kernel (and perhaps some conveniences, e.g. DayOfWeekOptions::IsoWeek())?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a nice idea.
I'm still trying to exactly match WEEK from MySQL and once I do I'll look into this. Sorry for the WIP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no worries. I can hold off looking at this until you're ready.

@rokrokAug 31, 2021

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early feedback is great though! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this? Since it seems the two kernels are very similar.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

@ianmcook This now covers MySQL WEEK modes 1, 3, 4 and 6 (week 1 is the first week with 4 or more days this year).
If we want to cover modes 0, 2, 5, and 7 (week 1 is the first week with a Monday/Sunday in this year) we could add another parameter e.g.: DayOfWeekOptions.week_start_in_year. Do you think we should?

Another thing to note here is that DayOfWeekOptions.one_based_numbering doesn't exactly mean we count from 0 or 1 but rather that a date from iso week 52 of previous year that is in this year will be counted as 0 instead of 52. It's a MySQL convention.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

we could to add another parameter e.g.: DayOfWeekOptions.week_start_in_year.

Perhaps DayOfWeekOptions.count_full_weeks is more idiomatic.

@lidavidm

Copy link
Copy Markdown
Member

If the option doesn't apply to DayOfWeek, maybe it should be a separate WeekOptions in that case.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

So then we now have:
DayOfWeekOptions with week_start and one_based_numbering

We would need to add three binary parameters to match the 8 modes of MySQL:

  • WeekOptions with week_start (first day of week),count_from_zero (range), count_full_weeks (week 1 is ..)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

I tried adding WeekOptions with the following parameters:

 /// What day does the week start with (Monday=true, Sunday=false)
bool week_starts_monday;
/// Days in current year that fall into last years ISO week return week 0 if true
bool count_from_zero;
/// Is the first week fully in the the year or only its 4 or more days
bool first_week_in_year;

I've also added tests with all the MySQL modes. Docs and the logic need some more work, but first: do we go this way or stick to iso week only?

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from ef87424 to 062e5f2CompareSeptember 2, 2021 10:02
@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

@lidavidm@pitrou I've removed the ISOWeek kernel and added iso_week and us_week functions that use week with specific options.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

R CI is reporting:

── Error (test-dplyr-lubridate.R:80:3): extract isoweek from timestamp ─────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions
Backtrace:
█
1. ├─arrow:::expect_dplyr_equal(...) test-dplyr-lubridate.R:80:2
2. │ ├─testthat::expect_warning(...) helper-expectation.R:101:4
3. │ │ └─testthat:::quasi_capture(enquo(object), label, capture_warnings)
4. │ │ ├─testthat:::.capture(...)
5. │ │ │ └─base::withCallingHandlers(...)
6. │ │ └─rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
7. │ └─rlang::eval_tidy(expr, rlang::new_data_mask(rlang::env(input = record_batch(tbl))))
8. ├─input %>% mutate(x = isoweek(datetime)) %>% collect()
9. ├─dplyr::collect(.)
10. └─arrow:::collect.arrow_dplyr_query(.)
11. └─arrow:::do_exec_plan(x)
12. └─plan$Build(.data)
13. └─node$Project(projection)
14. ├─self$preserve_sort(ExecNode_Project(self, cols, names(cols)))
15. └─arrow:::ExecNode_Project(self, cols, names(cols))
── Error (test-dplyr-lubridate.R:205:3): extract isoweek from date ─────────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions

I suppose we then need ISOWeek and USWeek declared with options in the API.

@lidavidm

Copy link
Copy Markdown
Member

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@lidavidm oh, didn't realize it had to be there.
Maybe would be good to add R tests as well then?

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits on style/wording.

If you're up to add R tests, I think that would be appreciated, but otherwise we can put that in a follow-up JIRA (since there might be other work to bind the new kernels to dplyr features or whatnot).

Comment threadr/src/compute.cpp Outdated
Comment threaddocs/source/cpp/compute.rst Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, can we put comments for the parameter literals? Or actually, it might be nice to define WeekOptions::IsoDefaults and WeekOptions::UsDefaults which could then be used here and in the R bindings.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added WeekOptions::ISODefaults and WeekOptions::USDefaults.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a helper for USWeek?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to be missing its counterpart in api_scalar.cc.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13561 branch 3 times, most recently from 1d4a49c to 4f68c1cCompareSeptember 23, 2021 14:49

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @lidavidm ! :)

@rok
rok requested a review from pitrouSeptember 23, 2021 16:04

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased, will merge

@rok

rok commented Sep 27, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
This is to resolve [ARROW-13561](https://issues.apache.org/jira/browse/ARROW-13561`).
Closesapache#11026 from rok/ARROW-13561
Lead-authored-by: Rok <rok@mihevc.org>
Co-authored-by: Rok Mihevc <rok@mihevc.org>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@rok@lidavidm@ianmcook@nealrichardson@pitrou@jorisvandenbossche
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions - #11026

Closed
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561
Closed

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions#11026
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561

Conversation

@rok

@rokrok commented Aug 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13561.

@github-actions

Copy link
Copy Markdown

@rok

rok commented Aug 28, 2021

Copy link
Copy Markdown
MemberAuthor

Shall we also change DayOfWeekOptions to WeekOptions? It would be a better fit overall if this PR is merged.

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from f8d1e4c to 6997246CompareAugust 29, 2021 11:38
@rok
rokforce-pushed the ARROW-13561 branch 4 times, most recently from 33b27e7 to 4a1b8a7CompareAugust 30, 2021 10:59

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

@lidavidm

Copy link
Copy Markdown
Member

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

I'm just trying to understand if it does :)

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

This evaluates to true in MySQL on sqlfiddle:

SELECT WEEK('2008-1-6', 1) != WEEK('2008-1-6', 4)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from 18a2b49 to 69eed89CompareAugust 30, 2021 22:09
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given ISOWeek is a special case of Week now, maybe we should just have one kernel (and perhaps some conveniences, e.g. DayOfWeekOptions::IsoWeek())?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a nice idea.
I'm still trying to exactly match WEEK from MySQL and once I do I'll look into this. Sorry for the WIP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no worries. I can hold off looking at this until you're ready.

@rokrokAug 31, 2021

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early feedback is great though! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this? Since it seems the two kernels are very similar.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

@ianmcook This now covers MySQL WEEK modes 1, 3, 4 and 6 (week 1 is the first week with 4 or more days this year).
If we want to cover modes 0, 2, 5, and 7 (week 1 is the first week with a Monday/Sunday in this year) we could add another parameter e.g.: DayOfWeekOptions.week_start_in_year. Do you think we should?

Another thing to note here is that DayOfWeekOptions.one_based_numbering doesn't exactly mean we count from 0 or 1 but rather that a date from iso week 52 of previous year that is in this year will be counted as 0 instead of 52. It's a MySQL convention.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

we could to add another parameter e.g.: DayOfWeekOptions.week_start_in_year.

Perhaps DayOfWeekOptions.count_full_weeks is more idiomatic.

@lidavidm

Copy link
Copy Markdown
Member

If the option doesn't apply to DayOfWeek, maybe it should be a separate WeekOptions in that case.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

So then we now have:
DayOfWeekOptions with week_start and one_based_numbering

We would need to add three binary parameters to match the 8 modes of MySQL:

  • WeekOptions with week_start (first day of week),count_from_zero (range), count_full_weeks (week 1 is ..)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

I tried adding WeekOptions with the following parameters:

 /// What day does the week start with (Monday=true, Sunday=false)
bool week_starts_monday;
/// Days in current year that fall into last years ISO week return week 0 if true
bool count_from_zero;
/// Is the first week fully in the the year or only its 4 or more days
bool first_week_in_year;

I've also added tests with all the MySQL modes. Docs and the logic need some more work, but first: do we go this way or stick to iso week only?

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from ef87424 to 062e5f2CompareSeptember 2, 2021 10:02
@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

@lidavidm@pitrou I've removed the ISOWeek kernel and added iso_week and us_week functions that use week with specific options.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

R CI is reporting:

── Error (test-dplyr-lubridate.R:80:3): extract isoweek from timestamp ─────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions
Backtrace:
█
1. ├─arrow:::expect_dplyr_equal(...) test-dplyr-lubridate.R:80:2
2. │ ├─testthat::expect_warning(...) helper-expectation.R:101:4
3. │ │ └─testthat:::quasi_capture(enquo(object), label, capture_warnings)
4. │ │ ├─testthat:::.capture(...)
5. │ │ │ └─base::withCallingHandlers(...)
6. │ │ └─rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
7. │ └─rlang::eval_tidy(expr, rlang::new_data_mask(rlang::env(input = record_batch(tbl))))
8. ├─input %>% mutate(x = isoweek(datetime)) %>% collect()
9. ├─dplyr::collect(.)
10. └─arrow:::collect.arrow_dplyr_query(.)
11. └─arrow:::do_exec_plan(x)
12. └─plan$Build(.data)
13. └─node$Project(projection)
14. ├─self$preserve_sort(ExecNode_Project(self, cols, names(cols)))
15. └─arrow:::ExecNode_Project(self, cols, names(cols))
── Error (test-dplyr-lubridate.R:205:3): extract isoweek from date ─────────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions

I suppose we then need ISOWeek and USWeek declared with options in the API.

@lidavidm

Copy link
Copy Markdown
Member

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@lidavidm oh, didn't realize it had to be there.
Maybe would be good to add R tests as well then?

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits on style/wording.

If you're up to add R tests, I think that would be appreciated, but otherwise we can put that in a follow-up JIRA (since there might be other work to bind the new kernels to dplyr features or whatnot).

Comment threadr/src/compute.cpp Outdated
Comment threaddocs/source/cpp/compute.rst Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, can we put comments for the parameter literals? Or actually, it might be nice to define WeekOptions::IsoDefaults and WeekOptions::UsDefaults which could then be used here and in the R bindings.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added WeekOptions::ISODefaults and WeekOptions::USDefaults.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a helper for USWeek?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to be missing its counterpart in api_scalar.cc.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13561 branch 3 times, most recently from 1d4a49c to 4f68c1cCompareSeptember 23, 2021 14:49

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @lidavidm ! :)

@rok
rok requested a review from pitrouSeptember 23, 2021 16:04

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased, will merge

@rok

rok commented Sep 27, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
This is to resolve [ARROW-13561](https://issues.apache.org/jira/browse/ARROW-13561`).
Closesapache#11026 from rok/ARROW-13561
Lead-authored-by: Rok <rok@mihevc.org>
Co-authored-by: Rok Mihevc <rok@mihevc.org>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@rok@lidavidm@ianmcook@nealrichardson@pitrou@jorisvandenbossche
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions - #11026

Closed
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561
Closed

ARROW-13561: [C++] Implement week kernel that accepts WeekOptions#11026
rok wants to merge 11 commits into
apache:masterfrom
rok:ARROW-13561

Conversation

@rok

@rokrok commented Aug 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13561.

@github-actions

Copy link
Copy Markdown

@rok

rok commented Aug 28, 2021

Copy link
Copy Markdown
MemberAuthor

Shall we also change DayOfWeekOptions to WeekOptions? It would be a better fit overall if this PR is merged.

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from f8d1e4c to 6997246CompareAugust 29, 2021 11:38
@rok
rokforce-pushed the ARROW-13561 branch 4 times, most recently from 33b27e7 to 4a1b8a7CompareAugust 30, 2021 10:59

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

@lidavidm

Copy link
Copy Markdown
Member

So essentially, ISOWeek starts from 1, Week starts from 0, and neither use DayOfWeekOptions.week_start? In that case I would just make them two optionless kernels.

To get parity with MySQLDayOfWeekOptions.week_start should be settable either 1 or 7.

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

Ah, ok. But unless I'm mistaken, week_start is not actually used by the week kernel.

I'm just trying to understand if it does :)

@rok

rok commented Aug 30, 2021

Copy link
Copy Markdown
MemberAuthor

This evaluates to true in MySQL on sqlfiddle:

SELECT WEEK('2008-1-6', 1) != WEEK('2008-1-6', 4)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from 18a2b49 to 69eed89CompareAugust 30, 2021 22:09
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given ISOWeek is a special case of Week now, maybe we should just have one kernel (and perhaps some conveniences, e.g. DayOfWeekOptions::IsoWeek())?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a nice idea.
I'm still trying to exactly match WEEK from MySQL and once I do I'll look into this. Sorry for the WIP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no worries. I can hold off looking at this until you're ready.

@rokrokAug 31, 2021

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early feedback is great though! :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this? Since it seems the two kernels are very similar.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

@ianmcook This now covers MySQL WEEK modes 1, 3, 4 and 6 (week 1 is the first week with 4 or more days this year).
If we want to cover modes 0, 2, 5, and 7 (week 1 is the first week with a Monday/Sunday in this year) we could add another parameter e.g.: DayOfWeekOptions.week_start_in_year. Do you think we should?

Another thing to note here is that DayOfWeekOptions.one_based_numbering doesn't exactly mean we count from 0 or 1 but rather that a date from iso week 52 of previous year that is in this year will be counted as 0 instead of 52. It's a MySQL convention.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

we could to add another parameter e.g.: DayOfWeekOptions.week_start_in_year.

Perhaps DayOfWeekOptions.count_full_weeks is more idiomatic.

@lidavidm

Copy link
Copy Markdown
Member

If the option doesn't apply to DayOfWeek, maybe it should be a separate WeekOptions in that case.

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

So then we now have:
DayOfWeekOptions with week_start and one_based_numbering

We would need to add three binary parameters to match the 8 modes of MySQL:

  • WeekOptions with week_start (first day of week),count_from_zero (range), count_full_weeks (week 1 is ..)
ModeFirst day of weekRangeWeek 1 is the first week
0Sunday0-53with a Sunday in this year
1Monday0-53with 4 or more days this year
2Sunday1-53with a Sunday in this year
3Monday1-53with 4 or more days this year
4Sunday0-53with 4 or more days this year
5Monday0-53with a Monday in this year
6Sunday1-53with 4 or more days this year
7Monday1-53with a Monday in this year

@rok

rok commented Sep 1, 2021

Copy link
Copy Markdown
MemberAuthor

I tried adding WeekOptions with the following parameters:

 /// What day does the week start with (Monday=true, Sunday=false)
bool week_starts_monday;
/// Days in current year that fall into last years ISO week return week 0 if true
bool count_from_zero;
/// Is the first week fully in the the year or only its 4 or more days
bool first_week_in_year;

I've also added tests with all the MySQL modes. Docs and the logic need some more work, but first: do we go this way or stick to iso week only?

@rok
rokforce-pushed the ARROW-13561 branch 2 times, most recently from ef87424 to 062e5f2CompareSeptember 2, 2021 10:02
@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

@lidavidm@pitrou I've removed the ISOWeek kernel and added iso_week and us_week functions that use week with specific options.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

R CI is reporting:

── Error (test-dplyr-lubridate.R:80:3): extract isoweek from timestamp ─────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions
Backtrace:
█
1. ├─arrow:::expect_dplyr_equal(...) test-dplyr-lubridate.R:80:2
2. │ ├─testthat::expect_warning(...) helper-expectation.R:101:4
3. │ │ └─testthat:::quasi_capture(enquo(object), label, capture_warnings)
4. │ │ ├─testthat:::.capture(...)
5. │ │ │ └─base::withCallingHandlers(...)
6. │ │ └─rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
7. │ └─rlang::eval_tidy(expr, rlang::new_data_mask(rlang::env(input = record_batch(tbl))))
8. ├─input %>% mutate(x = isoweek(datetime)) %>% collect()
9. ├─dplyr::collect(.)
10. └─arrow:::collect.arrow_dplyr_query(.)
11. └─arrow:::do_exec_plan(x)
12. └─plan$Build(.data)
13. └─node$Project(projection)
14. ├─self$preserve_sort(ExecNode_Project(self, cols, names(cols)))
15. └─arrow:::ExecNode_Project(self, cols, names(cols))
── Error (test-dplyr-lubridate.R:205:3): extract isoweek from date ─────────────
Error: Invalid: Attempted to initialize KernelState from null FunctionOptions

I suppose we then need ISOWeek and USWeek declared with options in the API.

@lidavidm

Copy link
Copy Markdown
Member

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Yeah, we'd need a case here:

std::shared_ptr<arrow::compute::FunctionOptions> make_compute_options(

@lidavidm oh, didn't realize it had to be there.
Maybe would be good to add R tests as well then?

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits on style/wording.

If you're up to add R tests, I think that would be appreciated, but otherwise we can put that in a follow-up JIRA (since there might be other work to bind the new kernels to dplyr features or whatnot).

Comment threadr/src/compute.cpp Outdated
Comment threaddocs/source/cpp/compute.rst Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, can we put comments for the parameter literals? Or actually, it might be nice to define WeekOptions::IsoDefaults and WeekOptions::UsDefaults which could then be used here and in the R bindings.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added WeekOptions::ISODefaults and WeekOptions::USDefaults.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a helper for USWeek?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to be missing its counterpart in api_scalar.cc.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13561 branch 3 times, most recently from 1d4a49c to 4f68c1cCompareSeptember 23, 2021 14:49

@lidavidmlidavidm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

@rok

rok commented Sep 23, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @lidavidm ! :)

@rok
rok requested a review from pitrouSeptember 23, 2021 16:04

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased, will merge

@rok

rok commented Sep 27, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
This is to resolve [ARROW-13561](https://issues.apache.org/jira/browse/ARROW-13561`).
Closesapache#11026 from rok/ARROW-13561
Lead-authored-by: Rok <rok@mihevc.org>
Co-authored-by: Rok Mihevc <rok@mihevc.org>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@rok@lidavidm@ianmcook@nealrichardson@pitrou@jorisvandenbossche