prestodb/presto · error · PrestoException

FUNCTION_IMPLEMENTATION_ERROR

FUNCTION_IMPLEMENTATION_ERROR

Error message

When function got no input, it should either produce output or return Blocked state

What it means

EmptyTableFunctionPartition drives a table function over partitions. The TableFunctionProcessorState contract requires that when the processor receives no input, it must either return an output page or a Blocked state. If a Processed state with a null result is produced with no input, the library throws FUNCTION_IMPLEMENTATION_ERROR — this is a bug in the table function implementation, not the query.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/operator/EmptyTableFunctionPartition.java:71

        this.passThroughTypes = passThroughTypes.toArray(new Type[] {});
    }

    @Override
    public WorkProcessor<Page> toOutputPages()
    {
        return WorkProcessor.create(() -> {
            TableFunctionProcessorState state = tableFunction.process(null);
            if (state == FINISHED) {
                return WorkProcessor.ProcessState.finished();
            }
            if (state instanceof TableFunctionProcessorState.Blocked) {
                return WorkProcessor.ProcessState.blocked(toListenableFuture(((TableFunctionProcessorState.Blocked) state).getFuture()));
            }
            TableFunctionProcessorState.Processed processed = (TableFunctionProcessorState.Processed) state;
            if (processed.getResult() != null) {
                return WorkProcessor.ProcessState.ofResult(appendNullsForPassThroughColumns(processed.getResult()));
            }
            throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, "When function got no input, it should either produce output or return Blocked state");
        });
    }

    private Page appendNullsForPassThroughColumns(Page page)
    {
        if (page.getChannelCount() != properChannelsCount + passThroughSourcesCount) {
            throw new PrestoException(
                    FUNCTION_IMPLEMENTATION_ERROR,
                    format(
                            "Table function returned a page containing %s channels. Expected channel number: %s (%s proper columns, %s pass-through index columns)",
                            page.getChannelCount(),
                            properChannelsCount + passThroughSourcesCount,
                            properChannelsCount,
                            passThroughSourcesCount));
        }

        Block[] resultBlocks = new Block[properChannelsCount + passThroughTypes.length];

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Fix the table function processor to return Processed.nonBlocking(/* page */) with output or TableFunctionProcessorState.blocked(future) when input is empty
  2. Upgrade Presto / the connector providing the table function to a version with the empty-input bug fixed
  3. Avoid the table function on empty partitions (guard the query) as a workaround

Example fix

// before
if (!hasInput) {
    return Processed.nonBlocking(null); // INVALID
}
// after
if (!hasInput) {
    return Processed.nonBlocking(buildEmptyOutputPage()); // or blocked(future)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// for table function authors: verify empty-input behavior in a unit test
TableFunctionProcessorState s = processor.process(new Page(0));
checkState(!(s instanceof Processed) || ((Processed) s).getResult() != null,
    "empty input must yield output or Blocked");

Try / catch

try {
    return tableFunctionPartition.toOutputPages();
} catch (PrestoException e) {
    if (e.getErrorCode().getName().equals("FUNCTION_IMPLEMENTATION_ERROR")) {
        // treat as connector bug: fail query with function name context or skip partition
    }
    throw e;
}

Prevention

When it happens

Trigger: A custom TableFunctionProcessor returning TableFunctionProcessorState.Processed with a null result when called with an empty/no-input partition, inside EmptyTableFunctionPartition.toOutputPages.

Common situations: Third-party or newly written table functions that mishandle the empty-partition case; upstream Presto bugs in a table function fixed in later versions.

Related errors


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