From 2de6eaf8380a5d184db595fb5382fc031a440821 Mon Sep 17 00:00:00 2001 From: vdimir Date: Tue, 15 Feb 2022 11:11:59 +0000 Subject: [PATCH] Fix LowCardinality using key for join_use_nulls in pipeline --- src/Interpreters/HashJoin.cpp | 10 +++++----- src/Interpreters/join_common.cpp | 8 ++++++++ src/Interpreters/join_common.h | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Interpreters/HashJoin.cpp b/src/Interpreters/HashJoin.cpp index 8268dc20b01..feb5ecd4261 100644 --- a/src/Interpreters/HashJoin.cpp +++ b/src/Interpreters/HashJoin.cpp @@ -1524,13 +1524,13 @@ void HashJoin::joinBlockImpl( continue; const auto & col = block.getByName(left_name); - bool is_nullable = nullable_right_side || right_key.type->isNullable(); + bool is_nullable = JoinCommon::isNullable(right_key.type); auto right_col_name = getTableJoin().renamedRightColumnName(right_key.name); ColumnWithTypeAndName right_col(col.column, col.type, right_col_name); if (right_col.type->lowCardinality() != right_key.type->lowCardinality()) JoinCommon::changeLowCardinalityInplace(right_col); right_col = correctNullability(std::move(right_col), is_nullable); - block.insert(right_col); + block.insert(std::move(right_col)); } } } @@ -1556,7 +1556,7 @@ void HashJoin::joinBlockImpl( continue; const auto & col = block.getByName(left_name); - bool is_nullable = nullable_right_side || right_key.type->isNullable(); + bool is_nullable = JoinCommon::isNullable(right_key.type); ColumnPtr thin_column = filterWithBlanks(col.column, filter); @@ -1564,7 +1564,7 @@ void HashJoin::joinBlockImpl( if (right_col.type->lowCardinality() != right_key.type->lowCardinality()) JoinCommon::changeLowCardinalityInplace(right_col); right_col = correctNullability(std::move(right_col), is_nullable, null_map_filter); - block.insert(right_col); + block.insert(std::move(right_col)); if constexpr (jf.need_replication) right_keys_to_replicate.push_back(block.getPositionByName(right_key.name)); @@ -2088,7 +2088,7 @@ void HashJoin::reuseJoinedData(const HashJoin & join) const ColumnWithTypeAndName & HashJoin::rightAsofKeyColumn() const { - /// It should be nullable if nullable_right_side is true + /// It should be nullable when right side is nullable return savedBlockSample().getByName(table_join->getOnlyClause().key_names_right.back()); } diff --git a/src/Interpreters/join_common.cpp b/src/Interpreters/join_common.cpp index ca6d3124934..60f67c8a9d1 100644 --- a/src/Interpreters/join_common.cpp +++ b/src/Interpreters/join_common.cpp @@ -115,6 +115,14 @@ bool canBecomeNullable(const DataTypePtr & type) return can_be_inside; } +bool isNullable(const DataTypePtr & type) +{ + bool is_nullable = type->isNullable(); + if (const auto * low_cardinality_type = typeid_cast(type.get())) + is_nullable |= low_cardinality_type->getDictionaryType()->isNullable(); + return is_nullable; +} + /// Add nullability to type. /// Note: LowCardinality(T) transformed to LowCardinality(Nullable(T)) DataTypePtr convertTypeToNullable(const DataTypePtr & type) diff --git a/src/Interpreters/join_common.h b/src/Interpreters/join_common.h index 3e5a22f33bf..38b431db3e0 100644 --- a/src/Interpreters/join_common.h +++ b/src/Interpreters/join_common.h @@ -59,6 +59,7 @@ private: }; +bool isNullable(const DataTypePtr & type); bool canBecomeNullable(const DataTypePtr & type); DataTypePtr convertTypeToNullable(const DataTypePtr & type); void convertColumnToNullable(ColumnWithTypeAndName & column);