{"record":{"id":"b0aa15b789beee11","repo":"prestodb/presto","slug":"numeric-value-out-of-range-b0aa15","errorCode":"NUMERIC_VALUE_OUT_OF_RANGE","errorMessage":"Overflow adding interval year-month values: ","messagePattern":"Overflow adding interval year-month values: ","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/type/IntervalYearMonthOperators.java","lineNumber":65,"sourceCode":"import static com.facebook.presto.type.IntervalYearMonthType.INTERVAL_YEAR_MONTH;\nimport static io.airlift.slice.Slices.utf8Slice;\nimport static java.lang.Math.toIntExact;\n\npublic final class IntervalYearMonthOperators\n{\n    private IntervalYearMonthOperators()\n    {\n    }\n\n    @ScalarOperator(ADD)\n    @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH)\n    public static long add(@SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long left, @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long right)\n    {\n        try {\n            return Math.addExact((int) left, (int) right);\n        }\n        catch (ArithmeticException e) {\n            throw new PrestoException(NUMERIC_VALUE_OUT_OF_RANGE, \"Overflow adding interval year-month values: \" + left + \" + \" + right);\n        }\n    }\n\n    @ScalarOperator(SUBTRACT)\n    @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH)\n    public static long subtract(@SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long left, @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long right)\n    {\n        try {\n            return Math.subtractExact((int) left, (int) right);\n        }\n        catch (ArithmeticException e) {\n            throw new PrestoException(NUMERIC_VALUE_OUT_OF_RANGE, \"Overflow subtracting interval year-month values: \" + left + \" - \" + right);\n        }\n    }\n\n    @ScalarOperator(MULTIPLY)\n    @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH)\n    public static long multiplyByInteger(@SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long left, @SqlType(StandardTypes.INTEGER) long right)","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/type/IntervalYearMonthOperators.java#L47-L83","documentation":"Thrown by IntervalDayTimeOperators.add when adding two INTERVAL YEAR TO MONTH values overflows a 32-bit int. Year-month intervals are stored as the number of months in an int; Math.addExact on the two ints throws ArithmeticException when the sum leaves Integer range, wrapped as PrestoException NUMERIC_VALUE_OUT_OF_RANGE. Long.MAX_VALUE (Long.MIN_VALUE / 1000, Long.MIN_VALUE / 1000) boundaries.","triggerScenarios":"ADD operator on two INTERVAL YEAR TO SECOND values whose combined month count exceeds Integer.MAX_VALUE (+2147483647 months, ~178,956,970 years) or is below Integer.MIN_VALUE, e.g. SELECT INTERVAL '150000000' YEAR + INTERVAL '150000000' YEAR.","commonSituations":"Accidentally treating year-month intervals as day-level magnitudes and summing many of them; programmatic generation of huge intervals; sentinel month values (like Integer.MIN_VALUE) from external data being added.","solutions":["Reduce operand sizes so the sum fits in 32-bit month space","Use try(a + b) in SQL to get NULL on overflow instead of a failed query","Filter sentinel/outlier interval values before summing","Catch PrestoException NUMERIC_VALUE_OUT_OF_RANGE in the engine/plugin layer"],"exampleFix":"// before\nSELECT INTERVAL '200000000' YEAR + INTERVAL '200000000' YEAR; -- > int max months\n// after\nSELECT try(INTERVAL '200000000' YEAR + INTERVAL '200000000' YEAR); -- NULL, or use smaller intervals","handlingStrategy":"validation","validationCode":"-- before adding, ensure month sums fit in 32-bit int\nSELECT CASE WHEN abs(cast(a AS bigint) + cast(b AS bigint)) > 2147483647\n       THEN NULL ELSE a + b END\n-- or simply\nSELECT try(a + b)","typeGuard":"public static boolean safeYearMonthAdd(long monthsA, long monthsB) {\n    long sum = monthsA + monthsB; // evaluate in long\n    return sum >= Integer.MIN_VALUE && sum <= Integer.MAX_VALUE;\n}","tryCatchPattern":"try {\n    long r = IntervalYearMonthOperators.add(a, b);\n} catch (PrestoException e) {\n    if (e.getErrorCode().getCode() == StandardErrorCode.NUMERIC_VALUE_OUT_OF_RANGE.getCode()) {\n        // return NULL / log and skip row\n    } else {\n        throw e;\n    }\n}","preventionTips":["Remember year-month intervals are int month counts (max ~178M years)","Promote to BIGINT for pre-checks before interval arithmetic","Use try(...) in SQL on untrusted interval data","Sanitize externally loaded month values for sentinels"],"tags":["presto","interval-year-to-month","arithmetic-overflow","numeric-value-out-of-range"],"backgroundTag":"arithmetic-overflow","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}