Merge branch 'master' of github.com:ClickHouse/ClickHouse into collect-binary-size

This commit is contained in:
Alexey Milovidov 2023-11-13 05:06:56 +01:00
commit 6e910f002f
40 changed files with 240 additions and 79 deletions

2
contrib/grpc vendored

@ -1 +1 @@
Subproject commit 267af8c3a1ea4a5a4d9e5a070ad2d1ac7c701923
Subproject commit b723ecae0991bb873fe87a595dfb187178733fde

View File

@ -7,6 +7,7 @@ echo '/*' > $FILES_TO_CHECKOUT
echo '!/test/*' >> $FILES_TO_CHECKOUT
echo '/test/build/*' >> $FILES_TO_CHECKOUT
echo '/test/core/tsi/alts/fake_handshaker/*' >> $FILES_TO_CHECKOUT
echo '/test/core/event_engine/fuzzing_event_engine/*' >> $FILES_TO_CHECKOUT
echo '!/tools/*' >> $FILES_TO_CHECKOUT
echo '/tools/codegen/*' >> $FILES_TO_CHECKOUT
echo '!/examples/*' >> $FILES_TO_CHECKOUT

View File

@ -4159,6 +4159,61 @@ arguments, result_type, input_rows_count); \
};
}
template <typename EnumType>
WrapperType createEnumToStringWrapper() const
{
const char * function_name = cast_name;
return [function_name] (
ColumnsWithTypeAndName & arguments, const DataTypePtr & res_type, const ColumnNullable * nullable_col, size_t /*input_rows_count*/)
{
using ColumnEnumType = EnumType::ColumnType;
const auto & first_col = arguments.front().column.get();
const auto & first_type = arguments.front().type.get();
const ColumnEnumType * enum_col = typeid_cast<const ColumnEnumType *>(first_col);
const EnumType * enum_type = typeid_cast<const EnumType *>(first_type);
if (enum_col && nullable_col && nullable_col->size() != enum_col->size())
throw Exception(ErrorCodes::LOGICAL_ERROR, "ColumnNullable is not compatible with original");
if (enum_col && enum_type)
{
const auto size = enum_col->size();
const auto & enum_data = enum_col->getData();
auto res = res_type->createColumn();
if (nullable_col)
{
for (size_t i = 0; i < size; ++i)
{
if (!nullable_col->isNullAt(i))
{
const auto & value = enum_type->getNameForValue(enum_data[i]);
res->insertData(value.data, value.size);
}
else
res->insertDefault();
}
}
else
{
for (size_t i = 0; i < size; ++i)
{
const auto & value = enum_type->getNameForValue(enum_data[i]);
res->insertData(value.data, value.size);
}
}
return res;
}
else
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unexpected column {} as first argument of function {}",
first_col->getName(), function_name);
};
}
static WrapperType createIdentityWrapper(const DataTypePtr &)
{
return [] (ColumnsWithTypeAndName & arguments, const DataTypePtr &, const ColumnNullable *, size_t /*input_rows_count*/)
@ -4546,7 +4601,12 @@ arguments, result_type, input_rows_count); \
if constexpr (WhichDataType(ToDataType::type_id).isStringOrFixedString())
{
if (from_type->getCustomSerialization())
if constexpr (WhichDataType(FromDataType::type_id).isEnum())
{
ret = createEnumToStringWrapper<FromDataType>();
return true;
}
else if (from_type->getCustomSerialization())
{
ret = [](ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, const ColumnNullable *, size_t input_rows_count) -> ColumnPtr
{

View File

@ -147,17 +147,18 @@ QueryCache::Key::Key(ASTPtr ast_, const String & user_name_)
{
}
/// Hashing of ASTs must consider aliases (issue #56258)
constexpr bool ignore_aliases = false;
bool QueryCache::Key::operator==(const Key & other) const
{
return ast->getTreeHash() == other.ast->getTreeHash();
return ast->getTreeHash(ignore_aliases) == other.ast->getTreeHash(ignore_aliases);
}
size_t QueryCache::KeyHasher::operator()(const Key & key) const
{
SipHash hash;
hash.update(key.ast->getTreeHash());
auto res = hash.get64();
return res;
IAST::Hash hash = key.ast->getTreeHash(ignore_aliases);
return hash.low64;
}
size_t QueryCache::QueryCacheEntryWeight::operator()(const Entry & entry) const

View File

@ -46,11 +46,11 @@ void ASTColumnsRegexpMatcher::appendColumnName(WriteBuffer & ostr) const
writeChar(')', ostr);
}
void ASTColumnsRegexpMatcher::updateTreeHashImpl(SipHash & hash_state) const
void ASTColumnsRegexpMatcher::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(original_pattern.size());
hash_state.update(original_pattern);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
void ASTColumnsRegexpMatcher::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
@ -201,11 +201,11 @@ const std::shared_ptr<re2::RE2> & ASTQualifiedColumnsRegexpMatcher::getMatcher()
return column_matcher;
}
void ASTQualifiedColumnsRegexpMatcher::updateTreeHashImpl(SipHash & hash_state) const
void ASTQualifiedColumnsRegexpMatcher::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(original_pattern.size());
hash_state.update(original_pattern);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
void ASTQualifiedColumnsRegexpMatcher::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const

View File

@ -27,7 +27,7 @@ public:
const String & getPattern() const;
const std::shared_ptr<re2::RE2> & getMatcher() const;
bool isColumnMatching(const String & column_name) const;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
ASTPtr expression;
ASTPtr transformers;
@ -65,7 +65,7 @@ public:
const std::shared_ptr<re2::RE2> & getMatcher() const;
void setPattern(String pattern, bool set_matcher = true);
void setMatcher(std::shared_ptr<re2::RE2> matcher);
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
ASTPtr qualifier;
ASTPtr transformers;

View File

@ -151,15 +151,15 @@ void ASTColumnsApplyTransformer::appendColumnName(WriteBuffer & ostr) const
}
}
void ASTColumnsApplyTransformer::updateTreeHashImpl(SipHash & hash_state) const
void ASTColumnsApplyTransformer::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(func_name.size());
hash_state.update(func_name);
if (parameters)
parameters->updateTreeHashImpl(hash_state);
parameters->updateTreeHashImpl(hash_state, ignore_aliases);
if (lambda)
lambda->updateTreeHashImpl(hash_state);
lambda->updateTreeHashImpl(hash_state, ignore_aliases);
hash_state.update(lambda_arg.size());
hash_state.update(lambda_arg);
@ -167,7 +167,7 @@ void ASTColumnsApplyTransformer::updateTreeHashImpl(SipHash & hash_state) const
hash_state.update(column_name_prefix.size());
hash_state.update(column_name_prefix);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
void ASTColumnsExceptTransformer::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
@ -216,13 +216,13 @@ void ASTColumnsExceptTransformer::appendColumnName(WriteBuffer & ostr) const
writeChar(')', ostr);
}
void ASTColumnsExceptTransformer::updateTreeHashImpl(SipHash & hash_state) const
void ASTColumnsExceptTransformer::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(is_strict);
hash_state.update(original_pattern.size());
hash_state.update(original_pattern);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
void ASTColumnsExceptTransformer::transform(ASTs & nodes) const
@ -312,14 +312,14 @@ void ASTColumnsReplaceTransformer::Replacement::appendColumnName(WriteBuffer & o
writeProbablyBackQuotedString(name, ostr);
}
void ASTColumnsReplaceTransformer::Replacement::updateTreeHashImpl(SipHash & hash_state) const
void ASTColumnsReplaceTransformer::Replacement::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
assert(children.size() == 1);
hash_state.update(name.size());
hash_state.update(name);
children[0]->updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state);
children[0]->updateTreeHashImpl(hash_state, ignore_aliases);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
void ASTColumnsReplaceTransformer::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
@ -361,10 +361,10 @@ void ASTColumnsReplaceTransformer::appendColumnName(WriteBuffer & ostr) const
writeChar(')', ostr);
}
void ASTColumnsReplaceTransformer::updateTreeHashImpl(SipHash & hash_state) const
void ASTColumnsReplaceTransformer::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(is_strict);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
void ASTColumnsReplaceTransformer::replaceChildren(ASTPtr & node, const ASTPtr & replacement, const String & name)

View File

@ -48,7 +48,7 @@ public:
}
void transform(ASTs & nodes) const override;
void appendColumnName(WriteBuffer & ostr) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
// Case 1 APPLY (quantile(0.9))
String func_name;
@ -80,7 +80,7 @@ public:
const std::shared_ptr<re2::RE2> & getMatcher() const;
bool isColumnMatching(const String & column_name) const;
void appendColumnName(WriteBuffer & ostr) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
protected:
void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override;
@ -103,7 +103,7 @@ public:
}
void appendColumnName(WriteBuffer & ostr) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
String name;
@ -121,7 +121,7 @@ public:
}
void transform(ASTs & nodes) const override;
void appendColumnName(WriteBuffer & ostr) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
protected:
void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override;

View File

@ -599,11 +599,11 @@ ASTPtr ASTFunction::clone() const
}
void ASTFunction::updateTreeHashImpl(SipHash & hash_state) const
void ASTFunction::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(name.size());
hash_state.update(name);
IAST::updateTreeHashImpl(hash_state);
ASTWithAlias::updateTreeHashImpl(hash_state, ignore_aliases);
}
template <typename Container>

View File

@ -63,7 +63,7 @@ public:
ASTPtr clone() const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
ASTSelectWithUnionQuery * tryGetQueryArgument() const;

View File

@ -53,12 +53,12 @@ bool ASTPair::hasSecretParts() const
}
void ASTPair::updateTreeHashImpl(SipHash & hash_state) const
void ASTPair::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(first.size());
hash_state.update(first);
hash_state.update(second_with_brackets);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
@ -92,12 +92,12 @@ void ASTFunctionWithKeyValueArguments::formatImpl(const FormatSettings & setting
}
void ASTFunctionWithKeyValueArguments::updateTreeHashImpl(SipHash & hash_state) const
void ASTFunctionWithKeyValueArguments::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(name.size());
hash_state.update(name);
hash_state.update(has_brackets);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
}

View File

@ -32,7 +32,7 @@ public:
bool hasSecretParts() const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
void forEachPointerToChild(std::function<void(void**)> f) override
{
@ -66,7 +66,7 @@ public:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
};
}

View File

@ -87,6 +87,11 @@ void ASTIdentifier::setShortName(const String & new_name)
semantic->table = table;
}
void ASTIdentifier::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
ASTWithAlias::updateTreeHashImpl(hash_state, ignore_aliases);
}
const String & ASTIdentifier::name() const
{
if (children.empty())
@ -244,10 +249,10 @@ void ASTTableIdentifier::resetTable(const String & database_name, const String &
uuid = identifier->uuid;
}
void ASTTableIdentifier::updateTreeHashImpl(SipHash & hash_state) const
void ASTTableIdentifier::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(uuid);
IAST::updateTreeHashImpl(hash_state);
ASTIdentifier::updateTreeHashImpl(hash_state, ignore_aliases);
}
String getIdentifierName(const IAST * ast)

View File

@ -47,6 +47,8 @@ public:
const String & shortName() const { return name_parts.back(); }
const String & name() const;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_alias) const override;
void restoreTable(); // TODO(ilezhankin): get rid of this
std::shared_ptr<ASTTableIdentifier> createTable() const; // returns |nullptr| if identifier is not table.
@ -91,7 +93,7 @@ public:
// FIXME: used only when it's needed to rewrite distributed table name to real remote table name.
void resetTable(const String & database_name, const String & table_name); // TODO(ilezhankin): get rid of this
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
};
}

View File

@ -138,13 +138,13 @@ void ASTInsertQuery::formatImpl(const FormatSettings & settings, FormatState & s
}
}
void ASTInsertQuery::updateTreeHashImpl(SipHash & hash_state) const
void ASTInsertQuery::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(table_id.database_name);
hash_state.update(table_id.table_name);
hash_state.update(table_id.uuid);
hash_state.update(format);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}

View File

@ -72,7 +72,7 @@ public:
protected:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
};
}

View File

@ -10,11 +10,13 @@
namespace DB
{
void ASTLiteral::updateTreeHashImpl(SipHash & hash_state) const
void ASTLiteral::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
const char * prefix = "Literal_";
hash_state.update(prefix, strlen(prefix));
applyVisitor(FieldVisitorHash(hash_state), value);
if (!ignore_aliases)
ASTWithAlias::updateTreeHashImpl(hash_state, ignore_aliases);
}
ASTPtr ASTLiteral::clone() const

View File

@ -41,7 +41,7 @@ public:
ASTPtr clone() const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
protected:
void formatImplWithoutAlias(const FormatSettings & settings, FormatState &, FormatStateStacked) const override;

View File

@ -7,13 +7,13 @@
namespace DB
{
void ASTOrderByElement::updateTreeHashImpl(SipHash & hash_state) const
void ASTOrderByElement::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(direction);
hash_state.update(nulls_direction);
hash_state.update(nulls_direction_was_explicitly_specified);
hash_state.update(with_fill);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
void ASTOrderByElement::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const

View File

@ -32,7 +32,7 @@ public:
return clone;
}
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
protected:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;

View File

@ -23,4 +23,9 @@ void ASTQueryParameter::appendColumnNameImpl(WriteBuffer & ostr) const
writeString(name, ostr);
}
void ASTQueryParameter::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
ASTWithAlias::updateTreeHashImpl(hash_state, ignore_aliases);
}
}

View File

@ -21,6 +21,8 @@ public:
ASTPtr clone() const override { return std::make_shared<ASTQueryParameter>(*this); }
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
protected:
void formatImplWithoutAlias(const FormatSettings & settings, FormatState &, FormatStateStacked) const override;
void appendColumnNameImpl(WriteBuffer & ostr) const override;

View File

@ -42,14 +42,14 @@ ASTPtr ASTSelectQuery::clone() const
}
void ASTSelectQuery::updateTreeHashImpl(SipHash & hash_state) const
void ASTSelectQuery::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(distinct);
hash_state.update(group_by_with_totals);
hash_state.update(group_by_with_rollup);
hash_state.update(group_by_with_cube);
hash_state.update(limit_with_ties);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}

View File

@ -137,7 +137,7 @@ public:
void replaceDatabaseAndTable(const String & database_name, const String & table_name);
void replaceDatabaseAndTable(const StorageID & table_id);
void addTableFunction(ASTPtr & table_function_ptr);
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
void setFinal();

View File

@ -9,7 +9,7 @@
namespace DB
{
void ASTSetQuery::updateTreeHashImpl(SipHash & hash_state) const
void ASTSetQuery::updateTreeHashImpl(SipHash & hash_state, bool /*ignore_aliases*/) const
{
for (const auto & change : changes)
{

View File

@ -34,7 +34,7 @@ public:
void formatImpl(const FormatSettings & format, FormatState &, FormatStateStacked) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
QueryKind getQueryKind() const override { return QueryKind::Set; }

View File

@ -51,11 +51,11 @@ void ASTSubquery::formatImplWithoutAlias(const FormatSettings & settings, Format
settings.ostr << nl_or_nothing << indent_str << ")";
}
void ASTSubquery::updateTreeHashImpl(SipHash & hash_state) const
void ASTSubquery::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
if (!cte_name.empty())
hash_state.update(cte_name);
IAST::updateTreeHashImpl(hash_state);
ASTWithAlias::updateTreeHashImpl(hash_state, ignore_aliases);
}
String ASTSubquery::getAliasOrColumnName() const

View File

@ -14,7 +14,7 @@ class ASTSubquery : public ASTWithAlias
public:
// Stored the name when the subquery is defined in WITH clause. For example:
// WITH (SELECT 1) AS a SELECT * FROM a AS b; cte_name will be `a`.
std::string cte_name;
String cte_name;
/** Get the text that identifies this element. */
String getID(char) const override { return "Subquery"; }
@ -26,7 +26,7 @@ public:
return clone;
}
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
String getAliasOrColumnName() const override;
String tryGetAlias() const override;

View File

@ -21,10 +21,10 @@ do \
while (false)
void ASTTableExpression::updateTreeHashImpl(SipHash & hash_state) const
void ASTTableExpression::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(final);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
@ -42,12 +42,12 @@ ASTPtr ASTTableExpression::clone() const
return res;
}
void ASTTableJoin::updateTreeHashImpl(SipHash & hash_state) const
void ASTTableJoin::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(locality);
hash_state.update(strictness);
hash_state.update(kind);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
ASTPtr ASTTableJoin::clone() const
@ -61,10 +61,10 @@ ASTPtr ASTTableJoin::clone() const
return res;
}
void ASTArrayJoin::updateTreeHashImpl(SipHash & hash_state) const
void ASTArrayJoin::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(kind);
IAST::updateTreeHashImpl(hash_state);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
ASTPtr ASTArrayJoin::clone() const

View File

@ -59,7 +59,7 @@ struct ASTTableExpression : public IAST
String getID(char) const override { return "TableExpression"; }
ASTPtr clone() const override;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
};
@ -81,7 +81,7 @@ struct ASTTableJoin : public IAST
void formatImplBeforeTable(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const;
void formatImplAfterTable(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
};
/// Specification of ARRAY JOIN.
@ -102,7 +102,7 @@ struct ASTArrayJoin : public IAST
String getID(char) const override { return "ArrayJoin"; }
ASTPtr clone() const override;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
};

View File

@ -39,7 +39,7 @@ IAST::QueryKind ASTTransactionControl::getQueryKind() const
}
}
void ASTTransactionControl::updateTreeHashImpl(SipHash & hash_state) const
void ASTTransactionControl::updateTreeHashImpl(SipHash & hash_state, bool /*ignore_aliases*/) const
{
hash_state.update(action);
}

View File

@ -20,13 +20,13 @@ public:
UInt64 snapshot; /// For SET TRANSACTION SNAPSHOT ...
ASTTransactionControl(QueryType action_) : action(action_) {}
explicit ASTTransactionControl(QueryType action_) : action(action_) {}
String getID(char /*delimiter*/) const override { return "ASTTransactionControl"; }
ASTPtr clone() const override { return std::make_shared<ASTTransactionControl>(*this); }
void formatImpl(const FormatSettings & format, FormatState & /*state*/, FormatStateStacked /*frame*/) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
QueryKind getQueryKind() const override;
};

View File

@ -1,3 +1,4 @@
#include <Common/SipHash.h>
#include <Parsers/ASTWithAlias.h>
#include <IO/WriteHelpers.h>
#include <IO/Operators.h>
@ -42,6 +43,13 @@ void ASTWithAlias::formatImpl(const FormatSettings & settings, FormatState & sta
}
}
void ASTWithAlias::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
if (!alias.empty() && !ignore_aliases)
hash_state.update(alias);
IAST::updateTreeHashImpl(hash_state, ignore_aliases);
}
void ASTWithAlias::appendColumnName(WriteBuffer & ostr) const
{
if (prefer_alias_to_column_name && !alias.empty())

View File

@ -27,7 +27,9 @@ public:
void setAlias(const String & to) override { alias = to; }
/// Calls formatImplWithoutAlias, and also outputs an alias. If necessary, encloses the entire expression in brackets.
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override final;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const final;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
virtual void formatImplWithoutAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const = 0;

View File

@ -114,24 +114,24 @@ size_t IAST::checkSize(size_t max_size) const
}
IAST::Hash IAST::getTreeHash() const
IAST::Hash IAST::getTreeHash(bool ignore_aliases) const
{
SipHash hash_state;
updateTreeHash(hash_state);
updateTreeHash(hash_state, ignore_aliases);
return getSipHash128AsPair(hash_state);
}
void IAST::updateTreeHash(SipHash & hash_state) const
void IAST::updateTreeHash(SipHash & hash_state, bool ignore_aliases) const
{
updateTreeHashImpl(hash_state);
updateTreeHashImpl(hash_state, ignore_aliases);
hash_state.update(children.size());
for (const auto & child : children)
child->updateTreeHash(hash_state);
child->updateTreeHash(hash_state, ignore_aliases);
}
void IAST::updateTreeHashImpl(SipHash & hash_state) const
void IAST::updateTreeHashImpl(SipHash & hash_state, bool /*ignore_aliases*/) const
{
auto id = getID();
hash_state.update(id.data(), id.size());

View File

@ -78,11 +78,13 @@ public:
virtual ASTPtr clone() const = 0;
/** Get hash code, identifying this element and its subtree.
* Hashing by default ignores aliases (e.g. identifier aliases, function aliases, literal aliases) which is
* useful for common subexpression elimination. Set 'ignore_aliases = false' if you don't want that behavior.
*/
using Hash = CityHash_v1_0_2::uint128;
Hash getTreeHash() const;
void updateTreeHash(SipHash & hash_state) const;
virtual void updateTreeHashImpl(SipHash & hash_state) const;
Hash getTreeHash(bool ignore_aliases = true) const;
void updateTreeHash(SipHash & hash_state, bool ignore_aliases = true) const;
virtual void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const;
void dumpTree(WriteBuffer & ostr, size_t indent = 0) const;
std::string dumpTree(size_t indent = 0) const;

View File

@ -0,0 +1,24 @@
-- Bug 56258: Check literals (ASTLiteral)
Row 1:
──────
10: 10
Row 1:
──────
x: 10
2
-- Bug 56258: Check functions (ASTFunction)
Row 1:
──────
toUInt64(42): 42
Row 1:
──────
x: 42
2
-- Bug 56258: Check identifiers (ASTIdentifier)
Row 1:
──────
c: 1
Row 1:
──────
x: 1
2

View File

@ -0,0 +1,39 @@
-- Tags: no-parallel
-- Tag no-parallel: Messes with internal cache
-- Test for Bug 56258
SYSTEM DROP QUERY CACHE;
SELECT '-- Bug 56258: Check literals (ASTLiteral)';
SELECT 10 FORMAT Vertical SETTINGS use_query_cache = 1;
SELECT 10 AS x FORMAT Vertical SETTINGS use_query_cache = 1;
SELECT count(*) FROM system.query_cache;
SYSTEM DROP QUERY CACHE;
SELECT '-- Bug 56258: Check functions (ASTFunction)';
SELECT toUInt64(42) FORMAT Vertical SETTINGS use_query_cache = 1;
SELECT toUInt64(42) AS x FORMAT Vertical SETTINGS use_query_cache = 1;
SELECT count(*) FROM system.query_cache;
SYSTEM DROP QUERY CACHE;
SELECT '-- Bug 56258: Check identifiers (ASTIdentifier)';
DROP TABLE IF EXISTS tab;
CREATE TABLE tab(c UInt64) ENGINE = Memory AS SELECT 1;
SELECT c FROM tab FORMAT Vertical SETTINGS use_query_cache = 1;
SELECT c AS x FROM tab FORMAT Vertical SETTINGS use_query_cache = 1;
SELECT count(*) FROM system.query_cache;
DROP TABLE tab;
SYSTEM DROP QUERY CACHE;

View File

@ -0,0 +1,4 @@
\N
\N
A
A

View File

@ -0,0 +1,4 @@
SELECT CAST(materialize(CAST(NULL, 'Nullable(Enum(\'A\' = 1, \'B\' = 2))')), 'Nullable(String)');
SELECT CAST(CAST(NULL, 'Nullable(Enum(\'A\' = 1, \'B\' = 2))'), 'Nullable(String)');
SELECT CAST(materialize(CAST(1, 'Nullable(Enum(\'A\' = 1, \'B\' = 2))')), 'Nullable(String)');
SELECT CAST(CAST(1, 'Nullable(Enum(\'A\' = 1, \'B\' = 2))'), 'Nullable(String)');