apache/iceberg · error · UnsupportedOperationException

errMsg(variant, "long")

Error message

errMsg(variant, "long")

What it means

longValue converts a Variant to a Flink long, accepting TINYINT, SMALLINT, INT, and BIGINT. Any other variant type throws UnsupportedOperationException with errMsg(variant, "long"), which includes the variant's actual type. This prevents a non-numeric variant (string, double, etc.) from being read through getLong or an array/map element accessor.

Source

Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/data/VariantRowDataWrapper.java:265

    return new GenericArrayData(elements);
  }

  private static int intValue(Variant variant) {
    return switch (variant.getType()) {
      case TINYINT -> variant.getByte();
      case SMALLINT -> variant.getShort();
      case INT -> variant.getInt();
      default -> throw new UnsupportedOperationException(errMsg(variant, "int"));
    };
  }

  private static long longValue(Variant variant) {
    return switch (variant.getType()) {
      case TINYINT -> variant.getByte();
      case SMALLINT -> variant.getShort();
      case INT -> variant.getInt();
      case BIGINT -> variant.getLong();
      default -> throw new UnsupportedOperationException(errMsg(variant, "long"));
    };
  }

  private static double doubleValue(Variant variant) {
    return switch (variant.getType()) {
      case FLOAT -> variant.getFloat();
      case DOUBLE -> variant.getDouble();
      default -> throw new UnsupportedOperationException(errMsg(variant, "double"));
    };
  }

  private static DecimalData decimalDataValue(Variant variant, DecimalType decimalType) {
    return DecimalData.fromBigDecimal(
        variant.getDecimal(), decimalType.getPrecision(), decimalType.getScale());
  }

  private static TimestampData timestampValue(Variant variant, int precision) {
    return switch (variant.getType()) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the variant's stored type and align the Flink field type (DOUBLE -> getDouble, STRING -> getString).
  2. Cast the value explicitly before reading through the wrapper.
  3. Fix the writer producing the variant so numeric fields use integral types.

Example fix

// before
long v = wrapper.getLong(pos); // variant is DOUBLE
// after
double d = wrapper.getDouble(pos);
long v = (long) d;
Defensive patterns

Strategy: type-guard

Validate before calling

if (EnumSet.of(Variant.Type.TINYINT, Variant.Type.SMALLINT, Variant.Type.INT, Variant.Type.BIGINT).contains(variant.getType())) { /* safe to getLong */ }

Type guard

boolean isLongVariant(Variant v) { return switch (v.getType()) { case TINYINT, SMALLINT, INT, BIGINT -> true; default -> false; }; }

Try / catch

try { long v = wrapper.getLong(pos); } catch (UnsupportedOperationException e) { /* fall back to getDouble/getString based on actual type */ }

Prevention

When it happens

Trigger: Calling getLong(pos) or elementValue for a Variant whose getType() is not TINYINT/SMALLINT/INT/BIGINT — e.g. a DOUBLE or STRING variant read through a BIGINT Flink field.

Common situations: Variant column contains mixed numeric types; declared Flink type BIGINT but data written as double; downstream job changed variant schema upstream.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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