prestodb/presto · error · PrestoException

PINOT_UNSUPPORTED_COLUMN_TYPE

PINOT_UNSUPPORTED_COLUMN_TYPE

Error message

Failed to write column %s. pinotColumnType %s, javaType %s

What it means

fillNextPage delegates each column to writeBlock, which dispatches on the column's Java type (Boolean, Long, Double, BigDecimal, Slice). If the Pinot column type maps to a Java type none of the block writers support, this PrestoException is thrown rather than silently producing wrong data.

Source

Thrown at presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/PinotSegmentPageSource.java:324

        else if (javaType.equals(long.class)) {
            if (pinotColumnType.toDataType().equals(FieldSpec.DataType.TIMESTAMP)) {
                writeTimestampBlock(blockBuilder, columnType, columnIndex);
            }
            else {
                writeLongBlock(blockBuilder, columnType, columnIndex);
            }
        }
        else if (javaType.equals(double.class)) {
            writeDoubleBlock(blockBuilder, columnType, columnIndex);
        }
        else if (pinotColumnType == DataSchema.ColumnDataType.BIG_DECIMAL) {
            writeBigDecimalBlock(blockBuilder, columnType, columnIndex);
        }
        else if (javaType.equals(Slice.class)) {
            writeSliceBlock(blockBuilder, columnType, columnIndex);
        }
        else {
            throw new PrestoException(
                    PINOT_UNSUPPORTED_COLUMN_TYPE,
                    String.format(
                            "Failed to write column %s. pinotColumnType %s, javaType %s",
                            split.getExpectedColumnHandles().get(columnIndex).getColumnName(),
                            pinotColumnType,
                            javaType));
        }
    }

    private void writeArrayBlock(BlockBuilder blockBuilder, Type columnType, int columnIndex)
    {
        for (int rowIndex = 0; rowIndex < currentDataTable.getDataTable().getNumberOfRows(); rowIndex++) {
            DataSchema.ColumnDataType columnPinotType = currentDataTable.getDataTable().getDataSchema().getColumnDataType(columnIndex);
            Type columnPrestoType = ((ArrayType) columnType).getElementType();
            BlockBuilder childBuilder = blockBuilder.beginBlockEntry();
            switch (columnPinotType) {
                case BOOLEAN_ARRAY:
                    int[] booleanArray = currentDataTable.getDataTable().getIntArray(rowIndex, columnIndex);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Identify the offending column from the message and exclude it from the SELECT projection or cast it to a supported type in the query
  2. Add/extend the type mapping in the connector so the Pinot type maps to a supported Presto type (e.g. VARCHAR/Slice)
  3. Check the Pinot table schema for recent type changes on that column
  4. Upgrade the connector if a newer version supports the type

Example fix

// before
SELECT * FROM pinot_table
// after
SELECT col_a, CAST(new_unsupported_col AS VARCHAR) FROM pinot_table
Defensive patterns

Strategy: validation

Validate before calling

// check expected types before running the query
for (PinotColumnHandle h : expectedColumnHandles) {
  Type t = h.getExpectedType();
  if (!(t.getJavaType() == Boolean.class || t.getJavaType() == Long.class ||
        t.getJavaType() == Double.class || t.getJavaType() == Slice.class ||
        t.getJavaType() == BigDecimal.class)) {
    throw new IllegalStateException("Unsupported column type in projection: " + h.getColumnName() + " -> " + t);
  }
}

Try / catch

try {
  page = pageSource.getNextPage();
} catch (PrestoException e) {
  if (e.getErrorCode().getCode() == PINOT_UNSUPPORTED_COLUMN_TYPE.toErrorCode().getCode()) {
    log.error("Unsupported pinot column: %s", e.getMessage());
    // re-plan excluding/casting the offending column
    executeWithRewrittenQuery(stripOffendingColumn(originalQuery, e.getMessage()));
  } else throw e;
}

Prevention

When it happens

Trigger: writeBlock receives a javaType outside {Boolean, Long, Double, BigDecimal/Slice} for a column returned by Pinot, e.g. custom object columns, unknown serialized types, or type mapping drift between PinotColumnHandle.expectedType and the actual server payload.

Common situations: Schema changed in Pinot (column converted to a type the connector can't map); connector type-mapping table missing a Pinot type (e.g. JSON/bytes mapped incorrectly); SELECT * picking up new columns of unsupported types.

Related errors


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