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
Fix reading Iceberg stats when table has nested fields #8647
Conversation
6009357
to
602d85a
Compare
602d85a
to
bd760af
Compare
.projected(0, 2, 3, 4, 5, 6) // ignore data size which is available for Parquet, but not for ORC | ||
.skippingTypesCheck() | ||
.matches("VALUES " + | ||
// TODO (https://github.com/trinodb/trino/issues/8648) the NDV numbers are wrong, should be 1, not 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't projected index 3 map to nulls-fraction which is correctly 0?
spec mentions that distinct values are deprecated anyway, so keeping them null (index 2) seems fine to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@phd3 good catch. i fell into my own trap here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was surprised to see that these were deprecated, but it looks like they were just added back: apache/iceberg#2805
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@electrum i don't think per-file NDV is that useful, unless query is very selective.
Do we return them today, if they are present?
Since things like apache/iceberg#2805 depend on the writer, i guess we need to have SHOW STATS coverage with Trino and Spark writers.
cc @joshthoward
plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/BaseIcebergConnectorTest.java
Outdated
Show resolved
Hide resolved
The method is oneliner. This also makes `PartitionTable#getPartitions` even more similar to analogous code inside `TableStatisticsMaker#makeTableStatistics` method.
be06564
to
e2e1d03
Compare
Looks good to me, just checking that the other changes in the existing PR to fix this issue wound up not being necessary? https://github.com/trinodb/trino/pull/8337/files#diff-b610df3211e6549a57e131f03074eb1b133c6ab227cf4a0ae3868758d4c40491R294 |
I think |
this.idToTypeMapping = icebergTable.schema().columns().stream() | ||
.filter(column -> column.type().isPrimitiveType()) | ||
.collect(Collectors.toMap(Types.NestedField::fieldId, (column) -> column.type().asPrimitiveType())); | ||
this.idToTypeMapping = primitiveFieldTypes(icebergTable.schema()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should somehow indicate/note that the idToTypeMapping
contains the source fields instead of transformed ones. Not sure how though.
Only PartitionField
refers to transformed field and to get to source field you need to use PartitionField#sourceId
. The inconsistency is a bit confusing to me but that all happens within Iceberg API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should somehow indicate/note that the idToTypeMapping contains the source fields instead of transformed ones.
this didn't change, right?
Only PartitionField refers to transformed field and to get to source field you need to use PartitionField#sourceId.
We could narrow the map to only partition fields (and rename appropriately) , is that what you mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing changed - I'm just expressing frustration at something which I had to spend a bit of time fighting when debugging a past issue. 🙂
I don't think we can do anything other than people being aware of the difference between PartitionField
and NestedField
even though they sound the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
.projected(0, 2, 3, 4, 5, 6) // ignore data size which is available for Parquet, but not for ORC | ||
.skippingTypesCheck() | ||
.matches("VALUES " + | ||
// TODO (https://github.com/trinodb/trino/issues/8648) the NDV numbers are wrong, should be 1, not 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't projected index 3 map to nulls-fraction which is correctly 0?
spec mentions that distinct values are deprecated anyway, so keeping them null (index 2) seems fine to me.
@@ -227,7 +227,7 @@ public void updateNullCount(Map<Integer, Long> nullCounts) | |||
this.nullCounts.merge(key, counts, Long::sum)); | |||
} | |||
|
|||
public static Map<Integer, Object> toMap(Map<Integer, Type.PrimitiveType> idToTypeMapping, Map<Integer, ByteBuffer> idToMetricMap) | |||
public static Map<Integer, Object> convertBounds(Map<Integer, Type.PrimitiveType> idToTypeMapping, Map<Integer, ByteBuffer> idToMetricMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional: the method doesn't have anything specific to "bounds". May be convertToValues
or getValuesFromByteBuffers
, or convertMetrics
, but don't have a suggestion that sounds obviously better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the method doesn't have anything specific to "bounds".
i think it actually has, because bounds come as byte buffers, whole ordinary partition values do not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeping current iceberg data structures aside, is there a reason why logically byte buffers would be more suitable for representing bounds, and hence this naming is more appropriate?
(either way convertBounds reads more easily than toMap, so feel free to resolve this.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason why logically byte buffers would be more suitable for representing bounds
i don't see why we would use different representation in different code paths.
some performance reason?
or some unintentional API difference?
i need to find out.
(also seen here:
trino/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/PartitionTable.java
Line 293 in 4e30d82
// Partition values are passed as String, but min/max values are passed as a CharBuffer |
(either way convertBounds reads more easily than toMap, so feel free to resolve this.)
👍
e2e1d03
to
c8a933d
Compare
Fixes #7999