I am reading clickhouse mutation code. In StorageMergeTree->selectPartsToMutate() function, there is a check 
`if (current_ast_elements + commands_size >= max_ast_elements)
                break;`

I think if there are many mutations then the check result will be true, so that it will skip the remaining mutations.
But the new part's mutation is set to the last one in mutation map, and it does not apply the remaining mutations actually.
`new_part_info.mutation = current_mutations_by_version.rbegin()->first;`

Then the new part will miss the remaining mutations in future mutation job.

I think it's wrong here. Am I right?

If it is right, I will submit a PR 

bool attach,
                  BrokenPartCallback broken_part_callback_ = [](const String &){});
    
    
    
    
    
    
    
    
    
    
    Block getMinMaxCountProjectionBlock(
        const StorageMetadataPtr & metadata_snapshot,
        const Names & required_columns,
        const SelectQueryInfo & query_info,
        const DataPartsVector & parts,
        DataPartsVector & normal_parts,
        ContextPtr query_context) const;
    std::optional<ProjectionCandidate> getQueryProcessingStageWithAggregateProjection(
        ContextPtr query_context, const StorageMetadataPtr & metadata_snapshot, SelectQueryInfo & query_info) const;
    QueryProcessingStage::Enum getQueryProcessingStage(
        ContextPtr query_context,
        QueryProcessingStage::Enum to_stage,
        const StorageMetadataPtr & metadata_snapshot,
        SelectQueryInfo & info) const override;
    ReservationPtr reserveSpace(UInt64 expected_size, VolumePtr & volume) const;
    static bool partsContainSameProjections(const DataPartPtr & left, const DataPartPtr & right);
    StoragePolicyPtr getStoragePolicy() const override;
    bool supportsPrewhere() const override { return true; }