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 partIsLastQuorumPart(const MergeTreePartInfo & part_info) const;
    
    bool partIsInsertingWithParallelQuorum(const MergeTreePartInfo & part_info) const;
    
    
    
    std::optional<EphemeralLockInZooKeeper> allocateBlockNumber(
        const String & partition_id, const zkutil::ZooKeeperPtr & zookeeper,
        const String & zookeeper_block_id_path = "", const String & zookeeper_path_prefix = "") const;
    /** Wait until all replicas, including this, execute the specified action from the log.
      * If replicas are added at the same time, it can not wait the added replica.
      *
      * Waits for inactive replicas no more than wait_for_inactive_timeout.
      * Returns list of inactive replicas that have not executed entry or throws exception.
      *
      * NOTE: This method must be called without table lock held.
      * Because it effectively waits for other thread that usually has to also acquire a lock to proceed and this yields deadlock.
      */
    void waitForAllReplicasToProcessLogEntry(const String & table_zookeeper_path, const ReplicatedMergeTreeLogEntryData & entry,
                                             Int64 wait_for_inactive_timeout, const String & error_context = {});
    Strings tryWaitForAllReplicasToProcessLogEntry(const String & table_zookeeper_path, const ReplicatedMergeTreeLogEntryData & entry,
                                                   Int64 wait_for_inactive_timeout);
    /** Wait until the specified replica executes the specified action from the log.
      * NOTE: See comment about locks above.
      */
    bool tryWaitForReplicaToProcessLogEntry(const String & table_zookeeper_path, const String & replica_name,
                                            const ReplicatedMergeTreeLogEntryData & entry, Int64 wait_for_inactive_timeout = 0);
    
    void waitForLogEntryToBeProcessedIfNecessary(const ReplicatedMergeTreeLogEntryData & entry, ContextPtr query_context, const String & error_context = {});