Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport #46856 to 22.12: Fix a bug in Map data type #46872

Merged
merged 1 commit into from
Feb 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 10 additions & 8 deletions src/Functions/FunctionsHashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,7 @@ class FunctionAnyHash : public IFunction
{
/// NOTE: here, of course, you can do without the materialization of the column.
ColumnPtr full_column = col_from_const->convertToFullColumn();
executeArray<first>(type, &*full_column, vec_to);
executeArray<first>(type, full_column.get(), vec_to);
}
else
throw Exception("Illegal column " + column->getName()
Expand All @@ -1123,6 +1123,10 @@ class FunctionAnyHash : public IFunction
{
WhichDataType which(from_type);

if (icolumn->size() != vec_to.size())
throw Exception(ErrorCodes::LOGICAL_ERROR, "Argument column '{}' size {} doesn't match result column size {} of function {}",
icolumn->getName(), icolumn->size(), vec_to.size(), getName());

if (which.isUInt8()) executeIntType<UInt8, first>(icolumn, vec_to);
else if (which.isUInt16()) executeIntType<UInt16, first>(icolumn, vec_to);
else if (which.isUInt32()) executeIntType<UInt32, first>(icolumn, vec_to);
Expand Down Expand Up @@ -1181,10 +1185,9 @@ class FunctionAnyHash : public IFunction
const auto & type_map = assert_cast<const DataTypeMap &>(*type);
executeForArgument(type_map.getNestedType().get(), map->getNestedColumnPtr().get(), vec_to, is_first);
}
else if (const auto * const_map = checkAndGetColumnConstData<ColumnMap>(column))
else if (const auto * const_map = checkAndGetColumnConst<ColumnMap>(column))
{
const auto & type_map = assert_cast<const DataTypeMap &>(*type);
executeForArgument(type_map.getNestedType().get(), const_map->getNestedColumnPtr().get(), vec_to, is_first);
executeForArgument(type, const_map->convertToFullColumnIfConst().get(), vec_to, is_first);
}
else
{
Expand Down Expand Up @@ -1220,15 +1223,14 @@ class FunctionAnyHash : public IFunction

ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{
size_t rows = input_rows_count;
auto col_to = ColumnVector<ToType>::create(rows);
auto col_to = ColumnVector<ToType>::create(input_rows_count);

typename ColumnVector<ToType>::Container & vec_to = col_to->getData();

if (arguments.empty())
{
/// Constant random number from /dev/urandom is used as a hash value of empty list of arguments.
vec_to.assign(rows, static_cast<ToType>(0xe28dbde7fe22e41c));
/// Return a fixed random-looking magic number when input is empty
vec_to.assign(input_rows_count, static_cast<ToType>(0xe28dbde7fe22e41c));
}

/// The function supports arbitrary number of arguments of arbitrary types.
Expand Down
6 changes: 4 additions & 2 deletions src/Functions/IFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
# pragma GCC diagnostic pop
#endif


namespace DB
{

Expand Down Expand Up @@ -66,12 +67,12 @@ ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(

if (!low_cardinality_type)
throw Exception(ErrorCodes::LOGICAL_ERROR,
"Incompatible type for low cardinality column: {}",
"Incompatible type for LowCardinality column: {}",
column.type->getName());

if (can_be_executed_on_default_arguments)
{
/// Normal case, when function can be executed on values's default.
/// Normal case, when function can be executed on values' default.
column.column = low_cardinality_column->getDictionary().getNestedColumn();
indexes = low_cardinality_column->getIndexesPtr();
}
Expand Down Expand Up @@ -280,6 +281,7 @@ ColumnPtr IExecutableFunction::executeWithoutSparseColumns(const ColumnsWithType

auto res = executeWithoutLowCardinalityColumns(columns_without_low_cardinality, dictionary_type, new_input_rows_count, dry_run);
bool res_is_constant = isColumnConst(*res);

auto keys = res_is_constant
? res->cloneResized(1)->convertToFullColumnIfConst()
: res;
Expand Down
2 changes: 1 addition & 1 deletion src/Functions/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ class FunctionMapContainsKeyLike : public IFunction
}

size_t col_key_size = sub_map_column->size();
auto column = is_const? ColumnConst::create(std::move(sub_map_column), std::move(col_key_size)) : std::move(sub_map_column);
auto column = is_const ? ColumnConst::create(std::move(sub_map_column), std::move(col_key_size)) : std::move(sub_map_column);

ColumnsWithTypeAndName new_arguments =
{
Expand Down
6 changes: 6 additions & 0 deletions tests/queries/0_stateless/02673_map_hashing_msan.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
4786021384179797717
5368498105280294197
42 15687122600100720591
42 15687122600100720591
42 15687122600100720591
\N
7 changes: 7 additions & 0 deletions tests/queries/0_stateless/02673_map_hashing_msan.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
SELECT cityHash64(map(1, 'Hello'), CAST(materialize('World') AS LowCardinality(String)));
SELECT cityHash64(map(), CAST(materialize('') AS LowCardinality(Nullable(String))));
SELECT materialize(42) as last_element, cityHash64(map(), CAST(materialize('') AS LowCardinality(Nullable(String))), last_element) from numbers(3);

SET allow_suspicious_low_cardinality_types = 1;
CREATE TEMPORARY TABLE datetime__fuzz_14 (`d` LowCardinality(Nullable(UInt128)));
SELECT max(mapPopulateSeries(mapPopulateSeries(map(toInt64(1048), toInt64(9223), 3, -2147))), toInt64(1048), map('11', 257, '', NULL), cityHash64(*)) > NULL FROM (SELECT max(cityHash64(mapPopulateSeries(mapPopulateSeries(map(toInt64(1048), toInt64(2147), 655, -2147))), *)) > NULL, map(toInt64(-2147), toInt64(100.0001), -2147, NULL), mapPopulateSeries(map(toInt64(1024), toInt64(1048), 1048, -1)), map(toInt64(256), toInt64(NULL), -1, NULL), quantile(0.0001)(d) FROM datetime__fuzz_14 WITH TOTALS);