{"record":{"id":"745942dac67b1f9f","repo":"prestodb/presto","slug":"binary-literal-must-contain-an-even-number-of-digi","errorCode":null,"errorMessage":"Binary literal must contain an even number of digits","messagePattern":"Binary literal must contain an even number of digits","errorType":"exception","errorClass":"ParsingException","httpStatus":null,"severity":"error","filePath":"presto-parser/src/main/java/com/facebook/presto/sql/tree/BinaryLiteral.java","lineNumber":50,"sourceCode":"    private static final Pattern NOT_HEX_DIGIT_PATTERN = Pattern.compile(\".*[^A-F0-9].*\");\n\n    private final Slice value;\n\n    public BinaryLiteral(String value)\n    {\n        this(Optional.empty(), value);\n    }\n\n    public BinaryLiteral(Optional<NodeLocation> location, String value)\n    {\n        super(location);\n        requireNonNull(value, \"value is null\");\n        String hexString = WHITESPACE_PATTERN.matcher(value).replaceAll(\"\").toUpperCase();\n        if (NOT_HEX_DIGIT_PATTERN.matcher(hexString).matches()) {\n            throw new ParsingException(\"Binary literal can only contain hexadecimal digits\", location.get());\n        }\n        if (hexString.length() % 2 != 0) {\n            throw new ParsingException(\"Binary literal must contain an even number of digits\", location.get());\n        }\n        this.value = Slices.wrappedBuffer(BaseEncoding.base16().decode(hexString));\n    }\n\n    public BinaryLiteral(NodeLocation location, String value)\n    {\n        this(Optional.of(location), value);\n    }\n\n    /**\n     * Return the valued as a hex-formatted string with upper-case characters\n     */\n    public String toHexString()\n    {\n        return BaseEncoding.base16().encode(value.getBytes());\n    }\n\n    public Slice getValue()","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-parser/src/main/java/com/facebook/presto/sql/tree/BinaryLiteral.java#L32-L68","documentation":"A binary literal must encode whole bytes, so the hex string must have an even number of digits. BinaryLiteral checks hexString.length() % 2 and throws this ParsingException for odd-length values, since they cannot be decoded into complete bytes.","triggerScenarios":"Constructing BinaryLiteral with an odd-length hex string, e.g. X'ABC' or X'123'.","commonSituations":"Hand-truncated hex dumps, off-by-one slicing of hex strings, padding dropped by string processing.","solutions":["Pad the hex string with a leading zero to make the length even","Fix the data source so full bytes are emitted","Validate value.replaceAll(\"\\\\s\",\"\").length() % 2 == 0 before constructing"],"exampleFix":"// before\nnew BinaryLiteral(location, \"ABC\"); // 3 digits\n// after\nnew BinaryLiteral(location, \"0ABC\"); // 4 digits, even","handlingStrategy":"validation","validationCode":"String hex = value.replaceAll(\"\\\\s\", \"\");\nif (hex.length() % 2 != 0) {\n    hex = \"0\" + hex; // left-pad to a whole byte\n}","typeGuard":"boolean isEvenLengthHex(String value) {\n    return value != null && value.replaceAll(\"\\\\s\", \"\").length() % 2 == 0;\n}","tryCatchPattern":"try {\n    BinaryLiteral lit = new BinaryLiteral(location, value);\n} catch (ParsingException e) {\n    if (e.getMessage().contains(\"even number of digits\")) {\n        throw new MalformedBinaryLiteralException(value, e);\n    }\n    throw e;\n}","preventionTips":["Left-pad odd hex strings with a leading zero","Check byte-array-to-hex encoders emit pairs (they should)","Fix truncation points where hex dumps get sliced","Validate length parity at the input boundary"],"tags":["sql","literal","binary","hex"],"backgroundTag":"invalid-literal-value","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"}