| 770 | } |
| 771 | |
| 772 | void RemoteQueryExecutor::finish() |
| 773 | { |
| 774 | LockAndBlocker guard(was_cancelled_mutex); |
| 775 | |
| 776 | /** If one of: |
| 777 | * - nothing started to do; |
| 778 | * - received all packets before EndOfStream; |
| 779 | * - received exception from one replica; |
| 780 | * - received an unknown packet from one replica; |
| 781 | * then you do not need to read anything. |
| 782 | */ |
| 783 | if (!isQueryPending() || hasThrownException() || was_cancelled) |
| 784 | return; |
| 785 | |
| 786 | /// To make sure finish is only called once |
| 787 | SCOPE_EXIT({ finished = true; }); |
| 788 | |
| 789 | /** If you have not read all the data yet, but they are no longer needed. |
| 790 | * This may be due to the fact that the data is sufficient (for example, when using LIMIT). |
| 791 | */ |
| 792 | |
| 793 | /// Send the request to abort the execution of the request, if not already sent. |
| 794 | tryCancel("Cancelling query because enough data has been read"); |
| 795 | |
| 796 | /// If connections weren't created yet, query wasn't sent or was already finished, nothing to do. |
| 797 | if (!connections || !sent_query || finished) |
| 798 | return; |
| 799 | |
| 800 | /// Get the remaining packets so that there is no out of sync in the connections to the replicas. |
| 801 | /// We do this manually instead of calling drain() because we want to process Log, ProfileEvents and Progress |
| 802 | /// packets that had been sent before the connection is fully finished in order to have final statistics of what |
| 803 | /// was executed in the remote queries |
| 804 | while (connections->hasActiveConnections() && !finished) |
| 805 | { |
| 806 | Packet packet = connections->receivePacket(); |
| 807 | |
| 808 | switch (packet.type) |
| 809 | { |
| 810 | case Protocol::Server::EndOfStream: |
| 811 | finished = true; |
| 812 | break; |
| 813 | |
| 814 | case Protocol::Server::Exception: |
| 815 | got_exception_from_replica = true; |
| 816 | packet.exception->rethrow(); |
| 817 | break; |
| 818 | |
| 819 | case Protocol::Server::Log: |
| 820 | /// Pass logs from remote server to client |
| 821 | if (auto log_queue = CurrentThread::getInternalTextLogsQueue()) |
| 822 | log_queue->pushBlock(std::move(packet.block)); |
| 823 | break; |
| 824 | |
| 825 | case Protocol::Server::ProfileEvents: |
| 826 | /// Pass profile events from remote server to client |
| 827 | if (auto profile_queue = CurrentThread::getInternalProfileEventsQueue()) |
| 828 | if (!profile_queue->emplace(std::move(packet.block))) |
| 829 | throw Exception(ErrorCodes::SYSTEM_ERROR, "Could not push into profile queue"); |
nothing calls this directly
no test coverage detected