prestodb/presto · error · PrestoException

NUMERIC_VALUE_OUT_OF_RANGE

NUMERIC_VALUE_OUT_OF_RANGE

Error message

interval_day_to_second addition overflow: %s ms + %s ms

What it means

Thrown by the INTERVAL DAY TO SECOND addition operator when Math.addExact detects that adding two intervals (millisecond encodings in a long) overflows the 64-bit range. Presto raises NUMERIC_VALUE_OUT_OF_RANGE with both operand millisecond values instead of silently wrapping.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/type/IntervalDayTimeOperators.java:66

import static com.facebook.presto.type.IntervalDayTimeType.INTERVAL_DAY_TIME;
import static io.airlift.slice.Slices.utf8Slice;
import static java.lang.String.format;

public final class IntervalDayTimeOperators
{
    private IntervalDayTimeOperators()
    {
    }

    @ScalarOperator(ADD)
    @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND)
    public static long add(@SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long left, @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long right)
    {
        try {
            return Math.addExact(left, right);
        }
        catch (ArithmeticException e) {
            throw new PrestoException(NUMERIC_VALUE_OUT_OF_RANGE, format("interval_day_to_second addition overflow: %s ms + %s ms", left, right), e);
        }
    }

    @ScalarOperator(SUBTRACT)
    @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND)
    public static long subtract(@SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long left, @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long right)
    {
        try {
            return Math.subtractExact(left, right);
        }
        catch (ArithmeticException e) {
            throw new PrestoException(NUMERIC_VALUE_OUT_OF_RANGE, format("interval_day_to_second subtraction overflow: %s ms - %s ms", left, right), e);
        }
    }

    @ScalarOperator(MULTIPLY)
    @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND)
    public static long multiplyByBigint(@SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long left, @SqlType(StandardTypes.BIGINT) long right)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check interval magnitudes before adding; normalize durations to smaller realistic units.
  2. Verify the code building the INTERVAL is not multiplying days by the wrong factor (ms vs seconds).
  3. Accumulate as BIGINT milliseconds in application logic with its own bounds check before constructing intervals.

Example fix

// before
SELECT huge_interval + INTERVAL '1000000000' DAY; -- overflow
// after
-- validate: SELECT huge_interval; then add only if within representable range
SELECT huge_interval + INTERVAL '1' DAY;
Defensive patterns

Strategy: validation

Validate before calling

-- Cap and validate interval magnitudes before adding
SELECT interval_add FROM t
WHERE day(interval_add) < 106751991;  -- ~Long.MAX_VALUE ms in days
-- Or validate in code that source millis are within realistic bounds
if (millis < 0 || millis > MAX_REASONABLE_DURATION_MS) throw new IllegalArgumentException(...);

Try / catch

try { run("SELECT iv1 + iv2 FROM t"); }
catch (PrestoException e) {
  if (StandardErrorCode.NUMERIC_VALUE_OUT_OF_RANGE.toErrorCode().equals(e.getErrorCode())) {
    // handle overflow: clamp or route row to error path
  } else throw e;
}

Prevention

When it happens

Trigger: Executing SQL '+' on two INTERVAL DAY TO SECOND values whose combined millisecond total exceeds Long.MAX_VALUE, e.g. repeatedly adding huge intervals like INTERVAL '106751991' DAY to itself.

Common situations: Accumulating intervals in a loop/aggregation where durations are mistakenly expressed in extreme units (e.g. building INTERVAL from an unchecked millisecond counter), and pathological data from ETL conversions.

Related errors


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