prestodb/presto · error · PrestoException

CLICKHOUSE_QUERY_GENERATOR_FAILURE

CLICKHOUSE_QUERY_GENERATOR_FAILURE

Error message

Expected to find a clickhouse table scan node

What it means

ClickHouseComputePushdown.tryCreatingNewScanNode() builds the pushed-down plan by replacing the original ClickHouse table scan node. If the generator context lacks a table scan node id, or the resolved id is not among the collected tableScanNodes, it throws CLICKHOUSE_QUERY_GENERATOR_FAILURE — meaning the pushdown optimizer could not locate the scan node to rewrite. This indicates an unexpected plan shape and is a connector-internal failure.

Source

Thrown at presto-clickhouse/src/main/java/com/facebook/presto/plugin/clickhouse/optimization/ClickHouseComputePushdown.java:170

        public Visitor(Map<PlanNodeId, TableScanNode> tableScanNodes, ConnectorSession session, PlanNodeIdAllocator idAllocator)
        {
            this.session = requireNonNull(session, "session is null");
            this.idAllocator = requireNonNull(idAllocator, "idAllocator is null");
            this.tableScanNodes = tableScanNodes;
            tableScanNodes.forEach((key, value) -> getClickHouseTableHandle(value).get().getTableName());
        }

        private Optional<PlanNode> tryCreatingNewScanNode(PlanNode plan)
        {
            Optional<ClickHouseQueryGenerator.ClickHouseQueryGeneratorResult> clickhouseSQL = clickhouseQueryGenerator.generate(plan, session);
            if (!clickhouseSQL.isPresent()) {
                return Optional.empty();
            }
            ClickHouseQueryGeneratorContext context = clickhouseSQL.get().getContext();
            final PlanNodeId tableScanNodeId = context.getTableScanNodeId().orElseThrow(() -> new PrestoException(CLICKHOUSE_QUERY_GENERATOR_FAILURE, "Expected to find a clickhouse table scan node id"));
            if (!tableScanNodes.containsKey(tableScanNodeId)) {
                throw new PrestoException(CLICKHOUSE_QUERY_GENERATOR_FAILURE, "Expected to find a clickhouse table scan node");
            }

            final TableScanNode tableScanNode = tableScanNodes.get(tableScanNodeId);
            ClickHouseTableHandle clickHouseTableHandle = getClickHouseTableHandle(tableScanNode).orElseThrow(() -> new PrestoException(CLICKHOUSE_QUERY_GENERATOR_FAILURE, "Expected to find a clickhouse table handle"));
            TableHandle oldTableHandle = tableScanNode.getTable();
            Map<VariableReferenceExpression, ClickHouseColumnHandle> assignments = context.getAssignments();

            ClickHouseTableHandle oldConnectorTable = (ClickHouseTableHandle) oldTableHandle.getConnectorHandle();
            ClickHouseTableLayoutHandle oldTableLayoutHandle = (ClickHouseTableLayoutHandle) oldTableHandle.getLayout().get();
            ClickHouseTableLayoutHandle newTableLayoutHandle = new ClickHouseTableLayoutHandle(
                    oldConnectorTable,
                    oldTableLayoutHandle.getTupleDomain(),
                    Optional.empty(), Optional.empty(), Optional.of(clickhouseSQL.get().getGeneratedClickhouseSQL()));

            TableHandle newTableHandle = new TableHandle(
                    oldTableHandle.getConnectorId(),
                    new ClickHouseTableHandle(clickHouseTableHandle.getConnectorId(),
                            new SchemaTableName(clickHouseTableHandle.getSchemaName(), clickHouseTableHandle.getTableName()),

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Disable ClickHouse compute pushdown (catalog property for pushdown/optimization) to fall back to regular execution
  2. Simplify the query (remove intermediate views/wrappers) so the scan node survives optimization
  3. Retry with a rewritten query form
  4. File a connector bug with the query and EXPLAIN plan

Example fix

// before (catalog properties)
connector.name=clickhouse
# pushdown enabled
// after
connector.name=clickhouse
presto-clickhouse.compute-pushdown-enabled=false
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check plan before enabling compute pushdown
PlanNodeId scanId = context.getTableScanNodeId().orElse(null);
if (scanId == null || !tableScanNodes.containsKey(scanId)) {
    log.warn("ClickHouse pushdown skipped: table scan node not found in plan");
    return Optional.empty();
}

Try / catch

try {
    plan = createPushedDownPlan(...);
} catch (PrestoException e) {
    if (e.getErrorCode().getCode() == CLICKHOUSE_QUERY_GENERATOR_FAILURE.toErrorCode().getCode()
            && e.getMessage().contains("Expected to find a clickhouse table scan node")) {
        return originalPlan; // fall back to unpushed plan
    }
    throw e;
}

Prevention

When it happens

Trigger: A query eligible for ClickHouse compute pushdown whose plan contains the ClickHouse table handle but where the plan-node id recorded in the query-generation context does not match any TableScanNode in the plan (unexpected plan transformations between generation and rewrite).

Common situations: Plans altered by other rules/optimizers (e.g. additional exchanges or node rewrites) breaking the recorded id; queries over views or complex wrappers around the scan; connector bug on certain plan shapes.

Related errors


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