{"record":{"id":"2e209325b569e11c","repo":"apache/shardingsphere","slug":"clustered-into-n-buckets-and-order-by-col-list","errorCode":null,"errorMessage":"[CLUSTERED INTO n BUCKETS] and [ORDER BY col_list] clauses can only be used with REBALANCE compaction","messagePattern":"\\[CLUSTERED INTO n BUCKETS\\] and \\[ORDER BY col_list\\] clauses can only be used with REBALANCE compaction","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"parser/sql/engine/dialect/hive/src/main/java/org/apache/shardingsphere/sql/parser/engine/hive/visitor/statement/type/HiveDDLStatementVisitor.java","lineNumber":153,"sourceCode":"            ChangeColumnDefinitionSegment changeColumnSegment = (ChangeColumnDefinitionSegment) visit(ctx.changeColumn());\n            result.changeColumnDefinition(changeColumnSegment);\n        }\n        if (null != ctx.addColumns()) {\n            AddColumnDefinitionSegment addSeg = (AddColumnDefinitionSegment) visit(ctx.addColumns());\n            result.addColumnDefinition(addSeg);\n        }\n        if (null != ctx.replaceColumns()) {\n            ReplaceColumnDefinitionSegment repSeg = (ReplaceColumnDefinitionSegment) visit(ctx.replaceColumns());\n            result.replaceColumnDefinition(repSeg);\n        }\n        if (null != ctx.COMPACT()) {\n            String compactionType = ctx.string_().getText().replace(\"'\", \"\");\n            if (!isValidCompactionType(compactionType)) {\n                throw new IllegalArgumentException(\"Invalid compaction type. Must be 'MAJOR', 'MINOR' or 'REBALANCE'\");\n            }\n            if ((null != ctx.clusteredIntoClause() || null != ctx.orderByClause())\n                    && !\"REBALANCE\".equalsIgnoreCase(compactionType)) {\n                throw new IllegalArgumentException(\"[CLUSTERED INTO n BUCKETS] and [ORDER BY col_list] clauses can only be used with REBALANCE compaction\");\n            }\n        }\n        if (null != ctx.cherryPickClause()) {\n            int numberStartIndex = ctx.cherryPickClause().NUMBER_().getSymbol().getStartIndex();\n            int numberStopIndex = ctx.cherryPickClause().NUMBER_().getSymbol().getStopIndex();\n            LiteralExpressionSegment snapshotId = new LiteralExpressionSegment(numberStartIndex, numberStopIndex,\n                    new NumberLiteralValue(ctx.cherryPickClause().NUMBER_().getText()).getValue());\n            result.cherryPickDefinition(new CherryPickDefinitionSegment(ctx.cherryPickClause().EXECUTE().getSymbol().getStartIndex(), numberStopIndex, snapshotId));\n        }\n        if (null != ctx.tableRollback()) {\n            int startIndex = ctx.tableRollback().EXECUTE().getSymbol().getStartIndex();\n            if (null != ctx.tableRollback().string_()) {\n                int stringStartIndex = ctx.tableRollback().string_().getStart().getStartIndex();\n                int stringStopIndex = ctx.tableRollback().string_().getStop().getStopIndex();\n                LiteralExpressionSegment timestamp = new LiteralExpressionSegment(stringStartIndex, stringStopIndex,\n                        new StringLiteralValue(ctx.tableRollback().string_().getText()).getValue());\n                result.tableRollbackDefinition(new TableRollbackDefinitionSegment(startIndex, stringStopIndex, timestamp, null));\n            } else {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/parser/sql/engine/dialect/hive/src/main/java/org/apache/shardingsphere/sql/parser/engine/hive/visitor/statement/type/HiveDDLStatementVisitor.java#L135-L171","documentation":"Thrown by HiveDDLStatementVisitor when an ALTER TABLE ... COMPACT statement uses CLUSTERED INTO n BUCKETS or ORDER BY col_list while the compaction type is anything other than REBALANCE. Those two clauses are only meaningful for REBALANCE compaction, so the visitor enforces the pairing at parse time with an IllegalArgumentException.","triggerScenarios":"Statements like ALTER TABLE t COMPACT 'MAJOR' CLUSTERED INTO 8 BUCKETS or COMPACT 'MINOR' ORDER BY col: ctx.COMPACT() is present, the type passes the whitelist check, but (clusteredIntoClause() != null || orderByClause() != null) while the type is not REBALANCE.","commonSituations":"Assembling compaction statements from templates that always append bucket/order-by clauses; porting REBALANCE examples onto MAJOR/MINOR compactions; scripted DDL generation that mixes clause sets.","solutions":["Remove CLUSTERED INTO / ORDER BY clauses when using MAJOR or MINOR compaction","Or switch the compaction type to 'REBALANCE' if bucket/order rebalancing is intended","Add statement-building guards in your DDL templates so these clause combinations are never emitted"],"exampleFix":"// before\nALTER TABLE t COMPACT 'MAJOR' CLUSTERED INTO 8 BUCKETS\n\n// after\nALTER TABLE t COMPACT 'REBALANCE' CLUSTERED INTO 8 BUCKETS","handlingStrategy":"validation","validationCode":"void assertCompactClauses(String type, boolean hasClusteredInto, boolean hasOrderBy) {\n    if ((hasClusteredInto || hasOrderBy) && !\"REBALANCE\".equalsIgnoreCase(type)) {\n        throw new IllegalArgumentException(\"CLUSTERED INTO / ORDER BY require REBALANCE compaction\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try { ddlEngine.parse(alterSql); } catch (IllegalArgumentException e) { rejectInvalidCompaction(e); }","preventionTips":["Make DDL templates conditional: only append bucket/order-by clauses for REBALANCE","Unit-test statement builders against the clause-combination matrix"],"tags":["hive","ddl","compaction","rebalance","clause-validation"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}