Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support partitioning on nested ROW fields in Iceberg #15712

Merged
merged 2 commits into from
Jun 24, 2024

Conversation

krvikash
Copy link
Contributor

@krvikash krvikash commented Jan 13, 2023

Description

Fixes #15109
Support partitioning on nested ROW fields in Iceberg

Release notes

( ) This is not user-visible or docs only and no release notes are required.
( ) Release notes are required, please propose a release note for me.
(X) Release notes are required, with the following suggested text:

# Iceberg
* Add support for partitioning on nested ROW fields. ({issue}`15712`)

@ebyhr
Copy link
Member

ebyhr commented Jan 17, 2023

@krvikash Could you rebase on upstream to resolve conflicts?

@krvikash krvikash force-pushed the support-nested-partitioning-fields branch 2 times, most recently from 0d38c8c to 53011d6 Compare January 17, 2023 10:11
@krvikash
Copy link
Contributor Author

Rebased the PR with latest code.

assertThat(onTrino().executeQuery(format(selectByString, trinoTableName)))
.containsOnly(row1);
// TODO
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO task. Parquet format returning null for partition nested field.

Copy link
Contributor

Choose a reason for hiding this comment

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

If Spark Iceberg can't handle this kind of use-case please see whether there is already reported an issue to address this missing functionality.
We shouldn't introduce TODOs in the code relating to Spark limitations. Trino does not depend on Spark.

Simply add an assertion that the query is failing with an expected message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could not find any existing issue for PARQUET issue. Where Saprk returns null for the partitioned nested field.

@krvikash krvikash force-pushed the support-nested-partitioning-fields branch from 53011d6 to 46d91a8 Compare January 23, 2023 13:48
@krvikash
Copy link
Contributor Author

Hi, @alexjo2144 | @ebyhr | @findepi | @findepi, when you get time could you please review this?

@krvikash krvikash force-pushed the support-nested-partitioning-fields branch from 46d91a8 to dbf698f Compare January 26, 2023 08:17
@krvikash
Copy link
Contributor Author

Rebased the PR with latest code.

assertThat(onTrino().executeQuery(format(selectByString, trinoTableName)))
.containsOnly(row1);
// TODO
Copy link
Contributor

Choose a reason for hiding this comment

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

If Spark Iceberg can't handle this kind of use-case please see whether there is already reported an issue to address this missing functionality.
We shouldn't introduce TODOs in the code relating to Spark limitations. Trino does not depend on Spark.

Simply add an assertion that the query is failing with an expected message.


Row row1 = row("a", new byte[] {15, -15, 2, -16, -2, -1}, 1001, "field1");
String select = "SELECT _string, _varbinary, _bigint, _struct._field FROM %s WHERE _string = 'a'";
// ORC: Job aborted due to stage failure: Task 0 in stage 40.0 failed 1 times, most recent failure: Lost task 0.0 in stage 40.0 (TID 70) (spark executor driver): java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as for Parquet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could not find any existing issue for PARQUET issue. Where Saprk returns null for the partitioned nested field.

Copy link
Member

@alexjo2144 alexjo2144 left a comment

Choose a reason for hiding this comment

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

Can you also add some predicate pushdown tests? Similar to one of these tests that use isFullyPushedDown https://github.com/trinodb/trino/blob/master/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/BaseIcebergConnectorTest.java#L1611

Comment on lines 759 to 767
int parentSourceId = getParentSourceId(indexParents, field.sourceId());
Type sourceType = tableSchema.findType(parentSourceId);
if (sourceType.isMapType()) {
throw new TrinoException(NOT_SUPPORTED, "Partitioning field [" + field.name() + "] cannot be contained in a map");
}
if (sourceType.isListType()) {
throw new TrinoException(NOT_SUPPORTED, "Partitioning field [" + field.name() + "] cannot be contained in a array");
}
return requireNonNull(columnById.get(parentSourceId), () -> "Cannot find source column for partition field " + field);
Copy link
Member

Choose a reason for hiding this comment

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

This block is a bit confusing to me since it relies on getParentSourceId returning the field id that was passed to it if it's already a base column. Is an integer column the parent of itself? That's fuzzy. I might rephrase it as

boolean isBaseColumn = !parentIndex.contains(fieldId);
if (isBaseColumn) {
    ...
}
else {
    ...
}

.map(column -> {
org.apache.iceberg.types.Type type = toIcebergType(column.getType());
if (!type.isPrimitiveType()) {
type = TypeUtil.assignFreshIds(type, nextNestedFieldId::getAndIncrement);
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't seem right to me.
Doing tricks like this can get us into trouble (there are some syntethic columns - see org.apache.iceberg.MetadataColumns#FILE_PATH ) which have the id set to Integer.MAX_VALUE - 1. Incrementing this value to get artificially a new field id for the row can lead to problems.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was looking for where schemaFromHandles is being used and found the following:

  • deletes handling in IcebergPageSourceProvider
  • bucketing function in IcebergNodePartitioningProvider

In both places we do have schema available.

Please investigate whether using schema in schemaFromHandles would be possible.
If yes, we could work with TypeUtil.indexParents(schema) to get only the extra "row" contents we need from the schema.

Copy link
Member

Choose a reason for hiding this comment

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

This is related to some changes in #14837

Maybe we can pull some of those changes in here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, @findinpath | @alexjo2144 for pointing this out. I have added some changes from #14837 and now I do not need to reassign indexes.

IMO, It will be better if #14837 gets merged first because the current PR contains changes, that are unrelated to the supporting partitioning field.

@github-actions
Copy link

This pull request has gone a while without any activity. Tagging the Trino developer relations team: @bitsondatadev @colebow @mosabua

@github-actions github-actions bot added the stale label Feb 27, 2023
@findepi
Copy link
Member

findepi commented Feb 28, 2023

@krvikash @alexjo2144 @findinpath I see no approvals and some yet unresolved conversations. Where are we with the PR?

@ebyhr
Copy link
Member

ebyhr commented Feb 28, 2023

I believe this PR is waiting for #14837 (#15712 (comment))

@github-actions github-actions bot removed the stale label Feb 28, 2023
@krvikash krvikash force-pushed the support-nested-partitioning-fields branch from 9d97902 to 958a762 Compare March 1, 2023 05:16
@krvikash
Copy link
Contributor Author

krvikash commented Mar 1, 2023

Rebased on top of #14837 's commit and resolved conflicts. This PR (2nd commit of this PR) is ready for review now.

@krvikash
Copy link
Contributor Author

krvikash commented Mar 7, 2024

(some refactoring in TestIcebergV2)

@ebyhr ebyhr force-pushed the support-nested-partitioning-fields branch 2 times, most recently from e2afa24 to 39c59dd Compare March 19, 2024 10:22
List<Integer> path = new ArrayList<>(requireNonNull(indexPaths.get(fieldId)));
if (!path.isEmpty()) {
// Path does not include the base field id
baseField = indexById.get(path.removeFirst());
Copy link
Contributor

Choose a reason for hiding this comment

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

It is hard to follow what is happening when we have mutations.

Why do we remove the first element from the list?

Copy link
Member

Choose a reason for hiding this comment

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

The first element is used for getting the root field id, but the element shouldn't exist for IcebergColumnHandle.path. I updated the comment and slightly modified the logic.

@ebyhr ebyhr force-pushed the support-nested-partitioning-fields branch from 39c59dd to 76e3886 Compare March 21, 2024 08:18
@ebyhr ebyhr force-pushed the support-nested-partitioning-fields branch from 76e3886 to bfe8da9 Compare April 3, 2024 05:53
@ebyhr
Copy link
Member

ebyhr commented Apr 3, 2024

Rebased on master to resolve conflicts.

@findinpath
Copy link
Contributor

Pls rebase the code to resolve conflicts.

Copy link

This pull request has gone a while without any activity. Tagging the Trino developer relations team: @bitsondatadev @colebow @mosabua

@github-actions github-actions bot added the stale label May 10, 2024
@ebyhr ebyhr added the stale-ignore Use this label on PRs that should be ignored by the stale bot so they are not flagged or closed. label May 10, 2024
@ebyhr ebyhr force-pushed the support-nested-partitioning-fields branch from bf37211 to 336ec37 Compare June 24, 2024 00:26
@ebyhr ebyhr merged commit a48a0a6 into trinodb:master Jun 24, 2024
52 checks passed
@github-actions github-actions bot added this to the 451 milestone Jun 24, 2024
@krvikash krvikash deleted the support-nested-partitioning-fields branch June 24, 2024 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed docs iceberg Iceberg connector stale stale-ignore Use this label on PRs that should be ignored by the stale bot so they are not flagged or closed.
Development

Successfully merging this pull request may close these issues.

Support partitioning on nested fields in Iceberg