apache/shardingsphere · error · IllegalArgumentException

[CLUSTERED INTO n BUCKETS] and [ORDER BY col_list] clauses c

Error message

[CLUSTERED INTO n BUCKETS] and [ORDER BY col_list] clauses can only be used with REBALANCE compaction

What it means

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.

Source

Thrown at parser/sql/engine/dialect/hive/src/main/java/org/apache/shardingsphere/sql/parser/engine/hive/visitor/statement/type/HiveDDLStatementVisitor.java:153

            ChangeColumnDefinitionSegment changeColumnSegment = (ChangeColumnDefinitionSegment) visit(ctx.changeColumn());
            result.changeColumnDefinition(changeColumnSegment);
        }
        if (null != ctx.addColumns()) {
            AddColumnDefinitionSegment addSeg = (AddColumnDefinitionSegment) visit(ctx.addColumns());
            result.addColumnDefinition(addSeg);
        }
        if (null != ctx.replaceColumns()) {
            ReplaceColumnDefinitionSegment repSeg = (ReplaceColumnDefinitionSegment) visit(ctx.replaceColumns());
            result.replaceColumnDefinition(repSeg);
        }
        if (null != ctx.COMPACT()) {
            String compactionType = ctx.string_().getText().replace("'", "");
            if (!isValidCompactionType(compactionType)) {
                throw new IllegalArgumentException("Invalid compaction type. Must be 'MAJOR', 'MINOR' or 'REBALANCE'");
            }
            if ((null != ctx.clusteredIntoClause() || null != ctx.orderByClause())
                    && !"REBALANCE".equalsIgnoreCase(compactionType)) {
                throw new IllegalArgumentException("[CLUSTERED INTO n BUCKETS] and [ORDER BY col_list] clauses can only be used with REBALANCE compaction");
            }
        }
        if (null != ctx.cherryPickClause()) {
            int numberStartIndex = ctx.cherryPickClause().NUMBER_().getSymbol().getStartIndex();
            int numberStopIndex = ctx.cherryPickClause().NUMBER_().getSymbol().getStopIndex();
            LiteralExpressionSegment snapshotId = new LiteralExpressionSegment(numberStartIndex, numberStopIndex,
                    new NumberLiteralValue(ctx.cherryPickClause().NUMBER_().getText()).getValue());
            result.cherryPickDefinition(new CherryPickDefinitionSegment(ctx.cherryPickClause().EXECUTE().getSymbol().getStartIndex(), numberStopIndex, snapshotId));
        }
        if (null != ctx.tableRollback()) {
            int startIndex = ctx.tableRollback().EXECUTE().getSymbol().getStartIndex();
            if (null != ctx.tableRollback().string_()) {
                int stringStartIndex = ctx.tableRollback().string_().getStart().getStartIndex();
                int stringStopIndex = ctx.tableRollback().string_().getStop().getStopIndex();
                LiteralExpressionSegment timestamp = new LiteralExpressionSegment(stringStartIndex, stringStopIndex,
                        new StringLiteralValue(ctx.tableRollback().string_().getText()).getValue());
                result.tableRollbackDefinition(new TableRollbackDefinitionSegment(startIndex, stringStopIndex, timestamp, null));
            } else {

View on GitHub (pinned to e952770a21)

Solutions

  1. Remove CLUSTERED INTO / ORDER BY clauses when using MAJOR or MINOR compaction
  2. Or switch the compaction type to 'REBALANCE' if bucket/order rebalancing is intended
  3. Add statement-building guards in your DDL templates so these clause combinations are never emitted

Example fix

// before
ALTER TABLE t COMPACT 'MAJOR' CLUSTERED INTO 8 BUCKETS

// after
ALTER TABLE t COMPACT 'REBALANCE' CLUSTERED INTO 8 BUCKETS
Defensive patterns

Strategy: validation

Validate before calling

void assertCompactClauses(String type, boolean hasClusteredInto, boolean hasOrderBy) {
    if ((hasClusteredInto || hasOrderBy) && !"REBALANCE".equalsIgnoreCase(type)) {
        throw new IllegalArgumentException("CLUSTERED INTO / ORDER BY require REBALANCE compaction");
    }
}

Try / catch

try { ddlEngine.parse(alterSql); } catch (IllegalArgumentException e) { rejectInvalidCompaction(e); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/2e209325b569e11c. Report an issue: GitHub.