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 

void checkTableStructure(const String & zookeeper_prefix, const StorageMetadataPtr & metadata_snapshot);
    
    
    void setTableStructure(ColumnsDescription new_columns, const ReplicatedMergeTreeTableMetadata::Diff & metadata_diff);
    /** Check that the set of parts corresponds to that in ZK (/replicas/me/parts/).
      * If any parts described in ZK are not locally, throw an exception.
      * If any local parts are not mentioned in ZK, remove them.
      *  But if there are too many, throw an exception just in case - it's probably a configuration error.
      */
    void checkParts(bool skip_sanity_checks);
    
    
    void syncPinnedPartUUIDs();
    /** Check that the part's checksum is the same as the checksum of the same part on some other replica.
      * If no one has such a part, nothing checks.
      * Not very reliable: if two replicas add a part almost at the same time, no checks will occur.
      * Adds actions to `ops` that add data about the part into ZooKeeper.
      * Call under lockForShare.
      */
    void checkPartChecksumsAndAddCommitOps(const zkutil::ZooKeeperPtr & zookeeper, const DataPartPtr & part,
                                           Coordination::Requests & ops, String part_name = "", NameSet * absent_replicas_paths = nullptr);
    String getChecksumsForZooKeeper(const MergeTreeDataPartChecksums & checksums) const;
    
    DataPartsVector checkPartChecksumsAndCommit(Transaction & transaction, const DataPartPtr & part);
    bool partIsAssignedToBackgroundOperation(const DataPartPtr & part) const override;
    void getCommitPartOps(Coordination::Requests & ops, MutableDataPartPtr & part, const String & block_id_path = "") const;
    
    
    void removePartFromZooKeeper(const String & part_name, Coordination::Requests & ops, bool has_children);