diff --git a/dbms/src/Columns/ColumnFunction.cpp b/dbms/src/Columns/ColumnFunction.cpp index 852f6f03adf..8bc239eb657 100644 --- a/dbms/src/Columns/ColumnFunction.cpp +++ b/dbms/src/Columns/ColumnFunction.cpp @@ -183,7 +183,7 @@ void ColumnFunction::appendArgument(const ColumnWithTypeAndName & column) auto index = captured_columns.size(); if (!column.type->equals(*argumnet_types[index])) throw Exception("Cannot capture column " + std::to_string(argumnet_types.size()) + - "because it has incompatible type: got " + column.type->getName() + + " because it has incompatible type: got " + column.type->getName() + ", but " + argumnet_types[index]->getName() + " is expected.", ErrorCodes::LOGICAL_ERROR); captured_columns.push_back(column); diff --git a/dbms/src/Functions/FunctionArrayMapped.h b/dbms/src/Functions/FunctionArrayMapped.h index c23e756d4d8..f14ac244a99 100644 --- a/dbms/src/Functions/FunctionArrayMapped.h +++ b/dbms/src/Functions/FunctionArrayMapped.h @@ -9,6 +9,7 @@ #include #include #include +#include namespace DB @@ -70,7 +71,7 @@ public: if (!array_type) throw Exception("Argument " + toString(i + 2) + " of function " + getName() + " must be array. Found " + arguments[i + 1]->getName() + " instead.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - nested_types[i] = array_type->getNestedType(); + nested_types[i] = removeLowCardinality(array_type->getNestedType()); } const DataTypeFunction * function_type = checkAndGetDataType(arguments[0].get()); @@ -121,7 +122,7 @@ public: /// The types of the remaining arguments are already checked in getLambdaArgumentTypes. - DataTypePtr return_type = data_type_function->getReturnType(); + DataTypePtr return_type = removeLowCardinality(data_type_function->getReturnType()); if (Impl::needBoolean() && !WhichDataType(return_type).isUInt8()) throw Exception("Expression for function " + getName() + " must return UInt8, found " + return_type->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); @@ -184,6 +185,8 @@ public: if (!column_const_array) throw Exception("Expected array column, found " + column_array_ptr->getName(), ErrorCodes::ILLEGAL_COLUMN); column_array_ptr = column_const_array->convertToFullColumn(); + if (column_array_ptr->lowCardinality()) + column_array_ptr = column_array_ptr->convertToFullColumnIfLowCardinality(); column_array = checkAndGetColumn(column_array_ptr.get()); } @@ -209,7 +212,8 @@ public: } arrays.emplace_back(ColumnWithTypeAndName(column_array->getDataPtr(), - array_type->getNestedType(), array_with_type_and_name.name)); + removeLowCardinality(array_type->getNestedType()), + array_with_type_and_name.name)); } /// Put all the necessary columns multiplied by the sizes of arrays into the block. @@ -217,8 +221,11 @@ public: auto * replicated_column_function = typeid_cast(replicated_column_function_ptr.get()); replicated_column_function->appendArguments(arrays); - block.getByPosition(result).column = Impl::execute(*column_first_array, - replicated_column_function->reduce().column); + auto lambda_result = replicated_column_function->reduce().column; + if (lambda_result->lowCardinality()) + lambda_result = lambda_result->convertToFullColumnIfLowCardinality(); + + block.getByPosition(result).column = Impl::execute(*column_first_array, lambda_result); } } }; diff --git a/dbms/tests/queries/0_stateless/00752_low_cardinality_lambda_argument.reference b/dbms/tests/queries/0_stateless/00752_low_cardinality_lambda_argument.reference new file mode 100644 index 00000000000..20076c05d5d --- /dev/null +++ b/dbms/tests/queries/0_stateless/00752_low_cardinality_lambda_argument.reference @@ -0,0 +1,10 @@ +[] +[0] +[0] +[0,2] +[0,2] +[0,2,4] +[0,2,4] +[0,2,4,6] +[0,2,4,6] +[0,2,4,6,8] diff --git a/dbms/tests/queries/0_stateless/00752_low_cardinality_lambda_argument.sql b/dbms/tests/queries/0_stateless/00752_low_cardinality_lambda_argument.sql new file mode 100644 index 00000000000..eea080d7b9a --- /dev/null +++ b/dbms/tests/queries/0_stateless/00752_low_cardinality_lambda_argument.sql @@ -0,0 +1,7 @@ +set allow_experimental_low_cardinality_type = 1; +drop table if exists test.lc_lambda; +create table test.lc_lambda (arr Array(LowCardinality(UInt64))) engine = Memory; +insert into test.lc_lambda select range(number) from system.numbers limit 10; +select arrayFilter(x -> x % 2 == 0, arr) from test.lc_lambda; +drop table if exists test.lc_lambda; +