prestodb/presto · error · UnsupportedOperationException

toEpochMicros is not supported for TIMESTAMP(

Error message

toEpochMicros is not supported for TIMESTAMP(

What it means

toEpochMicros converts the packed long TIMESTAMP value to epoch microseconds and is only valid for short precisions (p=0..6). Precisions 7-12 require a 128-bit representation and are unsupported here, so UnsupportedOperationException is thrown.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/type/TimestampType.java:191

    }

    // Supported for all short precisions (p=0 through p=6, i.e. isShort()==true).
    // Long precisions (p=7-12) require a 128-bit representation and are not yet supported.
    public long toEpochMillis(long timestamp)
    {
        if (!isShort()) {
            throw new UnsupportedOperationException(
                    "toEpochMillis is not supported for TIMESTAMP(" + precision + ")");
        }
        return getEpochSecond(timestamp) * 1_000L + getNanos(timestamp) / 1_000_000;
    }

    // Supported for all short precisions (p=0 through p=6, i.e. isShort()==true).
    // Long precisions (p=7-12) require a 128-bit representation and are not yet supported.
    public long toEpochMicros(long timestamp)
    {
        if (!isShort()) {
            throw new UnsupportedOperationException(
                    "toEpochMicros is not supported for TIMESTAMP(" + precision + ")");
        }
        return getEpochSecond(timestamp) * 1_000_000L + getNanos(timestamp) / 1_000;
    }

    public long fromEpochComponents(long epochSecond, int nanos)
    {
        if (!isShort()) {
            throw new UnsupportedOperationException(
                    "fromEpochComponents is not supported for TIMESTAMP(" + precision + ")");
        }
        if (nanos < 0 || nanos >= 1_000_000_000) {
            throw new IllegalArgumentException("nanos must be in range [0, 999_999_999]: " + nanos);
        }
        long scale = PRECISION_SCALE[precision];
        return epochSecond * scale + nanos / (1_000_000_000L / scale);
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check type.isShort() first and route long precisions to the 128-bit representation path.
  2. Use TIMESTAMP(6) columns when microsecond helpers are needed.
  3. Convert via LongTimestamp supporting APIs if high precision must be preserved.

Example fix

// before
long micros = type.toEpochMicros(value);
// after
long micros = type.isShort()
        ? type.toEpochMicros(value)
        : longTimestampToEpochMicros(value); // 128-bit path
Defensive patterns

Strategy: type-guard

Validate before calling

if (!timestampType.isShort()) {
    throw new IllegalStateException("toEpochMicros requires short precision, got " + timestampType.getPrecision());
}

Type guard

boolean supportsEpochMicros(TimestampType t) { return t.isShort(); }

Try / catch

try {
    micros = type.toEpochMicros(packed);
} catch (UnsupportedOperationException e) {
    micros = longTimestampToEpochMicros(value); // 128-bit path
}

Prevention

When it happens

Trigger: Calling toEpochMicros(timestamp) on a TimestampType with precision 7 or higher (isShort() == false).

Common situations: Iceberg/partition-transform style code computing epoch micros on columns declared with high precision; connectors reading long-precision timestamps as longs.

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 prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/29f1452b9642fdf3. Report an issue: GitHub.