{"record":{"id":"9136a26978d98244","repo":"prestodb/presto","slug":"invalid-plan-error","errorCode":"INVALID_PLAN_ERROR","errorMessage":"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.","messagePattern":"When grouped execution can't be enabled, merge join plan is not valid\\.(.+?) is currently set to (.+?); left node grouped execution capable is (.+?) and right node grouped execution capable is (.+?)\\.","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/sql/planner/GroupedExecutionTagger.java","lineNumber":182,"sourceCode":"        GroupedExecutionTagger.GroupedExecutionProperties right = node.getRight().accept(this, null);\n\n        if (groupedExecutionEnabled && left.currentNodeCapable && right.currentNodeCapable) {\n            return mergeJoinSides(left, right, node.getCriteria());\n        }\n        if (preferSortMergeJoin(session)) {\n            // TODO: This will break the other use case for merge join operating on sorted tables, which requires grouped execution for correctness.\n            return GroupedExecutionTagger.GroupedExecutionProperties.notCapable();\n        }\n\n        if (isPrestoOnSpark) {\n            GroupedExecutionTagger.GroupedExecutionProperties mergeJoinLeft = node.getLeft().accept(new GroupedExecutionTagger(session, metadata, nodePartitioningManager, true, true), null);\n            GroupedExecutionTagger.GroupedExecutionProperties mergeJoinRight = node.getRight().accept(new GroupedExecutionTagger(session, metadata, nodePartitioningManager, true, true), null);\n            if (mergeJoinLeft.currentNodeCapable || mergeJoinRight.currentNodeCapable) {\n                return GroupedExecutionTagger.GroupedExecutionProperties.notCapable();\n            }\n        }\n\n        throw new PrestoException(\n                INVALID_PLAN_ERROR,\n                format(\"When grouped execution can't be enabled, merge join plan is not valid.\" +\n                                \"%s is currently set to %s; left node grouped execution capable is %s and \" +\n                                \"right node grouped execution capable is %s.\",\n                        GROUPED_EXECUTION,\n                        groupedExecutionEnabled,\n                        left.currentNodeCapable,\n                        right.currentNodeCapable));\n    }\n\n    /**\n     * Merge partition column tracking from both sides of a partitioned join (hash, merge, or index).\n     * For each equi-join clause where both sides have usable partition columns,\n     * union the corresponding TableScanColumns in the union-find and track which vars participated.\n     * Drop vars whose TableScanColumn is not in any equivalence class with a joined var.\n     */\n    private GroupedExecutionTagger.GroupedExecutionProperties mergeJoinSides(\n            GroupedExecutionTagger.GroupedExecutionProperties left,","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/sql/planner/GroupedExecutionTagger.java#L164-L200","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set grouped_execution=true in the session so merge join can be enabled.","Disable the merge join feature/optimizer rule to fall back to hash join.","Restructure the query or data source so at least one join side is grouped-execution capable."],"exampleFix":"// before\nSET SESSION grouped_execution = false;\nSELECT * FROM a JOIN b ON a.k = b.k;\n// after\nSET SESSION grouped_execution = true;\nSELECT * FROM a JOIN b ON a.k = b.k;","handlingStrategy":"validation","validationCode":"if (\"false\".equalsIgnoreCase(session.getProperty(\"grouped_execution\", \"true\")) && planContainsMergeJoin(plan)) { /* force hash join or enable grouped execution */ }","typeGuard":"boolean mergeJoinPlanValid(Session session, PlanNode joinNode) { return \"true\".equalsIgnoreCase(session.getSystemProperty(\"grouped_execution\")); }","tryCatchPattern":"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; } }","preventionTips":["Set grouped_execution=true when relying on merge join","Or disable the merge join optimizer rule if connectors lack grouped execution support","Validate connector capabilities before enabling merge-join optimizations"],"tags":["planner","merge-join","grouped-execution"],"backgroundTag":"invalid-plan-configuration","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}