diff --git a/dbms/include/DB/Common/UInt128.h b/dbms/include/DB/Common/UInt128.h index a975a004302..f780a627b76 100644 --- a/dbms/include/DB/Common/UInt128.h +++ b/dbms/include/DB/Common/UInt128.h @@ -21,11 +21,6 @@ struct UInt128 bool operator!= (const UInt64 rhs) const { return first != rhs || second != 0; } UInt128 & operator= (const UInt64 rhs) { first = rhs; second = 0; return *this; } - - bool operator< (const UInt128 rhs) const - { - return std::tie(first, second) < std::tie(rhs.first, rhs.second); - } }; struct UInt128Hash diff --git a/dbms/include/DB/Core/Field.h b/dbms/include/DB/Core/Field.h index 3070758d571..33c0835f7fa 100644 --- a/dbms/include/DB/Core/Field.h +++ b/dbms/include/DB/Core/Field.h @@ -18,7 +18,6 @@ #include #include -#include namespace DB @@ -573,64 +572,6 @@ public: } }; -/** Обновляет состояние хэш-функции значением. */ -class FieldVisitorUpdateHash : public StaticVisitor<> -{ -private: - SipHash & hash; - -public: - FieldVisitorUpdateHash(SipHash & hash_) : hash(hash_) {} - - void operator() (const Null & x) const - { - auto type = Field::Types::Null; - hash.update(reinterpret_cast(&type), 1); - } - - void operator() (const UInt64 & x) const - { - auto type = Field::Types::UInt64; - hash.update(reinterpret_cast(&type), 1); - hash.update(reinterpret_cast(&x), sizeof(x)); - } - - void operator() (const Int64 & x) const - { - auto type = Field::Types::Int64; - hash.update(reinterpret_cast(&type), 1); - hash.update(reinterpret_cast(&x), sizeof(x)); - } - - void operator() (const Float64 & x) const - { - auto type = Field::Types::Float64; - hash.update(reinterpret_cast(&type), 1); - hash.update(reinterpret_cast(&x), sizeof(x)); - } - - void operator() (const String & x) const - { - auto type = Field::Types::String; - hash.update(reinterpret_cast(&type), 1); - size_t size = x.size(); - hash.update(reinterpret_cast(&size), sizeof(size)); - hash.update(x.data(), x.size()); - } - - void operator() (const Array & x) const - { - auto type = Field::Types::Array; - hash.update(reinterpret_cast(&type), 1); - size_t size = x.size(); - hash.update(reinterpret_cast(&size), sizeof(size)); - - for (const auto & elem : x) - apply_visitor(*this, elem); - } -}; - - /** Выводит текстовое представление типа, как литерала в SQL запросе */ class FieldVisitorToString : public StaticVisitor { diff --git a/dbms/include/DB/Interpreters/LogicalExpressionsOptimizer.h b/dbms/include/DB/Interpreters/LogicalExpressionsOptimizer.h index e3491322558..653dc80d5d7 100644 --- a/dbms/include/DB/Interpreters/LogicalExpressionsOptimizer.h +++ b/dbms/include/DB/Interpreters/LogicalExpressionsOptimizer.h @@ -39,11 +39,11 @@ private: */ struct OrWithExpression { - OrWithExpression(ASTFunction * or_function_, UInt128 expression_); + OrWithExpression(ASTFunction * or_function_, const std::string & expression_); bool operator<(const OrWithExpression & rhs) const; ASTFunction * or_function; - const UInt128 expression; + const std::string expression; }; struct Equalities diff --git a/dbms/include/DB/Parsers/ASTAlterQuery.h b/dbms/include/DB/Parsers/ASTAlterQuery.h index 914f8ad6d72..1d22d25e186 100644 --- a/dbms/include/DB/Parsers/ASTAlterQuery.h +++ b/dbms/include/DB/Parsers/ASTAlterQuery.h @@ -89,13 +89,6 @@ public: /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return ("AlterQuery_" + database + "_" + table); }; - void updateHashWith(SipHash & hash) const override - { - hash.update("AlterQuery", strlen("AlterQuery") + 1); - hash.update(database.data(), database.size() + 1); - hash.update(table.data(), table.size() + 1); - } - ASTPtr clone() const override { ASTAlterQuery * res = new ASTAlterQuery(*this); diff --git a/dbms/include/DB/Parsers/ASTAsterisk.h b/dbms/include/DB/Parsers/ASTAsterisk.h index e881f6b3845..aa90d676c71 100644 --- a/dbms/include/DB/Parsers/ASTAsterisk.h +++ b/dbms/include/DB/Parsers/ASTAsterisk.h @@ -16,11 +16,6 @@ public: String getID() const override { return "Asterisk"; } ASTPtr clone() const override { return new ASTAsterisk(*this); } String getColumnName() const override { return "*"; } - - void updateHashWith(SipHash & hash) const override - { - hash.update("Asterisk", strlen("Asterisk") + 1); - } }; } diff --git a/dbms/include/DB/Parsers/ASTCheckQuery.h b/dbms/include/DB/Parsers/ASTCheckQuery.h index 18019751e99..901ad7ef567 100644 --- a/dbms/include/DB/Parsers/ASTCheckQuery.h +++ b/dbms/include/DB/Parsers/ASTCheckQuery.h @@ -12,13 +12,6 @@ struct ASTCheckQuery : public IAST /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return ("CheckQuery_" + database + "_" + table); }; - void updateHashWith(SipHash & hash) const override - { - hash.update("CheckQuery", strlen("CheckQuery") + 1); - hash.update(database.data(), database.size() + 1); - hash.update(table.data(), table.size() + 1); - } - ASTPtr clone() const override { return new ASTCheckQuery(*this); diff --git a/dbms/include/DB/Parsers/ASTColumnDeclaration.h b/dbms/include/DB/Parsers/ASTColumnDeclaration.h index 2f343549ad8..9862c5a81b6 100644 --- a/dbms/include/DB/Parsers/ASTColumnDeclaration.h +++ b/dbms/include/DB/Parsers/ASTColumnDeclaration.h @@ -21,12 +21,6 @@ public: String getID() const override { return "ColumnDeclaration_" + name; } - void updateHashWith(SipHash & hash) const override - { - hash.update("ColumnDeclaration", strlen("ColumnDeclaration") + 1); - hash.update(name.data(), name.size() + 1); - } - ASTPtr clone() const override { const auto res = new ASTColumnDeclaration{*this}; diff --git a/dbms/include/DB/Parsers/ASTCreateQuery.h b/dbms/include/DB/Parsers/ASTCreateQuery.h index d5f75f000ce..33d69a8e8e3 100644 --- a/dbms/include/DB/Parsers/ASTCreateQuery.h +++ b/dbms/include/DB/Parsers/ASTCreateQuery.h @@ -30,18 +30,10 @@ public: ASTCreateQuery() = default; ASTCreateQuery(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return (attach ? "AttachQuery_" : "CreateQuery_") + database + "_" + table; }; - void updateHashWith(SipHash & hash) const override - { - hash.update(reinterpret_cast(&attach), sizeof(attach)); - hash.update("CreateQuery", strlen("CreateQuery") + 1); - hash.update(database.data(), database.size() + 1); - hash.update(table.data(), table.size() + 1); - } - ASTPtr clone() const override { ASTCreateQuery * res = new ASTCreateQuery(*this); diff --git a/dbms/include/DB/Parsers/ASTDropQuery.h b/dbms/include/DB/Parsers/ASTDropQuery.h index 137f9c3e071..c0ac24017d0 100644 --- a/dbms/include/DB/Parsers/ASTDropQuery.h +++ b/dbms/include/DB/Parsers/ASTDropQuery.h @@ -19,18 +19,10 @@ public: ASTDropQuery() = default; ASTDropQuery(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return (detach ? "DetachQuery_" : "DropQuery_") + database + "_" + table; }; - void updateHashWith(SipHash & hash) const override - { - hash.update(reinterpret_cast(&detach), sizeof(detach)); - hash.update("DropQuery", strlen("DropQuery") + 1); - hash.update(database.data(), database.size() + 1); - hash.update(table.data(), table.size() + 1); - } - ASTPtr clone() const override { return new ASTDropQuery(*this); } }; diff --git a/dbms/include/DB/Parsers/ASTExpressionList.h b/dbms/include/DB/Parsers/ASTExpressionList.h index 63935dfb42a..1ec814a8d1b 100644 --- a/dbms/include/DB/Parsers/ASTExpressionList.h +++ b/dbms/include/DB/Parsers/ASTExpressionList.h @@ -16,21 +16,16 @@ class ASTExpressionList : public IAST public: ASTExpressionList() = default; ASTExpressionList(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "ExpressionList"; } - void updateHashWith(SipHash & hash) const override - { - hash.update("ExpressionList", strlen("ExpressionList") + 1); - } - ASTPtr clone() const override { const auto res = new ASTExpressionList(*this); ASTPtr ptr{res}; res->children.clear(); - + for (const auto & child : children) res->children.emplace_back(child->clone()); diff --git a/dbms/include/DB/Parsers/ASTFunction.h b/dbms/include/DB/Parsers/ASTFunction.h index 3d4e0819e91..8f981eec593 100644 --- a/dbms/include/DB/Parsers/ASTFunction.h +++ b/dbms/include/DB/Parsers/ASTFunction.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace DB @@ -37,15 +38,40 @@ public: ASTFunction() = default; ASTFunction(const StringRange range_) : ASTWithAlias(range_) {} + String getColumnName() const override + { + SipHash hash; + + hash.update(name.data(), name.size()); + + if (parameters) + { + hash.update("(", 1); + for (const auto & param : parameters->children) + { + String param_name = param->getColumnName(); /// TODO Сделать метод updateHashWith. + hash.update(param_name.data(), param_name.size() + 1); + } + hash.update(")", 1); + } + + hash.update("(", 1); + for (const auto & arg : arguments->children) + { + String arg_name = arg->getColumnName(); + hash.update(arg_name.data(), arg_name.size() + 1); + } + hash.update(")", 1); + + UInt64 low, high; + hash.get128(low, high); + + return toString(high) + "_" + toString(low); /// TODO hex. + } + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "Function_" + name; } - void updateHashWith(SipHash & hash) const override - { - hash.update("Function", strlen("Function") + 1); - hash.update(name.data(), name.size() + 1); - } - ASTPtr clone() const override { ASTFunction * res = new ASTFunction(*this); diff --git a/dbms/include/DB/Parsers/ASTIdentifier.h b/dbms/include/DB/Parsers/ASTIdentifier.h index 25ba2a19a33..58ae38ca434 100644 --- a/dbms/include/DB/Parsers/ASTIdentifier.h +++ b/dbms/include/DB/Parsers/ASTIdentifier.h @@ -35,12 +35,6 @@ public: /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "Identifier_" + name; } - void updateHashWith(SipHash & hash) const override - { - hash.update("Identifier", strlen("Identifier") + 1); - hash.update(name.data(), name.size() + 1); - } - ASTPtr clone() const override { return new ASTIdentifier(*this); } void collectIdentifierNames(IdentifierNameSet & set) const override diff --git a/dbms/include/DB/Parsers/ASTInsertQuery.h b/dbms/include/DB/Parsers/ASTInsertQuery.h index 51728ecb5d1..5e6988bcfc6 100644 --- a/dbms/include/DB/Parsers/ASTInsertQuery.h +++ b/dbms/include/DB/Parsers/ASTInsertQuery.h @@ -26,17 +26,10 @@ public: ASTInsertQuery() = default; ASTInsertQuery(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "InsertQuery_" + database + "_" + table; }; - void updateHashWith(SipHash & hash) const override - { - hash.update("InsertQuery", strlen("InsertQuery") + 1); - hash.update(database.data(), database.size() + 1); - hash.update(table.data(), table.size() + 1); - } - ASTPtr clone() const override { ASTInsertQuery * res = new ASTInsertQuery(*this); diff --git a/dbms/include/DB/Parsers/ASTJoin.h b/dbms/include/DB/Parsers/ASTJoin.h index 5aaee2528b4..5809c8b4eb5 100644 --- a/dbms/include/DB/Parsers/ASTJoin.h +++ b/dbms/include/DB/Parsers/ASTJoin.h @@ -69,14 +69,6 @@ public: return res; }; - void updateHashWith(SipHash & hash) const override - { - hash.update("Join", strlen("Join") + 1); - hash.update(reinterpret_cast(&locality), sizeof(locality)); - hash.update(reinterpret_cast(&strictness), sizeof(strictness)); - hash.update(reinterpret_cast(&kind), sizeof(kind)); - } - ASTPtr clone() const override { ASTJoin * res = new ASTJoin(*this); diff --git a/dbms/include/DB/Parsers/ASTLiteral.h b/dbms/include/DB/Parsers/ASTLiteral.h index 73004c8dfa3..b7b24ef56db 100644 --- a/dbms/include/DB/Parsers/ASTLiteral.h +++ b/dbms/include/DB/Parsers/ASTLiteral.h @@ -25,12 +25,6 @@ public: /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "Literal_" + apply_visitor(FieldVisitorDump(), value); } - void updateHashWith(SipHash & hash) const override - { - hash.update("Literal", strlen("Literal") + 1); - apply_visitor(FieldVisitorUpdateHash(hash), value); - } - ASTPtr clone() const override { return new ASTLiteral(*this); } }; diff --git a/dbms/include/DB/Parsers/ASTNameTypePair.h b/dbms/include/DB/Parsers/ASTNameTypePair.h index 87232c23e4c..176c431cafa 100644 --- a/dbms/include/DB/Parsers/ASTNameTypePair.h +++ b/dbms/include/DB/Parsers/ASTNameTypePair.h @@ -23,12 +23,6 @@ public: /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "NameTypePair_" + name; } - void updateHashWith(SipHash & hash) const override - { - hash.update("NameTypePair", strlen("NameTypePair") + 1); - hash.update(name.data(), name.size() + 1); - } - ASTPtr clone() const override { ASTNameTypePair * res = new ASTNameTypePair(*this); diff --git a/dbms/include/DB/Parsers/ASTOptimizeQuery.h b/dbms/include/DB/Parsers/ASTOptimizeQuery.h index 305ef4788e7..906b3d1edb5 100644 --- a/dbms/include/DB/Parsers/ASTOptimizeQuery.h +++ b/dbms/include/DB/Parsers/ASTOptimizeQuery.h @@ -17,17 +17,10 @@ public: ASTOptimizeQuery() = default; ASTOptimizeQuery(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "OptimizeQuery_" + database + "_" + table; }; - void updateHashWith(SipHash & hash) const override - { - hash.update("OptimizeQuery", strlen("OptimizeQuery") + 1); - hash.update(database.data(), database.size() + 1); - hash.update(table.data(), table.size() + 1); - } - ASTPtr clone() const override { return new ASTOptimizeQuery(*this); } }; diff --git a/dbms/include/DB/Parsers/ASTOrderByElement.h b/dbms/include/DB/Parsers/ASTOrderByElement.h index ba87eef3666..f341265d93b 100644 --- a/dbms/include/DB/Parsers/ASTOrderByElement.h +++ b/dbms/include/DB/Parsers/ASTOrderByElement.h @@ -15,24 +15,19 @@ class ASTOrderByElement : public IAST { public: int direction; /// 1, если ASC, -1, если DESC - + /** Collator для locale-specific сортировки строк. * Если nullptr, то производится сортировка по байтам. */ Poco::SharedPtr collator; - + ASTOrderByElement() = default; ASTOrderByElement(const StringRange range_, const int direction_, const Poco::SharedPtr & collator_ = nullptr) : IAST(range_), direction(direction_), collator(collator_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "OrderByElement"; } - void updateHashWith(SipHash & hash) const override - { - hash.update("OrderByElement", strlen("OrderByElement") + 1); - } - ASTPtr clone() const override { return new ASTOrderByElement(*this); } }; diff --git a/dbms/include/DB/Parsers/ASTQueryWithOutput.h b/dbms/include/DB/Parsers/ASTQueryWithOutput.h index 1ab8aecfa69..2b5723249f2 100644 --- a/dbms/include/DB/Parsers/ASTQueryWithOutput.h +++ b/dbms/include/DB/Parsers/ASTQueryWithOutput.h @@ -5,8 +5,8 @@ namespace DB { - - + + /** Запрос с секцией FORMAT. */ class ASTQueryWithOutput : public IAST @@ -28,11 +28,6 @@ public: \ Name(StringRange range_) : ASTQueryWithOutput(range_) {} \ String getID() const override { return ID; }; \ \ - void updateHashWith(SipHash & hash) const override \ - { \ - hash.update(ID, strlen(ID) + 1); \ - } \ - \ ASTPtr clone() const override \ { \ Name * res = new Name(*this); \ diff --git a/dbms/include/DB/Parsers/ASTQueryWithTableAndOutput.h b/dbms/include/DB/Parsers/ASTQueryWithTableAndOutput.h index 7dfd61ec1fc..32ebb1e528d 100644 --- a/dbms/include/DB/Parsers/ASTQueryWithTableAndOutput.h +++ b/dbms/include/DB/Parsers/ASTQueryWithTableAndOutput.h @@ -6,8 +6,8 @@ namespace DB { - - + + /** Запрос с указанием названия таблицы и, возможно, БД и секцией FORMAT. */ class ASTQueryWithTableAndOutput : public ASTQueryWithOutput @@ -15,12 +15,12 @@ namespace DB public: String database; String table; - + ASTQueryWithTableAndOutput() = default; ASTQueryWithTableAndOutput(const StringRange range_) : ASTQueryWithOutput(range_) {} }; - - + + /// Объявляет класс-наследник ASTQueryWithTableAndOutput с реализованными методами getID и clone. #define DEFINE_AST_QUERY_WITH_TABLE_AND_OUTPUT(Name, ID) \ class Name : public ASTQueryWithTableAndOutput \ @@ -29,14 +29,7 @@ public: \ Name() = default; \ Name(const StringRange range_) : ASTQueryWithTableAndOutput(range_) {} \ String getID() const override { return ID"_" + database + "_" + table; }; \ - \ - void updateHashWith(SipHash & hash) const override \ - { \ - hash.update(ID, strlen(ID) + 1); \ - hash.update(database.data(), database.size() + 1); \ - hash.update(table.data(), table.size() + 1); \ - } \ - \ + \ ASTPtr clone() const override \ { \ Name * res = new Name(*this); \ diff --git a/dbms/include/DB/Parsers/ASTRenameQuery.h b/dbms/include/DB/Parsers/ASTRenameQuery.h index 4074a0a50e4..4eb6624e4c3 100644 --- a/dbms/include/DB/Parsers/ASTRenameQuery.h +++ b/dbms/include/DB/Parsers/ASTRenameQuery.h @@ -29,15 +29,10 @@ public: ASTRenameQuery() = default; ASTRenameQuery(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "Rename"; }; - void updateHashWith(SipHash & hash) const override - { - hash.update("Rename", strlen("Rename") + 1); - } - ASTPtr clone() const override { return new ASTRenameQuery(*this); } }; diff --git a/dbms/include/DB/Parsers/ASTSelectQuery.h b/dbms/include/DB/Parsers/ASTSelectQuery.h index 43aeb219a99..20b2065310a 100644 --- a/dbms/include/DB/Parsers/ASTSelectQuery.h +++ b/dbms/include/DB/Parsers/ASTSelectQuery.h @@ -39,11 +39,6 @@ public: /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "SelectQuery"; }; - void updateHashWith(SipHash & hash) const override - { - hash.update("SelectQuery", strlen("SelectQuery") + 1); - } - /// Проверить наличие функции arrayJoin. (Не большого ARRAY JOIN.) static bool hasArrayJoin(const ASTPtr & ast) { diff --git a/dbms/include/DB/Parsers/ASTSet.h b/dbms/include/DB/Parsers/ASTSet.h index 3761f0775f3..18edddc999f 100644 --- a/dbms/include/DB/Parsers/ASTSet.h +++ b/dbms/include/DB/Parsers/ASTSet.h @@ -22,11 +22,6 @@ public: String getID() const override { return "Set_" + getColumnName(); } ASTPtr clone() const override { return new ASTSet(*this); } String getColumnName() const override { return column_name; } - - void updateHashWith(SipHash & hash) const override - { - hash.update("Set", strlen("Set") + 1); - } }; } diff --git a/dbms/include/DB/Parsers/ASTSetQuery.h b/dbms/include/DB/Parsers/ASTSetQuery.h index 12c0e9c85c1..0334d1167bb 100644 --- a/dbms/include/DB/Parsers/ASTSetQuery.h +++ b/dbms/include/DB/Parsers/ASTSetQuery.h @@ -26,14 +26,9 @@ public: ASTSetQuery() = default; ASTSetQuery(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ - String getID() const override { return "SetQuery"; }; - - void updateHashWith(SipHash & hash) const override - { - hash.update("SetQuery", strlen("SetQuery") + 1); - } + String getID() const override { return "Set"; }; ASTPtr clone() const override { return new ASTSetQuery(*this); } }; diff --git a/dbms/include/DB/Parsers/ASTShowTablesQuery.h b/dbms/include/DB/Parsers/ASTShowTablesQuery.h index 671716d7202..4b51b8f1aba 100644 --- a/dbms/include/DB/Parsers/ASTShowTablesQuery.h +++ b/dbms/include/DB/Parsers/ASTShowTablesQuery.h @@ -20,14 +20,9 @@ public: ASTShowTablesQuery() = default; ASTShowTablesQuery(const StringRange range_) : ASTQueryWithOutput(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ - String getID() const override { return "ShowTablesQuery"; }; - - void updateHashWith(SipHash & hash) const override - { - hash.update("ShowTablesQuery", strlen("ShowTablesQuery") + 1); - } + String getID() const override { return "ShowTables"; }; ASTPtr clone() const override { @@ -35,13 +30,13 @@ public: ASTPtr ptr{res}; res->children.clear(); - + if (format) { res->format = format->clone(); res->children.push_back(res->format); } - + return ptr; } }; diff --git a/dbms/include/DB/Parsers/ASTSubquery.h b/dbms/include/DB/Parsers/ASTSubquery.h index f3cefd87ea0..f94cbfe8346 100644 --- a/dbms/include/DB/Parsers/ASTSubquery.h +++ b/dbms/include/DB/Parsers/ASTSubquery.h @@ -16,15 +16,10 @@ class ASTSubquery : public IAST public: ASTSubquery() = default; ASTSubquery(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "Subquery"; } - void updateHashWith(SipHash & hash) const override - { - hash.update("Subquery", strlen("Subquery") + 1); - } - ASTPtr clone() const override { const auto res = new ASTSubquery{*this}; @@ -38,11 +33,7 @@ public: return ptr; } - String getColumnName() const override - { - auto id = getTreeID(); - return toString(id.first) + "_" + toString(id.second); - } + String getColumnName() const override { return getTreeID(); } }; } diff --git a/dbms/include/DB/Parsers/ASTUseQuery.h b/dbms/include/DB/Parsers/ASTUseQuery.h index 6a2d60353e5..eafe3496293 100644 --- a/dbms/include/DB/Parsers/ASTUseQuery.h +++ b/dbms/include/DB/Parsers/ASTUseQuery.h @@ -16,16 +16,10 @@ public: ASTUseQuery() = default; ASTUseQuery(const StringRange range_) : IAST(range_) {} - + /** Получить текст, который идентифицирует этот элемент. */ String getID() const override { return "UseQuery_" + database; }; - void updateHashWith(SipHash & hash) const override - { - hash.update("UseQuery", strlen("UseQuery") + 1); - hash.update(database.data(), database.size() + 1); - } - ASTPtr clone() const override { return new ASTUseQuery(*this); } }; diff --git a/dbms/include/DB/Parsers/IAST.h b/dbms/include/DB/Parsers/IAST.h index d81b8156a4b..803cc9eb31f 100644 --- a/dbms/include/DB/Parsers/IAST.h +++ b/dbms/include/DB/Parsers/IAST.h @@ -9,10 +9,8 @@ #include #include -#include #include #include -#include #include #include @@ -45,67 +43,15 @@ public: IAST(const StringRange range_) : range(range_) {} virtual ~IAST() = default; - /** Получить имя, однозначно идентифицирующее выражение, если элемент является столбцом. У одинаковых выражений будет одинаковое имя. */ - virtual String getColumnName() const - { - /// По-умолчанию - подчёркивание, а затем getTreeID в hex-е. + /** Получить каноническое имя столбца, если элемент является столбцом */ + virtual String getColumnName() const { throw Exception("Trying to get name of not a column: " + getID(), ErrorCodes::NOT_A_COLUMN); } - union - { - UInt128 id; - UInt8 id_bytes[16]; - }; - - id = getTreeID(); - String res(1 + 2 * sizeof(id), '_'); - - for (size_t i = 0; i < sizeof(id); ++i) - { - res[i * 2 + 1] = (id_bytes[i] / 16) < 10 ? ('0' + (id_bytes[i] / 16)) : ('A' + (id_bytes[i] / 16 - 10)); - res[i * 2 + 2] = (id_bytes[i] % 16) < 10 ? ('0' + (id_bytes[i] % 16)) : ('A' + (id_bytes[i] % 16 - 10)); - } - - return res; - } - - /** Получить алиас, если он есть, или имя столбца, если его нет. */ + /** Получить алиас, если он есть, или каноническое имя столбца, если его нет. */ virtual String getAliasOrColumnName() const { return getColumnName(); } /** Получить алиас, если он есть, или пустую строку, если его нет, или если элемент не поддерживает алиасы. */ virtual String tryGetAlias() const { return String(); } - /** Обновить состояние хэш-функции элементом дерева. */ - virtual void updateHashWith(SipHash & hash) const = 0; - - /** Обновить состояние хэш-функции целым поддеревом. Используется для склейки одинаковых выражений. */ - void updateHashWithTree(SipHash & hash) const - { - updateHashWith(hash); - - if (!children.empty()) - { - size_t size = children.size(); - hash.update(reinterpret_cast(&size), sizeof(size)); - - for (size_t i = 0; i < size; ++i) - { - hash.update(reinterpret_cast(&i), sizeof(i)); - children[i]->updateHashWithTree(hash); - } - } - } - - /** Получить идентификатор поддерева. Используется для склейки одинаковых выражений. - */ - UInt128 getTreeID() const - { - SipHash hash; - updateHashWithTree(hash); - UInt128 res; - hash.get128(reinterpret_cast(&res)); - return res; - } - /** Установить алиас. */ virtual void setAlias(const String & to) { @@ -125,6 +71,37 @@ public: (*it)->is_visited = false; } + /** Получить текст, который идентифицирует этот элемент и всё поддерево. + * Обычно он содержит идентификатор элемента и getTreeID от всех детей. + */ + String getTreeID() const + { + std::stringstream s; + s << getID(); + + if (!children.empty()) + { + s << "("; + for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) + { + if (it != children.begin()) + s << ", "; + s << (*it)->getTreeID(); + } + s << ")"; + } + + return s.str(); + } + + void dumpTree(std::ostream & ostr, size_t indent = 0) const + { + String indent_str(indent, '-'); + ostr << indent_str << getID() << ", " << this << std::endl; + for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) + (*it)->dumpTree(ostr, indent + 1); + } + /** Проверить глубину дерева. * Если задано max_depth и глубина больше - кинуть исключение. * Возвращает глубину дерева. @@ -139,8 +116,8 @@ public: size_t checkSize(size_t max_size) const { size_t res = 1; - for (const auto & ast : children) - res += ast->checkSize(max_size); + for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) + res += (*it)->checkSize(max_size); if (res > max_size) throw Exception("AST is too big. Maximum: " + toString(max_size), ErrorCodes::TOO_BIG_AST); @@ -149,22 +126,22 @@ public: } /** Получить set из имен индентификаторов - */ + */ virtual void collectIdentifierNames(IdentifierNameSet & set) const { - for (const auto & ast : children) - ast->collectIdentifierNames(set); + for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) + (*it)->collectIdentifierNames(set); } private: size_t checkDepthImpl(size_t max_depth, size_t level) const { size_t res = level + 1; - for (const auto & ast : children) + for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) { if (level >= max_depth) throw Exception("AST is too deep. Maximum: " + toString(max_depth), ErrorCodes::TOO_DEEP_AST); - res = std::max(res, ast->checkDepthImpl(max_depth, level + 1)); + res = std::max(res, (*it)->checkDepthImpl(max_depth, level + 1)); } return res; diff --git a/dbms/src/DataStreams/tests/filter_stream.cpp b/dbms/src/DataStreams/tests/filter_stream.cpp index 639a434880a..2893d16b5ec 100644 --- a/dbms/src/DataStreams/tests/filter_stream.cpp +++ b/dbms/src/DataStreams/tests/filter_stream.cpp @@ -41,6 +41,7 @@ int main(int argc, char ** argv) formatAST(*ast, std::cerr); std::cerr << std::endl; + std::cerr << ast->getTreeID() << std::endl; Context context; context.getColumns().push_back(NameAndTypePair("number", new DataTypeUInt64)); diff --git a/dbms/src/DataStreams/tests/filter_stream_hitlog.cpp b/dbms/src/DataStreams/tests/filter_stream_hitlog.cpp index 4f2b58c3843..b383715a0a1 100644 --- a/dbms/src/DataStreams/tests/filter_stream_hitlog.cpp +++ b/dbms/src/DataStreams/tests/filter_stream_hitlog.cpp @@ -106,6 +106,7 @@ int main(int argc, char ** argv) formatAST(*ast, std::cerr); std::cerr << std::endl; + std::cerr << ast->getTreeID() << std::endl; /// создаём объект существующей таблицы хит лога diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index ff2c3e27afc..f233d0d100d 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -1653,43 +1653,10 @@ void ExpressionAnalyzer::appendProjectResult(DB::ExpressionActionsChain & chain, NamesWithAliases result_columns; ASTs asts = select_query->select_expression_list->children; - - /// Выбор имён для столбцов результата. - size_t i = 1; - for (const auto & ast : asts) + for (size_t i = 0; i < asts.size(); ++i) { - String source_column_name = ast->getColumnName(); - String result_column_name = ast->tryGetAlias(); - - /// Если не задан алиас - нужно сгенерировать какое-нибудь имя автоматически. - if (result_column_name.empty()) - { - if (typeid_cast(ast.get()) || typeid_cast(ast.get())) - { - /// Если выражение простое, то будем использовать его имя. - result_column_name = source_column_name; - } - else if (auto func = typeid_cast(ast.get())) - { - /// Для функций используем имя вида _1_func, где func - имя функции. - WriteBufferFromString wb(result_column_name); - writeChar('_', wb); - writeIntText(i, wb); - writeChar('_', wb); - writeString(func->name, wb); - } - else - { - /// Если выражение сложное и для него не задан алиас, будем использовать имя вида _1, _2, ... - WriteBufferFromString wb(result_column_name); - writeChar('_', wb); - writeIntText(i, wb); - } - } - - result_columns.emplace_back(source_column_name, result_column_name); - step.required_output.emplace_back(result_columns.back().second); - ++i; + result_columns.emplace_back(asts[i]->getColumnName(), asts[i]->getAliasOrColumnName()); + step.required_output.push_back(result_columns.back().second); } step.actions->add(ExpressionAction::project(result_columns)); diff --git a/dbms/src/Interpreters/LogicalExpressionsOptimizer.cpp b/dbms/src/Interpreters/LogicalExpressionsOptimizer.cpp index 637ec65ddf0..bf3fb1a274e 100644 --- a/dbms/src/Interpreters/LogicalExpressionsOptimizer.cpp +++ b/dbms/src/Interpreters/LogicalExpressionsOptimizer.cpp @@ -12,7 +12,7 @@ namespace DB { -LogicalExpressionsOptimizer::OrWithExpression::OrWithExpression(ASTFunction * or_function_, UInt128 expression_) +LogicalExpressionsOptimizer::OrWithExpression::OrWithExpression(ASTFunction * or_function_, const std::string & expression_) : or_function(or_function_), expression(expression_) { } diff --git a/dbms/src/Parsers/tests/select_parser.cpp b/dbms/src/Parsers/tests/select_parser.cpp index 22ff2d4770e..690cf27a391 100644 --- a/dbms/src/Parsers/tests/select_parser.cpp +++ b/dbms/src/Parsers/tests/select_parser.cpp @@ -27,6 +27,7 @@ int main(int argc, char ** argv) std::cout << "Success." << std::endl; formatAST(*ast, std::cerr); std::cout << std::endl; + std::cout << std::endl << ast->getTreeID() << std::endl; return 0; }