diff --git a/dbms/programs/server/HTTPHandler.cpp b/dbms/programs/server/HTTPHandler.cpp index ee8a50662c9..1d31ba0e3a6 100644 --- a/dbms/programs/server/HTTPHandler.cpp +++ b/dbms/programs/server/HTTPHandler.cpp @@ -453,30 +453,6 @@ void HTTPHandler::processQuery( return false; }; - /// Used in case of POST request with form-data, but it isn't expected to be deleted after that scope. - std::string full_query; - - /// Support for "external data for query processing". - if (startsWith(request.getContentType().data(), "multipart/form-data")) - { - ExternalTablesHandler handler(context, params); - params.load(request, istr, handler); - - /// Skip unneeded parameters to avoid confusing them later with context settings or query parameters. - reserved_param_suffixes.emplace_back("_format"); - reserved_param_suffixes.emplace_back("_types"); - reserved_param_suffixes.emplace_back("_structure"); - - /// Params are of both form params POST and uri (GET params) - for (const auto & it : params) - if (it.first == "query") - full_query += it.second; - - in = std::make_unique(full_query); - } - else - in = std::make_unique(*in_param, *in_post_maybe_compressed); - /// Settings can be overridden in the query. /// Some parameters (database, default_format, everything used in the code above) do not /// belong to the Settings class. @@ -497,30 +473,63 @@ void HTTPHandler::processQuery( settings.readonly = 2; } - SettingsChanges settings_changes; - for (auto it = params.begin(); it != params.end(); ++it) + bool isExternalData = startsWith(request.getContentType().data(), "multipart/form-data"); + + if (isExternalData) { - if (it->first == "database") + /// Skip unneeded parameters to avoid confusing them later with context settings or query parameters. + reserved_param_suffixes.reserve(3); + /// It is a bug and ambiguity with `date_time_input_format` and `low_cardinality_allow_in_native_format` formats/settings. + reserved_param_suffixes.emplace_back("_format"); + reserved_param_suffixes.emplace_back("_types"); + reserved_param_suffixes.emplace_back("_structure"); + } + + SettingsChanges settings_changes; + for (const auto& [key, value] : params) + { + if (key == "database") { - context.setCurrentDatabase(it->second); + context.setCurrentDatabase(value); } - else if (it->first == "default_format") + else if (key == "default_format") { - context.setDefaultFormat(it->second); + context.setDefaultFormat(value); } - else if (param_could_be_skipped(it->first)) + else if (param_could_be_skipped(key)) { } else { /// All other query parameters are treated as settings. - settings_changes.push_back({it->first, it->second}); + settings_changes.push_back({key, value}); } } + /// For external data we also want settings context.checkSettingsConstraints(settings_changes); context.applySettingsChanges(settings_changes); + /// Used in case of POST request with form-data, but it isn't expected to be deleted after that scope. + std::string full_query; + + /// Support for "external data for query processing". + if (isExternalData) + { + ExternalTablesHandler handler(context, params); + params.load(request, istr, handler); + + /// Params are of both form params POST and uri (GET params) + for (const auto & it : params) + if (it.first == "query") + full_query += it.second; + + in = std::make_unique(full_query); + } + else + in = std::make_unique(*in_param, *in_post_maybe_compressed); + + /// HTTP response compression is turned on only if the client signalled that they support it /// (using Accept-Encoding header) and 'enable_http_compression' setting is turned on. used_output.out->setCompression(client_supports_http_compression && settings.enable_http_compression); diff --git a/dbms/tests/queries/0_stateless/00304_http_external_data.reference b/dbms/tests/queries/0_stateless/00304_http_external_data.reference index 3a2c90e1eb4..93428f8768e 100644 --- a/dbms/tests/queries/0_stateless/00304_http_external_data.reference +++ b/dbms/tests/queries/0_stateless/00304_http_external_data.reference @@ -1,2 +1,4 @@ 1 Hello 2 World +1 Hello +2 World diff --git a/dbms/tests/queries/0_stateless/00304_http_external_data.sh b/dbms/tests/queries/0_stateless/00304_http_external_data.sh index 4b2b8b14359..0914094f8bd 100755 --- a/dbms/tests/queries/0_stateless/00304_http_external_data.sh +++ b/dbms/tests/queries/0_stateless/00304_http_external_data.sh @@ -4,3 +4,4 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh echo -ne '1,Hello\n2,World\n' | ${CLICKHOUSE_CURL} -sSF 'file=@-' "${CLICKHOUSE_URL}?query=SELECT+*+FROM+file&file_format=CSV&file_types=UInt8,String"; +echo -ne '1@Hello\n2@World\n' | ${CLICKHOUSE_CURL} -sSF 'file=@-' "${CLICKHOUSE_URL}?query=SELECT+*+FROM+file&file_format=CSV&file_types=UInt8,String&format_csv_delimiter=@";