提交 3843fecc 编写于 作者: R robot-clickhouse

Backport #17397 to 20.12: Fix crash while reading from JOIN table with LowCardinality types

上级 8f2d33f5
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <DataTypes/NestedUtils.h> #include <DataTypes/NestedUtils.h>
#include <Interpreters/joinDispatch.h> #include <Interpreters/joinDispatch.h>
#include <Interpreters/TableJoin.h> #include <Interpreters/TableJoin.h>
#include <Interpreters/castColumn.h>
#include <Common/assert_cast.h> #include <Common/assert_cast.h>
#include <Common/quoteString.h> #include <Common/quoteString.h>
...@@ -321,7 +322,7 @@ private: ...@@ -321,7 +322,7 @@ private:
template <ASTTableJoin::Kind KIND, ASTTableJoin::Strictness STRICTNESS, typename Maps> template <ASTTableJoin::Kind KIND, ASTTableJoin::Strictness STRICTNESS, typename Maps>
Chunk createChunk(const Maps & maps) Chunk createChunk(const Maps & maps)
{ {
MutableColumns columns = restored_block.cloneEmpty().mutateColumns(); MutableColumns mut_columns = restored_block.cloneEmpty().mutateColumns();
size_t rows_added = 0; size_t rows_added = 0;
...@@ -329,7 +330,7 @@ private: ...@@ -329,7 +330,7 @@ private:
{ {
#define M(TYPE) \ #define M(TYPE) \
case HashJoin::Type::TYPE: \ case HashJoin::Type::TYPE: \
rows_added = fillColumns<KIND, STRICTNESS>(*maps.TYPE, columns); \ rows_added = fillColumns<KIND, STRICTNESS>(*maps.TYPE, mut_columns); \
break; break;
APPLY_FOR_JOIN_VARIANTS_LIMITED(M) APPLY_FOR_JOIN_VARIANTS_LIMITED(M)
#undef M #undef M
...@@ -342,19 +343,23 @@ private: ...@@ -342,19 +343,23 @@ private:
if (!rows_added) if (!rows_added)
return {}; return {};
/// Correct nullability Columns columns;
columns.reserve(mut_columns.size());
for (auto & col : mut_columns)
columns.emplace_back(std::move(col));
/// Correct nullability and LowCardinality types
for (size_t i = 0; i < columns.size(); ++i) for (size_t i = 0; i < columns.size(); ++i)
{ {
bool src_nullable = restored_block.getByPosition(i).type->isNullable(); const auto & src = restored_block.getByPosition(i);
bool dst_nullable = sample_block.getByPosition(i).type->isNullable(); const auto & dst = sample_block.getByPosition(i);
if (src_nullable && !dst_nullable) if (!src.type->equals(*dst.type))
{ {
auto & nullable_column = assert_cast<ColumnNullable &>(*columns[i]); auto arg = src;
columns[i] = nullable_column.getNestedColumnPtr()->assumeMutable(); arg.column = std::move(columns[i]);
columns[i] = castColumn(arg, dst.type);
} }
else if (!src_nullable && dst_nullable)
columns[i] = makeNullable(std::move(columns[i]))->assumeMutable();
} }
UInt64 num_rows = columns.at(0)->size(); UInt64 num_rows = columns.at(0)->size();
......
CREATE TABLE low_card
(
`lc` LowCardinality(String)
)
ENGINE = Join(ANY, LEFT, lc);
INSERT INTO low_card VALUES ( '1' );
SELECT * FROM low_card;
SELECT * FROM low_card WHERE lc = '1';
SELECT CAST(lc AS String) FROM low_card;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册