prestodb/presto · error · PrestoException

GENERIC_INTERNAL_ERROR

GENERIC_INTERNAL_ERROR

Error message

Unenforced filter found %s but not handled

What it means

BaseSubfieldExtractionRewriter.visitTableScan runs Hive partition/subfield pushdown and asserts that the pushdown result left no unenforced constraint. If the remaining unenforced filter is not the TRUE constant, it means the planner expected the connector to fully enforce a filter that it did not, so it throws GENERIC_INTERNAL_ERROR — an engine invariant violation, not a user mistake.

Source

Thrown at presto-hive-common/src/main/java/com/facebook/presto/hive/rule/BaseSubfieldExtractionRewriter.java:193

        }

        TableHandle handle = tableScan.getTable();
        ConnectorMetadata metadata = transactionToMetadata.apply(handle);
        ConnectorPushdownFilterResult pushdownFilterResult = pushdownFilter(
                session,
                metadata,
                handle.getConnectorHandle(),
                TRUE_CONSTANT,
                handle.getLayout());
        if (pushdownFilterResult.getLayout().getPredicate().isNone()) {
            return getValuesNode(tableScan);
        }

        TableScanNode node = getTableScanNode(tableScan, handle, pushdownFilterResult);

        RowExpression unenforcedFilter = pushdownFilterResult.getUnenforcedConstraint();
        if (!TRUE_CONSTANT.equals(unenforcedFilter)) {
            throw new PrestoException(
                    GENERIC_INTERNAL_ERROR,
                    format("Unenforced filter found %s but not handled", unenforcedFilter));
        }

        return node;
    }

    public ConnectorPushdownFilterResult pushdownFilter(
            ConnectorSession session,
            ConnectorMetadata metadata,
            ConnectorTableHandle tableHandle,
            RowExpression filter,
            Optional<ConnectorTableLayoutHandle> currentLayoutHandle)
    {
        checkArgument(!FALSE_CONSTANT.equals(filter), "Cannot pushdown filter that is always false");

        if (TRUE_CONSTANT.equals(filter) && currentLayoutHandle.isPresent()) {
            return new ConnectorPushdownFilterResult(metadata.getTableLayout(session, currentLayoutHandle.get()), TRUE_CONSTANT);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Retry/rewrite the query to simplify predicates over partition columns (e.g., precompute values, avoid exotic functions in WHERE).
  2. Check whether the error appeared right after a Presto upgrade — search the changelog/release notes for pushdown fixes and upgrade or downgrade accordingly.
  3. Capture the unenforced filter text from the error and the full plan; file a bug with repro — this indicates a planner/connector bug.
  4. Disable the experimental subfield-extraction/pushdown feature flag if one is enabled in your config, as a workaround.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    plan = rewriteTableScan(...);
} catch (PrestoException e) {
    if (e.getErrorCode() == GENERIC_INTERNAL_ERROR.toErrorCode()
            && e.getMessage().startsWith("Unenforced filter")) {
        // capture filter text + plan for bug report; retry with simplified predicate
    }
}

Prevention

When it happens

Trigger: HiveTableLayoutHandle pushdownFilterResult returns an unenforced constraint after rewriting a TableScanNode — i.e., a filter the rule classified as pushable but did not attach to the layout handle.

Common situations: New expression types (complex functions over partition columns, certain RowExpression rewrites) hitting a rule gap after a Presto upgrade; custom function-registry plugins producing expressions the rewriter cannot fold to TRUE.

Related errors


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