prestodb/presto · error · ParquetDecodingException

Unable to read BINARY type decimal of size

Error message

Unable to read BINARY type decimal of size 

What it means

ShortDecimalRLEDictionaryValuesDecoder decodes BINARY-encoded dictionary pages backing a short decimal (precision <= 18, must fit in a long / at most 8 bytes of two's-complement data). While copying variable-width dictionary values, it measures each entry's length from the offsets array; when an entry exceeds 8 bytes it throws ParquetDecodingException("Unable to read BINARY type decimal of size " + positionLength + " as a short decimal"), because the value cannot be represented as a short decimal long. This indicates the file's declared decimal precision/scale does not match the actual stored byte widths.

Source

Thrown at presto-parquet/src/main/java/com/facebook/presto/parquet/batchreader/decoders/rle/ShortDecimalRLEDictionaryValuesDecoder.java:54

        requireNonNull(dictionary, "dictionary is null");
        delegate = new BinaryRLEDictionaryValuesDecoder(bitWidth, inputStream, dictionary);
    }

    @Override
    public void readNext(long[] values, int offset, int length)
            throws IOException
    {
        ValueBuffer valueBuffer = delegate.readNext(length);
        int bufferSize = valueBuffer.getBufferSize();
        byte[] byteBuffer = new byte[bufferSize];
        int[] offsets = new int[length + 1];
        delegate.readIntoBuffer(byteBuffer, 0, offsets, 0, valueBuffer);

        for (int i = 0; i < length; i++) {
            int positionOffset = offsets[i];
            int positionLength = offsets[i + 1] - positionOffset;
            if (positionLength > 8) {
                throw new ParquetDecodingException("Unable to read BINARY type decimal of size " + positionLength + " as a short decimal");
            }

            values[offset + i] = getShortDecimalValue(byteBuffer, positionOffset, positionLength);
        }
    }

    @Override
    public void skip(int length)
            throws IOException
    {
        delegate.skip(length);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Fix the table/column schema so the Parquet column's decimal precision is <= 18 (or that Presto maps it as a long decimal), then re-run the query.
  2. If the data is truly DECIMAL(19+), alter the Hive table column type so Presto reads it as a long decimal instead of a short decimal.
  3. Validate with parquet-tools that the BINARY dictionary entries match the declared precision; re-export the file if data and schema disagree.
  4. Cast/rewrite the column with a compatible precision on the writer side before Presto reads it.

Example fix

// before: schema declares short decimal but data is wider
CREATE TABLE t (d DECIMAL(10,2)) ... -- parquet actually holds DECIMAL(20,2)
-- ParquetDecodingException: Unable to read BINARY type decimal of size 9 ...

// after: align schema with physical data
CREATE TABLE t (d DECIMAL(20,2)) ... -- read as long decimal
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the declared decimal precision fits a short decimal before reading
int precision = column.getType().getPrecision();
if (precision > 18) {
    throw new IllegalArgumentException(
        "Column maps to short decimal but precision is " + precision + "; fix table schema");
}

Try / catch

try {
    decoder.readNext(values, offset, length);
} catch (ParquetDecodingException e) {
    throw new PrestoException(PARQUET_CORRUPT_DATA,
        "BINARY decimal entry exceeds 8 bytes; check schema precision for " + column, e);
}

Prevention

When it happens

Trigger: readNext() — called from nonNullCount, rleOnlyBlockReadHelper, hybridReadInBatchesHelper, tryReadingTooMany paths — encounters a dictionary BINARY entry whose byte length (offsets[i+1]-offsets[i]) is greater than 8, i.e., the physical bytes cannot fit into a short decimal.

Common situations: Hive/Impala/Spark writing a DECIMAL(>18) column that Presto's schema maps as a short decimal; schema drift where the table's precision was changed after data was written; corrupt variable-length dictionary entries; reading a BINARY column through a decimal-typed mapping by mistake.

Related errors


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