{"record":{"id":"c9d77f9c92529827","repo":"apache/iceberg","slug":"does-not-implement-eval-datafile","errorCode":null,"errorMessage":" does not implement eval(DataFile)","messagePattern":" does not implement eval\\(DataFile\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/expressions/BoundAggregate.java","lineNumber":40,"sourceCode":"import org.apache.iceberg.DataFile;\nimport org.apache.iceberg.StructLike;\nimport org.apache.iceberg.types.Type;\nimport org.apache.iceberg.types.Types;\n\npublic class BoundAggregate<T, C> extends Aggregate<BoundTerm<T>> implements Bound<C> {\n\n  protected BoundAggregate(Operation op, BoundTerm<T> term) {\n    super(op, term);\n  }\n\n  @Override\n  public C eval(StructLike struct) {\n    throw new UnsupportedOperationException(\n        this.getClass().getName() + \" does not implement eval(StructLike)\");\n  }\n\n  C eval(DataFile file) {\n    throw new UnsupportedOperationException(\n        this.getClass().getName() + \" does not implement eval(DataFile)\");\n  }\n\n  boolean hasValue(DataFile file) {\n    throw new UnsupportedOperationException(\n        this.getClass().getName() + \" does not implement hasValue(DataFile)\");\n  }\n\n  Aggregator<C> newAggregator() {\n    throw new UnsupportedOperationException(\n        this.getClass().getName() + \" does not implement newAggregator()\");\n  }\n\n  boolean containsNan(DataFile file, int fieldId) {\n    Long nanCount = safeGet(file.nanValueCounts(), fieldId);\n    return nanCount != null && nanCount > 0;\n  }\n","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/expressions/BoundAggregate.java#L22-L58","documentation":"BoundAggregate.eval(DataFile) is a stub that concrete aggregate subclasses must override to compute aggregate values from a data file's metrics. Calling it on a subclass that does not support file-level evaluation throws this UnsupportedOperationException naming the class.","triggerScenarios":"Calling eval(DataFile) on a BoundAggregate subclass that only supports row evaluation (implements eval(StructLike) but not file metrics evaluation).","commonSituations":"Custom metrics-pruning code evaluating unsupported aggregate types against files; new aggregate operations added in API code without a DataFile implementation.","solutions":["Check the bound aggregate's op() before file-level evaluation and skip unsupported ops","Use AggregateEvaluator which routes to supported implementations","Override eval(DataFile) in custom BoundAggregate subclasses","Fall back to not pruning the file when the aggregate cannot be evaluated"],"exampleFix":"// before\nObject v = agg.eval(dataFile); // throws for unsupported types\n// after\nif (agg.op() == Operation.COUNT || agg.op() == Operation.MAX || agg.op() == Operation.MIN) {\n  Object v = agg.eval(dataFile);\n}","handlingStrategy":"try-catch","validationCode":"boolean supported = Set.of(Operation.COUNT, Operation.MAX, Operation.MIN).contains(agg.op());","typeGuard":null,"tryCatchPattern":"try { v = agg.eval(dataFile); } catch (UnsupportedOperationException e) { v = null; /* skip pruning for this file */ }","preventionTips":["Only evaluate known-supported aggregate ops at file level","Default to conservative (no-prune) behavior on failure","Prefer AggregateEvaluator over direct eval calls"],"tags":["expressions","aggregates","unsupported-operation"],"backgroundTag":"method-not-implemented","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}