{"record":{"id":"7ec96bc50bd22995","repo":"prestodb/presto","slug":"value-d-is-less-than-min-int","errorCode":null,"errorMessage":"Value %d is less than MIN_INT","messagePattern":"Value (.+?) is less than MIN_INT","errorType":"exception","errorClass":"GenericInternalException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/type/IntegerType.java","lineNumber":51,"sourceCode":"\n    @Override\n    public Object getObjectValue(SqlFunctionProperties properties, Block block, int position)\n    {\n        if (block.isNull(position)) {\n            return null;\n        }\n\n        return block.getInt(position);\n    }\n\n    @Override\n    public final void writeLong(BlockBuilder blockBuilder, long value)\n    {\n        if (value > Integer.MAX_VALUE) {\n            throw new GenericInternalException(format(\"Value %d exceeds MAX_INT\", value));\n        }\n        else if (value < Integer.MIN_VALUE) {\n            throw new GenericInternalException(format(\"Value %d is less than MIN_INT\", value));\n        }\n\n        blockBuilder.writeInt((int) value).closeEntry();\n    }\n\n    @Override\n    @SuppressWarnings(\"EqualsWhichDoesntCheckParameterClass\")\n    public boolean equals(Object other)\n    {\n        return other == INTEGER;\n    }\n\n    @Override\n    public int hashCode()\n    {\n        return getClass().hashCode();\n    }\n}","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/type/IntegerType.java#L33-L69","documentation":"IntegerType.writeLong's underflow branch: a long value below Integer.MIN_VALUE (-2147483648) cannot be cast to int without wraparound, so it throws GenericInternalException 'Value %d is less than MIN_INT' to prevent silent truncation of the block data.","triggerScenarios":"Writing a long < -2147483648 via IntegerType's writeLong; negative BIGINT values (e.g. huge negative ids, timestamps in ms before 1970 by centuries) funneled into an INTEGER writer.","commonSituations":"BIGINT→INTEGER table copies; sentinel negative values (-1L<<40) used as 'unset' markers in sources; epoch-milli math producing negatives far below int range.","solutions":["Range-check the value against Integer.MIN_VALUE before writing; write NULL on underflow","Cast via SQL CAST to INTEGER for well-defined overflow behavior at the engine level","Widen the target column to BIGINT for values that legitimately go below int range","Fix sentinel/marker values in upstream data to fit int range"],"exampleFix":"// before\nintegerBlockBuilder.writeLong(negativeBigint); // throws when < MIN_INT\n// after\nif (negativeBigint < Integer.MIN_VALUE || negativeBigint > Integer.MAX_VALUE) {\n    integerBlockBuilder.appendNull();\n} else {\n    integerBlockBuilder.writeLong(negativeBigint);\n}","handlingStrategy":"type-guard","validationCode":"public static boolean fitsInInt(long value) {\n    return value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE;\n}\n// check specifically for negatives: if (v < Integer.MIN_VALUE) -> NULL or BIGINT column","typeGuard":"public static Integer toIntOrNull(Long value) {\n    return (value == null || value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) ? null : value.intValue();\n}","tryCatchPattern":"try {\n    integerBlockBuilder.writeLong(value);\n} catch (GenericInternalException e) {\n    integerBlockBuilder.appendNull(); // underflow: NULL out or escalate\n}","preventionTips":["Watch for large negative sentinel values in source data","Keep negative epoch math on BIGINT, not INTEGER columns","Apply Ints.checkedCast-style checks at ETL boundaries"],"tags":["presto","integer","underflow","block-builder"],"backgroundTag":"integer-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"}