| 191 | } |
| 192 | |
| 193 | void executeQueryByProxy(ContextMutablePtr context, const HostWithPorts & server, const ASTPtr & ast, BlockIO & res, bool in_interactive_txn, const String & query) |
| 194 | { |
| 195 | auto session_txn = in_interactive_txn ? context->getSessionContext()->getCurrentTransaction() : nullptr; |
| 196 | ProxyTransactionPtr proxy_txn; |
| 197 | if (session_txn && session_txn->isPrimary()) |
| 198 | { |
| 199 | proxy_txn = context->getCnchTransactionCoordinator().createProxyTransaction(server, session_txn->getPrimaryTransactionID(), |
| 200 | isReadOnlyTransaction(ast.get())); |
| 201 | context->setCurrentTransaction(proxy_txn); |
| 202 | session_txn->as<CnchExplicitTransaction>()->addStatement(query); |
| 203 | } |
| 204 | |
| 205 | /// Create connection to host |
| 206 | const auto & query_client_info = context->getClientInfo(); |
| 207 | auto settings = context->getSettingsRef(); |
| 208 | res.remote_execution_conn = std::make_shared<Connection>( |
| 209 | server.getHost(), |
| 210 | server.tcp_port, |
| 211 | context->getCurrentDatabase(), /*default_database_*/ |
| 212 | query_client_info.current_user, |
| 213 | query_client_info.current_password, |
| 214 | "", /*cluster_*/ |
| 215 | "", /*cluster_secret*/ |
| 216 | "server", /*client_name_*/ |
| 217 | Protocol::Compression::Enable, |
| 218 | Protocol::Secure::Disable); |
| 219 | res.remote_execution_conn->setDefaultDatabase(context->getCurrentDatabase()); |
| 220 | |
| 221 | // PipelineExecutor requires block header. |
| 222 | LOG_DEBUG(&Poco::Logger::get("executeQuery"), "Sending query as ordinary query"); |
| 223 | Block header; |
| 224 | if (context->getSettingsRef().enable_select_query_forwarding && ast->as<ASTSelectWithUnionQuery>()) |
| 225 | { |
| 226 | if (settings.enable_optimizer && QueryUseOptimizerChecker::check(ast, context)) |
| 227 | header = InterpreterSelectQueryUseOptimizer(ast, context, SelectQueryOptions(QueryProcessingStage::Complete).analyze()).getSampleBlock(); |
| 228 | else |
| 229 | header = InterpreterSelectWithUnionQuery(ast, context, SelectQueryOptions(QueryProcessingStage::Complete).analyze()).getSampleBlock(); |
| 230 | } |
| 231 | |
| 232 | Pipes remote_pipes; |
| 233 | auto remote_query_executor = std::make_shared<RemoteQueryExecutor>(*res.remote_execution_conn, query, header, context); |
| 234 | remote_query_executor->setPoolMode(PoolMode::GET_ONE); |
| 235 | remote_query_executor->setServerForwarding(true); |
| 236 | remote_query_executor->setQueryId(query_client_info.initial_query_id); |
| 237 | remote_pipes.emplace_back(createRemoteSourcePipe(remote_query_executor, true, false, false, true)); |
| 238 | remote_pipes.back().addInterpreterContext(context); |
| 239 | |
| 240 | auto plan = std::make_unique<QueryPlan>(); |
| 241 | auto read_from_remote = std::make_unique<ReadFromPreparedSource>(Pipe::unitePipes(std::move(remote_pipes))); |
| 242 | read_from_remote->setStepDescription("Read from remote server"); |
| 243 | plan->addStep(std::move(read_from_remote)); |
| 244 | res.pipeline = std::move( |
| 245 | *plan->buildQueryPipeline(QueryPlanOptimizationSettings::fromContext(context), BuildQueryPipelineSettings::fromContext(context))); |
| 246 | res.pipeline.addInterpreterContext(context); |
| 247 | |
| 248 | res.finish_callback = [proxy_txn, context, remote_query_executor](IBlockInputStream *, IBlockOutputStream *, QueryPipeline *) { |
| 249 | /// Get the extended profile info which is mainly for INSERT SELECT/INSERT INFILE |
| 250 | context->setExtendedProfileInfo(remote_query_executor->getExtendedProfileInfo()); |
no test coverage detected