mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Revert "dbms: improvement (incomplete) [#METR-16164]."
This reverts commit 6f4f44ce7980cace32edd0913b8d1d53cd51682b.
This commit is contained in:
parent
3b5fe94b82
commit
310ed66b00
@ -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
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <DB/IO/WriteBufferFromString.h>
|
||||
|
||||
#include <DB/IO/DoubleConverter.h>
|
||||
#include <DB/Common/SipHash.h>
|
||||
|
||||
|
||||
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<const char *>(&type), 1);
|
||||
}
|
||||
|
||||
void operator() (const UInt64 & x) const
|
||||
{
|
||||
auto type = Field::Types::UInt64;
|
||||
hash.update(reinterpret_cast<const char *>(&type), 1);
|
||||
hash.update(reinterpret_cast<const char *>(&x), sizeof(x));
|
||||
}
|
||||
|
||||
void operator() (const Int64 & x) const
|
||||
{
|
||||
auto type = Field::Types::Int64;
|
||||
hash.update(reinterpret_cast<const char *>(&type), 1);
|
||||
hash.update(reinterpret_cast<const char *>(&x), sizeof(x));
|
||||
}
|
||||
|
||||
void operator() (const Float64 & x) const
|
||||
{
|
||||
auto type = Field::Types::Float64;
|
||||
hash.update(reinterpret_cast<const char *>(&type), 1);
|
||||
hash.update(reinterpret_cast<const char *>(&x), sizeof(x));
|
||||
}
|
||||
|
||||
void operator() (const String & x) const
|
||||
{
|
||||
auto type = Field::Types::String;
|
||||
hash.update(reinterpret_cast<const char *>(&type), 1);
|
||||
size_t size = x.size();
|
||||
hash.update(reinterpret_cast<const char *>(&size), sizeof(size));
|
||||
hash.update(x.data(), x.size());
|
||||
}
|
||||
|
||||
void operator() (const Array & x) const
|
||||
{
|
||||
auto type = Field::Types::Array;
|
||||
hash.update(reinterpret_cast<const char *>(&type), 1);
|
||||
size_t size = x.size();
|
||||
hash.update(reinterpret_cast<const char *>(&size), sizeof(size));
|
||||
|
||||
for (const auto & elem : x)
|
||||
apply_visitor(*this, elem);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Выводит текстовое представление типа, как литерала в SQL запросе */
|
||||
class FieldVisitorToString : public StaticVisitor<String>
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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};
|
||||
|
@ -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<const char *>(&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);
|
||||
|
@ -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<const char *>(&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); }
|
||||
};
|
||||
|
||||
|
@ -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());
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <DB/Functions/IFunction.h>
|
||||
#include <DB/AggregateFunctions/IAggregateFunction.h>
|
||||
#include <DB/IO/WriteBufferFromString.h>
|
||||
#include <DB/Common/SipHash.h>
|
||||
|
||||
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -69,14 +69,6 @@ public:
|
||||
return res;
|
||||
};
|
||||
|
||||
void updateHashWith(SipHash & hash) const override
|
||||
{
|
||||
hash.update("Join", strlen("Join") + 1);
|
||||
hash.update(reinterpret_cast<const char *>(&locality), sizeof(locality));
|
||||
hash.update(reinterpret_cast<const char *>(&strictness), sizeof(strictness));
|
||||
hash.update(reinterpret_cast<const char *>(&kind), sizeof(kind));
|
||||
}
|
||||
|
||||
ASTPtr clone() const override
|
||||
{
|
||||
ASTJoin * res = new ASTJoin(*this);
|
||||
|
@ -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); }
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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); }
|
||||
};
|
||||
|
||||
|
@ -15,24 +15,19 @@ class ASTOrderByElement : public IAST
|
||||
{
|
||||
public:
|
||||
int direction; /// 1, если ASC, -1, если DESC
|
||||
|
||||
|
||||
/** Collator для locale-specific сортировки строк.
|
||||
* Если nullptr, то производится сортировка по байтам.
|
||||
*/
|
||||
Poco::SharedPtr<Collator> collator;
|
||||
|
||||
|
||||
ASTOrderByElement() = default;
|
||||
ASTOrderByElement(const StringRange range_, const int direction_, const Poco::SharedPtr<Collator> & 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); }
|
||||
};
|
||||
|
||||
|
@ -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); \
|
||||
|
@ -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); \
|
||||
|
@ -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); }
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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); }
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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); }
|
||||
};
|
||||
|
||||
|
@ -9,10 +9,8 @@
|
||||
#include <Yandex/Common.h>
|
||||
|
||||
#include <DB/Core/Types.h>
|
||||
#include <DB/Common/UInt128.h>
|
||||
#include <DB/Core/Exception.h>
|
||||
#include <DB/Core/ErrorCodes.h>
|
||||
#include <DB/Common/SipHash.h>
|
||||
#include <DB/IO/WriteHelpers.h>
|
||||
#include <DB/Parsers/StringRange.h>
|
||||
|
||||
@ -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<const char *>(&size), sizeof(size));
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
hash.update(reinterpret_cast<const char *>(&i), sizeof(i));
|
||||
children[i]->updateHashWithTree(hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Получить идентификатор поддерева. Используется для склейки одинаковых выражений.
|
||||
*/
|
||||
UInt128 getTreeID() const
|
||||
{
|
||||
SipHash hash;
|
||||
updateHashWithTree(hash);
|
||||
UInt128 res;
|
||||
hash.get128(reinterpret_cast<char *>(&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;
|
||||
|
@ -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));
|
||||
|
@ -106,6 +106,7 @@ int main(int argc, char ** argv)
|
||||
|
||||
formatAST(*ast, std::cerr);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << ast->getTreeID() << std::endl;
|
||||
|
||||
/// создаём объект существующей таблицы хит лога
|
||||
|
||||
|
@ -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<const ASTLiteral *>(ast.get()) || typeid_cast<const ASTIdentifier *>(ast.get()))
|
||||
{
|
||||
/// Если выражение простое, то будем использовать его имя.
|
||||
result_column_name = source_column_name;
|
||||
}
|
||||
else if (auto func = typeid_cast<const ASTFunction *>(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));
|
||||
|
@ -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_)
|
||||
{
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user