From 6f7c057753777825f236947172fa7fcbe3a40f1f Mon Sep 17 00:00:00 2001 From: zanmato1984 Date: Thu, 29 Aug 2019 14:36:20 +0800 Subject: [PATCH 1/3] Let qualified column reference not resolve to alias, partial based on ClickHouse #4351 --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 4 +++- dbms/src/Parsers/ASTIdentifier.h | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 02faff83e91..962cc0fb8eb 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -342,6 +342,7 @@ void ExpressionAnalyzer::translateQualifiedNamesImpl(ASTPtr & ast, const String { String node_alias = ast->tryGetAlias(); ast = ast->children.back(); + static_cast(*ast.get()).can_be_alias = false; if (!node_alias.empty()) ast->setAlias(node_alias); } @@ -356,6 +357,7 @@ void ExpressionAnalyzer::translateQualifiedNamesImpl(ASTPtr & ast, const String new_name += '.'; new_name += static_cast(*child.get()).name; } + ident->can_be_alias = false; ident->name = new_name; } } @@ -1011,7 +1013,7 @@ void ExpressionAnalyzer::normalizeTreeImpl( { /// If it is an alias, but not a parent alias (for constructs like "SELECT column + 1 AS column"). auto it_alias = aliases.find(identifier_node->name); - if (it_alias != aliases.end() && current_alias != identifier_node->name) + if (it_alias != aliases.end() && current_alias != identifier_node->name && identifier_node->can_be_alias) { /// Let's replace it with the corresponding tree node. if (current_asts.count(it_alias->second.get())) diff --git a/dbms/src/Parsers/ASTIdentifier.h b/dbms/src/Parsers/ASTIdentifier.h index 017e33af500..0ab607dfa09 100644 --- a/dbms/src/Parsers/ASTIdentifier.h +++ b/dbms/src/Parsers/ASTIdentifier.h @@ -25,8 +25,11 @@ class ASTIdentifier : public ASTWithAlias /// what this identifier identifies Kind kind; + /// if it's a cropped name it could not be an alias + bool can_be_alias; + ASTIdentifier(const String & name_, const Kind kind_ = Column) - : name(name_), kind(kind_) {} + : name(name_), kind(kind_), can_be_alias(true) {} /** Get the text that identifies this element. */ String getID() const override { return "Identifier_" + name; } From 8b7dfceb3b2cf5ceba049386c1a309dcf88f30bc Mon Sep 17 00:00:00 2001 From: zanmato1984 Date: Thu, 29 Aug 2019 14:44:57 +0800 Subject: [PATCH 2/3] Add alias test --- tests/mutable-test/bugs/flash-451.test | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/mutable-test/bugs/flash-451.test diff --git a/tests/mutable-test/bugs/flash-451.test b/tests/mutable-test/bugs/flash-451.test new file mode 100644 index 00000000000..30640376ceb --- /dev/null +++ b/tests/mutable-test/bugs/flash-451.test @@ -0,0 +1,17 @@ +>> DBGInvoke __enable_schema_sync_service('false') + +# Unqualified identifiers resolve to alias in select list. +>> select 0 as c, c + 1 as c1 from (select 1 as c) as t where c = 1; + +# Qualified identifiers resolve to column in table. +>> select 0 as c, t.c + 1 as c1 from (select 1 as c) as t where t.c = 1; +┌─c─┬─c1─┐ +│ 0 │ 2 │ +└───┴────┘ + +# Combine the above two. +>> select 0 as c, c + 1 as c1 from (select 1 as c) as t where t.c = 1; +┌─c─┬─c1─┐ +│ 0 │ 1 │ +└───┴────┘ + From cf86a43e37152140de4f3f97ebed2ff0dbda58d6 Mon Sep 17 00:00:00 2001 From: zanmato1984 Date: Thu, 29 Aug 2019 18:28:51 +0800 Subject: [PATCH 3/3] Address comments --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 962cc0fb8eb..63d2ceb557b 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -1009,11 +1009,11 @@ void ExpressionAnalyzer::normalizeTreeImpl( } else if ((identifier_node = typeid_cast(ast.get()))) { - if (identifier_node->kind == ASTIdentifier::Column) + if (identifier_node->kind == ASTIdentifier::Column && identifier_node->can_be_alias) { /// If it is an alias, but not a parent alias (for constructs like "SELECT column + 1 AS column"). auto it_alias = aliases.find(identifier_node->name); - if (it_alias != aliases.end() && current_alias != identifier_node->name && identifier_node->can_be_alias) + if (it_alias != aliases.end() && current_alias != identifier_node->name) { /// Let's replace it with the corresponding tree node. if (current_asts.count(it_alias->second.get()))