Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crop column names in GLOBAL JOIN ON #6181

Merged
merged 1 commit into from
Jul 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,14 @@ void TranslateQualifiedNamesMatcher::extractJoinUsingColumns(const ASTPtr ast, D
}
}

void RestoreQualifiedNamesData::visit(ASTIdentifier & identifier, ASTPtr & ast)
{
if (IdentifierSemantic::getColumnName(identifier) &&
IdentifierSemantic::getMembership(identifier))
{
ast = identifier.clone();
ast->as<ASTIdentifier>()->restoreCompoundName();
}
}

}
11 changes: 11 additions & 0 deletions dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,15 @@ class TranslateQualifiedNamesMatcher
/// It finds columns and translate their names to the normal form. Expand asterisks and qualified asterisks with column names.
using TranslateQualifiedNamesVisitor = TranslateQualifiedNamesMatcher::Visitor;

/// Restore ASTIdentifiers to long form
struct RestoreQualifiedNamesData
{
using TypeToVisit = ASTIdentifier;

void visit(ASTIdentifier & identifier, ASTPtr & ast);
};

using RestoreQualifiedNamesMatcher = OneTypeMatcher<RestoreQualifiedNamesData>;
using RestoreQualifiedNamesVisitor = InDepthNodeVisitor<RestoreQualifiedNamesMatcher, true>;

}
9 changes: 9 additions & 0 deletions dbms/src/Parsers/ASTIdentifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ void ASTIdentifier::setShortName(const String & new_name)
semantic->special = special;
}

void ASTIdentifier::restoreCompoundName()
{
if (name_parts.empty())
return;
name = name_parts[0];
for (size_t i = 1; i < name_parts.size(); ++i)
name += '.' + name_parts[i];
}

void ASTIdentifier::formatImplWithoutAlias(const FormatSettings & settings, FormatState &, FormatStateStacked) const
{
auto format_element = [&](const String & elem_name)
Expand Down
1 change: 1 addition & 0 deletions dbms/src/Parsers/ASTIdentifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class ASTIdentifier : public ASTWithAlias
bool isShort() const { return name_parts.empty() || name == name_parts.back(); }

void setShortName(const String & new_name);
void restoreCompoundName();

const String & shortName() const
{
Expand Down
15 changes: 13 additions & 2 deletions dbms/src/Storages/StorageDistributed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <Interpreters/InterpreterAlterQuery.h>
#include <Interpreters/InterpreterDescribeQuery.h>
#include <Interpreters/InterpreterSelectQuery.h>
#include <Interpreters/TranslateQualifiedNamesVisitor.h>
#include <Interpreters/SyntaxAnalyzer.h>
#include <Interpreters/createBlockSelector.h>
#include <Interpreters/evaluateConstantExpression.h>
Expand Down Expand Up @@ -78,10 +79,20 @@ namespace
ASTPtr rewriteSelectQuery(const ASTPtr & query, const std::string & database, const std::string & table, ASTPtr table_function_ptr = nullptr)
{
auto modified_query_ast = query->clone();

ASTSelectQuery & select_query = modified_query_ast->as<ASTSelectQuery &>();

/// restore long column names in JOIN ON expressions
if (auto tables = select_query.tables())
{
RestoreQualifiedNamesVisitor::Data data;
RestoreQualifiedNamesVisitor(data).visit(tables);
}

if (table_function_ptr)
modified_query_ast->as<ASTSelectQuery &>().addTableFunction(table_function_ptr);
select_query.addTableFunction(table_function_ptr);
else
modified_query_ast->as<ASTSelectQuery &>().replaceDatabaseAndTable(database, table);
select_query.replaceDatabaseAndTable(database, table);
return modified_query_ast;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
1
1
1
1
1
1
42 42
42 42
34 changes: 34 additions & 0 deletions dbms/tests/queries/0_stateless/00974_distributed_join_on.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
DROP TABLE IF EXISTS source_table1;
DROP TABLE IF EXISTS source_table2;
DROP TABLE IF EXISTS distributed_table1;
DROP TABLE IF EXISTS distributed_table2;

CREATE TABLE source_table1 (a Int64, b String) ENGINE = Memory;
CREATE TABLE source_table2 (c Int64, d String) ENGINE = Memory;

INSERT INTO source_table1 VALUES (42, 'qwe');
INSERT INTO source_table2 VALUES (42, 'qwe');

CREATE TABLE distributed_table1 AS source_table1
ENGINE = Distributed('test_shard_localhost', currentDatabase(), source_table1);

CREATE TABLE distributed_table2 AS source_table2
ENGINE = Distributed('test_shard_localhost', currentDatabase(), source_table2);

SET prefer_localhost_replica = 1;
SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table2 AS t2 ON t1.a = t2.c LIMIT 1;
SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table2 AS t2 ON t2.c = t1.a LIMIT 1;
SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table1 AS t2 ON t1.a = t2.a LIMIT 1;

SET prefer_localhost_replica = 0;
SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table2 AS t2 ON t1.a = t2.c LIMIT 1;
SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table2 AS t2 ON t2.c = t1.a LIMIT 1;
SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table1 AS t2 ON t1.a = t2.a LIMIT 1;

SELECT t1.a as t1_a, t2.a as t2_a FROM source_table1 AS t1 JOIN source_table1 AS t2 ON t1_a = t2_a LIMIT 1;
SELECT t1.a as t1_a, t2.a as t2_a FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table1 AS t2 ON t1_a = t2_a LIMIT 1;

DROP TABLE source_table1;
DROP TABLE source_table2;
DROP TABLE distributed_table1;
DROP TABLE distributed_table2;