') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); ARROW-16549: [C++] Simplify AggregateNodeOptions aggregates/targets by vibhatha · Pull Request #13150 · apache/arrow · GitHub
Skip to content

ARROW-16549: [C++] Simplify AggregateNodeOptions aggregates/targets - #13150

Merged
westonpace merged 32 commits into
apache:masterfrom
vibhatha:arrow-16549
Jun 27, 2022
Merged

ARROW-16549: [C++] Simplify AggregateNodeOptions aggregates/targets#13150
westonpace merged 32 commits into
apache:masterfrom
vibhatha:arrow-16549

Conversation

@vibhatha

@vibhathavibhatha commented May 13, 2022

Copy link
Copy Markdown
Contributor

This PR is simplifying the existing AggregateNodeOptions usage. This work is still in progress and need to evaluate the existing refactor and usage.

Todos

  • Test
  • Update documentation
  • Update function docs
  • Evaluate CI failures (only tested on Mac M1 with C++/Python, need to check if the change breaks other language bindings

@github-actions

Copy link
Copy Markdown

@lidavidm

Copy link
Copy Markdown
Member

FWIW, you can use "draft" status when something is WIP but you still want CI runs.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@lidavidm Yes, I want to run the CIs and see what is failing. Is it possible with a draft PR? (I mean selecting the draft option, I remember it pausing the CIs, may be I am mistaken.)

@lidavidm

Copy link
Copy Markdown
Member

Draft runs CI. Only "WIP" skips CI.

@vibhatha
vibhatha marked this pull request as draft May 17, 2022 11:51
@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

C Glib is WIP, but appreciate thoughts on the core change.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

Thank you @kou !!!
It is still failing for a different reason now.

@vibhatha
vibhatha marked this pull request as ready for review May 20, 2022 12:21
@westonpace
westonpace self-requested a review May 21, 2022 01:25
@kou

kou commented May 22, 2022

Copy link
Copy Markdown
Member

I've fixed C GLib failures.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

I've fixed C GLib failures.

Thank you @kou

Comment threadr/src/compute-exec.cpp Outdated
Comment threadr/R/query-engine.R Outdated
Comment threadr/R/query-engine.R Outdated
Comment threadr/R/query-engine.R 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.

If "target" and "name" are always the same, why are we passing them twice? Can't we reuse the same std::vector<std::string> in the C++ bindings?

Also, why put target names inside the aggregations elements when we're just going to pull them back out and make a vector in C++? If you pass target_names directly, you already have std::vector<std::string>.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah my_bad, I should have added an affix here.

The idea of this PR was to simplify the usage of AggregateNodeOptions. In that case, (referring to the JIRA) we thought it is better to put what is relevant to an aggregation within the object itself. It is not always the same, you're correct.

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.

For reference, the equivalent SQL is...

SELECT function_1(target_1) as name_1, function_2(target_2) as name_2, ... FROM ... GROUP BY ...

Each aggregate has (up to) three parts. The C++ is changing from passing in three vectors of strings (which is error-prone) to passing in one vectors of structs where each item has up to three parts.

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.

Ah got it, you're right, I misread, I see that you're making a vector of structs now, so disregard my last comment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@nealrichardson Since you pointed out the names and target being the same, in previous implementation they were set to the same value. As far as I understood, the test cases are also following that. Is it wise to affix this or just leave it as it is? I have doubts about which one to select.

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.

Hmm...do we have any test case doing something like...

mtcars %>% group_by(cyl)
%>% summarise(
disp_mean = mean(disp),
hp_mean = mean(hp)
)

I would expect target to be disp and name to be disp_mean. It's always possible we are renaming the columns somewhere else in the generated plan as well in which case name is meaningless here.

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.

Yeah I think what's happening (IIRC) is that we Project before Aggregate. So if someone does

mtcars %>% group_by(cyl)
%>% summarise(
disp_mean = mean(disp / hp)
)

we first project disp_mean = disp / hp and them aggregate over that.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@nealrichardson I will work on these suggestions, thank you!

@westonpacewestonpace 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 minor suggestions but overall this is looking good.

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.

We should convert this to std::unique_ptr<FunctionOptions> but I don't mind if we leave that for a follow-up PR.

@vibhathavibhathaMay 30, 2022

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

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.

Why should it be unique_ptr? It's not obvious there's a need for ownership here; also, the caller might want to keep ownership as well.

Comment threadcpp/src/arrow/compute/api_aggregate.h Outdated
Comment threadcpp/src/arrow/compute/api_aggregate.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.

I'm not sure this is correct. Ideally we would have something like...

aggregates=[{function=hash_sum<>,target=a,name=sum(a)}]

I think the way it is now it would print:

aggregates={hash_sum<a<sum_a<>,},

Comment threadr/R/query-engine.R 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.

Hmm...do we have any test case doing something like...

mtcars %>% group_by(cyl)
%>% summarise(
disp_mean = mean(disp),
hp_mean = mean(hp)
)

I would expect target to be disp and name to be disp_mean. It's always possible we are renaming the columns somewhere else in the generated plan as well in which case name is meaningless here.

Comment threadr/src/compute-exec.cpp Outdated
Comment on lines 978 to 972

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.

I don't think we should have to make these changes and they do not make the test easier to read. Could we change the definition of GroupByTest so that instead of taking in const std::vector<internal::Aggregate>& aggregates it takes in const std::vector<TestAggregate>& aggregates where we define:

struct TestAggregate {
std::string function;
const FunctionOptions* options;
};

The old style makes sense for these unit tests since we don't really care about what we are naming the columns.

@vibhatha
vibhathaforce-pushed the arrow-16549 branch 3 times, most recently from c1d7572 to d47bfeeCompareMay 31, 2022 08:16
@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@nealrichardson regarding the following

file=r/R/query-engine.R,line=18,col=1,functions should have cyclomatic complexity of less than 26, this has 28.

Should we create a few util functions external to theR6Class to mitigate this issue? What's the best?

Comment threadr/R/query-engine.R Outdated
@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@nealrichardson I think it resolved the CI issue. Thank you.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@westonpace should we take the Aggregate out from internal namespace?

@westonpace

Copy link
Copy Markdown
Member

@westonpace should we take the Aggregate out from internal namespace?

Yes.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@kou need some help with the C-Glib, when I rebased I tried to fix it, but didn't succeed. Appreciate your help.

@kou

kou commented Jun 23, 2022

Copy link
Copy Markdown
Member

Done.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

Done.

Thank you @kou

Comment threadr/R/query-engine.R Outdated
)
}
}
config_agg <- private$.set_aggregation(node, .data, grouped, group_vars)

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.

Sorry, I don't like this refactoring. I think it obfuscates what is happening here, and that's not worth doing just to try to trick a misguided linter. Would you mind reverting it? I'd rather tune the linting.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Sure I will. Do you mind just making it one function or do you want a full revert where there are no helper functions?

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.

Full revert, the helpers don't seem to be helping with the lint warning

@nealrichardson

Copy link
Copy Markdown
Member

I just pushed a commit applying the suggestion from #13150 (comment), and that makes the lint warning go away. Also updated the lintr config and added a reference to an issue about cyclocomp for R6 classes.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

I just pushed a commit applying the suggestion from #13150 (comment), and that makes the lint warning go away. Also updated the lintr config and added a reference to an issue about cyclocomp for R6 classes.

Thank you @nealrichardson I have missed that comment.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@nealrichardson the CI is failing here: https://github.com/apache/arrow/runs/7029848711?check_suite_focus=true#step:5:1040

Errorin linters_with_defaults(line_length_linter= line_length_linter(120), :couldnotfindfunction"linters_with_defaults"Calls:<Anonymous>->read_settings->get_setting->eval->eval

@nealrichardson

Copy link
Copy Markdown
Member

@nealrichardson the CI is failing here: https://github.com/apache/arrow/runs/7029848711?check_suite_focus=true#step:5:1040

Errorin linters_with_defaults(line_length_linter= line_length_linter(120), :couldnotfindfunction"linters_with_defaults"Calls:<Anonymous>->read_settings->get_setting->eval->eval

I backed out the lintr changes (they were just cleaning up warnings that show on the latest release of lintr, but we have pinned an old version elsewhere apparently). Will handle in ARROW-16900.

@vibhatha

Copy link
Copy Markdown
ContributorAuthor

@nealrichardson the CI is failing here: https://github.com/apache/arrow/runs/7029848711?check_suite_focus=true#step:5:1040

Errorin linters_with_defaults(line_length_linter= line_length_linter(120), :couldnotfindfunction"linters_with_defaults"Calls:<Anonymous>->read_settings->get_setting->eval->eval

I backed out the lintr changes (they were just cleaning up warnings that show on the latest release of lintr, but we have pinned an old version elsewhere apparently). Will handle in ARROW-16900.

Thanks @nealrichardson

@westonpacewestonpace 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 for sticking with this cleanup.

@westonpace
westonpace merged commit bb67f8d into apache:masterJun 27, 2022
@vibhatha

Copy link
Copy Markdown
ContributorAuthor

Appreciate the support !.

@assignUser

assignUser commented Jul 4, 2022

Copy link
Copy Markdown
Member

@github-actions crossbow submit verify-rc-source-cpp-macos-arm64 wheel-macos-big-sur-cp38-arm64

@github-actions

Copy link
Copy Markdown

Revision: 0a09d22

Submitted crossbow builds: ursacomputing/crossbow @ actions-17830e587b

TaskStatus
verify-rc-source-cpp-macos-arm64Github Actions
wheel-macos-big-sur-cp38-arm64Github Actions

vibhatha added a commit to vibhatha/arrow that referenced this pull request Jul 5, 2022
…pache#13150)
This PR is simplifying the existing `AggregateNodeOptions` usage. This work is still in progress and need to evaluate the existing refactor and usage. Todos
- [x] Test - [ ] Update documentation
- [ ] Update function docs
- [x] Evaluate CI failures (only tested on Mac M1 with C++/Python, need to check if the change breaks other language bindings
Authored-by: Vibhatha Abeykoon <vibhatha@gmail.com>
Signed-off-by: Weston Pace <weston.pace@gmail.com>
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.

8 participants

@vibhatha@lidavidm@kou@westonpace@nealrichardson@assignUser@pitrou@paleolimbot