Code review comment: I think rollup job can be changed to same as schema change job.

Code under review:
public void processAlterTable(AlterTableStmt stmt) throws UserException {
        TableName dbTableName = stmt.getTbl();
        String dbName = dbTableName.getDb();
        final String clusterName = stmt.getClusterName();

        Database db = Catalog.getInstance().getDb(dbName);
        if (db == null) {
            ErrorReport.reportDdlException(ErrorCode.ERR_BAD_DB_ERROR, dbName);
        }

        
        Catalog.getCurrentSystemInfo().checkClusterCapacity(clusterName);

        
        boolean hasSchemaChange = false;
        
        boolean hasAddMaterializedView = false;
        boolean hasDropRollup = false;
        
        boolean hasPartition = false;
        
        boolean hasRename = false;
        
        boolean hasModifyProp = false;

        
        List<AlterClause> alterClauses = stmt.getOps();
        

        
        boolean allIsDropOps = true;
        for (AlterClause alterClause : alterClauses) {
            if (!(alterClause instanceof DropPartitionClause)
                    && !(alterClause instanceof DropRollupClause)) {
                allIsDropOps = false;
                break;
            }
        }

        if (!allIsDropOps) {
            
            db.checkQuota();
        }

        boolean needTableStable = false;
        for (AlterClause alterClause : alterClauses) {
            if (!needTableStable) {
                needTableStable = ((AlterTableClause) alterClause).isNeedTableStable();
            }
            if ((alterClause instanceof AddColumnClause
                    || alterClause instanceof AddColumnsClause
                    || alterClause instanceof DropColumnClause
                    || alterClause instanceof ModifyColumnClause
                    || alterClause instanceof ReorderColumnsClause
                    || alterClause instanceof CreateIndexClause
                    || alterClause instanceof DropIndexClause)
                    && !hasAddMaterializedView && !hasDropRollup && !hasPartition && !hasRename) {
                hasSchemaChange = true;
                if (alterClause instanceof CreateIndexClause) {
                    Table table = db.getTable(dbTableName.getTbl());
                    if (!(table instanceof OlapTable)) {
                        throw new AnalysisException("create index only support in olap table at current version.");
                    }
                    List<Index> indexes = ((OlapTable) table).getIndexes();
                    IndexDef indexDef = ((CreateIndexClause) alterClause).getIndexDef();
                    Set<String> newColset = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
                    newColset.addAll(indexDef.getColumns());
                    for (Index idx : indexes) {
                        if (idx.getIndexName().equalsIgnoreCase(indexDef.getIndexName())) {
                            throw new AnalysisException("index `" + indexDef.getIndexName() + "` already exist.");
                        }
                        Set<String> idxSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
                        idxSet.addAll(idx.getColumns());
                            if (newColset.equals(idxSet)) {
                                throw new AnalysisException("index for columns (" + String
                                        .join(",", indexDef.getColumns()) + " ) already exist.");
                            }
                        }

                } else if (alterClause instanceof DropIndexClause) {
                    Table table = db.getTable(dbTableName.getTbl());
                    if (!(table instanceof OlapTable)) {
                        throw new AnalysisException("drop index only support in olap table at current version.");
                    }
                    String indexName = ((DropIndexClause) alterClause).getIndexName();
                    List<Index> indexes = ((OlapTable) table).getIndexes();
                    Index found = null;
                    for (Index idx : indexes) {
                        if (idx.getIndexName().equalsIgnoreCase(indexName)) {
                            found = idx;
                            break;
                        }
                    }
                    if (found == null) {
                            throw new AnalysisException("index " + indexName + " does not exist");
                        }
                }
            } else if ((alterClause instanceof AddRollupClause)
                    && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
                    && !hasPartition && !hasRename && !hasModifyProp) {
                hasAddMaterializedView = true;
            } else if (alterClause instanceof DropRollupClause && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
                    && !hasPartition && !hasRename && !hasModifyProp) {
                hasDropRollup = true;
            } else if (alterClause instanceof AddPartitionClause && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
                    && !hasPartition && !hasRename && !hasModifyProp) {
                hasPartition = true;
            } else if (alterClause instanceof DropPartitionClause && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
                    && !hasPartition && !hasRename && !hasModifyProp) {
                hasPartition = true;
            } else if (alterClause instanceof ModifyPartitionClause && !hasSchemaChange && !hasAddMaterializedView
                    && !hasDropRollup && !hasPartition && !hasRename && !hasModifyProp) {
                hasPartition = true;
            } else if ((alterClause instanceof TableRenameClause || alterClause instanceof RollupRenameClause
                    || alterClause instanceof PartitionRenameClause || alterClause instanceof ColumnRenameClause)
                    && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup && !hasPartition && !hasRename
                    && !hasModifyProp) {
                hasRename = true;
            } else if (alterClause instanceof ModifyTablePropertiesClause && !hasSchemaChange && !hasAddMaterializedView
                    && !hasDropRollup && !hasPartition && !hasRename && !hasModifyProp) {
                hasModifyProp = true;
            } else {
                throw new DdlException("Conflicting alter clauses. see help for more information");
            }
        } 

        boolean hasAddPartition = false;
        String tableName = dbTableName.getTbl();
        db.writeLock();
        try {
            Table table = db.getTable(tableName);
            if (table == null) {
                ErrorReport.reportDdlException(ErrorCode.ERR_BAD_TABLE_ERROR, tableName);
            }

            if (table.getType() != TableType.OLAP) {
                throw new DdlException("Do not support alter non-OLAP table[" + tableName + "]");
            }

            OlapTable olapTable = (OlapTable) table;

            if (olapTable.getPartitions().size() == 0 && !hasPartition) {
                throw new DdlException("table with empty parition cannot do schema change. [" + tableName + "]");
            }

            if (olapTable.getState() != OlapTableState.NORMAL) {
                throw new DdlException("Table[" + table.getName() + "]'s state is not NORMAL. Do not allow doing ALTER ops");
            }

            
            if (needTableStable && !hasSchemaChange) {
                
                boolean isStable = olapTable.isStable(Catalog.getCurrentSystemInfo(),
                        Catalog.getCurrentCatalog().getTabletScheduler(),
                        db.getClusterName());
                if (!isStable) {
                    throw new DdlException("table [" + olapTable.getName() + "] is not stable."
                            + " Some tablets of this table may not be healthy or are being scheduled."
                            + " You need to repair the table first"
                            + " or stop cluster balance. See 'help admin;'.");
                }
            }

            if (hasSchemaChange || hasModifyProp) {
                
                schemaChangeHandler.process(alterClauses, clusterName, db, olapTable);
            } else if (hasAddMaterializedView || hasDropRollup) {
                materializedViewHandler.process(alterClauses, clusterName, db, olapTable);
            } else if (hasPartition) {
                Preconditions.checkState(alterClauses.size() == 1);
                AlterClause alterClause = alterClauses.get(0);
                if (alterClause instanceof DropPartitionClause) {
                    DynamicPartitionUtil.checkAlterAllowed(olapTable);
                    Catalog.getInstance().dropPartition(db, olapTable, ((DropPartitionClause) alterClause));
                } else if (alterClause instanceof ModifyPartitionClause) {
                    DynamicPartitionUtil.checkAlterAllowed(olapTable);
                    Catalog.getInstance().modifyPartition(db, olapTable, ((ModifyPartitionClause) alterClause));
                } else {
                    hasAddPartition = true;
                }
            } else if (hasRename) {
                processRename(db, olapTable, alterClauses);
            }
        } finally {
            db.writeUnlock();
        }

        
        if (hasAddPartition) {
            Preconditions.checkState(alterClauses.size() == 1);
            AlterClause alterClause = alterClauses.get(0);
            if (alterClause instanceof AddPartitionClause) {
                DynamicPartitionUtil.checkAlterAllowed((OlapTable) db.getTable(tableName));
                Catalog.getInstance().addPartition(db, tableName, (AddPartitionClause) alterClause);
            } else {
                Preconditions.checkState(false);
            }
        }
    }

Line commented on: if (needTableStable && !hasSchemaChange) {

Revised code:
public void processAlterTable(AlterTableStmt stmt) throws UserException {
        TableName dbTableName = stmt.getTbl();
        String dbName = dbTableName.getDb();
        final String clusterName = stmt.getClusterName();

        Database db = Catalog.getInstance().getDb(dbName);
        if (db == null) {
            ErrorReport.reportDdlException(ErrorCode.ERR_BAD_DB_ERROR, dbName);
        }

        
        Catalog.getCurrentSystemInfo().checkClusterCapacity(clusterName);

        
        boolean hasSchemaChange = false;
        
        boolean hasAddMaterializedView = false;
        boolean hasDropRollup = false;
        
        boolean hasPartition = false;
        
        boolean hasRename = false;
        
        boolean hasModifyProp = false;

        
        List<AlterClause> alterClauses = stmt.getOps();
        

        
        boolean allIsDropOps = true;
        for (AlterClause alterClause : alterClauses) {
            if (!(alterClause instanceof DropPartitionClause)
                    && !(alterClause instanceof DropRollupClause)) {
                allIsDropOps = false;
                break;
            }
        }

        if (!allIsDropOps) {
            
            db.checkQuota();
        }

        boolean needTableStable = false;
        for (AlterClause alterClause : alterClauses) {
            if (!needTableStable) {
                needTableStable = ((AlterTableClause) alterClause).isNeedTableStable();
            }
            if ((alterClause instanceof AddColumnClause
                    || alterClause instanceof AddColumnsClause
                    || alterClause instanceof DropColumnClause
                    || alterClause instanceof ModifyColumnClause
                    || alterClause instanceof ReorderColumnsClause
                    || alterClause instanceof CreateIndexClause
                    || alterClause instanceof DropIndexClause)
                    && !hasAddMaterializedView && !hasDropRollup && !hasPartition && !hasRename) {
                hasSchemaChange = true;
                if (alterClause instanceof CreateIndexClause) {
                    Table table = db.getTable(dbTableName.getTbl());
                    if (!(table instanceof OlapTable)) {
                        throw new AnalysisException("create index only support in olap table at current version.");
                    }
                    List<Index> indexes = ((OlapTable) table).getIndexes();
                    IndexDef indexDef = ((CreateIndexClause) alterClause).getIndexDef();
                    Set<String> newColset = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
                    newColset.addAll(indexDef.getColumns());
                    for (Index idx : indexes) {
                        if (idx.getIndexName().equalsIgnoreCase(indexDef.getIndexName())) {
                            throw new AnalysisException("index `" + indexDef.getIndexName() + "` already exist.");
                        }
                        Set<String> idxSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
                        idxSet.addAll(idx.getColumns());
                            if (newColset.equals(idxSet)) {
                                throw new AnalysisException("index for columns (" + String
                                        .join(",", indexDef.getColumns()) + " ) already exist.");
                            }
                        }

                } else if (alterClause instanceof DropIndexClause) {
                    Table table = db.getTable(dbTableName.getTbl());
                    if (!(table instanceof OlapTable)) {
                        throw new AnalysisException("drop index only support in olap table at current version.");
                    }
                    String indexName = ((DropIndexClause) alterClause).getIndexName();
                    List<Index> indexes = ((OlapTable) table).getIndexes();
                    Index found = null;
                    for (Index idx : indexes) {
                        if (idx.getIndexName().equalsIgnoreCase(indexName)) {
                            found = idx;
                            break;
                        }
                    }
                    if (found == null) {
                            throw new AnalysisException("index " + indexName + " does not exist");
                        }
                }
            } else if ((alterClause instanceof AddRollupClause)
                    && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
                    && !hasPartition && !hasRename && !hasModifyProp) {
                hasAddMaterializedView = true;
            } else if (alterClause instanceof DropRollupClause && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
                    && !hasPartition && !hasRename && !hasModifyProp) {
                hasDropRollup = true;
            } else if (alterClause instanceof AddPartitionClause && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
                    && !hasPartition && !hasRename && !hasModifyProp) {
                hasPartition = true;
            } else if (alterClause instanceof DropPartitionClause && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
                    && !hasPartition && !hasRename && !hasModifyProp) {
                hasPartition = true;
            } else if (alterClause instanceof ModifyPartitionClause && !hasSchemaChange && !hasAddMaterializedView
                    && !hasDropRollup && !hasPartition && !hasRename && !hasModifyProp) {
                hasPartition = true;
            } else if ((alterClause instanceof TableRenameClause || alterClause instanceof RollupRenameClause
                    || alterClause instanceof PartitionRenameClause || alterClause instanceof ColumnRenameClause)
                    && !hasSchemaChange && !hasAddMaterializedView && !hasDropRollup && !hasPartition && !hasRename
                    && !hasModifyProp) {
                hasRename = true;
            } else if (alterClause instanceof ModifyTablePropertiesClause && !hasSchemaChange && !hasAddMaterializedView
                    && !hasDropRollup && !hasPartition && !hasRename && !hasModifyProp) {
                hasModifyProp = true;
            } else {
                throw new DdlException("Conflicting alter clauses. see help for more information");
            }
        } 

        boolean hasAddPartition = false;
        String tableName = dbTableName.getTbl();
        db.writeLock();
        try {
            Table table = db.getTable(tableName);
            if (table == null) {
                ErrorReport.reportDdlException(ErrorCode.ERR_BAD_TABLE_ERROR, tableName);
            }

            if (table.getType() != TableType.OLAP) {
                throw new DdlException("Do not support alter non-OLAP table[" + tableName + "]");
            }

            OlapTable olapTable = (OlapTable) table;

            if (olapTable.getPartitions().size() == 0 && !hasPartition) {
                throw new DdlException("table with empty parition cannot do schema change. [" + tableName + "]");
            }

            if (olapTable.getState() != OlapTableState.NORMAL) {
                throw new DdlException("Table[" + table.getName() + "]'s state is not NORMAL. Do not allow doing ALTER ops");
            }

            
            if (needTableStable && !hasSchemaChange && !hasAddMaterializedView) {
                
                boolean isStable = olapTable.isStable(Catalog.getCurrentSystemInfo(),
                        Catalog.getCurrentCatalog().getTabletScheduler(),
                        db.getClusterName());
                if (!isStable) {
                    throw new DdlException("table [" + olapTable.getName() + "] is not stable."
                            + " Some tablets of this table may not be healthy or are being scheduled."
                            + " You need to repair the table first"
                            + " or stop cluster balance. See 'help admin;'.");
                }
            }

            if (hasSchemaChange || hasModifyProp) {
                
                schemaChangeHandler.process(alterClauses, clusterName, db, olapTable);
            } else if (hasAddMaterializedView || hasDropRollup) {
                materializedViewHandler.process(alterClauses, clusterName, db, olapTable);
            } else if (hasPartition) {
                Preconditions.checkState(alterClauses.size() == 1);
                AlterClause alterClause = alterClauses.get(0);
                if (alterClause instanceof DropPartitionClause) {
                    DynamicPartitionUtil.checkAlterAllowed(olapTable);
                    Catalog.getInstance().dropPartition(db, olapTable, ((DropPartitionClause) alterClause));
                } else if (alterClause instanceof ModifyPartitionClause) {
                    DynamicPartitionUtil.checkAlterAllowed(olapTable);
                    Catalog.getInstance().modifyPartition(db, olapTable, ((ModifyPartitionClause) alterClause));
                } else {
                    hasAddPartition = true;
                }
            } else if (hasRename) {
                processRename(db, olapTable, alterClauses);
            }
        } finally {
            db.writeUnlock();
        }

        
        if (hasAddPartition) {
            Preconditions.checkState(alterClauses.size() == 1);
            AlterClause alterClause = alterClauses.get(0);
            if (alterClause instanceof AddPartitionClause) {
                DynamicPartitionUtil.checkAlterAllowed((OlapTable) db.getTable(tableName));
                Catalog.getInstance().addPartition(db, tableName, (AddPartitionClause) alterClause);
            } else {
                Preconditions.checkState(false);
            }
        }
    }