This commit is contained in:
kssenii 2021-07-12 17:01:46 +03:00
parent 9ff54216ea
commit bc3c038ac7
5 changed files with 48 additions and 80 deletions

View File

@ -159,20 +159,12 @@ private:
bool supportPasswordOption() const override { return true; }
bool splitQueryIntoParts() const override { return true; }
void reconnectIfNeeded() override
{
if (!connection->checkConnected())
connect();
}
void setDatabase(const String & new_database) override
{
/// If the connection initiates the reconnection, it uses its variable.
connection->setDefaultDatabase(new_database);
}
void initialize(Poco::Util::Application & self) override
{
Poco::Util::Application::initialize(self);
@ -197,17 +189,6 @@ private:
/// Set path for format schema files
if (config().has("format_schema_path"))
global_context->setFormatSchemaPath(fs::weakly_canonical(config().getString("format_schema_path")));
/// Initialize query_id_formats if any
if (config().has("query_id_formats"))
{
Poco::Util::AbstractConfiguration::Keys keys;
config().keys("query_id_formats", keys);
for (const auto & name : keys)
query_id_formats.emplace_back(name + ":", config().getString("query_id_formats." + name));
}
if (query_id_formats.empty())
query_id_formats.emplace_back("Query id:", " {query_id}\n");
}
void processMainImplException(const Exception & e) override
@ -655,7 +636,7 @@ private:
parsed_query = ast_to_process;
query_to_execute = parsed_query->formatForErrorMessage();
executeSingleQuery();
executeParsedQuery();
}
catch (...)
{
@ -920,7 +901,7 @@ private:
}
}
void executeSingleQueryPrefix() override
void executeParsedQueryPrefix() override
{
auto query = query_to_execute;
/// Some parts of a query (result output and formatting) are executed
@ -937,7 +918,7 @@ private:
query_to_execute = full_query.substr(0, insert->data - query.data());
}
void executeSingleQueryImpl() override
void executeParsedQueryImpl() override
{
client_exception.reset();
server_exception.reset();
@ -986,7 +967,7 @@ private:
}
}
void executeSingleQuerySuffix() override
void executeParsedQuerySuffix() override
{
/// Do not change context (current DB, settings) in case of an exception.
if (!have_error)
@ -1008,7 +989,8 @@ private:
const String & new_database = use_query->database;
/// If the client initiates the reconnection, it takes the settings from the config.
config().setString("database", new_database);
setDatabase(new_database);
/// If the connection initiates the reconnection, it uses its variable.
connection->setDefaultDatabase(new_database);
}
}
}

View File

@ -249,21 +249,11 @@ std::string LocalServer::getInitialCreateTableQuery()
}
void LocalServer::executeSingleQueryImpl()
void LocalServer::executeParsedQueryImpl()
{
written_first_block = false;
progress_indication.resetProgress();
ReadBufferFromString read_buf(query_to_execute);
WriteBufferFromFileDescriptor write_buf(STDOUT_FILENO);
if (echo_queries)
{
writeString(query_to_execute, write_buf);
writeChar('\n', write_buf);
write_buf.next();
}
std::function<void()> finalize_progress;
if (need_render_progress)
{
@ -315,10 +305,7 @@ void LocalServer::processQueries()
throw Exception("Cannot parse and execute the following part of query: " + String(parse_res.first), ErrorCodes::SYNTAX_ERROR);
for (const auto & query : queries)
{
query_to_execute = query;
executeSingleQueryImpl();
}
prepareAndExecuteQuery(query);
if (exception)
std::rethrow_exception(exception);

View File

@ -54,15 +54,10 @@ protected:
bool processQueryFromInteractive(const String & input) override
{
if (exit_strings.end() != exit_strings.find(trim(input, [](char c) { return isWhitespaceASCII(c) || c == ';'; })))
return false;
query_to_execute = input;
executeSingleQueryImpl();
return true;
return processQueryText(input);
}
void executeSingleQueryImpl() override;
void executeParsedQueryImpl() override;
void reportQueryError() const override;
@ -78,8 +73,6 @@ protected:
bool supportPasswordOption() const override { return false; }
bool splitQueryIntoParts() const override { return false; }
std::optional<std::filesystem::path> temporary_directory_to_delete;
private:

View File

@ -349,7 +349,7 @@ void IClient::outputQueryInfo(bool echo_query_)
}
void IClient::processQuery(const String & query)
void IClient::prepareAndExecuteQuery(const String & query)
{
/* Parameters are in global variables:
* 'parsed_query' -- the query AST,
@ -359,11 +359,13 @@ void IClient::processQuery(const String & query)
**/
full_query = query_to_execute = query;
executeSingleQuery();
executeParsedQueryPrefix();
executeParsedQuery();
}
void IClient::executeSingleQuery(std::optional<bool> echo_query_)
void IClient::executeParsedQuery(std::optional<bool> echo_query_, bool report_error)
{
have_error = false;
processed_rows = 0;
@ -373,9 +375,8 @@ void IClient::executeSingleQuery(std::optional<bool> echo_query_)
resetOutput();
outputQueryInfo(echo_query_.value_or(echo_queries));
executeSingleQueryPrefix();
executeSingleQueryImpl();
executeSingleQuerySuffix();
executeParsedQueryImpl();
executeParsedQuerySuffix();
if (is_interactive)
{
@ -388,7 +389,7 @@ void IClient::executeSingleQuery(std::optional<bool> echo_query_)
std::cerr << progress_indication.elapsedSeconds() << "\n";
}
if (have_error)
if (have_error && report_error)
reportQueryError();
}
@ -404,7 +405,7 @@ bool IClient::processMultiQuery(const String & all_queries_text)
/// disable logs if expects errors
TestHint test_hint(test_mode, all_queries_text);
if (test_hint.clientError() || test_hint.serverError())
processQuery("SET send_logs_level = 'fatal'");
prepareAndExecuteQuery("SET send_logs_level = 'fatal'");
}
bool echo_query = echo_queries;
@ -505,7 +506,7 @@ bool IClient::processMultiQuery(const String & all_queries_text)
// unlike VALUES.
auto * insert_ast = parsed_query->as<ASTInsertQuery>();
/// But do not split query for clickhouse-local.
if (splitQueryIntoParts() && insert_ast && insert_ast->data)
if (insert_ast && insert_ast->data)
{
this_query_end = find_first_symbols<'\n'>(insert_ast->data, all_queries_end);
insert_ast->end = this_query_end;
@ -551,7 +552,7 @@ bool IClient::processMultiQuery(const String & all_queries_text)
try
{
executeSingleQuery(echo_query);
executeParsedQuery(echo_query, false);
}
catch (...)
{
@ -568,7 +569,7 @@ bool IClient::processMultiQuery(const String & all_queries_text)
// , where the inline data is delimited by semicolon and not by a
// newline.
/// TODO: Better way
if (splitQueryIntoParts() && insert_ast && insert_ast->data)
if (insert_ast && insert_ast->data)
{
this_query_end = insert_ast->end;
adjustQueryEnd(this_query_end, all_queries_end, global_context->getSettingsRef().max_parser_depth);
@ -676,7 +677,7 @@ bool IClient::processQueryText(const String & text)
if (!config().has("multiquery"))
{
assert(!query_fuzzer_runs);
processQuery(text);
prepareAndExecuteQuery(text);
return true;
}
@ -709,10 +710,20 @@ void IClient::runInteractive()
const char * home_path_cstr = getenv("HOME");
if (home_path_cstr)
home_path = home_path_cstr;
configReadClient(config(), home_path);
}
/// Initialize query_id_formats if any
if (config().has("query_id_formats"))
{
Poco::Util::AbstractConfiguration::Keys keys;
config().keys("query_id_formats", keys);
for (const auto & name : keys)
query_id_formats.emplace_back(name + ":", config().getString("query_id_formats." + name));
}
if (query_id_formats.empty())
query_id_formats.emplace_back("Query id:", " {query_id}\n");
/// Load command history if present.
if (config().has("history_file"))
history_file = config().getString("history_file");
@ -818,7 +829,6 @@ int IClient::mainImpl()
if (is_interactive)
{
clearTerminal();
showClientVersion();
}

View File

@ -1,13 +1,5 @@
#pragma once
#if USE_REPLXX
# include <common/ReplxxLineReader.h>
#elif defined(USE_READLINE) && USE_READLINE
# include <common/ReadlineLineReader.h>
#else
# include <common/LineReader.h>
#endif
#include <boost/program_options.hpp>
#include <Poco/Util/Application.h>
#include <Core/Names.h>
@ -18,6 +10,14 @@
#include <Client/QueryFuzzer.h>
#include <Common/ShellCommand.h>
#if USE_REPLXX
# include <common/ReplxxLineReader.h>
#elif defined(USE_READLINE) && USE_READLINE
# include <common/ReadlineLineReader.h>
#else
# include <common/LineReader.h>
#endif
namespace DB
{
@ -137,15 +137,15 @@ protected:
void resetOutput();
virtual void executeSingleQueryPrefix() {}
virtual void executeParsedQueryPrefix() {}
virtual void executeSingleQueryImpl() = 0;
virtual void executeParsedQueryImpl() = 0;
virtual void executeSingleQuerySuffix() {}
virtual void executeParsedQuerySuffix() {}
void processQuery(const String & query);
void prepareAndExecuteQuery(const String & query);
void executeSingleQuery(std::optional<bool> echo_query_ = {});
void executeParsedQuery(std::optional<bool> echo_query_ = {}, bool report_error = true);
virtual bool processQueryFromInteractive(const String & input) = 0;
@ -183,10 +183,6 @@ protected:
virtual bool supportPasswordOption() const = 0;
virtual bool splitQueryIntoParts() const = 0;
virtual void setDatabase(const String &) {}
private:
inline String prompt() const