prestodb/presto · error · PrestoException

INVALID_PLAN_ERROR

INVALID_PLAN_ERROR

Error message

When grouped execution can't be enabled, merge join plan is not valid.%s is currently set to %s; left node grouped execution capable is %s and right node grouped execution capable is %s.

What it means

The plan validator throws INVALID_PLAN_ERROR when a merge join is planned but grouped execution cannot be enabled for either side and the session disallows it. Merge joins only work under grouped execution, so such a plan is rejected.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/GroupedExecutionTagger.java:182

        GroupedExecutionTagger.GroupedExecutionProperties right = node.getRight().accept(this, null);

        if (groupedExecutionEnabled && left.currentNodeCapable && right.currentNodeCapable) {
            return mergeJoinSides(left, right, node.getCriteria());
        }
        if (preferSortMergeJoin(session)) {
            // TODO: This will break the other use case for merge join operating on sorted tables, which requires grouped execution for correctness.
            return GroupedExecutionTagger.GroupedExecutionProperties.notCapable();
        }

        if (isPrestoOnSpark) {
            GroupedExecutionTagger.GroupedExecutionProperties mergeJoinLeft = node.getLeft().accept(new GroupedExecutionTagger(session, metadata, nodePartitioningManager, true, true), null);
            GroupedExecutionTagger.GroupedExecutionProperties mergeJoinRight = node.getRight().accept(new GroupedExecutionTagger(session, metadata, nodePartitioningManager, true, true), null);
            if (mergeJoinLeft.currentNodeCapable || mergeJoinRight.currentNodeCapable) {
                return GroupedExecutionTagger.GroupedExecutionProperties.notCapable();
            }
        }

        throw new PrestoException(
                INVALID_PLAN_ERROR,
                format("When grouped execution can't be enabled, merge join plan is not valid." +
                                "%s is currently set to %s; left node grouped execution capable is %s and " +
                                "right node grouped execution capable is %s.",
                        GROUPED_EXECUTION,
                        groupedExecutionEnabled,
                        left.currentNodeCapable,
                        right.currentNodeCapable));
    }

    /**
     * Merge partition column tracking from both sides of a partitioned join (hash, merge, or index).
     * For each equi-join clause where both sides have usable partition columns,
     * union the corresponding TableScanColumns in the union-find and track which vars participated.
     * Drop vars whose TableScanColumn is not in any equivalence class with a joined var.
     */
    private GroupedExecutionTagger.GroupedExecutionProperties mergeJoinSides(
            GroupedExecutionTagger.GroupedExecutionProperties left,

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Set grouped_execution=true in the session so merge join can be enabled.
  2. Disable the merge join feature/optimizer rule to fall back to hash join.
  3. Restructure the query or data source so at least one join side is grouped-execution capable.

Example fix

// before
SET SESSION grouped_execution = false;
SELECT * FROM a JOIN b ON a.k = b.k;
// after
SET SESSION grouped_execution = true;
SELECT * FROM a JOIN b ON a.k = b.k;
Defensive patterns

Strategy: validation

Validate before calling

if ("false".equalsIgnoreCase(session.getProperty("grouped_execution", "true")) && planContainsMergeJoin(plan)) { /* force hash join or enable grouped execution */ }

Type guard

boolean mergeJoinPlanValid(Session session, PlanNode joinNode) { return "true".equalsIgnoreCase(session.getSystemProperty("grouped_execution")); }

Try / catch

try { plan = planner.plan(...); } catch (PrestoException e) { if (e.getErrorCode() == StandardErrorCode.INVALID_PLAN_ERROR.toErrorCode()) { session.setProperty("grouped_execution", "true"); plan = planner.plan(...); } else { throw e; } }

Prevention

When it happens

Trigger: A plan contains a merge join where neither left nor right subtree is grouped-execution capable while session property grouped_execution is not forced/enabled appropriately.

Common situations: Queries over connectors that don't support grouped execution combined with merge-join optimization; session config conflicts (grouped_execution=false or off) with merge join feature flags.

Related errors


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