From ce7f0e5ae781889cde1e621a35d07e2e38681611 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 6 Oct 2023 15:50:50 +0200 Subject: [PATCH] Fix functions execution over sparse columns Signed-off-by: Azat Khuzhin --- src/DataTypes/DataTypeFunction.h | 2 ++ src/Functions/IFunction.cpp | 16 +++++++++++++--- ...02891_functions_over_sparse_columns.reference | 10 ++++++++++ .../02891_functions_over_sparse_columns.sql | 4 ++++ 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 tests/queries/0_stateless/02891_functions_over_sparse_columns.reference create mode 100644 tests/queries/0_stateless/02891_functions_over_sparse_columns.sql diff --git a/src/DataTypes/DataTypeFunction.h b/src/DataTypes/DataTypeFunction.h index b57c0587dde..9acec676ce0 100644 --- a/src/DataTypes/DataTypeFunction.h +++ b/src/DataTypes/DataTypeFunction.h @@ -38,6 +38,8 @@ public: } bool equals(const IDataType & rhs) const override; + + bool supportsSparseSerialization() const override { return false; } }; } diff --git a/src/Functions/IFunction.cpp b/src/Functions/IFunction.cpp index d119b15733b..8aef1723479 100644 --- a/src/Functions/IFunction.cpp +++ b/src/Functions/IFunction.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -310,7 +311,10 @@ ColumnPtr IExecutableFunction::executeWithoutSparseColumns(const ColumnsWithType ColumnPtr IExecutableFunction::execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run) const { - if (useDefaultImplementationForSparseColumns()) + bool use_default_implementation_for_sparse_columns = useDefaultImplementationForSparseColumns(); + /// DataTypeFunction does not supports obtaining default (isDefaultAt()) + /// ColumnFunction does not uspport getting specific values + if (result_type->getTypeId() != TypeIndex::Function && use_default_implementation_for_sparse_columns) { size_t num_sparse_columns = 0; size_t num_full_columns = 0; @@ -373,8 +377,14 @@ ColumnPtr IExecutableFunction::execute(const ColumnsWithTypeAndName & arguments, convertSparseColumnsToFull(columns_without_sparse); return executeWithoutSparseColumns(columns_without_sparse, result_type, input_rows_count, dry_run); } - - return executeWithoutSparseColumns(arguments, result_type, input_rows_count, dry_run); + else if (use_default_implementation_for_sparse_columns) + { + auto columns_without_sparse = arguments; + convertSparseColumnsToFull(columns_without_sparse); + return executeWithoutSparseColumns(columns_without_sparse, result_type, input_rows_count, dry_run); + } + else + return executeWithoutSparseColumns(arguments, result_type, input_rows_count, dry_run); } void IFunctionOverloadResolver::checkNumberOfArguments(size_t number_of_arguments) const diff --git a/tests/queries/0_stateless/02891_functions_over_sparse_columns.reference b/tests/queries/0_stateless/02891_functions_over_sparse_columns.reference new file mode 100644 index 00000000000..309362c2122 --- /dev/null +++ b/tests/queries/0_stateless/02891_functions_over_sparse_columns.reference @@ -0,0 +1,10 @@ +[0] +[0] +[0] +[0] +[0] +[0] +[0] +[0] +[0] +[0] diff --git a/tests/queries/0_stateless/02891_functions_over_sparse_columns.sql b/tests/queries/0_stateless/02891_functions_over_sparse_columns.sql new file mode 100644 index 00000000000..982cd456b04 --- /dev/null +++ b/tests/queries/0_stateless/02891_functions_over_sparse_columns.sql @@ -0,0 +1,4 @@ +drop table if exists test; +create table test (key Int) engine=MergeTree() order by tuple() settings ratio_of_defaults_for_sparse_serialization=0.1; +insert into test select 0 from numbers(10); +select arrayMap(x -> (x <= key), [1]) from test;