mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Merge pull request #45184 from ClickHouse/vdimir/storage_join_null_44940
This commit is contained in:
commit
ac5ee471c7
@ -886,20 +886,20 @@ public:
|
|||||||
const auto & lhs = lhs_block.getByPosition(i);
|
const auto & lhs = lhs_block.getByPosition(i);
|
||||||
const auto & rhs = rhs_block.getByPosition(i);
|
const auto & rhs = rhs_block.getByPosition(i);
|
||||||
if (lhs.name != rhs.name)
|
if (lhs.name != rhs.name)
|
||||||
throw DB::Exception(ErrorCodes::LOGICAL_ERROR, "Block structure mismatch: [{}] != [{}]",
|
throw DB::Exception(ErrorCodes::LOGICAL_ERROR, "Block structure mismatch: [{}] != [{}] ({} != {})",
|
||||||
lhs_block.dumpStructure(), rhs_block.dumpStructure());
|
lhs_block.dumpStructure(), rhs_block.dumpStructure(), lhs.name, rhs.name);
|
||||||
|
|
||||||
const auto & ltype = recursiveRemoveLowCardinality(lhs.type);
|
const auto & ltype = recursiveRemoveLowCardinality(lhs.type);
|
||||||
const auto & rtype = recursiveRemoveLowCardinality(rhs.type);
|
const auto & rtype = recursiveRemoveLowCardinality(rhs.type);
|
||||||
if (!ltype->equals(*rtype))
|
if (!ltype->equals(*rtype))
|
||||||
throw DB::Exception(ErrorCodes::LOGICAL_ERROR, "Block structure mismatch: [{}] != [{}]",
|
throw DB::Exception(ErrorCodes::LOGICAL_ERROR, "Block structure mismatch: [{}] != [{}] ({} != {})",
|
||||||
lhs_block.dumpStructure(), rhs_block.dumpStructure());
|
lhs_block.dumpStructure(), rhs_block.dumpStructure(), ltype->getName(), rtype->getName());
|
||||||
|
|
||||||
const auto & lcol = recursiveRemoveLowCardinality(lhs.column);
|
const auto & lcol = recursiveRemoveLowCardinality(lhs.column);
|
||||||
const auto & rcol = recursiveRemoveLowCardinality(rhs.column);
|
const auto & rcol = recursiveRemoveLowCardinality(rhs.column);
|
||||||
if (lcol->getDataType() != rcol->getDataType())
|
if (lcol->getDataType() != rcol->getDataType())
|
||||||
throw DB::Exception(ErrorCodes::LOGICAL_ERROR, "Block structure mismatch: [{}] != [{}]",
|
throw DB::Exception(ErrorCodes::LOGICAL_ERROR, "Block structure mismatch: [{}] != [{}] ({} != {})",
|
||||||
lhs_block.dumpStructure(), rhs_block.dumpStructure());
|
lhs_block.dumpStructure(), rhs_block.dumpStructure(), lcol->getDataType(), rcol->getDataType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,16 +458,6 @@ TableJoin::createConvertingActions(
|
|||||||
LOG_DEBUG(&Poco::Logger::get("TableJoin"), "{} JOIN converting actions: empty", side);
|
LOG_DEBUG(&Poco::Logger::get("TableJoin"), "{} JOIN converting actions: empty", side);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto format_cols = [](const auto & cols) -> std::string
|
|
||||||
{
|
|
||||||
std::vector<std::string> str_cols;
|
|
||||||
str_cols.reserve(cols.size());
|
|
||||||
for (const auto & col : cols)
|
|
||||||
str_cols.push_back(fmt::format("'{}': {}", col.name, col.type->getName()));
|
|
||||||
return fmt::format("[{}]", fmt::join(str_cols, ", "));
|
|
||||||
};
|
|
||||||
LOG_DEBUG(&Poco::Logger::get("TableJoin"), "{} JOIN converting actions: {} -> {}",
|
|
||||||
side, format_cols(dag->getRequiredColumns()), format_cols(dag->getResultColumns()));
|
|
||||||
};
|
};
|
||||||
log_actions("Left", left_converting_actions);
|
log_actions("Left", left_converting_actions);
|
||||||
log_actions("Right", right_converting_actions);
|
log_actions("Right", right_converting_actions);
|
||||||
|
@ -229,11 +229,13 @@ HashJoinPtr StorageJoin::getJoinLocked(std::shared_ptr<TableJoin> analyzed_join,
|
|||||||
return join_clone;
|
return join_clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StorageJoin::insertBlock(const Block & block, ContextPtr context)
|
void StorageJoin::insertBlock(const Block & block, ContextPtr context)
|
||||||
{
|
{
|
||||||
|
Block block_to_insert = block;
|
||||||
|
convertRightBlock(block_to_insert);
|
||||||
|
|
||||||
TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, context);
|
TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, context);
|
||||||
join->addJoinedBlock(block, true);
|
join->addJoinedBlock(block_to_insert, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t StorageJoin::getSize(ContextPtr context) const
|
size_t StorageJoin::getSize(ContextPtr context) const
|
||||||
@ -265,6 +267,16 @@ ColumnWithTypeAndName StorageJoin::joinGet(const Block & block, const Block & bl
|
|||||||
return join->joinGet(block, block_with_columns_to_add);
|
return join->joinGet(block, block_with_columns_to_add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StorageJoin::convertRightBlock(Block & block) const
|
||||||
|
{
|
||||||
|
bool need_covert = use_nulls && isLeftOrFull(kind);
|
||||||
|
if (!need_covert)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto & col : block)
|
||||||
|
JoinCommon::convertColumnToNullable(col);
|
||||||
|
}
|
||||||
|
|
||||||
void registerStorageJoin(StorageFactory & factory)
|
void registerStorageJoin(StorageFactory & factory)
|
||||||
{
|
{
|
||||||
auto creator_fn = [](const StorageFactory::Arguments & args)
|
auto creator_fn = [](const StorageFactory::Arguments & args)
|
||||||
|
@ -77,9 +77,7 @@ public:
|
|||||||
{
|
{
|
||||||
auto metadata_snapshot = getInMemoryMetadataPtr();
|
auto metadata_snapshot = getInMemoryMetadataPtr();
|
||||||
Block block = metadata_snapshot->getSampleBlock();
|
Block block = metadata_snapshot->getSampleBlock();
|
||||||
if (use_nulls && isLeftOrFull(kind))
|
convertRightBlock(block);
|
||||||
for (auto & col : block)
|
|
||||||
JoinCommon::convertColumnToNullable(col);
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +106,8 @@ private:
|
|||||||
void finishInsert() override {}
|
void finishInsert() override {}
|
||||||
size_t getSize(ContextPtr context) const override;
|
size_t getSize(ContextPtr context) const override;
|
||||||
RWLockImpl::LockHolder tryLockTimedWithContext(const RWLock & lock, RWLockImpl::Type type, ContextPtr context) const;
|
RWLockImpl::LockHolder tryLockTimedWithContext(const RWLock & lock, RWLockImpl::Type type, ContextPtr context) const;
|
||||||
|
|
||||||
|
void convertRightBlock(Block & block) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
3 \N 3
|
||||||
|
2 2 2
|
||||||
|
1 1 1
|
18
tests/queries/0_stateless/02531_storage_join_null_44940.sql
Normal file
18
tests/queries/0_stateless/02531_storage_join_null_44940.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
SET allow_suspicious_low_cardinality_types = 1;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS t1__fuzz_8;
|
||||||
|
DROP TABLE IF EXISTS full_join__fuzz_4;
|
||||||
|
|
||||||
|
CREATE TABLE t1__fuzz_8 (`x` LowCardinality(UInt32), `str` Nullable(Int16)) ENGINE = Memory;
|
||||||
|
INSERT INTO t1__fuzz_8 VALUES (1, 1), (2, 2);
|
||||||
|
|
||||||
|
CREATE TABLE full_join__fuzz_4 (`x` LowCardinality(UInt32), `s` LowCardinality(String)) ENGINE = Join(`ALL`, FULL, x) SETTINGS join_use_nulls = 1;
|
||||||
|
INSERT INTO full_join__fuzz_4 VALUES (1, '1'), (2, '2'), (3, '3');
|
||||||
|
|
||||||
|
SET join_use_nulls = 1;
|
||||||
|
|
||||||
|
SELECT * FROM t1__fuzz_8 FULL OUTER JOIN full_join__fuzz_4 USING (x) ORDER BY x DESC, str ASC, s ASC NULLS LAST;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS t1__fuzz_8;
|
||||||
|
DROP TABLE IF EXISTS full_join__fuzz_4;
|
Loading…
Reference in New Issue
Block a user