mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
fix JOIN right table keys nullability
This commit is contained in:
parent
12b57aedf0
commit
deb2406b30
@ -37,11 +37,52 @@ namespace ErrorCodes
|
||||
}
|
||||
|
||||
|
||||
/// Converts column to nullable if needed. No backward convertion.
|
||||
static ColumnPtr filterWithBlanks(ColumnPtr src_column, const IColumn::Filter & filter, bool inverse_filter = false)
|
||||
{
|
||||
ColumnPtr column = src_column->convertToFullColumnIfConst();
|
||||
MutableColumnPtr mut_column = column->cloneEmpty();
|
||||
mut_column->reserve(column->size());
|
||||
|
||||
if (inverse_filter)
|
||||
{
|
||||
for (size_t row = 0; row < filter.size(); ++row)
|
||||
{
|
||||
if (filter[row])
|
||||
mut_column->insertDefault();
|
||||
else
|
||||
mut_column->insertFrom(*column, row);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t row = 0; row < filter.size(); ++row)
|
||||
{
|
||||
if (filter[row])
|
||||
mut_column->insertFrom(*column, row);
|
||||
else
|
||||
mut_column->insertDefault();
|
||||
}
|
||||
}
|
||||
|
||||
return mut_column;
|
||||
}
|
||||
|
||||
static ColumnWithTypeAndName correctNullability(ColumnWithTypeAndName && column, bool nullable)
|
||||
{
|
||||
if (nullable)
|
||||
{
|
||||
JoinCommon::convertColumnToNullable(column);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// We have to replace values masked by NULLs with defaults.
|
||||
if (column.column)
|
||||
if (auto * nullable_column = checkAndGetColumn<ColumnNullable>(*column.column))
|
||||
column.column = filterWithBlanks(column.column, nullable_column->getNullMapColumn().getData(), true);
|
||||
|
||||
JoinCommon::removeColumnNullability(column);
|
||||
}
|
||||
|
||||
return std::move(column);
|
||||
}
|
||||
|
||||
@ -57,6 +98,9 @@ static ColumnWithTypeAndName correctNullability(ColumnWithTypeAndName && column,
|
||||
column.column = std::move(mutable_column);
|
||||
}
|
||||
}
|
||||
else
|
||||
JoinCommon::removeColumnNullability(column);
|
||||
|
||||
return std::move(column);
|
||||
}
|
||||
|
||||
@ -769,7 +813,7 @@ void Join::joinBlockImpl(
|
||||
for (size_t i = 0; i < existing_columns; ++i)
|
||||
block.safeGetByPosition(i).column = block.safeGetByPosition(i).column->filter(row_filter, -1);
|
||||
|
||||
/// Add join key columns from right block if they has different name.
|
||||
/// Add join key columns from right block if needed.
|
||||
for (size_t i = 0; i < right_table_keys.columns(); ++i)
|
||||
{
|
||||
const auto & right_key = right_table_keys.getByPosition(i);
|
||||
@ -791,7 +835,7 @@ void Join::joinBlockImpl(
|
||||
null_map_filter.getData().swap(row_filter);
|
||||
const IColumn::Filter & filter = null_map_filter.getData();
|
||||
|
||||
/// Add join key columns from right block if they has different name.
|
||||
/// Add join key columns from right block if needed.
|
||||
for (size_t i = 0; i < right_table_keys.columns(); ++i)
|
||||
{
|
||||
const auto & right_key = right_table_keys.getByPosition(i);
|
||||
@ -800,20 +844,10 @@ void Join::joinBlockImpl(
|
||||
if (required_right_keys.count(right_key.name) && !block.has(right_key.name))
|
||||
{
|
||||
const auto & col = block.getByName(left_name);
|
||||
ColumnPtr column = col.column->convertToFullColumnIfConst();
|
||||
MutableColumnPtr mut_column = column->cloneEmpty();
|
||||
mut_column->reserve(column->size());
|
||||
|
||||
for (size_t row = 0; row < filter.size(); ++row)
|
||||
{
|
||||
if (filter[row])
|
||||
mut_column->insertFrom(*column, row);
|
||||
else
|
||||
mut_column->insertDefault();
|
||||
}
|
||||
|
||||
bool is_nullable = nullable_right_side || right_key.type->isNullable();
|
||||
block.insert(correctNullability({std::move(mut_column), col.type, right_key.name}, is_nullable, null_map_filter));
|
||||
|
||||
ColumnPtr thin_column = filterWithBlanks(col.column, filter);
|
||||
block.insert(correctNullability({thin_column, col.type, right_key.name}, is_nullable, null_map_filter));
|
||||
|
||||
if constexpr (is_all_join)
|
||||
right_keys_to_replicate.push_back(block.getPositionByName(right_key.name));
|
||||
|
@ -32,6 +32,22 @@ void convertColumnsToNullable(Block & block, size_t starting_pos)
|
||||
convertColumnToNullable(block.getByPosition(i));
|
||||
}
|
||||
|
||||
/// @warning It assumes that every NULL has default value in nested column (or it does not matter)
|
||||
void removeColumnNullability(ColumnWithTypeAndName & column)
|
||||
{
|
||||
if (!column.type->isNullable())
|
||||
return;
|
||||
|
||||
column.type = static_cast<const DataTypeNullable &>(*column.type).getNestedType();
|
||||
if (column.column)
|
||||
{
|
||||
auto * nullable_column = checkAndGetColumn<ColumnNullable>(*column.column);
|
||||
ColumnPtr nested_column = nullable_column->getNestedColumnPtr();
|
||||
MutableColumnPtr mutable_column = (*std::move(nested_column)).mutate();
|
||||
column.column = std::move(mutable_column);
|
||||
}
|
||||
}
|
||||
|
||||
ColumnRawPtrs temporaryMaterializeColumns(const Block & block, const Names & names, Columns & materialized)
|
||||
{
|
||||
ColumnRawPtrs ptrs;
|
||||
|
@ -15,6 +15,7 @@ namespace JoinCommon
|
||||
|
||||
void convertColumnToNullable(ColumnWithTypeAndName & column);
|
||||
void convertColumnsToNullable(Block & block, size_t starting_pos = 0);
|
||||
void removeColumnNullability(ColumnWithTypeAndName & column);
|
||||
ColumnRawPtrs temporaryMaterializeColumns(const Block & block, const Names & names, Columns & materialized);
|
||||
void removeLowCardinalityInplace(Block & block);
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
\N test 0 1 Nullable(String) Nullable(String)
|
||||
bar bar 1 2 Nullable(String) Nullable(String)
|
||||
\N 0 1 Nullable(String) Nullable(String)
|
||||
foo \N 2 0 Nullable(String) Nullable(String)
|
||||
\N test 0 1 Nullable(String) Nullable(String)
|
||||
bar bar 1 2 Nullable(String) Nullable(String)
|
||||
\N 0 1 Nullable(String) Nullable(String)
|
||||
foo \N 2 0 Nullable(String) Nullable(String)
|
||||
\N test 0 1 Nullable(String) String
|
||||
bar bar 1 2 Nullable(String) String
|
||||
\N 0 1 Nullable(String) String
|
||||
foo 2 0 Nullable(String) String
|
||||
\N test 0 1 Nullable(String) String
|
||||
bar bar 1 2 Nullable(String) String
|
||||
\N 0 1 Nullable(String) String
|
||||
foo 2 0 Nullable(String) String
|
||||
foo \N 2 0 String Nullable(String)
|
||||
bar bar 1 2 String Nullable(String)
|
||||
test 0 1 String Nullable(String)
|
||||
|
Loading…
Reference in New Issue
Block a user