| 140 | } |
| 141 | |
| 142 | void MultiplexedConnections::sendQuery( |
| 143 | const ConnectionTimeouts & timeouts, |
| 144 | const String & query, |
| 145 | const String & query_id, |
| 146 | UInt64 stage, |
| 147 | ClientInfo & client_info, |
| 148 | bool with_pending_data, |
| 149 | const std::vector<String> & external_roles) |
| 150 | { |
| 151 | std::lock_guard lock(cancel_mutex); |
| 152 | |
| 153 | if (sent_query) |
| 154 | throw Exception(ErrorCodes::LOGICAL_ERROR, "Query already sent."); |
| 155 | |
| 156 | Settings modified_settings = settings; |
| 157 | |
| 158 | /// Queries in foreign languages are transformed to ClickHouse-SQL. Ensure the setting before sending. |
| 159 | modified_settings[Setting::dialect] = Dialect::clickhouse; |
| 160 | modified_settings[Setting::dialect].changed = false; |
| 161 | |
| 162 | modified_settings[Setting::interactive_delay] = scaleInteractiveDelayByFanout( |
| 163 | modified_settings[Setting::interactive_delay], |
| 164 | distributed_fanout * replica_states.size()); |
| 165 | |
| 166 | for (auto & replica : replica_states) |
| 167 | { |
| 168 | if (!replica.connection) |
| 169 | throw Exception(ErrorCodes::LOGICAL_ERROR, "MultiplexedConnections: Internal error"); |
| 170 | |
| 171 | if (replica.connection->getServerRevision(timeouts) < DBMS_MIN_REVISION_WITH_CURRENT_AGGREGATION_VARIANT_SELECTION_METHOD) |
| 172 | { |
| 173 | /// Disable two-level aggregation due to version incompatibility. |
| 174 | modified_settings[Setting::group_by_two_level_threshold] = 0; |
| 175 | modified_settings[Setting::group_by_two_level_threshold_bytes] = 0; |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | if (replica_info) |
| 180 | { |
| 181 | client_info.collaborate_with_initiator = true; |
| 182 | client_info.number_of_current_replica = replica_info->number_of_current_replica; |
| 183 | } |
| 184 | |
| 185 | /// FIXME: Remove once we will make `allow_experimental_analyzer` obsolete setting. |
| 186 | /// Make the analyzer being set, so it will be effectively applied on the remote server. |
| 187 | /// In other words, the initiator always controls whether the analyzer enabled or not for |
| 188 | /// all servers involved in the distributed query processing. |
| 189 | modified_settings.set("allow_experimental_analyzer", static_cast<bool>(modified_settings[Setting::allow_experimental_analyzer])); |
| 190 | |
| 191 | const bool enable_offset_parallel_processing = context->canUseOffsetParallelReplicas(); |
| 192 | |
| 193 | size_t num_replicas = replica_states.size(); |
| 194 | chassert(num_replicas > 0); |
| 195 | if (num_replicas > 1) |
| 196 | { |
| 197 | if (enable_offset_parallel_processing) |
| 198 | /// Use multiple replicas for parallel query processing. |
| 199 | modified_settings[Setting::parallel_replicas_count] = num_replicas; |
nothing calls this directly
no test coverage detected