ClickHouse/dbms/include/DB/Parsers/ASTJoin.h

126 lines
4.2 KiB
C++
Raw Normal View History

#pragma once
#include <DB/Parsers/IAST.h>
namespace DB
{
/** [GLOBAL] ANY|ALL INNER|LEFT JOIN (subquery) USING (tuple)
* Замечание: ARRAY JOIN к этому не относится.
*/
class ASTJoin : public IAST
{
public:
/// Алгоритм работы при распределённой обработке запроса.
enum Locality
{
Local, /// Выполнить JOIN, используя соответствующие данные в пределах каждого удалённого сервера.
Global /// Собрать соединяемые данные со всех удалённых серверов, объединить их, затем отправить на каждый удалённый сервер.
};
/// Оптимизация JOIN-а для большинства простых случаев.
enum Strictness
{
Any, /// Если в "правой" таблице несколько подходящих строк - выбрать из них одну, любую.
All /// Если в "правой" таблице несколько подходящих строк - размножить строки по ним (обычная семантика JOIN-а).
};
/// Способ соединения.
enum Kind
{
Inner, /// Оставить только записи, для которых в "правой" таблице есть соответствующая.
Left, /// Если в "правой" таблице нет соответствующих записей, заполнить столбцы значениями "по-умолчанию".
Right,
2015-07-23 20:23:24 +00:00
Full,
Cross /// Прямое произведение. strictness и using_expr_list не используются.
};
Locality locality = Local;
Strictness strictness = Any;
Kind kind = Inner;
ASTPtr table; /// "Правая" таблица для соединения - подзапрос или имя таблицы.
ASTPtr using_expr_list; /// По каким столбцам выполнять соединение.
ASTPtr on_expr; /// Условие соединения. Поддерживается либо USING либо ON, но не одновременно.
2014-12-17 15:26:24 +00:00
ASTJoin() = default;
ASTJoin(const StringRange range_) : IAST(range_) {}
2014-06-12 23:21:38 +00:00
/** Получить текст, который идентифицирует этот элемент. */
2014-12-17 15:26:24 +00:00
String getID() const override
2014-06-12 23:21:38 +00:00
{
String res;
{
WriteBufferFromString wb(res);
if (locality == Global)
writeString("Global", wb);
writeString(strictness == Any ? "Any" : "All", wb);
writeString(
kind == Inner ? "Inner"
: (kind == Left ? "Left"
: (kind == Right ? "Right"
2015-07-23 20:23:24 +00:00
: (kind == Full ? "Full"
: "Cross"))), wb);
2014-06-12 23:21:38 +00:00
writeString("Join", wb);
}
2014-12-17 15:26:24 +00:00
return res;
2014-06-12 23:21:38 +00:00
};
2014-12-17 15:26:24 +00:00
ASTPtr clone() const override
{
ASTJoin * res = new ASTJoin(*this);
2014-12-17 15:26:24 +00:00
ASTPtr ptr{res};
res->children.clear();
if (table) { res->table = table->clone(); res->children.push_back(res->table); }
if (using_expr_list) { res->using_expr_list = using_expr_list->clone(); res->children.push_back(res->using_expr_list); }
2014-12-17 15:26:24 +00:00
return ptr;
}
protected:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override
{
frame.need_parens = false;
settings.ostr << (settings.hilite ? hilite_keyword : "");
if (locality == ASTJoin::Global)
settings.ostr << "GLOBAL ";
if (kind != ASTJoin::Cross)
settings.ostr << (strictness == ASTJoin::Any ? "ANY " : "ALL ");
settings.ostr << (kind == ASTJoin::Inner ? "INNER "
: (kind == ASTJoin::Left ? "LEFT "
: (kind == ASTJoin::Right ? "RIGHT "
: (kind == ASTJoin::Cross ? "CROSS "
: "FULL OUTER "))));
settings.ostr << "JOIN "
<< (settings.hilite ? hilite_none : "");
table->formatImpl(settings, state, frame);
if (using_expr_list)
{
settings.ostr << (settings.hilite ? hilite_keyword : "") << " USING " << (settings.hilite ? hilite_none : "");
using_expr_list->formatImpl(settings, state, frame);
}
else if (on_expr)
{
settings.ostr << (settings.hilite ? hilite_keyword : "") << " ON " << (settings.hilite ? hilite_none : "");
on_expr->formatImpl(settings, state, frame);
}
}
};
}