prestodb/presto · error · UnsupportedOperationException

SingleRowBlock does not support appendNull()

Error message

SingleRowBlock does not support appendNull()

What it means

SingleRowBlock is an immutable view over one row of an existing RowBlock. It does not support mutation, so appendNull() throws UnsupportedOperationException. Nulls belong in a RowBlockBuilder, not in a view over already-written data.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/SingleRowBlock.java:122

    {
        return format("SingleRowBlock(%d){numFields=%d}", hashCode(), fieldBlocks.length);
    }

    @Override
    public Block getLoadedBlock()
    {
        Block[] loadedFieldBlocks = ensureBlocksAreLoaded(fieldBlocks);
        if (loadedFieldBlocks == fieldBlocks) {
            // All blocks are already loaded
            return this;
        }
        return new SingleRowBlock(rowIndex, loadedFieldBlocks);
    }

    @Override
    public Block appendNull()
    {
        throw new UnsupportedOperationException("SingleRowBlock does not support appendNull()");
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        SingleRowBlock other = (SingleRowBlock) obj;
        return Arrays.equals(this.fieldBlocks, other.fieldBlocks);
    }

    @Override
    public int hashCode()
    {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Use a RowBlockBuilder and call appendNull() (or build field-wise) there instead.
  2. Copy the SingleRowBlock's fields into a builder via writePositionTo per field when mutation-free copying is the goal.
  3. Type-check with instanceof SingleRowBlock / RowBlock and route immutable blocks through a builder-based copy path.

Example fix

// before
Block row = rowColumn.getBlock(position);
Block out = row.appendNull(); // UnsupportedOperationException
// after
RowBlockBuilder out = (RowBlockBuilder) rowType.createBlockBuilder(null, 1);
out.appendNull(); // writes a NULL row into the builder
Defensive patterns

Strategy: type-guard

Validate before calling

if (block instanceof SingleRowBlock) {
    // read-only view: copy fields into a RowBlockBuilder before any mutation
}

Type guard

boolean isAppendableBlock(Block block) {
    return block instanceof BlockBuilder;
}

Try / catch

try {
    newBlock = block.appendNull();
} catch (UnsupportedOperationException e) {
    RowBlockBuilder builder = (RowBlockBuilder) rowType.createBlockBuilder(null, 1);
    builder.appendNull();
    newBlock = builder.build();
}

Prevention

When it happens

Trigger: Calling appendNull() on a SingleRowBlock, usually in generic code that appends to any Block without checking its type (e.g. building output pages row by row).

Common situations: Generic block-processing operators hitting a row-typed column; code assuming all blocks are mutable; using SingleRowBlock where a RowBlockBuilder was needed to assemble new rows.

Related errors


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