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
- Fix the table function processor to return Processed.nonBlocking(/* page */) with output or TableFunctionProcessorState.blocked(future) when input is empty
- Upgrade Presto / the connector providing the table function to a version with the empty-input bug fixed
- 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
- Table function authors: always return an output page or Blocked when input is empty
- Add empty-partition tests to every TableFunctionProcessor
- Keep Presto/connector versions patched for known table function bugs
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
- ALREADY_EXISTS
- FUNCTION_IMPLEMENTATION_MISSING
- FUNCTION_NOT_FOUND
- FUNCTION_IMPLEMENTATION_ERROR
- FUNCTION_IMPLEMENTATION_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/653ac7bb1ded1dc2.
Report an issue: GitHub.