Delayed interactive

This commit is contained in:
kssenii 2021-10-29 15:04:08 +03:00
parent 11b70a285c
commit 07bab5193f
15 changed files with 169 additions and 38 deletions

View File

@ -403,6 +403,33 @@ void Client::initialize(Poco::Util::Application & self)
}
void Client::prepareForInteractive()
{
clearTerminal();
showClientVersion();
/// 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 +456,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 +484,12 @@ try
// case so that at least we don't lose an error.
return -1;
}
if (delayed_interactive)
{
prepareForInteractive();
runInteractive();
}
}
return 0;
@ -1161,11 +1169,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

@ -412,6 +412,14 @@ void LocalServer::connect()
}
void LocalServer::prepareForInteractive()
{
clearTerminal();
showClientVersion();
std::cerr << std::endl;
}
int LocalServer::main(const std::vector<std::string> & /*args*/)
try
{
@ -422,7 +430,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
@ -443,17 +454,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();
@ -478,7 +492,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);
@ -490,6 +505,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

@ -1612,6 +1612,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);

View File

@ -57,6 +57,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;
@ -138,6 +139,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,30 @@
#!/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 ":) "
send -- "exit\r"
expect eof
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,30 @@
#!/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 ":) "
send -- "exit\r"
expect eof
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