Merge pull request #30851 from kssenii/clickhouse-local-improve

Allow delayed interactive mode
This commit is contained in:
Kseniia Sumarokova 2021-11-08 10:07:29 +03:00 committed by GitHub
commit 908d78febe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 171 additions and 39 deletions

View File

@ -403,6 +403,36 @@ void Client::initialize(Poco::Util::Application & self)
}
void Client::prepareForInteractive()
{
clearTerminal();
showClientVersion();
if (delayed_interactive)
std::cout << std::endl;
/// Load Warnings at the beginning of connection
if (!config().has("no-warnings"))
{
try
{
std::vector<String> messages = loadWarningMessages();
if (!messages.empty())
{
std::cout << "Warnings:" << std::endl;
for (const auto & message : messages)
std::cout << " * " << message << std::endl;
std::cout << std::endl;
}
}
catch (...)
{
/// Ignore exception
}
}
}
int Client::main(const std::vector<std::string> & /*args*/)
try
{
@ -429,36 +459,11 @@ try
processConfig();
if (is_interactive)
{
clearTerminal();
showClientVersion();
}
connect();
if (is_interactive)
if (is_interactive && !delayed_interactive)
{
/// Load Warnings at the beginning of connection
if (!config().has("no-warnings"))
{
try
{
std::vector<String> messages = loadWarningMessages();
if (!messages.empty())
{
std::cout << "Warnings:" << std::endl;
for (const auto & message : messages)
std::cout << " * " << message << std::endl;
std::cout << std::endl;
}
}
catch (...)
{
/// Ignore exception
}
}
prepareForInteractive();
runInteractive();
}
else
@ -482,6 +487,12 @@ try
// case so that at least we don't lose an error.
return -1;
}
if (delayed_interactive)
{
prepareForInteractive();
runInteractive();
}
}
return 0;
@ -555,8 +566,9 @@ void Client::connect()
if (is_interactive)
{
std::cout << "Connected to " << server_name << " server version " << server_version << " revision " << server_revision << "."
<< std::endl
<< std::endl;
if (!delayed_interactive)
std::cout << std::endl;
auto client_version_tuple = std::make_tuple(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
auto server_version_tuple = std::make_tuple(server_version_major, server_version_minor, server_version_patch);
@ -1156,11 +1168,11 @@ void Client::processConfig()
/// - stdin is not a terminal. In this case queries are read from it.
/// - -qf (--queries-file) command line option is present.
/// The value of the option is used as file with query (or of multiple queries) to execute.
if (stdin_is_a_tty && !config().has("query") && queries_files.empty())
{
if (config().has("query") && config().has("queries-file"))
throw Exception("Specify either `query` or `queries-file` option", ErrorCodes::BAD_ARGUMENTS);
delayed_interactive = config().has("interactive") && (config().has("query") || config().has("queries-file"));
if (stdin_is_a_tty
&& (delayed_interactive || (!config().has("query") && queries_files.empty())))
{
is_interactive = true;
}
else

View File

@ -20,6 +20,7 @@ protected:
bool processWithFuzzing(const String & full_query) override;
void connect() override;
void prepareForInteractive() override;
void processError(const String & query) const override;
String getName() const override { return "client"; }

View File

@ -396,6 +396,14 @@ void LocalServer::connect()
}
void LocalServer::prepareForInteractive()
{
clearTerminal();
showClientVersion();
std::cerr << std::endl;
}
int LocalServer::main(const std::vector<std::string> & /*args*/)
try
{
@ -406,7 +414,10 @@ try
std::cout << std::fixed << std::setprecision(3);
std::cerr << std::fixed << std::setprecision(3);
is_interactive = stdin_is_a_tty && !config().has("query") && !config().has("table-structure") && queries_files.empty();
is_interactive = stdin_is_a_tty
&& (config().hasOption("interactive")
|| (!config().has("query") && !config().has("table-structure") && queries_files.empty()));
if (!is_interactive)
{
/// We will terminate process on error
@ -427,17 +438,20 @@ try
applyCmdSettings(global_context);
connect();
if (is_interactive)
if (is_interactive && !delayed_interactive)
{
clearTerminal();
showClientVersion();
std::cerr << std::endl;
prepareForInteractive();
runInteractive();
}
else
{
runNonInteractive();
if (delayed_interactive)
{
prepareForInteractive();
runInteractive();
}
}
cleanup();
@ -462,7 +476,8 @@ catch (...)
void LocalServer::processConfig()
{
if (is_interactive)
delayed_interactive = config().has("interactive") && (config().has("query") || config().has("queries-file"));
if (is_interactive && !delayed_interactive)
{
if (config().has("query") && config().has("queries-file"))
throw Exception("Specify either `query` or `queries-file` option", ErrorCodes::BAD_ARGUMENTS);
@ -474,6 +489,11 @@ void LocalServer::processConfig()
}
else
{
if (delayed_interactive)
{
load_suggestions = true;
}
need_render_progress = config().getBool("progress", false);
echo_queries = config().hasOption("echo") || config().hasOption("verbose");
ignore_error = config().getBool("ignore-error", false);

View File

@ -34,6 +34,7 @@ protected:
bool executeMultiQuery(const String & all_queries_text) override;
void connect() override;
void prepareForInteractive() override;
void processError(const String & query) const override;
String getName() const override { return "local"; }

View File

@ -1675,6 +1675,8 @@ void ClientBase::init(int argc, char ** argv)
("hardware-utilization", "print hardware utilization information in progress bar")
("print-profile-events", po::value(&profile_events.print)->zero_tokens(), "Printing ProfileEvents packets")
("profile-events-delay-ms", po::value<UInt64>()->default_value(profile_events.delay_ms), "Delay between printing `ProfileEvents` packets (-1 - print only totals, 0 - print every single packet)")
("interactive", "Process queries-file or --query query and start interactive mode")
;
addOptions(options_description);
@ -1744,6 +1746,9 @@ void ClientBase::init(int argc, char ** argv)
config().setString("history_file", options["history_file"].as<std::string>());
if (options.count("verbose"))
config().setBool("verbose", true);
if (options.count("interactive"))
config().setBool("interactive", true);
if (options.count("log-level"))
Poco::Logger::root().setLevel(options["log-level"].as<std::string>());
if (options.count("server_logs_file"))

View File

@ -59,6 +59,7 @@ protected:
virtual bool executeMultiQuery(const String & all_queries_text) = 0;
virtual void connect() = 0;
virtual void prepareForInteractive() = 0;
virtual void processError(const String & query) const = 0;
virtual String getName() const = 0;
@ -141,6 +142,7 @@ private:
protected:
bool is_interactive = false; /// Use either interactive line editing interface or batch mode.
bool is_multiquery = false;
bool delayed_interactive = false;
bool echo_queries = false; /// Print queries before execution in batch mode.
bool ignore_error = false; /// In case of errors, don't print error message, continue to next query. Only applicable for non-interactive mode.

View File

@ -0,0 +1,27 @@
#!/usr/bin/expect -f
# Tags: no-parallel, no-fasttest
log_user 0
set timeout 20
match_max 100000
# A default timeout action is to fail
expect_after {
timeout {
exit 1
}
}
spawn bash -c "\$CLICKHOUSE_TESTS_DIR/helpers/02112_prepare.sh"
set basedir [file dirname $argv0]
spawn bash -c "source $basedir/../shell_config.sh ; \$CLICKHOUSE_CLIENT --disable_suggestion --interactive --queries-file \$CURDIR/file_02112"
expect ":) "
send -- "select * from t format TSV\r"
expect "1"
expect ":) "
spawn bash -c "\$CLICKHOUSE_TESTS_DIR/helpers/02112_clean.sh"

View File

@ -0,0 +1,24 @@
#!/usr/bin/expect -f
# Tags: no-unbundled, no-fasttest
log_user 0
set timeout 20
match_max 100000
# A default timeout action is to fail
expect_after {
timeout {
exit 1
}
}
set basedir [file dirname $argv0]
spawn bash -c "source $basedir/../shell_config.sh ; \$CLICKHOUSE_LOCAL --disable_suggestion --interactive --query 'create table t(i Int32) engine=Memory; insert into t select 1'"
expect ":) "
send -- "select * from t format TSV\r"
expect "1"
expect ":) "
send -- "exit\r"
expect eof

View File

@ -0,0 +1,27 @@
#!/usr/bin/expect -f
# Tags: no-parallel, no-fasttest
log_user 0
set timeout 20
match_max 100000
# A default timeout action is to fail
expect_after {
timeout {
exit 1
}
}
spawn bash -c "\$CLICKHOUSE_TESTS_DIR/helpers/02112_prepare.sh"
set basedir [file dirname $argv0]
spawn bash -c "source $basedir/../shell_config.sh ; \$CLICKHOUSE_LOCAL --disable_suggestion --interactive --queries-file \$CURDIR/file_02112"
expect ":) "
send -- "select * from t format TSV\r"
expect "1"
expect ":) "
spawn bash -c "\$CLICKHOUSE_TESTS_DIR/helpers/02112_clean.sh"

View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
FILE=${CURDIR}/file_02112
if [ -f $FILE ]; then
rm $FILE
fi

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
FILE=${CURDIR}/file_02112
if [ -f $FILE ]; then
rm $FILE
fi
echo "drop table if exists t;create table t(i Int32) engine=Memory; insert into t select 1" >> $FILE