join + array join: fix unexpected error

This commit is contained in:
chertus 2019-04-08 15:35:26 +03:00
parent 54ae20024f
commit 58d24c0840
4 changed files with 73 additions and 11 deletions

View File

@ -222,20 +222,38 @@ bool getTables(ASTSelectQuery & select, std::vector<JoinedTable> & joined_tables
return false;
joined_tables.reserve(num_tables);
size_t num_array_join = 0;
size_t num_using = 0;
for (auto & child : tables->children)
{
joined_tables.emplace_back(JoinedTable(child));
JoinedTable & t = joined_tables.back();
if (t.array_join)
return false;
{
++num_array_join;
continue;
}
if (num_tables > 2 && t.has_using)
throw Exception("Multiple CROSS/COMMA JOIN do not support USING", ErrorCodes::NOT_IMPLEMENTED);
if (t.has_using)
{
++num_using;
continue;
}
if (auto * join = t.join)
if (join->kind == ASTTableJoin::Kind::Comma)
++num_comma;
}
if (num_using && (num_tables - num_array_join) > 2)
throw Exception("Multiple CROSS/COMMA JOIN do not support USING", ErrorCodes::NOT_IMPLEMENTED);
if (num_comma && (num_comma != (joined_tables.size() - 1)))
throw Exception("Mix of COMMA and other JOINS is not supported", ErrorCodes::NOT_IMPLEMENTED);
if (num_array_join || num_using)
return false;
return true;
}
@ -259,9 +277,6 @@ void CrossToInnerJoinMatcher::visit(ASTSelectQuery & select, ASTPtr &, Data & da
if (num_comma)
{
if (num_comma != (joined_tables.size() - 1))
throw Exception("Mix of COMMA and other JOINS is not supported", ErrorCodes::NOT_IMPLEMENTED);
for (auto & table : joined_tables)
table.rewriteCommaToCross();
}

View File

@ -316,28 +316,47 @@ bool needRewrite(ASTSelectQuery & select, std::vector<const ASTTableExpression *
if (num_tables <= 2)
return false;
size_t num_array_join = 0;
size_t num_using = 0;
table_expressions.reserve(num_tables);
for (size_t i = 0; i < num_tables; ++i)
{
const auto * table = tables->children[i]->as<ASTTablesInSelectQueryElement>();
if (table && table->table_expression)
if (!table)
throw Exception("Table expected", ErrorCodes::LOGICAL_ERROR);
if (table->table_expression)
if (const auto * expression = table->table_expression->as<ASTTableExpression>())
table_expressions.push_back(expression);
if (!i)
continue;
if (!table || !table->table_join)
throw Exception("Multiple JOIN expects joined tables", ErrorCodes::LOGICAL_ERROR);
if (!table->table_join && !table->array_join)
throw Exception("Joined table expected", ErrorCodes::LOGICAL_ERROR);
if (table->array_join)
{
++num_array_join;
continue;
}
const auto & join = table->table_join->as<ASTTableJoin &>();
if (isComma(join.kind))
throw Exception("COMMA to CROSS JOIN rewriter is not enabled or cannot rewrite query", ErrorCodes::NOT_IMPLEMENTED);
/// it's not trivial to support mix of JOIN ON & JOIN USING cause of short names
if (join.using_expression_list)
throw Exception("Multiple JOIN does not support USING", ErrorCodes::NOT_IMPLEMENTED);
++num_using;
}
if (num_tables - num_array_join <= 2)
return false;
/// it's not trivial to support mix of JOIN ON & JOIN USING cause of short names
if (num_using)
throw Exception("Multiple JOIN does not support USING", ErrorCodes::NOT_IMPLEMENTED);
if (num_array_join)
throw Exception("Multiple JOIN does not support mix with ARRAY JOINs", ErrorCodes::NOT_IMPLEMENTED);
return true;
}

View File

@ -0,0 +1,12 @@
1 0
2 0
3 0
4 0
5 0
6 0
1 0
2 0
3 0
4 0
5 0
6 0

View File

@ -0,0 +1,16 @@
set allow_experimental_multiple_joins_emulation = 0;
set allow_experimental_cross_to_join_conversion = 0;
select ax, c from (select [1,2] ax, 0 c) array join ax join (select 0 c) using(c);
select ax, c from (select [3,4] ax, 0 c) join (select 0 c) using(c) array join ax;
select ax, c from (select [5,6] ax, 0 c) s1 join system.one s2 ON s1.c = s2.dummy array join ax;
set allow_experimental_multiple_joins_emulation = 1;
set allow_experimental_cross_to_join_conversion = 1;
select ax, c from (select [1,2] ax, 0 c) array join ax join (select 0 c) using(c);
select ax, c from (select [3,4] ax, 0 c) join (select 0 c) using(c) array join ax;
select ax, c from (select [5,6] ax, 0 c) s1 join system.one s2 ON s1.c = s2.dummy array join ax;
select ax, c from (select [7,8] ax, 0 c) s1
join system.one s2 ON s1.c = s2.dummy
join system.one s3 ON s1.c = s3.dummy
array join ax; -- { serverError 48 }