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
- Use a RowBlockBuilder and call appendNull() (or build field-wise) there instead.
- Copy the SingleRowBlock's fields into a builder via writePositionTo per field when mutation-free copying is the goal.
- 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
- Treat SingleRowBlock (from getBlock/getSingleValueBlock) as strictly read-only.
- Assemble new rows only via RowBlockBuilder.
- Centralize block-copy logic so mutation attempts on views fail at review time, not runtime.
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
- SingleMapBlock does not support appendNull()
- New column does not have same number of rows as old column
- Declared positions (%s) does not match block %s's number of
- Offset is not monotonically ascending. offsets[%s]=%s, offse
- A null map must have zero entries
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/b9eceb2c2be26261.
Report an issue: GitHub.