MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / processCopyQuery

Method processCopyQuery

src/Server/PostgreSQLHandler.cpp:426–583  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

424}
425
426bool PostgreSQLHandler::processCopyQuery(const String & query)
427{
428 ParserCopyQuery parser_copy;
429 ASTPtr copy_query_parsed;
430
431 try
432 {
433 copy_query_parsed = parseQuery(parser_copy, query, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH, DBMS_DEFAULT_MAX_PARSER_BACKTRACKS);
434 }
435 catch (const Exception &)
436 {
437 copy_query_parsed.reset();
438 }
439
440
441 /* The Postgres protocol for a copy query is different from simple queries such as SELECT.
442 * In the case of a COPY FROM request, the server sends CopyInResponse - a sign of readiness to receive data from the client.
443 * The client then sends CopyInData until all data has been sent.
444 * After this, the server sends a CommandComplete response.
445 * For more detailes see https://www.dolthub.com/blog/2024-09-17-tabular-data-imports/
446 */
447 if (copy_query_parsed && copy_query_parsed->as<ASTCopyQuery>()->type == ASTCopyQuery::QueryType::COPY_FROM)
448 {
449 auto * copy_query = copy_query_parsed->as<ASTCopyQuery>();
450 auto query_context = session->makeQueryContext();
451 query_context->setCurrentQueryId(fmt::format("postgres:{:d}:{:d}", connection_id, secret_key));
452 QueryScope query_scope = QueryScope::create(query_context);
453
454 String columns_to_insert;
455 if (!copy_query->column_names.empty())
456 {
457 for (const auto & column_name : copy_query->column_names)
458 columns_to_insert += fmt::format("{}, ", column_name);
459 columns_to_insert.pop_back();
460 columns_to_insert.pop_back();
461 columns_to_insert = "(" + columns_to_insert + ")";
462 }
463
464 auto [ast, io] = executeQuery(fmt::format("INSERT INTO `{}` {} FROM INFILE 'psql_copy'", copy_query->table_name, columns_to_insert), query_context, {}, QueryProcessingStage::Enum::Complete);
465 chassert(io.pipeline.pushing());
466 auto executor = std::make_unique<PushingPipelineExecutor>(io.pipeline);
467
468 String format;
469 switch (copy_query->format)
470 {
471 case ASTCopyQuery::Formats::TSV:
472 format = "TSV";
473 break;
474 case ASTCopyQuery::Formats::CSV:
475 format = "CSV";
476 break;
477 case ASTCopyQuery::Formats::Binary:
478 format = "RowBinary";
479 break;
480 }
481
482 const Settings & settings = query_context->getSettingsRef();
483

Callers

nothing calls this directly

Calls 15

parseQueryFunction · 0.85
CopyInResponseClass · 0.85
CommandCompleteClass · 0.85
CopyOutResponseClass · 0.85
materializeBlockFunction · 0.85
CopyOutDataClass · 0.85
setCurrentQueryIdMethod · 0.80
pushingMethod · 0.80
receiveMessageTypeMethod · 0.80
getInputMethod · 0.80
pullingMethod · 0.80

Tested by

no test coverage detected