mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
Better const resolution for LowCardinality type. [#CLICKHOUSE-3621]
This commit is contained in:
parent
6b3375393d
commit
f61fdf2076
@ -30,6 +30,11 @@ ColumnPtr ColumnConst::convertToFullColumn() const
|
|||||||
return data->replicate(Offsets(1, s));
|
return data->replicate(Offsets(1, s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColumnPtr ColumnConst::removeLowCardinality() const
|
||||||
|
{
|
||||||
|
return ColumnConst::create(data->convertToFullColumnIfWithDictionary(), s);
|
||||||
|
}
|
||||||
|
|
||||||
ColumnPtr ColumnConst::filter(const Filter & filt, ssize_t /*result_size_hint*/) const
|
ColumnPtr ColumnConst::filter(const Filter & filt, ssize_t /*result_size_hint*/) const
|
||||||
{
|
{
|
||||||
if (s != filt.size())
|
if (s != filt.size())
|
||||||
|
@ -36,6 +36,8 @@ public:
|
|||||||
return convertToFullColumn();
|
return convertToFullColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColumnPtr removeLowCardinality() const;
|
||||||
|
|
||||||
std::string getName() const override
|
std::string getName() const override
|
||||||
{
|
{
|
||||||
return "Const(" + data->getName() + ")";
|
return "Const(" + data->getName() + ")";
|
||||||
|
@ -253,14 +253,11 @@ static ColumnPtr replaceColumnsWithDictionaryByNestedAndGetDictionaryIndexes(Blo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!indexes)
|
|
||||||
throw Exception("Expected column with dictionary for any function argument.", ErrorCodes::LOGICAL_ERROR);
|
|
||||||
|
|
||||||
for (auto arg : args)
|
for (auto arg : args)
|
||||||
{
|
{
|
||||||
ColumnWithTypeAndName & column = block.getByPosition(arg);
|
ColumnWithTypeAndName & column = block.getByPosition(arg);
|
||||||
if (auto * column_const = checkAndGetColumn<ColumnConst>(column.column.get()))
|
if (auto * column_const = checkAndGetColumn<ColumnConst>(column.column.get()))
|
||||||
column.column = column_const->cloneResized(num_rows);
|
column.column = column_const->removeLowCardinality()->cloneResized(num_rows);
|
||||||
else if (auto * column_with_dict = checkAndGetColumn<ColumnWithDictionary>(column.column.get()))
|
else if (auto * column_with_dict = checkAndGetColumn<ColumnWithDictionary>(column.column.get()))
|
||||||
{
|
{
|
||||||
auto * type_with_dict = checkAndGetDataType<DataTypeWithDictionary>(column.type.get());
|
auto * type_with_dict = checkAndGetDataType<DataTypeWithDictionary>(column.type.get());
|
||||||
@ -289,7 +286,9 @@ static void convertColumnsWithDictionaryToFull(Block & block, const ColumnNumber
|
|||||||
for (auto arg : args)
|
for (auto arg : args)
|
||||||
{
|
{
|
||||||
ColumnWithTypeAndName & column = block.getByPosition(arg);
|
ColumnWithTypeAndName & column = block.getByPosition(arg);
|
||||||
if (auto * column_with_dict = checkAndGetColumn<ColumnWithDictionary>(column.column.get()))
|
if (auto * column_const = checkAndGetColumn<ColumnConst>(column.column.get()))
|
||||||
|
column.column = column_const->removeLowCardinality();
|
||||||
|
else if (auto * column_with_dict = checkAndGetColumn<ColumnWithDictionary>(column.column.get()))
|
||||||
{
|
{
|
||||||
auto * type_with_dict = checkAndGetDataType<DataTypeWithDictionary>(column.type.get());
|
auto * type_with_dict = checkAndGetDataType<DataTypeWithDictionary>(column.type.get());
|
||||||
|
|
||||||
@ -325,10 +324,13 @@ void PreparedFunctionImpl::execute(Block & block, const ColumnNumbers & args, si
|
|||||||
auto * column_with_dictionary = typeid_cast<ColumnWithDictionary *>(res_column.get());
|
auto * column_with_dictionary = typeid_cast<ColumnWithDictionary *>(res_column.get());
|
||||||
|
|
||||||
if (!column_with_dictionary)
|
if (!column_with_dictionary)
|
||||||
throw Exception("Expected ColumnWithDictionary, got" + res_column->getName(), ErrorCodes::LOGICAL_ERROR);
|
throw Exception("Expected LowCardinality column, got" + res_column->getName(), ErrorCodes::LOGICAL_ERROR);
|
||||||
|
|
||||||
const auto & keys = block_without_dicts.safeGetByPosition(result).column;
|
const auto & keys = block_without_dicts.safeGetByPosition(result).column;
|
||||||
column_with_dictionary->insertRangeFromDictionaryEncodedColumn(*keys, *indexes);
|
if (indexes)
|
||||||
|
column_with_dictionary->insertRangeFromDictionaryEncodedColumn(*keys, *indexes);
|
||||||
|
else
|
||||||
|
column_with_dictionary->insertRangeFromFullColumn(*keys->convertToFullColumnIfConst(), 0, keys->size());
|
||||||
|
|
||||||
res.column = std::move(res_column);
|
res.column = std::move(res_column);
|
||||||
}
|
}
|
||||||
@ -451,29 +453,28 @@ DataTypePtr FunctionBuilderImpl::getReturnType(const ColumnsWithTypeAndName & ar
|
|||||||
{
|
{
|
||||||
if (useDefaultImplementationForColumnsWithDictionary())
|
if (useDefaultImplementationForColumnsWithDictionary())
|
||||||
{
|
{
|
||||||
bool has_type_with_dictionary = false;
|
bool has_low_cardinality = false;
|
||||||
bool can_run_function_on_dictionary = true;
|
size_t num_full_low_cardinality_columns = 0;
|
||||||
|
|
||||||
ColumnsWithTypeAndName args_without_dictionary(arguments);
|
ColumnsWithTypeAndName args_without_dictionary(arguments);
|
||||||
|
|
||||||
for (ColumnWithTypeAndName & arg : args_without_dictionary)
|
for (ColumnWithTypeAndName & arg : args_without_dictionary)
|
||||||
{
|
{
|
||||||
if (arg.column && arg.column->isColumnConst())
|
bool is_const = arg.column && arg.column->isColumnConst();
|
||||||
continue;
|
if (is_const)
|
||||||
|
arg.column = static_cast<const ColumnConst &>(*arg.column).removeLowCardinality();
|
||||||
|
|
||||||
if (auto * type_with_dictionary = typeid_cast<const DataTypeWithDictionary *>(arg.type.get()))
|
if (auto * type_with_dictionary = typeid_cast<const DataTypeWithDictionary *>(arg.type.get()))
|
||||||
{
|
{
|
||||||
if (has_type_with_dictionary)
|
|
||||||
can_run_function_on_dictionary = false;
|
|
||||||
|
|
||||||
has_type_with_dictionary = true;
|
|
||||||
arg.type = type_with_dictionary->getDictionaryType();
|
arg.type = type_with_dictionary->getDictionaryType();
|
||||||
|
has_low_cardinality = true;
|
||||||
|
|
||||||
|
if (!is_const)
|
||||||
|
++num_full_low_cardinality_columns;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
can_run_function_on_dictionary = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canBeExecutedOnLowCardinalityDictionary() && has_type_with_dictionary && can_run_function_on_dictionary)
|
if (canBeExecutedOnLowCardinalityDictionary() && has_low_cardinality && num_full_low_cardinality_columns <= 1)
|
||||||
return std::make_shared<DataTypeWithDictionary>(getReturnTypeWithoutDictionary(args_without_dictionary));
|
return std::make_shared<DataTypeWithDictionary>(getReturnTypeWithoutDictionary(args_without_dictionary));
|
||||||
else
|
else
|
||||||
return getReturnTypeWithoutDictionary(args_without_dictionary);
|
return getReturnTypeWithoutDictionary(args_without_dictionary);
|
||||||
|
Loading…
Reference in New Issue
Block a user