提交 bfa59adb 编写于 作者: A Artem Zuikov

fix select from StorageJoin

上级 9028a25f
......@@ -251,22 +251,26 @@ public:
, max_block_size(max_block_size_)
, sample_block(std::move(sample_block_))
{
columns.resize(sample_block.columns());
column_indices.resize(sample_block.columns());
column_with_null.resize(sample_block.columns());
auto & saved_block = parent.getJoinedData()->sample_block;
for (size_t i = 0; i < sample_block.columns(); ++i)
{
auto & [_, type, name] = sample_block.getByPosition(i);
if (parent.right_table_keys.has(name))
{
key_pos = i;
column_with_null[i] = parent.right_table_keys.getByName(name).type->isNullable();
auto & column = parent.right_table_keys.getByName(name);
restored_block.insert(column);
}
else
{
auto pos = parent.sample_block_with_columns_to_add.getPositionByName(name);
size_t pos = saved_block.getPositionByName(name);
column_indices[i] = pos;
column_with_null[i] = !parent.sample_block_with_columns_to_add.getByPosition(pos).type->equals(*type);
auto & column = saved_block.getByPosition(pos);
restored_block.insert(column);
}
}
}
......@@ -291,11 +295,10 @@ private:
std::shared_lock<std::shared_mutex> lock;
UInt64 max_block_size;
Block sample_block;
Block restored_block; /// sample_block with parent column types
ColumnNumbers column_indices;
std::vector<bool> column_with_null;
std::optional<size_t> key_pos;
MutableColumns columns;
std::unique_ptr<void, std::function<void(void *)>> position; /// type erasure
......@@ -303,23 +306,7 @@ private:
template <ASTTableJoin::Kind KIND, ASTTableJoin::Strictness STRICTNESS, typename Maps>
Chunk createChunk(const Maps & maps)
{
for (size_t i = 0; i < sample_block.columns(); ++i)
{
const auto & src_col = sample_block.safeGetByPosition(i);
columns[i] = src_col.type->createColumn();
if (column_with_null[i])
{
if (key_pos == i)
{
// unwrap null key column
auto & nullable_col = assert_cast<ColumnNullable &>(*columns[i]);
columns[i] = nullable_col.getNestedColumnPtr()->assumeMutable();
}
else
// wrap non key column with null
columns[i] = makeNullable(std::move(columns[i]))->assumeMutable();
}
}
MutableColumns columns = restored_block.cloneEmpty().mutateColumns();
size_t rows_added = 0;
......@@ -327,7 +314,7 @@ private:
{
#define M(TYPE) \
case HashJoin::Type::TYPE: \
rows_added = fillColumns<KIND, STRICTNESS>(*maps.TYPE); \
rows_added = fillColumns<KIND, STRICTNESS>(*maps.TYPE, columns); \
break;
APPLY_FOR_JOIN_VARIANTS_LIMITED(M)
#undef M
......@@ -340,29 +327,27 @@ private:
if (!rows_added)
return {};
Columns res_columns;
res_columns.reserve(columns.size());
/// Correct nullability
for (size_t i = 0; i < columns.size(); ++i)
if (column_with_null[i])
{
bool src_nullable = restored_block.getByPosition(i).type->isNullable();
bool dst_nullable = sample_block.getByPosition(i).type->isNullable();
if (src_nullable && !dst_nullable)
{
if (key_pos == i)
res_columns.emplace_back(makeNullable(std::move(columns[i])));
else
{
const auto & nullable_col = assert_cast<const ColumnNullable &>(*columns[i]);
res_columns.emplace_back(makeNullable(nullable_col.getNestedColumnPtr()));
}
auto & nullable_column = assert_cast<ColumnNullable &>(*columns[i]);
columns[i] = nullable_column.getNestedColumnPtr()->assumeMutable();
}
else
res_columns.emplace_back(std::move(columns[i]));
else if (!src_nullable && dst_nullable)
columns[i] = makeNullable(std::move(columns[i]))->assumeMutable();
}
UInt64 num_rows = res_columns.at(0)->size();
return Chunk(std::move(res_columns), num_rows);
UInt64 num_rows = columns.at(0)->size();
return Chunk(std::move(columns), num_rows);
}
template <ASTTableJoin::Kind KIND, ASTTableJoin::Strictness STRICTNESS, typename Map>
size_t fillColumns(const Map & map)
size_t fillColumns(const Map & map, MutableColumns & columns)
{
size_t rows_added = 0;
......
1 s 1 String String
2 s 2 String String
3 s 3 Nullable(String) String
4 s 4 String Nullable(String)
1 s 1 String String
2 s 2 String String
3 s 3 Nullable(String) String
4 s 4 String Nullable(String)
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
DROP TABLE IF EXISTS t4;
CREATE TABLE t1 (id String, name String, value UInt32)
ENGINE = Join(ANY, LEFT, id)
SETTINGS join_use_nulls = 1;
CREATE TABLE t2 (id String, name String, value UInt32)
ENGINE = Join(ANY, LEFT, id)
SETTINGS join_use_nulls = 0;
CREATE TABLE t3 (id Nullable(String), name String, value UInt32)
ENGINE = Join(ANY, LEFT, id)
SETTINGS join_use_nulls = 1;
CREATE TABLE t4 (id String, name Nullable(String), value UInt32)
ENGINE = Join(ANY, LEFT, id)
SETTINGS join_use_nulls = 0;
insert into t1 values('1', 's', 1);
insert into t2 values('2', 's', 2);
insert into t3 values('3', 's', 3);
insert into t4 values('4', 's', 4);
select *, toTypeName(id), toTypeName(name) from t1;
select *, toTypeName(id), toTypeName(name) from t2;
select *, toTypeName(id), toTypeName(name) from t3;
select *, toTypeName(id), toTypeName(name) from t4;
SET join_use_nulls = 1;
select *, toTypeName(id), toTypeName(name) from t1;
select *, toTypeName(id), toTypeName(name) from t2;
select *, toTypeName(id), toTypeName(name) from t3;
select *, toTypeName(id), toTypeName(name) from t4;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册