diff --git a/programs/client/Client.cpp b/programs/client/Client.cpp index 02c8fe6defa..2fd6e0ed9fd 100644 --- a/programs/client/Client.cpp +++ b/programs/client/Client.cpp @@ -113,7 +113,7 @@ void Client::processSingleQuery(const String & full_query) else query_to_execute = full_query; - processSingleQueryImpl(full_query, [&]() { executeSingleQuery(query_to_execute, parsed_query); }); + processSingleQueryImpl(full_query, query_to_execute, parsed_query); if (have_error) reportQueryError(full_query); @@ -147,7 +147,7 @@ bool Client::processMultiQuery(const String & all_queries_text) echo_query = test_hint.echoQueries().value_or(echo_query); try { - processSingleQueryImpl(full_query, [&](){ executeSingleQuery(query_to_execute, parsed_query); }, echo_query, false); + processSingleQueryImpl(full_query, query_to_execute, parsed_query, echo_query, false); } catch (...) { @@ -708,7 +708,7 @@ bool Client::processWithFuzzing(const String & full_query) parsed_query = ast_to_process; query_to_execute = parsed_query->formatForErrorMessage(); - processSingleQueryImpl(full_query, [&]() { executeSingleQuery(query_to_execute, parsed_query); }); + processSingleQueryImpl(full_query, query_to_execute, parsed_query); } catch (...) { @@ -807,8 +807,7 @@ bool Client::processWithFuzzing(const String & full_query) { const auto * tmp_pos = query_to_execute.c_str(); - ast_2 = parseQuery(tmp_pos, tmp_pos + query_to_execute.size(), - false /* allow_multi_statements */); + ast_2 = parseQuery(tmp_pos, tmp_pos + query_to_execute.size(), false /* allow_multi_statements */); } catch (Exception & e) { diff --git a/programs/client/Client.h b/programs/client/Client.h index 12280107e93..dc7c6887fcd 100644 --- a/programs/client/Client.h +++ b/programs/client/Client.h @@ -24,6 +24,8 @@ protected: void reportQueryError(const String & query) const override; + void executeSingleQuery(const String & query_to_execute, ASTPtr parsed_query) override; + void loadSuggestionData() override; @@ -98,7 +100,6 @@ private: void onProfileInfo(const BlockStreamProfileInfo & profile_info); void onEndOfStream(); - void executeSingleQuery(const String & query_to_execute, ASTPtr parsed_query); std::vector loadWarningMessages(); void reconnectIfNeeded() override diff --git a/programs/local/LocalServer.cpp b/programs/local/LocalServer.cpp index cfc3d2188c2..1f36f8646e9 100644 --- a/programs/local/LocalServer.cpp +++ b/programs/local/LocalServer.cpp @@ -218,7 +218,7 @@ std::string LocalServer::getInitialCreateTableQuery() } -void LocalServer::executeSingleQuery(const String & query_to_execute) +void LocalServer::executeSingleQuery(const String & query_to_execute, ASTPtr /* parsed_query */) { ReadBufferFromString read_buf(query_to_execute); WriteBufferFromFileDescriptor write_buf(STDOUT_FILENO); @@ -335,7 +335,7 @@ int LocalServer::mainImpl() /// Use the same query_id (and thread group) for all queries CurrentThread::QueryScope query_scope_holder(query_context); - if (need_render_progress) + if (need_render_progress && !is_interactive) { /// Set progress callback, which can be run from multiple threads. query_context->setProgressCallback([&](const Progress & value) @@ -402,7 +402,7 @@ void LocalServer::processConfig() is_multiquery = true; need_render_progress = config().getBool("progress", false); - echo_queries = config().getBool("echo", false); + echo_queries = config().hasOption("echo") || config().hasOption("verbose"); ignore_error = config().getBool("ignore-error", false); } @@ -483,8 +483,6 @@ void LocalServer::processConfig() attachSystemTables(global_context); } - echo_queries = config().hasOption("echo") || config().hasOption("verbose"); - server_display_name = config().getString("display_name", getFQDNOrHostName()); prompt_by_server_display_name = config().getRawString("prompt_by_server_display_name.default", "{display_name} :) "); std::map prompt_substitutions{{"display_name", server_display_name}}; @@ -568,7 +566,7 @@ void LocalServer::applyCmdSettings(ContextMutablePtr context) void LocalServer::applyCmdOptions(ContextMutablePtr context) { - context->setDefaultFormat(config().getString("output-format", config().getString("format", "TSV"))); + context->setDefaultFormat(config().getString("output-format", config().getString("format", is_interactive ? "PrettyCompact" : "TSV"))); applyCmdSettings(context); } diff --git a/programs/local/LocalServer.h b/programs/local/LocalServer.h index 2244062e68e..0da62aeb971 100644 --- a/programs/local/LocalServer.h +++ b/programs/local/LocalServer.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace DB @@ -49,14 +50,22 @@ protected: bool processMultiQuery(const String & all_queries_text) override { - auto process_single_query = [&](const String & query, const String &, ASTPtr) { executeSingleQuery(query); }; + auto process_single_query = [&](const String & query_to_execute, const String &, ASTPtr) + { + processSingleQueryImpl(all_queries_text, query_to_execute, nullptr, echo_queries, false); + }; return processMultiQueryImpl(all_queries_text, process_single_query); } void processSingleQuery(const String & full_query) override { - auto process_single_query = [&]() { executeSingleQuery(full_query); }; - processSingleQueryImpl(full_query, process_single_query); + ASTPtr parsed_query; + if (is_interactive) + { + auto this_query_begin = full_query.data(); + parsed_query = parseQuery(this_query_begin, full_query.data() + full_query.size(), false); + } + processSingleQueryImpl(full_query, full_query, parsed_query, echo_queries); } @@ -65,13 +74,13 @@ protected: return getInitialCreateTableQuery(); } + void executeSingleQuery(const String & query_to_execute, ASTPtr parsed_query) override; + void reportQueryError(const String &) const override {} void printHelpMessage(const OptionsDescription & options_description) override; private: - void executeSingleQuery(const String & query_to_execute); - /** Composes CREATE subquery based on passed arguments (--structure --file --table and --input-format) * This query will be executed first, before queries passed through --query argument * Returns empty string if it cannot compose that query. diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index dbe94cb1dc4..2e2e3cfe851 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -167,7 +167,7 @@ void ClientBase::resetOutput() } -void ClientBase::processSingleQueryImpl(const String & full_query, std::function execute_single_query, std::optional echo_query_, bool report_error) +void ClientBase::processSingleQueryImpl(const String & full_query, const String & query_to_execute, ASTPtr parsed_query, std::optional echo_query_, bool report_error) { resetOutput(); have_error = false; @@ -196,7 +196,7 @@ void ClientBase::processSingleQueryImpl(const String & full_query, std::function written_first_block = false; progress_indication.resetProgress(); - execute_single_query(); + executeSingleQuery(query_to_execute, parsed_query); if (is_interactive) { diff --git a/src/Client/ClientBase.h b/src/Client/ClientBase.h index 375e8ad5dff..94d425e3dc9 100644 --- a/src/Client/ClientBase.h +++ b/src/Client/ClientBase.h @@ -44,29 +44,6 @@ protected: void runNonInteractive(); - /* - * full_query - current query as it was given to the client. - * parsed_query - parsed query (used to determine some settings e.g. format, output file). - * query_to_execute - current query as it will be executed by server. - * (It may differ from the full query for INSERT queries, for which the - * data that follows the query is stripped and sent separately.) - **/ - - - /* - * Process multiquery - several queries separated by ';'. - * Also in case of clickhouse-server: - * - INSERT data is ended by the end of line, not ';'. - * - An exception is VALUES format where we also support semicolon in addition to end of line. - **/ - bool processMultiQueryImpl(const String & all_queries_text, - std::function execute_single_query, - std::function process_parse_query_error = {}); - - /// Process parsed single query. - void processSingleQueryImpl(const String & query, - std::function execute_single_query, - std::optional echo_query_ = {}, bool report_error = false); /* * Method to implement multi-query processing. @@ -86,6 +63,32 @@ protected: } + /* + * Process multiquery - several queries separated by ';'. Depends on executeSingleQuery(). + * Also in case of clickhouse-server: + * - INSERT data is ended by the end of line, not ';'. + * - An exception is VALUES format where we also support semicolon in addition to end of line. + **/ + bool processMultiQueryImpl(const String & all_queries_text, + std::function execute_single_query, + std::function process_parse_query_error = {}); + + /* + * Process parsed single query. Depends on executeSingleQuery(). + **/ + void processSingleQueryImpl(const String & query, const String & query_to_execute, ASTPtr parsed_query, + std::optional echo_query_ = {}, bool report_error = false); + /* + * Just execute a single query. + * full_query - current query as it was given to the client. + * parsed_query - parsed query (used to determine some settings e.g. format, output file). + * query_to_execute - current query as it will be executed by server. + * (It may differ from the full query for INSERT queries, for which the + * data that follows the query is stripped and sent separately.) + **/ + virtual void executeSingleQuery(const String & query_to_execute, ASTPtr parsed_query) = 0; + + virtual void reportQueryError(const String & query) const = 0; /// For non-interactive multi-query mode get queries text prefix.