mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
dbms: improved query formatting for distributed queries [#METR-17606].
This commit is contained in:
parent
5ed70eeb27
commit
32da2a7d8c
@ -21,32 +21,8 @@ public:
|
||||
String tryGetAlias() const override { return alias; }
|
||||
void setAlias(const String & to) override { alias = to; }
|
||||
|
||||
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override final
|
||||
{
|
||||
if (!alias.empty())
|
||||
{
|
||||
/// Если мы уже ранее вывели этот узел в другом месте запроса, то теперь достаточно вывести лишь алиас.
|
||||
if (!state.printed_asts_with_alias.insert(this).second)
|
||||
{
|
||||
WriteBufferFromOStream wb(settings.ostr, 32);
|
||||
writeProbablyBackQuotedString(alias, wb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// Если есть алиас, то требуются скобки вокруг всего выражения, включая алиас. Потому что запись вида 0 AS x + 0 синтаксически некорректна.
|
||||
if (frame.need_parens && !alias.empty())
|
||||
settings.ostr <<'(';
|
||||
|
||||
formatImplWithAlias(settings, state, frame);
|
||||
|
||||
if (!alias.empty())
|
||||
{
|
||||
writeAlias(alias, settings.ostr, settings.hilite);
|
||||
if (frame.need_parens)
|
||||
settings.ostr <<')';
|
||||
}
|
||||
}
|
||||
/// Вызывает formatImplWithAlias, а также выводит алиас. Если надо - заключает всё выражение в скобки.
|
||||
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override final;
|
||||
|
||||
virtual void formatImplWithAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const = 0;
|
||||
};
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
|
||||
#include <Poco/SharedPtr.h>
|
||||
|
||||
@ -152,10 +152,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Состояние. Например, множество узлов DAG, которых мы уже обошли.
|
||||
/// Состояние. Например, может запоминаться множество узлов, которых мы уже обошли.
|
||||
struct FormatState
|
||||
{
|
||||
std::unordered_set<const IAST *> printed_asts_with_alias;
|
||||
/** Запрос SELECT, в котором найден алиас; идентификатор узла с таким алиасом.
|
||||
* Нужно, чтобы когда узел встретился повторно, выводить только алиас.
|
||||
*/
|
||||
std::set<std::pair<const IAST *, std::string>> printed_asts_with_alias;
|
||||
};
|
||||
|
||||
/// Состояние, которое копируется при форматировании каждого узла. Например, уровень вложенности.
|
||||
@ -163,6 +166,7 @@ public:
|
||||
{
|
||||
bool indent = 0;
|
||||
bool need_parens = false;
|
||||
const IAST * current_select = nullptr;
|
||||
};
|
||||
|
||||
void format(const FormatSettings & settings) const
|
||||
@ -171,16 +175,6 @@ public:
|
||||
formatImpl(settings, state, FormatStateStacked());
|
||||
}
|
||||
|
||||
|
||||
/// Для подсветки синтаксиса.
|
||||
static const char * hilite_keyword;
|
||||
static const char * hilite_identifier;
|
||||
static const char * hilite_function;
|
||||
static const char * hilite_operator;
|
||||
static const char * hilite_alias;
|
||||
static const char * hilite_none;
|
||||
|
||||
|
||||
virtual void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
|
||||
{
|
||||
throw Exception("Unknown element in AST: " + getID()
|
||||
@ -192,6 +186,15 @@ public:
|
||||
|
||||
void writeAlias(const String & name, std::ostream & s, bool hilite) const;
|
||||
|
||||
protected:
|
||||
/// Для подсветки синтаксиса.
|
||||
static const char * hilite_keyword;
|
||||
static const char * hilite_identifier;
|
||||
static const char * hilite_function;
|
||||
static const char * hilite_operator;
|
||||
static const char * hilite_alias;
|
||||
static const char * hilite_none;
|
||||
|
||||
private:
|
||||
size_t checkDepthImpl(size_t max_depth, size_t level) const
|
||||
{
|
||||
|
@ -222,6 +222,7 @@ const IAST * ASTSelectQuery::getFormat() const
|
||||
|
||||
void ASTSelectQuery::formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const
|
||||
{
|
||||
frame.current_select = this;
|
||||
frame.need_parens = false;
|
||||
std::string indent_str = s.one_line ? "" : std::string(4 * frame.indent, ' ');
|
||||
|
||||
|
33
dbms/src/Parsers/ASTWithAlias.cpp
Normal file
33
dbms/src/Parsers/ASTWithAlias.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include <DB/Parsers/ASTWithAlias.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void ASTWithAlias::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
|
||||
{
|
||||
if (!alias.empty())
|
||||
{
|
||||
/// Если мы уже ранее вывели этот узел в другом месте запроса, то теперь достаточно вывести лишь алиас.
|
||||
if (!state.printed_asts_with_alias.emplace(frame.current_select, getID()).second)
|
||||
{
|
||||
WriteBufferFromOStream wb(settings.ostr, 32);
|
||||
writeProbablyBackQuotedString(alias, wb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// Если есть алиас, то требуются скобки вокруг всего выражения, включая алиас. Потому что запись вида 0 AS x + 0 синтаксически некорректна.
|
||||
if (frame.need_parens && !alias.empty())
|
||||
settings.ostr <<'(';
|
||||
|
||||
formatImplWithAlias(settings, state, frame);
|
||||
|
||||
if (!alias.empty())
|
||||
{
|
||||
writeAlias(alias, settings.ostr, settings.hilite);
|
||||
if (frame.need_parens)
|
||||
settings.ostr <<')';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
@ -0,0 +1,6 @@
|
||||
SELECT toUInt64(1) IN (1234567890, 2345678901, 3456789012, 4567890123, 5678901234, 6789012345, 7890123456, 8901234567, 9012345678, 123456789) AS x,
|
||||
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
||||
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
||||
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
||||
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
|
||||
FROM remote('127.0.0.1', system, one) SETTINGS max_query_size = 10000;
|
Loading…
Reference in New Issue
Block a user