mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
global join: fix wrong name qualification (save replaced table name as alias)
This commit is contained in:
parent
f40ab95739
commit
ee6c83a2f7
@ -46,48 +46,36 @@ public:
|
|||||||
has_global_subqueries(has_global_subqueries_)
|
has_global_subqueries(has_global_subqueries_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void addExternalStorage(ASTPtr & subquery_or_table_name_or_table_expression)
|
void addExternalStorage(ASTPtr & ast, bool set_alias = false)
|
||||||
{
|
{
|
||||||
/// With nondistributed queries, creating temporary tables does not make sense.
|
/// With nondistributed queries, creating temporary tables does not make sense.
|
||||||
if (!is_remote)
|
if (!is_remote)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ASTPtr subquery;
|
bool is_table = false;
|
||||||
ASTPtr table_name;
|
ASTPtr subquery_or_table_name = ast; /// ASTIdentifier | ASTSubquery | ASTTableExpression
|
||||||
ASTPtr subquery_or_table_name;
|
|
||||||
|
|
||||||
if (subquery_or_table_name_or_table_expression->as<ASTIdentifier>())
|
if (const auto * ast_table_expr = ast->as<ASTTableExpression>())
|
||||||
{
|
|
||||||
table_name = subquery_or_table_name_or_table_expression;
|
|
||||||
subquery_or_table_name = table_name;
|
|
||||||
}
|
|
||||||
else if (const auto * ast_table_expr = subquery_or_table_name_or_table_expression->as<ASTTableExpression>())
|
|
||||||
{
|
{
|
||||||
|
subquery_or_table_name = ast_table_expr->subquery;
|
||||||
|
|
||||||
if (ast_table_expr->database_and_table_name)
|
if (ast_table_expr->database_and_table_name)
|
||||||
{
|
{
|
||||||
table_name = ast_table_expr->database_and_table_name;
|
subquery_or_table_name = ast_table_expr->database_and_table_name;
|
||||||
subquery_or_table_name = table_name;
|
is_table = true;
|
||||||
}
|
|
||||||
else if (ast_table_expr->subquery)
|
|
||||||
{
|
|
||||||
subquery = ast_table_expr->subquery;
|
|
||||||
subquery_or_table_name = subquery;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (subquery_or_table_name_or_table_expression->as<ASTSubquery>())
|
else if (ast->as<ASTIdentifier>())
|
||||||
{
|
is_table = true;
|
||||||
subquery = subquery_or_table_name_or_table_expression;
|
|
||||||
subquery_or_table_name = subquery;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!subquery_or_table_name)
|
if (!subquery_or_table_name)
|
||||||
throw Exception("Logical error: unknown AST element passed to ExpressionAnalyzer::addExternalStorage method",
|
throw Exception("Logical error: unknown AST element passed to ExpressionAnalyzer::addExternalStorage method",
|
||||||
ErrorCodes::LOGICAL_ERROR);
|
ErrorCodes::LOGICAL_ERROR);
|
||||||
|
|
||||||
if (table_name)
|
if (is_table)
|
||||||
{
|
{
|
||||||
/// If this is already an external table, you do not need to add anything. Just remember its presence.
|
/// If this is already an external table, you do not need to add anything. Just remember its presence.
|
||||||
if (external_tables.end() != external_tables.find(*getIdentifierName(table_name)))
|
if (external_tables.end() != external_tables.find(*getIdentifierName(subquery_or_table_name)))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +102,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
auto database_and_table_name = createTableIdentifier("", external_table_name);
|
auto database_and_table_name = createTableIdentifier("", external_table_name);
|
||||||
|
if (set_alias)
|
||||||
|
{
|
||||||
|
String alias = subquery_or_table_name->tryGetAlias();
|
||||||
|
if (auto * table_name = subquery_or_table_name->as<ASTIdentifier>())
|
||||||
|
if (alias.empty())
|
||||||
|
alias = table_name->shortName();
|
||||||
|
database_and_table_name->setAlias(alias);
|
||||||
|
}
|
||||||
|
|
||||||
if (auto * ast_table_expr = subquery_or_table_name_or_table_expression->as<ASTTableExpression>())
|
if (auto * ast_table_expr = ast->as<ASTTableExpression>())
|
||||||
{
|
{
|
||||||
ast_table_expr->subquery.reset();
|
ast_table_expr->subquery.reset();
|
||||||
ast_table_expr->database_and_table_name = database_and_table_name;
|
ast_table_expr->database_and_table_name = database_and_table_name;
|
||||||
@ -124,7 +120,7 @@ public:
|
|||||||
ast_table_expr->children.emplace_back(database_and_table_name);
|
ast_table_expr->children.emplace_back(database_and_table_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
subquery_or_table_name_or_table_expression = database_and_table_name;
|
ast = database_and_table_name;
|
||||||
|
|
||||||
external_tables[external_table_name] = external_storage;
|
external_tables[external_table_name] = external_storage;
|
||||||
subqueries_for_sets[external_table_name].source = interpreter->execute().in;
|
subqueries_for_sets[external_table_name].source = interpreter->execute().in;
|
||||||
@ -170,7 +166,7 @@ private:
|
|||||||
{
|
{
|
||||||
if (table_elem.table_join && table_elem.table_join->as<ASTTableJoin &>().locality == ASTTableJoin::Locality::Global)
|
if (table_elem.table_join && table_elem.table_join->as<ASTTableJoin &>().locality == ASTTableJoin::Locality::Global)
|
||||||
{
|
{
|
||||||
data.addExternalStorage(table_elem.table_expression);
|
data.addExternalStorage(table_elem.table_expression, true);
|
||||||
data.has_global_subqueries = true;
|
data.has_global_subqueries = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
One Hundred
|
||||||
|
Two Hundred
|
||||||
|
One Hundred
|
||||||
|
Two Hundred
|
||||||
|
One Hundred
|
||||||
|
Two Hundred
|
||||||
|
One Hundred
|
||||||
|
Two Hundred
|
||||||
|
One Hundred
|
||||||
|
Two Hundred
|
||||||
|
One Hundred
|
||||||
|
Two Hundred
|
@ -0,0 +1,59 @@
|
|||||||
|
USE test;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS local_table;
|
||||||
|
DROP TABLE IF EXISTS other_table;
|
||||||
|
|
||||||
|
CREATE TABLE local_table
|
||||||
|
(
|
||||||
|
id Int32,
|
||||||
|
name String,
|
||||||
|
ts DateTime,
|
||||||
|
oth_id Int32
|
||||||
|
) ENGINE = MergeTree() PARTITION BY toMonday(ts) ORDER BY (ts, id);
|
||||||
|
|
||||||
|
CREATE TABLE other_table
|
||||||
|
(
|
||||||
|
id Int32,
|
||||||
|
name String,
|
||||||
|
ts DateTime,
|
||||||
|
trd_id Int32
|
||||||
|
) ENGINE = MergeTree() PARTITION BY toMonday(ts) ORDER BY (ts, id);
|
||||||
|
|
||||||
|
INSERT INTO local_table VALUES(1, 'One', now(), 100);
|
||||||
|
INSERT INTO local_table VALUES(2, 'Two', now(), 200);
|
||||||
|
INSERT INTO other_table VALUES(100, 'One Hundred', now(), 1000);
|
||||||
|
INSERT INTO other_table VALUES(200, 'Two Hundred', now(), 2000);
|
||||||
|
|
||||||
|
-- FIXME: test.other_table -> other_table in first query breaks test (external tables cache error)
|
||||||
|
select t2.name from remote('127.0.0.2', 'test.local_table') as t1
|
||||||
|
left join test.other_table as t2
|
||||||
|
on t1.oth_id = t2.id
|
||||||
|
order by t2.name;
|
||||||
|
|
||||||
|
select t2.name from test.other_table as t2
|
||||||
|
global right join remote('127.0.0.2', 'test.local_table') as t1
|
||||||
|
on t1.oth_id = t2.id
|
||||||
|
order by t2.name;
|
||||||
|
|
||||||
|
select t2.name from remote('127.0.0.2', 'test.local_table') as t1
|
||||||
|
global left join other_table as t2
|
||||||
|
on t1.oth_id = t2.id
|
||||||
|
order by t2.name;
|
||||||
|
|
||||||
|
select t2.name from remote('127.0.0.2', 'test.local_table') as t1
|
||||||
|
global left join other_table as t2
|
||||||
|
on t1.oth_id = t2.id
|
||||||
|
order by t2.name;
|
||||||
|
|
||||||
|
select other_table.name from remote('127.0.0.2', 'test.local_table') as t1
|
||||||
|
global left join other_table
|
||||||
|
on t1.oth_id = other_table.id
|
||||||
|
order by other_table.name;
|
||||||
|
|
||||||
|
select other_table.name from remote('127.0.0.2', 'test.local_table') as t1
|
||||||
|
global left join other_table as t2
|
||||||
|
on t1.oth_id = other_table.id
|
||||||
|
order by other_table.name;
|
||||||
|
|
||||||
|
DROP TABLE local_table;
|
||||||
|
DROP TABLE other_table;
|
Loading…
Reference in New Issue
Block a user