prestodb/presto · error · UnsupportedOperationException

deleteRows called on EmptySplitPageSource

Error message

deleteRows called on EmptySplitPageSource

What it means

EmptySplitPageSource is a placeholder UpdatablePageSource used when a connector supplies an empty split; it does not support row deletion. Calling deleteRows on it throws UnsupportedOperationException because there are no underlying pages/rows to delete.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/split/EmptySplitPageSource.java:34

import com.facebook.presto.common.Page;
import com.facebook.presto.common.block.Block;
import com.facebook.presto.spi.UpdatablePageSource;
import com.google.common.collect.ImmutableList;
import io.airlift.slice.Slice;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import static java.util.concurrent.CompletableFuture.completedFuture;

public class EmptySplitPageSource
        implements UpdatablePageSource
{
    @Override
    public void deleteRows(Block rowIds)
    {
        throw new UnsupportedOperationException("deleteRows called on EmptySplitPageSource");
    }

    @Override
    public void updateRows(Page page, List<Integer> columnValueAndRowIdChannels)
    {
        throw new UnsupportedOperationException("updateRows called on EmptySplitPageSource");
    }

    @Override
    public CompletableFuture<Collection<Slice>> finish()
    {
        return completedFuture(ImmutableList.of());
    }

    @Override
    public long getCompletedBytes()
    {
        return 0;

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify the connector actually supports deletable tables and returns a real updatable page source instead of empty splits
  2. Avoid issuing DELETE/UPDATE against tables served by this connector
  3. If you are a connector author, implement deleteRows/updateRows or throw a clearer PrestoException (NOT_SUPPORTED) in the connector
  4. Check plan/split assignment for a bug where empty splits are wrongly chosen for DML
Defensive patterns

Strategy: validation

Validate before calling

// before issuing DELETE on a connector table, verify connector support:
if (!connectorMetadata.supportsRemove()) throw new IllegalStateException("connector does not support delete");

Type guard

function isUpdatable(src) { return src !== null && typeof src.deleteRows === 'function' && !(src instanceof EmptySplitPageSource); }

Try / catch

try { pageSource.deleteRows(rowIds); } catch (UnsupportedOperationException e) { throw new PrestoException(NOT_SUPPORTED, "table does not support delete", e); }

Prevention

When it happens

Trigger: An UPDATE/DELETE (MERGE delete) plan assigns an EmptySplitPageSource as the page source and the connector's page sink provider still routes deleteRows(Block rowIds) calls to it instead of a real updatable source.

Common situations: A connector that returns empty splits but does not fully implement updatable (upsert/delete) page sources; queries hitting connector tables whose split provider yields no data but the delete path still executes.

Related errors


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