prestodb/presto · error · IllegalArgumentException

Type must be a MapType for MapVector

Error message

Type must be a MapType for MapVector

What it means

assignBlockFromMapVector converts an Arrow MapVector into a Presto map block. It requires the Presto Type to be MapType because it needs the map's key/value types to build BlockMapGetter-style accessors and recursively convert entries. A non-MapType makes this impossible, so it throws this IllegalArgumentException.

Source

Thrown at presto-common-arrow/src/main/java/com/facebook/plugin/arrow/ArrowBlockBuilder.java:724

            throw new IllegalArgumentException("Expected TimestampType but got " + type.getClass().getName());
        }

        for (int i = startIndex; i < endIndex; i++) {
            if (vector.isNull(i)) {
                builder.appendNull();
            }
            else {
                long micros = vector.get(i);
                long millis = TimeUnit.MICROSECONDS.toMillis(micros);
                type.writeLong(builder, millis);
            }
        }
    }

    public void assignBlockFromMapVector(MapVector vector, Type type, BlockBuilder builder, int startIndex, int endIndex)
    {
        if (!(type instanceof MapType)) {
            throw new IllegalArgumentException("Type must be a MapType for MapVector");
        }

        MapType mapType = (MapType) type;
        StructVector entryVector = (StructVector) vector.getDataVector();
        ValueVector keyVector = entryVector.getChildByOrdinal(0);
        ValueVector valueVector = entryVector.getChildByOrdinal(1);

        for (int i = startIndex; i < endIndex; i++) {
            if (vector.isNull(i)) {
                builder.appendNull();
            }
            else {
                BlockBuilder entryBuilder = builder.beginBlockEntry();
                int entryStart = vector.getElementStartIndex(i);
                int entryEnd = vector.getElementEndIndex(i);
                for (int entryIndex = entryStart; entryIndex < entryEnd; entryIndex++) {
                    assignBlockFromValueVector(keyVector, mapType.getKeyType(), entryBuilder, entryIndex, entryIndex + 1);
                    assignBlockFromValueVector(valueVector, mapType.getValueType(), entryBuilder, entryIndex, entryIndex + 1);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Declare the Presto column as a map of matching key/value types (MapType)
  2. Fix the Type supplied in the assignBlockFromValueVector dispatch so the MapVector gets its own MapType
  3. Verify the Arrow child field (keys/values) types match the Presto map's key/value types

Example fix

// before
assignBlockFromMapVector(mapVector, ArrayType.from(rowType), builder, start, end);
// after
assignBlockFromMapVector(mapVector, MapType.from(keyType, valueType), builder, start, end);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(columnType instanceof MapType)) {
    throw new IllegalStateException("Column '" + name + "' must be MapType to receive MapVector, got " + columnType);
}

Type guard

boolean isMapColumn(Type type) {
    return type instanceof MapType;
}

Try / catch

try {
    builder.assignBlockFromMapVector(vector, type, blockBuilder, start, end);
} catch (IllegalArgumentException e) {
    if (!e.getMessage().contains("MapType for MapVector")) throw e;
    // coerce (e.g. array(row) -> map) or fail with context
}

Prevention

When it happens

Trigger: Calling assignBlockFromMapVector (directly or via assignBlockFromValueVector) with a non-MapType, e.g. an ARRAY or ROW column type paired with a MapVector, or a scalar type.

Common situations: Arrow producer encodes a column as MAP while the Presto table declares it as array(row) or json; schema mismatch after producer-side type change; column-index misalignment in the dispatch switch.

Related errors


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