| 1372 | |
| 1373 | |
| 1374 | void TCPHandler::processInsertQuery(QueryState & state) |
| 1375 | { |
| 1376 | size_t num_threads = state.io.pipeline.getNumThreads(); |
| 1377 | |
| 1378 | auto run_executor = [&](auto & executor, Block processed_data) |
| 1379 | { |
| 1380 | try |
| 1381 | { |
| 1382 | /// Made above the rest of the lines, |
| 1383 | /// so that in case of `start` function throws an exception, |
| 1384 | /// client receive exception before sending data. |
| 1385 | executor.start(); |
| 1386 | |
| 1387 | if (!processed_data.empty()) |
| 1388 | executor.push(std::move(processed_data)); |
| 1389 | else |
| 1390 | startInsertQuery(state); |
| 1391 | |
| 1392 | while (receivePacketsExpectDataConcurrentWithExecutor(state)) |
| 1393 | { |
| 1394 | executor.push(std::move(state.block_for_insert)); |
| 1395 | |
| 1396 | std::lock_guard lock(*callback_mutex); |
| 1397 | sendLogs(state); |
| 1398 | sendInsertProfileEvents(state); |
| 1399 | } |
| 1400 | |
| 1401 | executor.finish(); |
| 1402 | } |
| 1403 | catch (...) |
| 1404 | { |
| 1405 | executor.cancel(); |
| 1406 | throw; |
| 1407 | } |
| 1408 | }; |
| 1409 | |
| 1410 | Block processed_block; |
| 1411 | const auto & settings = state.query_context->getSettingsRef(); |
| 1412 | |
| 1413 | auto * insert_queue = state.query_context->tryGetAsynchronousInsertQueue(); |
| 1414 | const auto & insert_query = assert_cast<const ASTInsertQuery &>(*state.parsed_query); |
| 1415 | |
| 1416 | bool async_insert_enabled = settings[Setting::async_insert]; |
| 1417 | if (insert_query.table_id) |
| 1418 | if (auto table = DatabaseCatalog::instance().tryGetTable(insert_query.table_id, state.query_context)) |
| 1419 | async_insert_enabled |= table->areAsynchronousInsertsEnabled(); |
| 1420 | |
| 1421 | if (insert_queue && async_insert_enabled && !insert_query.select) |
| 1422 | { |
| 1423 | auto result = processAsyncInsertQuery(state, *insert_queue); |
| 1424 | if (result.status == AsynchronousInsertQueue::PushResult::OK) |
| 1425 | { |
| 1426 | /// Reset pipeline because it may hold write lock for some storages. |
| 1427 | state.io.resetPipeline(/*cancel=*/true); |
| 1428 | if (settings[Setting::wait_for_async_insert]) |
| 1429 | { |
| 1430 | size_t timeout_ms = settings[Setting::wait_for_async_insert_timeout].totalMilliseconds(); |
| 1431 | auto wait_status = result.future.wait_for(std::chrono::milliseconds(timeout_ms)); |
nothing calls this directly
no test coverage detected