Skip to content

Use any instead of for_each - #15289

Merged
xudong963 merged 1 commit into
apache:mainfrom
xudong963:refactor_2
Mar 21, 2025
Merged

Use any instead of for_each#15289
xudong963 merged 1 commit into
apache:mainfrom
xudong963:refactor_2

Conversation

@xudong963

@xudong963xudong963 commented Mar 18, 2025

Copy link
Copy Markdown
Member

Which issue does this PR close?

  • Closes #.

Rationale for this change

The statistics are calculated only for columns in the table schema that actually have statistics available in the parquet metadata, avoiding unnecessary work.

What changes are included in this PR?

Are these changes tested?

Are there any user-facing changes?

@berkaysynnadaberkaysynnada left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of either "try for all" or "skip at all", isn't better to only go over the columns which has statistics.is_some() ?

@xudong963

Copy link
Copy Markdown
MemberAuthor

Instead of either "try for all" or "skip at all", isn't better to only go over the columns which has statistics.is_some() ?

Do you mean the following?

// Instead of a single boolean flaglet columns_with_statistics:Vec<_> = row_group_meta.columns().iter().enumerate().filter_map(|(idx, column)| {if column.statistics().is_some(){Some(idx)}else{None}}).collect();// Then later, when processing column statisticsfor(col_idx, field)in table_schema.fields().iter().enumerate(){if columns_with_statistics.contains(&col_idx){// Process only columns that have statistics// Use the statistics converter and update min/max accumulators}}

@berkaysynnada

Copy link
Copy Markdown
Contributor

Instead of either "try for all" or "skip at all", isn't better to only go over the columns which has statistics.is_some() ?

Do you mean the following?

yep, even withing a single iteration after zipping

@xudong963xudong963 changed the title Use any instead of for_eachImprove the calculation of statistics in statistics_from_parquet_meta_calcMar 18, 2025
@xudong963
xudong963 marked this pull request as draft March 18, 2025 09:56
@github-actionsgithub-actionsBot added the functions Changes to functions implementation label Mar 19, 2025
Comment threaddatafusion/datasource-parquet/src/file_format.rs Outdated
@xudong963
xudong963 marked this pull request as ready for review March 19, 2025 09:32
@xudong963
xudong963 marked this pull request as draft March 19, 2025 16:55
@xudong963

Copy link
Copy Markdown
MemberAuthor

I have some new thoughts for the PR, still not ready to review.

@github-actionsgithub-actionsBot removed the functions Changes to functions implementation label Mar 21, 2025
@xudong963

Copy link
Copy Markdown
MemberAuthor

Instead of either "try for all" or "skip at all", isn't better to only go over the columns which has statistics.is_some() ?

In fact, even if a column in table_schema doesn't have the corresponding statistics in row_group_meta, it also may need to go summarize_min_max_null_counts to set statistics with null.

@xudong963xudong963 changed the title Improve the calculation of statistics in statistics_from_parquet_meta_calcUse any instead of for_eachMar 21, 2025
total_byte_size += row_group_meta.total_byte_size() as usize;

if !has_statistics {
row_group_meta.columns().iter().for_each(|column| {

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.

The key issue is how has_statistics is assigned within the for_each loop. During iteration, the value of has_statistics is overwritten by each column's statistics status.

Example Scenario

Assume there are 2 columns with the following statistics status:

  • Column 1: Has statistics (statistics is Some)
  • Column 2: No statistics (statistics is None)

Execution process:

  • Processing Column 1: has_statistics becomes true
  • Processing Column 2: has_statistics becomes false

if the last column processed has no statistics, the final value of has_statistics would be false.

if the goal is to check "whether any column has statistics", a more suitable approach would be to use any

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You are right, I wasn't oppose to your change. I was just thinking a further refactor of unifying these two iterations:

 row_group_meta.columns().iter().for_each(|column| {
has_statistics = column.statistics().is_some();});

and

 table_schema
.fields().iter().enumerate().for_each(|(idx, field)| {
...

but maybe not worth to try

@xudong963xudong963Mar 21, 2025

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.

Yes, because even if a column in table_schema doesn't have the corresponding statistics in row_group_meta, it also may need to go summarize_min_max_null_counts to set statistics with null., I think it isn't worth trying.

In fact, I have tried it, and it doesn't make much sense, they (row_group_meta.columns() and table_schema.fields())are not always aligned.

@xudong963
xudong963 marked this pull request as ready for review March 21, 2025 09:38
@xudong963
xudong963 requested a review from alambMarch 21, 2025 09:39
@xudong963

Copy link
Copy Markdown
MemberAuthor

Thanks for your review @berkaysynnada@alamb

@xudong963
xudong963 merged commit 7c902de into apache:mainMar 21, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@xudong963@berkaysynnada@alamb