diff --git a/src/Interpreters/Cache/QueryCache.cpp b/src/Interpreters/Cache/QueryCache.cpp index 603f7e2b254..2a67d7b93dd 100644 --- a/src/Interpreters/Cache/QueryCache.cpp +++ b/src/Interpreters/Cache/QueryCache.cpp @@ -147,14 +147,17 @@ QueryCache::Key::Key(ASTPtr ast_, const String & user_name_) { } +/// Hashing of ASTs must consider aliases (issue #56258) +const bool dont_ignore_aliases = false; + bool QueryCache::Key::operator==(const Key & other) const { - return ast->getTreeHash() == other.ast->getTreeHash(); + return ast->getTreeHash(dont_ignore_aliases) == other.ast->getTreeHash(dont_ignore_aliases); } size_t QueryCache::KeyHasher::operator()(const Key & key) const { - IAST::Hash hash = key.ast->getTreeHash(); + IAST::Hash hash = key.ast->getTreeHash(dont_ignore_aliases); return hash.low64; } diff --git a/src/Parsers/ASTColumnsMatcher.cpp b/src/Parsers/ASTColumnsMatcher.cpp index aff7d9fa833..30b172ecbb8 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 f31a8bd9a22..6fc5581a4eb 100644 --- a/src/Parsers/ASTColumnsMatcher.h +++ b/src/Parsers/ASTColumnsMatcher.h @@ -27,7 +27,7 @@ public: 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 @@ public: 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 27d56dec283..6976683678e 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 e42949ebfd8..a2a138e13c9 100644 --- a/src/Parsers/ASTColumnsTransformers.h +++ b/src/Parsers/ASTColumnsTransformers.h @@ -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 & 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; diff --git a/src/Parsers/ASTFunction.cpp b/src/Parsers/ASTFunction.cpp index 267148ee62b..80d9f2fb4a5 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 4a036c5e94a..fe30b7c6e95 100644 --- a/src/Parsers/ASTFunction.h +++ b/src/Parsers/ASTFunction.h @@ -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; diff --git a/src/Parsers/ASTFunctionWithKeyValueArguments.cpp b/src/Parsers/ASTFunctionWithKeyValueArguments.cpp index 2c28e342610..a5467bef363 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 75a8ae0415e..ec2a793154f 100644 --- a/src/Parsers/ASTFunctionWithKeyValueArguments.h +++ b/src/Parsers/ASTFunctionWithKeyValueArguments.h @@ -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 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; }; } diff --git a/src/Parsers/ASTIdentifier.cpp b/src/Parsers/ASTIdentifier.cpp index 042b4d9085d..80a618170c6 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 0e030c797ce..d986b9170f3 100644 --- a/src/Parsers/ASTIdentifier.h +++ b/src/Parsers/ASTIdentifier.h @@ -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 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; }; } diff --git a/src/Parsers/ASTInsertQuery.cpp b/src/Parsers/ASTInsertQuery.cpp index ecb2d4e331b..88e087dd4ee 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 45fd3d97950..6a4ce078f79 100644 --- a/src/Parsers/ASTInsertQuery.h +++ b/src/Parsers/ASTInsertQuery.h @@ -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; }; } diff --git a/src/Parsers/ASTLiteral.cpp b/src/Parsers/ASTLiteral.cpp index 425e5c73bee..d165914a71f 100644 --- a/src/Parsers/ASTLiteral.cpp +++ b/src/Parsers/ASTLiteral.cpp @@ -10,11 +10,9 @@ 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); + ASTWithAlias::updateTreeHashImpl(hash_state, ignore_aliases); } ASTPtr ASTLiteral::clone() const diff --git a/src/Parsers/ASTLiteral.h b/src/Parsers/ASTLiteral.h index e57bcfcd9d5..0c55aceb068 100644 --- a/src/Parsers/ASTLiteral.h +++ b/src/Parsers/ASTLiteral.h @@ -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; diff --git a/src/Parsers/ASTOrderByElement.cpp b/src/Parsers/ASTOrderByElement.cpp index 884d69a18e3..318849812aa 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 468d2161dff..4cebc30be31 100644 --- a/src/Parsers/ASTOrderByElement.h +++ b/src/Parsers/ASTOrderByElement.h @@ -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; diff --git a/src/Parsers/ASTQueryParameter.cpp b/src/Parsers/ASTQueryParameter.cpp index c10cced23ce..9e98252e779 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 858b23a0250..dd7f9bff863 100644 --- a/src/Parsers/ASTQueryParameter.h +++ b/src/Parsers/ASTQueryParameter.h @@ -21,6 +21,8 @@ public: 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 2d82708c70d..7c96db006c4 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 101dbe9d02c..57f45a8aacd 100644 --- a/src/Parsers/ASTSelectQuery.h +++ b/src/Parsers/ASTSelectQuery.h @@ -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(); diff --git a/src/Parsers/ASTSetQuery.cpp b/src/Parsers/ASTSetQuery.cpp index 1b7b76fe231..e2c60e8369d 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 beed052c79a..944f08dcbaa 100644 --- a/src/Parsers/ASTSetQuery.h +++ b/src/Parsers/ASTSetQuery.h @@ -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; } diff --git a/src/Parsers/ASTSubquery.cpp b/src/Parsers/ASTSubquery.cpp index 92adad666ed..75dfccd6e13 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 e4de766621a..ef277a63126 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 @@ 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; diff --git a/src/Parsers/ASTTablesInSelectQuery.cpp b/src/Parsers/ASTTablesInSelectQuery.cpp index 75c0ef26c07..e4e8c00879e 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 a004cbf9847..67370eaee14 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 3106d432c90..6964441622d 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 fb0058144dd..84a1dcf0970 100644 --- a/src/Parsers/ASTTransactionControl.h +++ b/src/Parsers/ASTTransactionControl.h @@ -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(*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 1b5397654fd..221b956255b 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 (!ignore_aliases && !alias.empty()) + 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 ea4419402b0..452e2038e55 100644 --- a/src/Parsers/ASTWithAlias.h +++ b/src/Parsers/ASTWithAlias.h @@ -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; diff --git a/src/Parsers/IAST.cpp b/src/Parsers/IAST.cpp index a494a528cd2..37d7f458d61 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 812fd082476..9afd59caa05 100644 --- a/src/Parsers/IAST.h +++ b/src/Parsers/IAST.h @@ -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; diff --git a/tests/queries/0_stateless/02494_query_cache_bugs.reference b/tests/queries/0_stateless/02494_query_cache_bugs.reference new file mode 100644 index 00000000000..448e1366ea7 --- /dev/null +++ b/tests/queries/0_stateless/02494_query_cache_bugs.reference @@ -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 diff --git a/tests/queries/0_stateless/02494_query_cache_bugs.sql b/tests/queries/0_stateless/02494_query_cache_bugs.sql new file mode 100644 index 00000000000..74496e0f77a --- /dev/null +++ b/tests/queries/0_stateless/02494_query_cache_bugs.sql @@ -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;