uros-b commented on code in PR #17430:
URL: https://github.com/apache/iceberg/pull/17430#discussion_r3684380092


##########
api/src/test/java/org/apache/iceberg/expressions/TestInclusiveMetricsEvaluator.java:
##########
@@ -210,150 +212,303 @@ public class TestInclusiveMetricsEvaluator {
           Row.of(),
           10,
           // any value counts, including nulls
-          ImmutableMap.of(100, 5L, 101, 5L, 102, 5L, 103, 5L, 104, 5L, 105, 
5L),
+          ImmutableMap.of(102, 5L, 103, 5L, 104, 5L, 105, 5L),
           // null value counts
-          ImmutableMap.of(100, 0L, 101, 5L, 103, 5L, 104, 5L, 105, 5L),
+          ImmutableMap.of(103, 5L, 104, 5L, 105, 5L),
           // nan value counts
           null,
           // lower bounds
           null,
           // upper bounds
           null);
 
+  private static final DataFile MISSING_STATS = new 
TestDataFile("file.parquet", Row.of(), 50);
+
+  private static final DataFile EMPTY_FILE = new TestDataFile("file.parquet", 
Row.of(), 0);
+
+  private static final DataFile RANGE_OF_VALUES =
+      new TestDataFile(
+          "range_of_values.avro",
+          Row.of(),
+          10,
+          ImmutableMap.of(3, 10L),
+          ImmutableMap.of(3, 0L),
+          null,
+          ImmutableMap.of(3, toByteBuffer(StringType.get(), "aaa")),
+          ImmutableMap.of(3, toByteBuffer(StringType.get(), "zzz")));
+
+  private static final DataFile SINGLE_VALUE_FILE =
+      new TestDataFile(
+          "single_value.avro",
+          Row.of(),
+          10,
+          ImmutableMap.of(3, 10L),
+          ImmutableMap.of(3, 0L),
+          null,
+          ImmutableMap.of(3, toByteBuffer(StringType.get(), "abc")),
+          ImmutableMap.of(3, toByteBuffer(StringType.get(), "abc")));
+
+  // some_empty is optional because a required column cannot contain nulls
+  private static final DataFile SINGLE_VALUE_WITH_NULLS =
+      new TestDataFile(
+          "single_value_nulls.avro",
+          Row.of(),
+          10,
+          ImmutableMap.of(14, 10L),
+          ImmutableMap.of(14, 2L),
+          null,
+          ImmutableMap.of(14, toByteBuffer(StringType.get(), "abc")),
+          ImmutableMap.of(14, toByteBuffer(StringType.get(), "abc")));
+
+  private static final DataFile SINGLE_VALUE_WITH_NAN =
+      new TestDataFile(
+          "single_value_nan.avro",
+          Row.of(),
+          10,
+          ImmutableMap.of(9, 10L),
+          ImmutableMap.of(9, 0L),
+          ImmutableMap.of(9, 2L),
+          ImmutableMap.of(9, toByteBuffer(Types.FloatType.get(), 5.0F)),
+          ImmutableMap.of(9, toByteBuffer(Types.FloatType.get(), 5.0F)));
+
+  private static final DataFile SINGLE_VALUE_NAN_BOUNDS =
+      new TestDataFile(
+          "single_value_nan_bounds.avro",
+          Row.of(),
+          10,
+          ImmutableMap.of(9, 10L),
+          ImmutableMap.of(9, 0L),
+          ImmutableMap.of(9, 0L),
+          ImmutableMap.of(9, toByteBuffer(Types.FloatType.get(), Float.NaN)),
+          ImmutableMap.of(9, toByteBuffer(Types.FloatType.get(), Float.NaN)));
+
+  private static final Map<Integer, ByteBuffer> FLOAT_BOUND =
+      ImmutableMap.of(1, toByteBuffer(Types.FloatType.get(), 1.0f));
+
+  private static final DataFile SINGLE_FLOAT_VALUE_FILE =
+      new TestDataFile(
+          "single_value_file.avro",
+          Row.of(),
+          10,
+          ImmutableMap.of(1, 10L),
+          ImmutableMap.of(1, 0L),
+          ImmutableMap.of(1, 0L),
+          FLOAT_BOUND,
+          FLOAT_BOUND);
+
+  private static final DataFile SINGLE_FLOAT_VALUE_FILE_WITH_NAN =
+      new TestDataFile(
+          "single_value_file.avro",
+          Row.of(),
+          10,
+          ImmutableMap.of(1, 10L),
+          ImmutableMap.of(1, 0L),
+          ImmutableMap.of(1, 1L), // contains a NaN value
+          FLOAT_BOUND,
+          FLOAT_BOUND);
+
+  protected boolean shouldRead(Schema schema, Expression expr, boolean 
caseSensitive, F testFile) {
+    return new InclusiveMetricsEvaluator(schema, expr, 
caseSensitive).eval((DataFile) testFile);
+  }
+
+  protected boolean shouldRead(Schema schema, Expression expr, F testFile) {
+    return shouldRead(schema, expr, true, testFile);
+  }
+
+  protected F file() {
+    return asFile(FILE);
+  }
+
+  protected F file2() {
+    return asFile(FILE_2);
+  }
+
+  protected F file3() {
+    return asFile(FILE_3);
+  }
+
+  protected F file4() {
+    return asFile(FILE_4);
+  }
+
+  protected F file5() {
+    return asFile(FILE_5);
+  }
+
+  protected F file6() {
+    return asFile(FILE_6);
+  }
+
+  protected F missingStats() {
+    return asFile(MISSING_STATS);
+  }
+
+  protected F emptyFile() {
+    return asFile(EMPTY_FILE);
+  }
+
+  protected F rangeOfValues() {
+    return asFile(RANGE_OF_VALUES);
+  }
+
+  protected F singleValueFile() {
+    return asFile(SINGLE_VALUE_FILE);
+  }
+
+  protected F singleValueWithNulls() {
+    return asFile(SINGLE_VALUE_WITH_NULLS);
+  }
+
+  protected F singleValueWithNaN() {
+    return asFile(SINGLE_VALUE_WITH_NAN);
+  }
+
+  protected F singleValueNaNBounds() {
+    return asFile(SINGLE_VALUE_NAN_BOUNDS);
+  }
+
+  protected F singleFloatValueFile() {
+    return asFile(SINGLE_FLOAT_VALUE_FILE);
+  }
+
+  protected F singleFloatValueFileWithNaN() {
+    return asFile(SINGLE_FLOAT_VALUE_FILE_WITH_NAN);
+  }
+
+  @SuppressWarnings("unchecked")

Review Comment:
   Nit: the 15 protected factory methods each delegate to the private 
asFile(DataFile), which performs an unchecked (F) dataFile cast. A subclass 
that extends the base with a non-DataFile type F (e.g. a ContentFile variant) 
and fails to override even one factory method will receive a runtime 
ClassCastException with no compile-time signal; the type parameter F has no 
bound, so the compiler cannot catch it. The @SuppressWarnings("unchecked") on 
asFile() is correct per convention, but the contract ("subclasses using a 
non-DataFile F must override every factory method and both shouldRead() 
overloads") is nowhere documented. A Javadoc block on the class and/or on 
asFile() noting this is the recommended fix.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to