Core: Add id tracking to MetricsConfig#17022
Conversation
3a5cd12 to
173594a
Compare
| } | ||
|
|
||
| @Test | ||
| public void testColumnModeAndFieldIdsFromColumnConfig() { |
There was a problem hiding this comment.
These are the tests for new behavior.
| } | ||
| } | ||
|
|
||
| public void validateReferencedColumns(Schema schema) { |
There was a problem hiding this comment.
These were moved above the private and static methods. It was hard to find them before.
| public static MetricsConfig forPositionDelete(Table table) { | ||
| ImmutableMap.Builder<String, MetricsMode> columnModes = ImmutableMap.builder(); | ||
| public Iterable<Integer> metricsFieldIds() { | ||
| return idToName.keySet(); |
There was a problem hiding this comment.
Should this return an empty list if idToName is null?
There was a problem hiding this comment.
No, I think it should fail if idToName is null because there could be a configuration, but the config wasn't initialized the right way. If idToName is null, then it was initialized without a schema, which we want to stop doing.
There was a problem hiding this comment.
I've updated this (and columnMode(int)) to check that idToName is present and throw an exception if not. That way, when we get rid of fromProperties, we can get rid of the check.
| Map<Integer, String> idToName) { | ||
| this.columnModes = SerializableMap.copyOf(columnModes).immutableMap(); | ||
| this.defaultMode = defaultMode; | ||
| if (idToName != null) { |
There was a problem hiding this comment.
Ok it's a bit confusing because there are accessor APIs below which assume that idToName is not null. Currently, we pass it in, but I'm not sure I understand the intent of if (idToName != null) check is. It's a private constructor, can't we force every where else to pass in the idToName and then work off that assumption that it's always defined?
There was a problem hiding this comment.
Right now, I don't think that we can force every code path to provide a schema, which is how this is derived. That would be more changes and those code paths don't need to use IDs, so I left it out. For instance, fromProperties is still defined (until next release) and we can't fake a schema for that call. We could cause it to fail, but that would defeat the purpose of deprecating it.
The approach I took here was to use idToName if it is present. I thought this was a better option than causing external calls to fromProperties to fail. We can tighten this up after the next release when we can guarantee all code paths pass a schema.
There was a problem hiding this comment.
Got it, okay I missed the original fromProperties, yeah in that case we can just keep it as is.
There was a problem hiding this comment.
I added assertions to ensure we don't get NPEs. We can remove them once idToName is always present.
| table == null | ||
| ? MetricsConfig.forPositionDelete() | ||
| : MetricsConfig.forPositionDelete(table); | ||
| MetricsConfig metricsConfig = MetricsConfig.forPositionDelete(); |
There was a problem hiding this comment.
Since we're just calling MetricsConfig.forPositionDelete(), now we're falling through to the default truncate(16) and changing what we collect bounds on (and it looks like Spark CI is failing). It is a behavior change for the position deletes where rows are stored but iirc nobody really even writes those and that was on a deprecation path anyways.
There was a problem hiding this comment.
Agreed, I have a separate PR aimed to remove deprecated method for 1.12 which include the MetricsConfig.forPositionDelete(table) in #16449
There was a problem hiding this comment.
I updated this to use None by default and fixed the tests so they are passing.
amogh-jahagirdar
left a comment
There was a problem hiding this comment.
Looks correct to me, we'll just need to fixup the wong preconditions import before we merge!
| schema); | ||
|
|
||
| ValidationException.check( | ||
| null == idToName || column.equals(idToName.get(field.fieldId())), |
There was a problem hiding this comment.
was thinking about the field rename and preserve the field id but I believe it's already covered in schema update https://github.com/apache/iceberg/blob/main/core/src/main/java/org/apache/iceberg/SchemaUpdate.java#L517-L524
| assertThat(bounds).hasSize(4); | ||
| assertThat((int) Conversions.fromByteBuffer(Types.IntegerType.get(), bounds.get(1))) | ||
| .isEqualTo(3); | ||
| assertThat(bounds).hasSize(2); |
There was a problem hiding this comment.
nit: we should be able to make a one-liner out of this entire check: assertThat(bounds).hasSize(2).doesNotContainKeys(1, 2, 3, 4, 5);
There was a problem hiding this comment.
also maybe we can just inline this check into the test that uses it and remove checkRowStatistics(), since it's really only used in a single test
| */ | ||
| public interface MetricsMode extends Serializable {} | ||
| public interface MetricsMode extends Serializable { | ||
| default boolean hasBounds() { |
There was a problem hiding this comment.
is this used anywhere? it's not clear from the PR description why this is being added
|
@nastra, sorry I missed your comments, I should have reloaded. I just saw tests passing and merged. The |
Metrics modes are configured in table properties based on column names, but content stats needs to look up
MetricsModebased on column ID. This adds support to look up metrics mode by ID,columnMode(int), and adds an accessor for the IDs for which there is a metrics mode. This is needed to build a table's current content stats struct for writing.This also cleans up a couple of issues with
MetricsConfig:forPositionDelete(Table)instead of modifying its behavior. Also removes uses of this deprecated method, usingforPositionDelete()instead.fromPropertiesto 1.13.0 instead of 2.0.0 because this is in core. Also removes uses of this deprecated method, which should be done when it is deprecated.validate(Map<String, String>,Schema)to replace uses offromProperties