prestodb/presto · error · IllegalArgumentException

Invalid row block:

Error message

Invalid row block: 

What it means

ColumnarRow.toColumnarRow only supports row blocks extending AbstractRowBlock (plus RunLengthEncodedBlock). Any other Block implementation reaches a hard cast and would fail, so the method throws IllegalArgumentException with the block's class name. It guarantees the subsequent field access methods (getFieldBlockOffset, etc.) are valid.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/ColumnarRow.java:42

    private final Block nullCheckBlock;
    private final Block[] fields;
    private final long retainedSizeInBytes;
    private final long estimatedSerializedSizeInBytes;

    public static ColumnarRow toColumnarRow(Block block)
    {
        requireNonNull(block, "block is null");

        if (block instanceof DictionaryBlock) {
            return toColumnarRow((DictionaryBlock) block);
        }
        if (block instanceof RunLengthEncodedBlock) {
            return toColumnarRow((RunLengthEncodedBlock) block);
        }

        if (!(block instanceof AbstractRowBlock)) {
            throw new IllegalArgumentException("Invalid row block: " + block.getClass().getName());
        }

        AbstractRowBlock rowBlock = (AbstractRowBlock) block;

        // get fields for visible region
        int firstRowPosition = rowBlock.getFieldBlockOffset(0);
        int totalRowCount = rowBlock.getFieldBlockOffset(block.getPositionCount()) - firstRowPosition;
        Block[] fieldBlocks = new Block[rowBlock.numFields];
        for (int i = 0; i < fieldBlocks.length; i++) {
            fieldBlocks[i] = rowBlock.getRawFieldBlocks()[i].getRegion(firstRowPosition, totalRowCount);
        }

        return new ColumnarRow(block, fieldBlocks, block.getRetainedSizeInBytes(), block.getSizeInBytes());
    }

    private static ColumnarRow toColumnarRow(DictionaryBlock dictionaryBlock)
    {
        // build a mapping from the old dictionary to a new dictionary with nulls removed

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Unwrap lazy blocks (block.getLoadedBlock() / LazyBlock.unwrap()) before converting
  2. Confirm the page column's Type is RowType and its block is a row block before calling toColumnarRow
  3. Make custom row Block implementations extend AbstractRowBlock
  4. Read the exception message for the concrete class name and trace where that block is produced

Example fix

// before
ColumnarRow row = ColumnarRow.toColumnarRow(rawBlock);
// after
Block block = rawBlock.getLoadedBlock();
checkArgument(block instanceof AbstractRowBlock || block instanceof RunLengthEncodedBlock, "Expected row block, got %s", block.getClass().getSimpleName());
ColumnarRow row = ColumnarRow.toColumnarRow(block);
Defensive patterns

Strategy: type-guard

Validate before calling

public static ColumnarRow safeToColumnarRow(Block block)
{
    Block loaded = block.getLoadedBlock();
    checkArgument(loaded instanceof AbstractRowBlock || loaded instanceof RunLengthEncodedBlock,
        "Expected row block, got %s", loaded.getClass().getName());
    return ColumnarRow.toColumnarRow(loaded);
}

Type guard

static boolean isRowBlock(Block block) {
    Block b = block.getLoadedBlock();
    return b instanceof AbstractRowBlock || b instanceof RunLengthEncodedBlock;
}

Try / catch

try {
    ColumnarRow row = ColumnarRow.toColumnarRow(block);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("Cannot convert column to row: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Calling ColumnarRow.toColumnarRow(block) or ColumnarRow.columnarRow(block) with a Block that is neither RunLengthEncodedBlock nor AbstractRowBlock — e.g. a ROW column encoded as dictionary or plain array block, or an unwrapped lazy block of the wrong concrete type.

Common situations: Connector/page deserialization bugs where a ROW column arrives as a different block class; forgetting to unwrap LazyBlock; passing an element block instead of the top-level row block; upgrading Presto where custom row block implementations were removed.

Related errors


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