mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-18 12:22:12 +00:00
Merge pull request #7062 from ClickHouse/fix-msan-for-low-cardinality
Fix msan for LowCardinality
(cherry picked from commit a314a36feb
)
This commit is contained in:
parent
9533ff12dd
commit
af5099b869
@ -219,11 +219,14 @@ size_t Block::getPositionByName(const std::string & name) const
|
||||
}
|
||||
|
||||
|
||||
void Block::checkNumberOfRows() const
|
||||
void Block::checkNumberOfRows(bool allow_null_columns) const
|
||||
{
|
||||
ssize_t rows = -1;
|
||||
for (const auto & elem : data)
|
||||
{
|
||||
if (!elem.column && allow_null_columns)
|
||||
continue;
|
||||
|
||||
if (!elem.column)
|
||||
throw Exception("Column " + elem.name + " in block is nullptr, in method checkNumberOfRows."
|
||||
, ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
size_t columns() const { return data.size(); }
|
||||
|
||||
/// Checks that every column in block is not nullptr and has same number of elements.
|
||||
void checkNumberOfRows() const;
|
||||
void checkNumberOfRows(bool allow_null_columns = false) const;
|
||||
|
||||
/// Approximate number of bytes in memory - for profiling and limits.
|
||||
size_t bytes() const;
|
||||
|
@ -337,19 +337,43 @@ static ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
|
||||
size_t num_rows = input_rows_count;
|
||||
ColumnPtr indexes;
|
||||
|
||||
/// Find first LowCardinality column and replace it to nested dictionary.
|
||||
for (auto arg : args)
|
||||
{
|
||||
ColumnWithTypeAndName & column = block.getByPosition(arg);
|
||||
if (auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(column.column.get()))
|
||||
{
|
||||
/// Single LowCardinality column is supported now.
|
||||
if (indexes)
|
||||
throw Exception("Expected single dictionary argument for function.", ErrorCodes::LOGICAL_ERROR);
|
||||
|
||||
auto * low_cardinality_type = checkAndGetDataType<DataTypeLowCardinality>(column.type.get());
|
||||
|
||||
if (!low_cardinality_type)
|
||||
throw Exception("Incompatible type for low cardinality column: " + column.type->getName(),
|
||||
ErrorCodes::LOGICAL_ERROR);
|
||||
|
||||
if (can_be_executed_on_default_arguments)
|
||||
{
|
||||
/// Normal case, when function can be executed on values's default.
|
||||
column.column = low_cardinality_column->getDictionary().getNestedColumn();
|
||||
indexes = low_cardinality_column->getIndexesPtr();
|
||||
num_rows = low_cardinality_column->getDictionary().size();
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Special case when default value can't be used. Example: 1 % LowCardinality(Int).
|
||||
/// LowCardinality always contains default, so 1 % 0 will throw exception in normal case.
|
||||
auto dict_encoded = low_cardinality_column->getMinimalDictionaryEncodedColumn(0, low_cardinality_column->size());
|
||||
column.column = dict_encoded.dictionary;
|
||||
indexes = dict_encoded.indexes;
|
||||
}
|
||||
|
||||
num_rows = column.column->size();
|
||||
column.type = low_cardinality_type->getDictionaryType();
|
||||
}
|
||||
}
|
||||
|
||||
/// Change size of constants.
|
||||
for (auto arg : args)
|
||||
{
|
||||
ColumnWithTypeAndName & column = block.getByPosition(arg);
|
||||
@ -358,25 +382,11 @@ static ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
|
||||
column.column = column_const->removeLowCardinality()->cloneResized(num_rows);
|
||||
column.type = removeLowCardinality(column.type);
|
||||
}
|
||||
else if (auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(column.column.get()))
|
||||
{
|
||||
auto * low_cardinality_type = checkAndGetDataType<DataTypeLowCardinality>(column.type.get());
|
||||
}
|
||||
|
||||
if (!low_cardinality_type)
|
||||
throw Exception("Incompatible type for low cardinality column: " + column.type->getName(),
|
||||
ErrorCodes::LOGICAL_ERROR);
|
||||
|
||||
if (can_be_executed_on_default_arguments)
|
||||
column.column = low_cardinality_column->getDictionary().getNestedColumn();
|
||||
else
|
||||
{
|
||||
auto dict_encoded = low_cardinality_column->getMinimalDictionaryEncodedColumn(0, low_cardinality_column->size());
|
||||
column.column = dict_encoded.dictionary;
|
||||
indexes = dict_encoded.indexes;
|
||||
}
|
||||
column.type = low_cardinality_type->getDictionaryType();
|
||||
}
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
block.checkNumberOfRows(true);
|
||||
#endif
|
||||
|
||||
return indexes;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user