mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Fix \G in clickhouse-client multiline mode #9933
This commit is contained in:
parent
92ac608447
commit
1bbbfc6e1b
@ -67,8 +67,8 @@ LineReader::Suggest::WordsRange LineReader::Suggest::getCompletions(const String
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LineReader::LineReader(const String & history_file_path_, char extender_, char delimiter_)
|
LineReader::LineReader(const String & history_file_path_, bool multiline_, Patterns extenders_, Patterns delimiters_)
|
||||||
: history_file_path(history_file_path_), extender(extender_), delimiter(delimiter_)
|
: history_file_path(history_file_path_), multiline(multiline_), extenders(std::move(extenders_)), delimiters(std::move(delimiters_))
|
||||||
{
|
{
|
||||||
/// FIXME: check extender != delimiter
|
/// FIXME: check extender != delimiter
|
||||||
}
|
}
|
||||||
@ -76,38 +76,60 @@ LineReader::LineReader(const String & history_file_path_, char extender_, char d
|
|||||||
String LineReader::readLine(const String & first_prompt, const String & second_prompt)
|
String LineReader::readLine(const String & first_prompt, const String & second_prompt)
|
||||||
{
|
{
|
||||||
String line;
|
String line;
|
||||||
bool is_multiline = false;
|
bool need_next_line = false;
|
||||||
|
|
||||||
while (auto status = readOneLine(is_multiline ? second_prompt : first_prompt))
|
while (auto status = readOneLine(need_next_line ? second_prompt : first_prompt))
|
||||||
{
|
{
|
||||||
if (status == RESET_LINE)
|
if (status == RESET_LINE)
|
||||||
{
|
{
|
||||||
line.clear();
|
line.clear();
|
||||||
is_multiline = false;
|
need_next_line = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.empty())
|
if (input.empty())
|
||||||
{
|
{
|
||||||
if (!line.empty() && !delimiter && !hasInputData())
|
if (!line.empty() && !multiline && !hasInputData())
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_multiline = (input.back() == extender) || (delimiter && input.back() != delimiter) || hasInputData();
|
#if !defined(ARCADIA_BUILD) /// C++20
|
||||||
|
const char * has_extender = nullptr;
|
||||||
if (input.back() == extender)
|
for (const auto * extender : extenders)
|
||||||
{
|
{
|
||||||
input = input.substr(0, input.size() - 1);
|
if (input.ends_with(extender))
|
||||||
|
{
|
||||||
|
has_extender = extender;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * has_delimiter = nullptr;
|
||||||
|
for (const auto * delimiter : delimiters)
|
||||||
|
{
|
||||||
|
if (input.ends_with(delimiter))
|
||||||
|
{
|
||||||
|
has_delimiter = delimiter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
need_next_line = has_extender || (multiline && !has_delimiter) || hasInputData();
|
||||||
|
|
||||||
|
if (has_extender)
|
||||||
|
{
|
||||||
|
input.resize(input.size() - strlen(has_extender));
|
||||||
trim(input);
|
trim(input);
|
||||||
if (input.empty())
|
if (input.empty())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
line += (line.empty() ? "" : " ") + input;
|
line += (line.empty() ? "" : " ") + input;
|
||||||
|
|
||||||
if (!is_multiline)
|
if (!need_next_line)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,10 @@ public:
|
|||||||
WordsRange getCompletions(const String & prefix, size_t prefix_length) const;
|
WordsRange getCompletions(const String & prefix, size_t prefix_length) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
LineReader(const String & history_file_path, char extender, char delimiter = 0); /// if delimiter != 0, then it's multiline mode
|
using Patterns = std::vector<const char *>;
|
||||||
|
|
||||||
|
/// if delimiter is set, then it's multiline mode
|
||||||
|
LineReader(const String & history_file_path, bool multiline, Patterns extenders, Patterns delimiters);
|
||||||
virtual ~LineReader() {}
|
virtual ~LineReader() {}
|
||||||
|
|
||||||
/// Reads the whole line until delimiter (in multiline mode) or until the last line without extender.
|
/// Reads the whole line until delimiter (in multiline mode) or until the last line without extender.
|
||||||
@ -51,8 +54,10 @@ protected:
|
|||||||
String input;
|
String input;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char extender;
|
bool multiline;
|
||||||
const char delimiter;
|
|
||||||
|
Patterns extenders;
|
||||||
|
Patterns delimiters;
|
||||||
|
|
||||||
String prev_line;
|
String prev_line;
|
||||||
|
|
||||||
|
@ -56,8 +56,9 @@ static char * generate(const char * text, int state)
|
|||||||
return nextMatch();
|
return nextMatch();
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadlineLineReader::ReadlineLineReader(const Suggest & suggest_, const String & history_file_path_, char extender_, char delimiter_)
|
ReadlineLineReader::ReadlineLineReader(
|
||||||
: LineReader(history_file_path_, extender_, delimiter_)
|
const Suggest & suggest_, const String & history_file_path_, bool multiline_, Patterns extender_, Patterns delimiter_)
|
||||||
|
: LineReader(history_file_path_, multiline_, std::move(extender_), std::move(delimiter_))
|
||||||
{
|
{
|
||||||
suggest = &suggest_;
|
suggest = &suggest_;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
class ReadlineLineReader : public LineReader
|
class ReadlineLineReader : public LineReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ReadlineLineReader(const Suggest & suggest, const String & history_file_path, char extender, char delimiter = 0);
|
ReadlineLineReader(const Suggest & suggest, const String & history_file_path, bool multiline, Patterns extender_, Patterns delimiter_);
|
||||||
~ReadlineLineReader() override;
|
~ReadlineLineReader() override;
|
||||||
|
|
||||||
void enableBracketedPaste() override;
|
void enableBracketedPaste() override;
|
||||||
|
@ -16,8 +16,9 @@ void trim(String & s)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplxxLineReader::ReplxxLineReader(const Suggest & suggest, const String & history_file_path_, char extender_, char delimiter_)
|
ReplxxLineReader::ReplxxLineReader(
|
||||||
: LineReader(history_file_path_, extender_, delimiter_)
|
const Suggest & suggest, const String & history_file_path_, bool multiline_, Patterns extender_, Patterns delimiter_)
|
||||||
|
: LineReader(history_file_path_, multiline_, std::move(extender_), std::move(delimiter_))
|
||||||
{
|
{
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
using Replxx = replxx::Replxx;
|
using Replxx = replxx::Replxx;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
class ReplxxLineReader : public LineReader
|
class ReplxxLineReader : public LineReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ReplxxLineReader(const Suggest & suggest, const String & history_file_path, char extender, char delimiter = 0);
|
ReplxxLineReader(const Suggest & suggest, const String & history_file_path, bool multiline, Patterns extenders_, Patterns delimiter_);
|
||||||
~ReplxxLineReader() override;
|
~ReplxxLineReader() override;
|
||||||
|
|
||||||
void enableBracketedPaste() override;
|
void enableBracketedPaste() override;
|
||||||
|
@ -498,12 +498,15 @@ private:
|
|||||||
if (!history_file.empty() && !Poco::File(history_file).exists())
|
if (!history_file.empty() && !Poco::File(history_file).exists())
|
||||||
Poco::File(history_file).createFile();
|
Poco::File(history_file).createFile();
|
||||||
|
|
||||||
|
LineReader::Patterns query_extenders = {"\\"};
|
||||||
|
LineReader::Patterns query_delimiters = {";", "\\G"};
|
||||||
|
|
||||||
#if USE_REPLXX
|
#if USE_REPLXX
|
||||||
ReplxxLineReader lr(Suggest::instance(), history_file, '\\', config().has("multiline") ? ';' : 0);
|
ReplxxLineReader lr(Suggest::instance(), history_file, config().has("multiline"), query_extenders, query_delimiters);
|
||||||
#elif defined(USE_READLINE) && USE_READLINE
|
#elif defined(USE_READLINE) && USE_READLINE
|
||||||
ReadlineLineReader lr(Suggest::instance(), history_file, '\\', config().has("multiline") ? ';' : 0);
|
ReadlineLineReader lr(Suggest::instance(), history_file, config().has("multiline"), query_extenders, query_delimiters);
|
||||||
#else
|
#else
|
||||||
LineReader lr(history_file, '\\', config().has("multiline") ? ';' : 0);
|
LineReader lr(history_file, config().has("multiline"), query_extenders, query_delimiters);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Enable bracketed-paste-mode only when multiquery is enabled and multiline is
|
/// Enable bracketed-paste-mode only when multiquery is enabled and multiline is
|
||||||
|
Loading…
Reference in New Issue
Block a user