apache/iceberg · error · UnsupportedOperationException

Type not supported in ORC SearchArguments

Error message

Type  not supported in ORC SearchArguments

What it means

ExpressionToSearchArgument converts Iceberg expressions into ORC SearchArguments for predicate pushdown. When a leaf predicate references an Iceberg type that has no ORC PredicateLeaf.Type mapping (anything not BOOLEAN, LONG/integer, DOUBLE/float, DATE, TIMESTAMP, STRING, DECIMAL), the type conversion throws UnsupportedOperationException. This means the predicate cannot be pushed down to the ORC reader and must be evaluated elsewhere.

Solutions

  1. Check the ORC schema/table columns involved in the filter and remove or rewrite predicates on unsupported types (UUID, BINARY, Fixed, Time, TimestampNano)
  2. Add a redundant cast/filter form that operates on a supported type (e.g. compare string representations)
  3. Upgrade Iceberg; support for more types in SearchArgument conversion may have been added in later versions
  4. Wrap the scan so unsupported predicates are evaluated post-scan (residual filter) instead of pushed down

Example fix

// before: filter on a binary column triggers the error
TableScan scan = table.newScan().filter(Expressions.equal("payload_bytes", value));
// after: filter on a supported column, or evaluate the unsupported predicate after the scan
TableScan scan = table.newScan().filter(Expressions.equal("payload_string", value));
Defensive patterns

Strategy: type-guard

Validate before calling

import org.apache.iceberg.types.Types;
static final Set<Types.TypeID> ORC_SUPPORTED = Set.of(Types.TypeID.BOOLEAN, Types.TypeID.INTEGER, Types.TypeID.LONG, Types.TypeID.FLOAT, Types.TypeID.DOUBLE, Types.TypeID.DATE, Types.TypeID.TIMESTAMP, Types.TypeID.STRING, Types.TypeID.DECIMAL);
boolean pushdownSafe(Expression expr) {
  return new ExpressionVisitors.ExpressionVisitor<Boolean>() {
    @Override public <T> Boolean predicate(BoundPredicate<T> p) { return ORC_SUPPORTED.contains(p.term().type().typeId()); }
  }.visit(expr);
}

Type guard

static boolean orcPushdownSupported(Types.TypeID id) {
  return switch (id) { case BOOLEAN, INTEGER, LONG, FLOAT, DOUBLE, DATE, TIMESTAMP, STRING, DECIMAL -> true; default -> false; };
}

Try / catch

try {
  searchArgument = ExpressionToSearchArgument.convert(expr);
} catch (UnsupportedOperationException e) {
  log.warn("Predicate not pushable to ORC, evaluating residually: {}", e.getMessage());
  searchArgument = null; // full scan; filter applied by engine
}

Prevention

When it happens

Trigger: Calling type() via isNull, notNull, isNaN, lt, ltEq, or gt on an expression whose operand type is one of the unmapped Iceberg types (e.g. UUID, BINARY, Fixed, Time, TimestampNano, struct/list/map types).

Common situations: Filtering ORC scans on binary/fixed columns, UUID columns, or timestamp-nano columns; newer Iceberg types added after the switch was written; engine-generated filters pushed down over non-primitive columns.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/edde4aa945b5f1fc. Report an issue: GitHub.

Appendix: source

Thrown at orc/src/main/java/org/apache/iceberg/orc/ExpressionToSearchArgument.java:317

        return PredicateLeaf.Type.BOOLEAN;
      case INTEGER:
      case LONG:
      case TIME:
        return PredicateLeaf.Type.LONG;
      case FLOAT:
      case DOUBLE:
        return PredicateLeaf.Type.FLOAT;
      case DATE:
        return PredicateLeaf.Type.DATE;
      case TIMESTAMP:
      case TIMESTAMP_NANO:
        return PredicateLeaf.Type.TIMESTAMP;
      case STRING:
        return PredicateLeaf.Type.STRING;
      case DECIMAL:
        return PredicateLeaf.Type.DECIMAL;
      default:
        throw new UnsupportedOperationException(
            "Type " + icebergType + " not supported in ORC SearchArguments");
    }
  }

  private <T> Object literal(Type icebergType, T icebergLiteral) {
    switch (icebergType.typeId()) {
      case BOOLEAN:
      case LONG:
      case TIME:
      case DOUBLE:
        return icebergLiteral;
      case INTEGER:
        return ((Integer) icebergLiteral).longValue();
      case FLOAT:
        return ((Float) icebergLiteral).doubleValue();
      case STRING:
        return icebergLiteral.toString();
      case DATE:

View on GitHub (pinned to 86d9c8fc54)