diff --git a/contrib/grpc b/contrib/grpc index 267af8c3a1ea..b723ecae0991 160000 --- a/contrib/grpc +++ b/contrib/grpc @@ -1 +1 @@ -Subproject commit 267af8c3a1ea4a5a4d9e5a070ad2d1ac7c701923 +Subproject commit b723ecae0991bb873fe87a595dfb187178733fde diff --git a/contrib/sparse-checkout/update-grpc.sh b/contrib/sparse-checkout/update-grpc.sh index 4571bd6307d5..21628ce8dd1c 100755 --- a/contrib/sparse-checkout/update-grpc.sh +++ b/contrib/sparse-checkout/update-grpc.sh @@ -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 diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index b0a262ff36b0..e3ec7ebd3201 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -4159,6 +4159,61 @@ arguments, result_type, input_rows_count); \ }; } + template + 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(first_col); + const EnumType * enum_type = typeid_cast(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(); + return true; + } + else if (from_type->getCustomSerialization()) { ret = [](ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, const ColumnNullable *, size_t input_rows_count) -> ColumnPtr { diff --git a/src/Interpreters/Cache/QueryCache.cpp b/src/Interpreters/Cache/QueryCache.cpp index 33cb124f3bcb..e8b52bbc6a0c 100644 --- a/src/Interpreters/Cache/QueryCache.cpp +++ b/src/Interpreters/Cache/QueryCache.cpp @@ -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 diff --git a/src/Parsers/ASTColumnsMatcher.cpp b/src/Parsers/ASTColumnsMatcher.cpp index aff7d9fa8336..30b172ecbb81 100644 --- a/src/Parsers/ASTColumnsMatcher.cpp +++ b/src/Parsers/ASTColumnsMatcher.cpp @@ -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 & 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 diff --git a/src/Parsers/ASTColumnsMatcher.h b/src/Parsers/ASTColumnsMatcher.h index f31a8bd9a22a..6fc5581a4ebe 100644 --- a/src/Parsers/ASTColumnsMatcher.h +++ b/src/Parsers/ASTColumnsMatcher.h @@ -27,7 +27,7 @@ class ASTColumnsRegexpMatcher : public IAST const String & getPattern() const; const std::shared_ptr & 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 @@ class ASTQualifiedColumnsRegexpMatcher : public IAST const std::shared_ptr & getMatcher() const; void setPattern(String pattern, bool set_matcher = true); void setMatcher(std::shared_ptr matcher); - void updateTreeHashImpl(SipHash & hash_state) const override; + void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override; ASTPtr qualifier; ASTPtr transformers; diff --git a/src/Parsers/ASTColumnsTransformers.cpp b/src/Parsers/ASTColumnsTransformers.cpp index 27d56dec283c..6976683678ef 100644 --- a/src/Parsers/ASTColumnsTransformers.cpp +++ b/src/Parsers/ASTColumnsTransformers.cpp @@ -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) diff --git a/src/Parsers/ASTColumnsTransformers.h b/src/Parsers/ASTColumnsTransformers.h index e42949ebfd8a..a2a138e13c9b 100644 --- a/src/Parsers/ASTColumnsTransformers.h +++ b/src/Parsers/ASTColumnsTransformers.h @@ -48,7 +48,7 @@ class ASTColumnsApplyTransformer : public IASTColumnsTransformer } 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 @@ class ASTColumnsExceptTransformer : public IASTColumnsTransformer const std::shared_ptr & 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 @@ class ASTColumnsReplaceTransformer : public IASTColumnsTransformer } 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 @@ class ASTColumnsReplaceTransformer : public IASTColumnsTransformer } 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; diff --git a/src/Parsers/ASTFunction.cpp b/src/Parsers/ASTFunction.cpp index 267148ee62b5..80d9f2fb4a53 100644 --- a/src/Parsers/ASTFunction.cpp +++ b/src/Parsers/ASTFunction.cpp @@ -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 diff --git a/src/Parsers/ASTFunction.h b/src/Parsers/ASTFunction.h index 4a036c5e94af..fe30b7c6e95b 100644 --- a/src/Parsers/ASTFunction.h +++ b/src/Parsers/ASTFunction.h @@ -63,7 +63,7 @@ class ASTFunction : public ASTWithAlias ASTPtr clone() const override; - void updateTreeHashImpl(SipHash & hash_state) const override; + void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override; ASTSelectWithUnionQuery * tryGetQueryArgument() const; diff --git a/src/Parsers/ASTFunctionWithKeyValueArguments.cpp b/src/Parsers/ASTFunctionWithKeyValueArguments.cpp index 2c28e3426105..a5467bef3631 100644 --- a/src/Parsers/ASTFunctionWithKeyValueArguments.cpp +++ b/src/Parsers/ASTFunctionWithKeyValueArguments.cpp @@ -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); } } diff --git a/src/Parsers/ASTFunctionWithKeyValueArguments.h b/src/Parsers/ASTFunctionWithKeyValueArguments.h index 75a8ae0415ea..ec2a793154fa 100644 --- a/src/Parsers/ASTFunctionWithKeyValueArguments.h +++ b/src/Parsers/ASTFunctionWithKeyValueArguments.h @@ -32,7 +32,7 @@ class ASTPair : public IAST 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 f) override { @@ -66,7 +66,7 @@ class ASTFunctionWithKeyValueArguments : public IAST 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; }; } diff --git a/src/Parsers/ASTIdentifier.cpp b/src/Parsers/ASTIdentifier.cpp index 042b4d9085d1..80a618170c6d 100644 --- a/src/Parsers/ASTIdentifier.cpp +++ b/src/Parsers/ASTIdentifier.cpp @@ -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) diff --git a/src/Parsers/ASTIdentifier.h b/src/Parsers/ASTIdentifier.h index 0e030c797ceb..d986b9170f3c 100644 --- a/src/Parsers/ASTIdentifier.h +++ b/src/Parsers/ASTIdentifier.h @@ -47,6 +47,8 @@ class ASTIdentifier : public ASTWithAlias 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 createTable() const; // returns |nullptr| if identifier is not table. @@ -91,7 +93,7 @@ class ASTTableIdentifier : public ASTIdentifier // 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; }; } diff --git a/src/Parsers/ASTInsertQuery.cpp b/src/Parsers/ASTInsertQuery.cpp index ecb2d4e331bc..88e087dd4eeb 100644 --- a/src/Parsers/ASTInsertQuery.cpp +++ b/src/Parsers/ASTInsertQuery.cpp @@ -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); } diff --git a/src/Parsers/ASTInsertQuery.h b/src/Parsers/ASTInsertQuery.h index 45fd3d979507..6a4ce078f79a 100644 --- a/src/Parsers/ASTInsertQuery.h +++ b/src/Parsers/ASTInsertQuery.h @@ -72,7 +72,7 @@ class ASTInsertQuery : public IAST 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; }; } diff --git a/src/Parsers/ASTLiteral.cpp b/src/Parsers/ASTLiteral.cpp index 425e5c73bee6..8dedc5dc95d2 100644 --- a/src/Parsers/ASTLiteral.cpp +++ b/src/Parsers/ASTLiteral.cpp @@ -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 diff --git a/src/Parsers/ASTLiteral.h b/src/Parsers/ASTLiteral.h index e57bcfcd9d5a..0c55aceb0682 100644 --- a/src/Parsers/ASTLiteral.h +++ b/src/Parsers/ASTLiteral.h @@ -41,7 +41,7 @@ class ASTLiteral : public ASTWithAlias 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; diff --git a/src/Parsers/ASTOrderByElement.cpp b/src/Parsers/ASTOrderByElement.cpp index 884d69a18e34..318849812aa5 100644 --- a/src/Parsers/ASTOrderByElement.cpp +++ b/src/Parsers/ASTOrderByElement.cpp @@ -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 diff --git a/src/Parsers/ASTOrderByElement.h b/src/Parsers/ASTOrderByElement.h index 468d2161dff5..4cebc30be31b 100644 --- a/src/Parsers/ASTOrderByElement.h +++ b/src/Parsers/ASTOrderByElement.h @@ -32,7 +32,7 @@ class ASTOrderByElement : public IAST 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; diff --git a/src/Parsers/ASTQueryParameter.cpp b/src/Parsers/ASTQueryParameter.cpp index c10cced23ce6..9e98252e779d 100644 --- a/src/Parsers/ASTQueryParameter.cpp +++ b/src/Parsers/ASTQueryParameter.cpp @@ -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); +} + } diff --git a/src/Parsers/ASTQueryParameter.h b/src/Parsers/ASTQueryParameter.h index 858b23a0250e..dd7f9bff863a 100644 --- a/src/Parsers/ASTQueryParameter.h +++ b/src/Parsers/ASTQueryParameter.h @@ -21,6 +21,8 @@ class ASTQueryParameter : public ASTWithAlias ASTPtr clone() const override { return std::make_shared(*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; diff --git a/src/Parsers/ASTSelectQuery.cpp b/src/Parsers/ASTSelectQuery.cpp index 2d82708c70df..7c96db006c4f 100644 --- a/src/Parsers/ASTSelectQuery.cpp +++ b/src/Parsers/ASTSelectQuery.cpp @@ -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); } diff --git a/src/Parsers/ASTSelectQuery.h b/src/Parsers/ASTSelectQuery.h index 101dbe9d02c5..57f45a8aacd9 100644 --- a/src/Parsers/ASTSelectQuery.h +++ b/src/Parsers/ASTSelectQuery.h @@ -137,7 +137,7 @@ class ASTSelectQuery : public IAST 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(); diff --git a/src/Parsers/ASTSetQuery.cpp b/src/Parsers/ASTSetQuery.cpp index 1b7b76fe2310..e2c60e8369d5 100644 --- a/src/Parsers/ASTSetQuery.cpp +++ b/src/Parsers/ASTSetQuery.cpp @@ -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) { diff --git a/src/Parsers/ASTSetQuery.h b/src/Parsers/ASTSetQuery.h index beed052c79a9..944f08dcbaa0 100644 --- a/src/Parsers/ASTSetQuery.h +++ b/src/Parsers/ASTSetQuery.h @@ -34,7 +34,7 @@ class ASTSetQuery : public IAST 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; } diff --git a/src/Parsers/ASTSubquery.cpp b/src/Parsers/ASTSubquery.cpp index 92adad666ed5..75dfccd6e139 100644 --- a/src/Parsers/ASTSubquery.cpp +++ b/src/Parsers/ASTSubquery.cpp @@ -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 diff --git a/src/Parsers/ASTSubquery.h b/src/Parsers/ASTSubquery.h index e4de766621a0..ef277a631260 100644 --- a/src/Parsers/ASTSubquery.h +++ b/src/Parsers/ASTSubquery.h @@ -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 @@ class ASTSubquery : public ASTWithAlias 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; diff --git a/src/Parsers/ASTTablesInSelectQuery.cpp b/src/Parsers/ASTTablesInSelectQuery.cpp index 75c0ef26c07e..e4e8c00879ee 100644 --- a/src/Parsers/ASTTablesInSelectQuery.cpp +++ b/src/Parsers/ASTTablesInSelectQuery.cpp @@ -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 diff --git a/src/Parsers/ASTTablesInSelectQuery.h b/src/Parsers/ASTTablesInSelectQuery.h index a004cbf9847a..67370eaee146 100644 --- a/src/Parsers/ASTTablesInSelectQuery.h +++ b/src/Parsers/ASTTablesInSelectQuery.h @@ -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; }; diff --git a/src/Parsers/ASTTransactionControl.cpp b/src/Parsers/ASTTransactionControl.cpp index 3106d432c909..6964441622d5 100644 --- a/src/Parsers/ASTTransactionControl.cpp +++ b/src/Parsers/ASTTransactionControl.cpp @@ -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); } diff --git a/src/Parsers/ASTTransactionControl.h b/src/Parsers/ASTTransactionControl.h index fb0058144dd9..84a1dcf09702 100644 --- a/src/Parsers/ASTTransactionControl.h +++ b/src/Parsers/ASTTransactionControl.h @@ -20,13 +20,13 @@ class ASTTransactionControl : public IAST 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(*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; }; diff --git a/src/Parsers/ASTWithAlias.cpp b/src/Parsers/ASTWithAlias.cpp index 1b5397654fd8..5d1122ae4d80 100644 --- a/src/Parsers/ASTWithAlias.cpp +++ b/src/Parsers/ASTWithAlias.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -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()) diff --git a/src/Parsers/ASTWithAlias.h b/src/Parsers/ASTWithAlias.h index ea4419402b0b..452e2038e55e 100644 --- a/src/Parsers/ASTWithAlias.h +++ b/src/Parsers/ASTWithAlias.h @@ -27,7 +27,9 @@ class ASTWithAlias : public IAST 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; diff --git a/src/Parsers/IAST.cpp b/src/Parsers/IAST.cpp index a494a528cd2f..37d7f458d613 100644 --- a/src/Parsers/IAST.cpp +++ b/src/Parsers/IAST.cpp @@ -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()); diff --git a/src/Parsers/IAST.h b/src/Parsers/IAST.h index 812fd082476d..9afd59caa05e 100644 --- a/src/Parsers/IAST.h +++ b/src/Parsers/IAST.h @@ -78,11 +78,13 @@ class IAST : public std::enable_shared_from_this, public TypePromotion