Skip to content
Prev Previous commit
Next Next commit
fix tests and simplify
  • Loading branch information
dejangvozdenac committed Aug 14, 2025
commit a05ba32d6f2edcdea31193a8b63d383e508cc758
4 changes: 4 additions & 0 deletions .palantir/revapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,10 @@ acceptedBreaks:
new: "method void org.apache.iceberg.data.parquet.BaseParquetWriter<T>::<init>()"
justification: "Changing deprecated code"
"1.9.0":
org.apache.iceberg:iceberg-api:
Comment thread
dejangvozdenac marked this conversation as resolved.
Outdated
- code: "java.method.addedToInterface"
new: "method boolean org.apache.iceberg.Accessor<T>::hasOptionalFieldInPath()"
justification: "All subclasses implement name"
Comment thread
dejangvozdenac marked this conversation as resolved.
Outdated
org.apache.iceberg:iceberg-common:
- code: "java.method.visibilityReduced"
old: "method <R> R org.apache.iceberg.common.DynConstructors.Ctor<C>::invokeChecked(java.lang.Object,\
Expand Down
11 changes: 2 additions & 9 deletions api/src/main/java/org/apache/iceberg/Accessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,6 @@ public interface Accessor<T> extends Serializable {

Type type();

/**
* Returns true if any ancestor in the access path to this field is optional.
*/
boolean hasOptionalAncestor();

/**
* Returns true if this accessor is optional.
*/
boolean isOptional();
/** Returns true if the current field or any ancestor in the access path is optional. */
boolean hasOptionalFieldInPath();
Comment thread
dejangvozdenac marked this conversation as resolved.
Outdated
}
52 changes: 16 additions & 36 deletions api/src/main/java/org/apache/iceberg/Accessors.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ private static class PositionAccessor implements Accessor<StructLike> {
private final int position;
private final Type type;
private final Class<?> javaClass;
private final boolean isOptional;
private final boolean hasOptionalFieldInPath;

PositionAccessor(int pos, boolean isOptional, Type type) {
Comment thread
dejangvozdenac marked this conversation as resolved.
Outdated
this.position = pos;
this.type = type;
this.javaClass = type.typeId().javaClass();
this.isOptional = isOptional;
this.hasOptionalFieldInPath = isOptional;
}

@Override
Expand All @@ -87,13 +87,8 @@ public Class<?> javaClass() {
}

@Override
public boolean isOptional() {
return isOptional;
}

@Override
public boolean hasOptionalAncestor() {
return false;
public boolean hasOptionalFieldInPath() {
return hasOptionalFieldInPath;
}

@Override
Expand All @@ -107,14 +102,14 @@ private static class Position2Accessor implements Accessor<StructLike> {
private final int p1;
private final Type type;
private final Class<?> javaClass;
private final boolean isOptional;
private final boolean hasOptionalFieldInPath;

Position2Accessor(int pos, PositionAccessor wrapped, boolean isOptional) {
this.p0 = pos;
this.p1 = wrapped.position();
this.type = wrapped.type();
this.javaClass = wrapped.javaClass();
this.isOptional = isOptional;
this.hasOptionalFieldInPath = isOptional || wrapped.hasOptionalFieldInPath();
}

@Override
Expand All @@ -132,13 +127,8 @@ public Class<?> javaClass() {
}

@Override
public boolean isOptional() {
return isOptional;
}

@Override
public boolean hasOptionalAncestor() {
return false;
public boolean hasOptionalFieldInPath() {
Comment thread
pvary marked this conversation as resolved.
return hasOptionalFieldInPath;
}

@Override
Expand All @@ -153,15 +143,15 @@ private static class Position3Accessor implements Accessor<StructLike> {
private final int p2;
private final Type type;
private final Class<?> javaClass;
private final boolean isOptional;
private final boolean hasOptionalFieldInPath;

Position3Accessor(int pos, Position2Accessor wrapped, boolean isOptional) {
this.p0 = pos;
this.p1 = wrapped.p0;
this.p2 = wrapped.p1;
this.type = wrapped.type();
this.javaClass = wrapped.javaClass();
this.isOptional = isOptional;
this.hasOptionalFieldInPath = isOptional || wrapped.hasOptionalFieldInPath();
}

@Override
Expand All @@ -175,13 +165,8 @@ public Type type() {
}

@Override
public boolean isOptional() {
return isOptional;
}

@Override
public boolean hasOptionalAncestor() {
return false;
public boolean hasOptionalFieldInPath() {
return hasOptionalFieldInPath;
}

@Override
Expand All @@ -193,12 +178,12 @@ public String toString() {
private static class WrappedPositionAccessor implements Accessor<StructLike> {
private final int position;
private final Accessor<StructLike> accessor;
private final boolean isOptional;
private final boolean hasOptionalFieldInPath;

WrappedPositionAccessor(int pos, Accessor<StructLike> accessor, boolean isOptional) {
this.position = pos;
this.accessor = accessor;
this.isOptional = isOptional;
this.hasOptionalFieldInPath = isOptional || accessor.hasOptionalFieldInPath();
}

@Override
Expand All @@ -216,13 +201,8 @@ public Type type() {
}

@Override
public boolean isOptional() {
return isOptional;
}

@Override
public boolean hasOptionalAncestor() {
return accessor.isOptional() || accessor.hasOptionalAncestor();
public boolean hasOptionalFieldInPath() {
return hasOptionalFieldInPath;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,9 @@ public Type type() {

@Override
public boolean producesNull() {
// A leaf required field can still evaluate to null if any ancestor struct on the path
// is optional and is null at runtime. Accessor implementations indicate this via
// hasOptionalAncestor().
return field.isOptional() || accessor.hasOptionalAncestor();
// A leaf required field can evaluate to null if it is optional itself or any
// ancestor on the path is optional.
return field.isOptional() || accessor.hasOptionalFieldInPath();
Comment thread
dejangvozdenac marked this conversation as resolved.
Outdated
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,7 @@ public void testNotNull() {
shouldRead =
new ParquetBloomRowGroupFilter(SCHEMA, notNull("struct_not_null.int_field"))
.shouldRead(parquetSchema, rowGroupMetadata, bloomStore);
assertThat(shouldRead)
.as("Should read: this field is required and are always not-null")
.isTrue();
assertThat(shouldRead).as("Should read: bloom filter doesn't help").isTrue();
}

@Test
Expand All @@ -322,9 +320,7 @@ public void testIsNull() {
shouldRead =
new ParquetBloomRowGroupFilter(SCHEMA, isNull("struct_not_null.int_field"))
.shouldRead(parquetSchema, rowGroupMetadata, bloomStore);
assertThat(shouldRead)
.as("Should skip: this field is required and are always not-null")
.isFalse();
assertThat(shouldRead).as("Should read: bloom filter doesn't help").isTrue();
Comment thread
dejangvozdenac marked this conversation as resolved.
Outdated
}

@Test
Expand Down