mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
dbms: fixed error with column order in RIGHT and FULL JOINs [#METR-17550].
This commit is contained in:
parent
bf6544693e
commit
7dc7144011
@ -163,8 +163,8 @@ private:
|
||||
* - в "левой" таблице, он будет доступен по имени expr(x), так как ещё не было выполнено действие Project.
|
||||
* Надо запомнить оба этих варианта.
|
||||
*/
|
||||
NameSet join_key_names_left_set;
|
||||
NameSet join_key_names_right_set;
|
||||
Names join_key_names_left;
|
||||
Names join_key_names_right;
|
||||
|
||||
NamesAndTypesList columns_added_by_join;
|
||||
|
||||
|
@ -1780,8 +1780,6 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty
|
||||
|
||||
if (!subquery_for_set.join)
|
||||
{
|
||||
Names join_key_names_left(join_key_names_left_set.begin(), join_key_names_left_set.end());
|
||||
Names join_key_names_right(join_key_names_right_set.begin(), join_key_names_right_set.end());
|
||||
JoinPtr join = new Join(join_key_names_left, join_key_names_right, settings.limits, ast_join.kind, ast_join.strictness);
|
||||
|
||||
Names required_joined_columns(join_key_names_right.begin(), join_key_names_right.end());
|
||||
@ -2174,27 +2172,31 @@ void ExpressionAnalyzer::collectJoinedColumns(NameSet & joined_columns, NamesAnd
|
||||
auto & keys = typeid_cast<ASTExpressionList &>(*node.using_expr_list);
|
||||
for (const auto & key : keys.children)
|
||||
{
|
||||
if (!join_key_names_left_set.insert(key->getColumnName()).second)
|
||||
throw Exception("Duplicate column in USING list", ErrorCodes::DUPLICATE_COLUMN);
|
||||
if (join_key_names_left.end() == std::find(join_key_names_left.begin(), join_key_names_left.end(), key->getColumnName()))
|
||||
join_key_names_left.push_back(key->getColumnName());
|
||||
else
|
||||
throw Exception("Duplicate column " + key->getColumnName() + " in USING list", ErrorCodes::DUPLICATE_COLUMN);
|
||||
|
||||
if (!join_key_names_right_set.insert(key->getAliasOrColumnName()).second)
|
||||
throw Exception("Duplicate column in USING list", ErrorCodes::DUPLICATE_COLUMN);
|
||||
if (join_key_names_right.end() == std::find(join_key_names_right.begin(), join_key_names_right.end(), key->getAliasOrColumnName()))
|
||||
join_key_names_right.push_back(key->getAliasOrColumnName());
|
||||
else
|
||||
throw Exception("Duplicate column " + key->getAliasOrColumnName() + " in USING list", ErrorCodes::DUPLICATE_COLUMN);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto i : ext::range(0, nested_result_sample.columns()))
|
||||
{
|
||||
const auto & col = nested_result_sample.getByPosition(i);
|
||||
if (!join_key_names_right_set.count(col.name))
|
||||
if (join_key_names_right.end() == std::find(join_key_names_right.begin(), join_key_names_right.end(), col.name))
|
||||
{
|
||||
joined_columns.insert(col.name);
|
||||
joined_columns_name_type.emplace_back(col.name, col.type);
|
||||
}
|
||||
}
|
||||
|
||||
/* for (const auto & name : join_key_names_left_set)
|
||||
/* for (const auto & name : join_key_names_left)
|
||||
std::cerr << "JOIN key (left): " << name << std::endl;
|
||||
for (const auto & name : join_key_names_right_set)
|
||||
for (const auto & name : join_key_names_right)
|
||||
std::cerr << "JOIN key (right): " << name << std::endl;
|
||||
std::cerr << std::endl;
|
||||
for (const auto & name : joined_columns)
|
||||
|
@ -376,12 +376,18 @@ void Join::setSampleBlock(const Block & block)
|
||||
|
||||
sample_block_with_columns_to_add = block;
|
||||
|
||||
/// Удаляем из sample_block_with_columns_to_add ключевые столбцы.
|
||||
for (const auto & name : key_names_right)
|
||||
/// Переносим из sample_block_with_columns_to_add ключевые столбцы в sample_block_with_keys, сохраняя порядок.
|
||||
size_t pos = 0;
|
||||
while (pos < sample_block_with_columns_to_add.columns())
|
||||
{
|
||||
size_t pos = sample_block_with_columns_to_add.getPositionByName(name);
|
||||
sample_block_with_keys.insert(sample_block_with_columns_to_add.unsafeGetByPosition(pos));
|
||||
sample_block_with_columns_to_add.erase(pos);
|
||||
const auto & name = sample_block_with_columns_to_add.unsafeGetByPosition(pos).name;
|
||||
if (key_names_right.end() != std::find(key_names_right.begin(), key_names_right.end(), name))
|
||||
{
|
||||
sample_block_with_keys.insert(sample_block_with_columns_to_add.unsafeGetByPosition(pos));
|
||||
sample_block_with_columns_to_add.erase(pos);
|
||||
}
|
||||
else
|
||||
++pos;
|
||||
}
|
||||
|
||||
for (size_t i = 0, size = sample_block_with_columns_to_add.columns(); i < size; ++i)
|
||||
@ -426,7 +432,9 @@ bool Join::insertFromBlock(const Block & block)
|
||||
|
||||
if (getFullness(kind))
|
||||
{
|
||||
/// Переносим ключевые столбцы в начало блока.
|
||||
/** Переносим ключевые столбцы в начало блока.
|
||||
* Именно там их будет ожидать NonJoinedBlockInputStream.
|
||||
*/
|
||||
size_t key_num = 0;
|
||||
for (const auto & name : key_names_right)
|
||||
{
|
||||
@ -810,6 +818,8 @@ void Join::checkTypesOfKeys(const Block & block_left, const Block & block_right)
|
||||
|
||||
void Join::joinBlock(Block & block) const
|
||||
{
|
||||
// std::cerr << "joinBlock: " << block.dumpStructure() << "\n";
|
||||
|
||||
Poco::ScopedReadRWLock lock(rwlock);
|
||||
|
||||
checkTypesOfKeys(block, sample_block_with_keys);
|
||||
@ -917,6 +927,8 @@ public:
|
||||
|
||||
result_sample_block = left_sample_block;
|
||||
|
||||
// std::cerr << result_sample_block.dumpStructure() << "\n";
|
||||
|
||||
/// Добавляем в блок новые столбцы.
|
||||
for (size_t i = 0; i < num_columns_right; ++i)
|
||||
{
|
||||
@ -932,10 +944,11 @@ public:
|
||||
{
|
||||
const String & name = left_sample_block.getByPosition(i).name;
|
||||
|
||||
if (parent.key_names_left.end() == std::find(parent.key_names_left.begin(), parent.key_names_left.end(), name))
|
||||
auto found_key_column = std::find(parent.key_names_left.begin(), parent.key_names_left.end(), name);
|
||||
if (parent.key_names_left.end() == found_key_column)
|
||||
column_numbers_left.push_back(i);
|
||||
else
|
||||
column_numbers_keys_and_right.push_back(i);
|
||||
column_numbers_keys_and_right.push_back(found_key_column - parent.key_names_left.begin());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_columns_right; ++i)
|
||||
@ -1046,8 +1059,6 @@ private:
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
// std::cerr << it->second.getUsed() << "\n";
|
||||
|
||||
if (it->second.getUsed())
|
||||
continue;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user