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 removePartFromZooKeeper(const String & part_name);
    
    void removePartsFromZooKeeper(zkutil::ZooKeeperPtr & zookeeper, const Strings & part_names,
                                  NameSet * parts_should_be_retried = nullptr);
    bool tryRemovePartsFromZooKeeperWithRetries(const Strings & part_names, size_t max_retries = 5);
    bool tryRemovePartsFromZooKeeperWithRetries(DataPartsVector & parts, size_t max_retries = 5);
    
    void removePartAndEnqueueFetch(const String & part_name);
    
    /** Execute the action from the queue. Throws an exception if something is wrong.
      * Returns whether or not it succeeds. If it did not work, write it to the end of the queue.
      */
    bool executeLogEntry(LogEntry & entry);
    
    
    MutableDataPartPtr attachPartHelperFoundValidPart(const LogEntry& entry) const;
    void executeDropRange(const LogEntry & entry);
    
    
    
    bool executeMetadataAlter(const LogEntry & entry);
    
    
    
    
    bool executeFetch(LogEntry & entry);
    bool executeReplaceRange(const LogEntry & entry);
    void executeClonePartFromShard(const LogEntry & entry);
    /** Updates the queue.
      */