prestodb/presto · error · UnsupportedOperationException

Precision not supported

Error message

Precision not supported 

What it means

SqlTimestamp.toString (renderer used by getTimestampLiteralAsString and toSqlTimestampString) only supports MILLISECONDS and MICROSECONDS precisions; any other precision throws UnsupportedOperationException("Precision not supported " + precision). It indicates a SqlTimestamp instance was built with an unexpected TimeUnit precision.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/type/SqlTimestamp.java:136

        SqlTimestamp other = (SqlTimestamp) obj;
        // The current semantics returns NOT equal for millis and micros timestamp,
        // even though they represent the same time. (ex. same second, millis/micros set to 0).
        return this.value == other.value &&
                this.precision == other.precision &&
                Objects.equals(this.sessionTimeZoneKey, other.sessionTimeZoneKey);
    }

    @JsonValue
    @Override
    public String toString()
    {
        if (precision == MILLISECONDS) {
            return formatInstant(millisToInstant(value), JSON_MILLIS_FORMATTER);
        }
        if (precision == MICROSECONDS) {
            return formatInstant(microsToInstant(value), JSON_MICROS_FORMATTER);
        }
        throw new UnsupportedOperationException("Precision not supported " + precision);
    }

    private String formatInstant(Instant instant, DateTimeFormatter formatter)
    {
        if (isLegacyTimestamp()) {
            return instant.atZone(ZoneId.of(sessionTimeZoneKey.get().getId())).format(formatter);
        }
        else {
            return instant.atZone(ZoneId.of(UTC_KEY.getId())).format(formatter);
        }
    }

    private static TimeUnit validatePrecision(TimeUnit precision)
    {
        requireNonNull(precision, "precision");
        if (precision == MILLISECONDS || precision == MICROSECONDS) {
            return precision;
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Construct SqlTimestamp only with TimeUnit.MILLISECONDS or TimeUnit.MICROSECONDS (use SqlTimestamp.newInstance with a supported precision).
  2. Convert nanosecond-precision values down to micros before wrapping in SqlTimestamp.
  3. If you need nanos, use the higher-precision type (e.g. LongTimestamp/LongTimestampWithTimeZone) instead of SqlTimestamp.

Example fix

// before
SqlTimestamp ts = new SqlTimestamp(epochValue, TimeUnit.NANOSECONDS, sessionKey);
ts.toString();
// after
SqlTimestamp ts = new SqlTimestamp(epochMicros, TimeUnit.MICROSECONDS, sessionKey);
Defensive patterns

Strategy: type-guard

Validate before calling

if (precision != TimeUnit.MILLISECONDS && precision != TimeUnit.MICROSECONDS) { /* convert precision first */ }

Type guard

boolean hasSupportedPrecision(SqlTimestamp ts) { ts.getPrecision() == TimeUnit.MILLISECONDS || ts.getPrecision() == TimeUnit.MICROSECONDS; }

Try / catch

try { ts.toString(); } catch (UnsupportedOperationException e) { /* re-create with MILLISECONDS/MICROSECONDS precision */ }

Prevention

When it happens

Trigger: Calling toString/getTimestampLiteralAsString/toSqlTimestampString on a SqlTimestamp whose precision TimeUnit is not MILLISECONDS or MICROSECONDS.

Common situations: Custom type systems mapping precision beyond micros (e.g. nanoseconds) into SqlTimestamp; version drift where a new precision was introduced elsewhere but not in formatting; test harnesses constructing SqlTimestamp with SECONDS/NANOSECONDS.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/eceb6c8c950d80d9. Report an issue: GitHub.