Merge pull request #52659 from CurtizJ/fix-crash-sparse-tuple

Fix crash in function `tuple` with one sparse column argument
This commit is contained in:
Anton Popov 2023-07-30 15:30:00 +02:00 committed by GitHub
commit 2ee83c9c45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 21 additions and 1 deletions

View File

@ -37,6 +37,7 @@ public:
bool canBeInsideNullable() const override { return false; } bool canBeInsideNullable() const override { return false; }
bool supportsSparseSerialization() const override { return true; } bool supportsSparseSerialization() const override { return true; }
bool canBeInsideSparseColumns() const override { return false; }
MutableColumnPtr createColumn() const override; MutableColumnPtr createColumn() const override;
MutableColumnPtr createColumn(const ISerialization & serialization) const override; MutableColumnPtr createColumn(const ISerialization & serialization) const override;

View File

@ -110,6 +110,7 @@ public:
/// TODO: support more types. /// TODO: support more types.
virtual bool supportsSparseSerialization() const { return !haveSubtypes(); } virtual bool supportsSparseSerialization() const { return !haveSubtypes(); }
virtual bool canBeInsideSparseColumns() const { return supportsSparseSerialization(); }
SerializationPtr getDefaultSerialization() const; SerializationPtr getDefaultSerialization() const;
SerializationPtr getSparseSerialization() const; SerializationPtr getSparseSerialization() const;

View File

@ -361,7 +361,7 @@ ColumnPtr IExecutableFunction::execute(const ColumnsWithTypeAndName & arguments,
/// If default of sparse column is changed after execution of function, convert to full column. /// If default of sparse column is changed after execution of function, convert to full column.
/// If there are any default in non-zero position after execution of function, convert to full column. /// If there are any default in non-zero position after execution of function, convert to full column.
/// Currently there is no easy way to rebuild sparse column with new offsets. /// Currently there is no easy way to rebuild sparse column with new offsets.
if (!result_type->supportsSparseSerialization() || !res->isDefaultAt(0) || res->getNumberOfDefaultRows() != 1) if (!result_type->canBeInsideSparseColumns() || !res->isDefaultAt(0) || res->getNumberOfDefaultRows() != 1)
{ {
const auto & offsets_data = assert_cast<const ColumnVector<UInt64> &>(*sparse_offsets).getData(); const auto & offsets_data = assert_cast<const ColumnVector<UInt64> &>(*sparse_offsets).getData();
return res->createWithOffsets(offsets_data, (*res)[0], input_rows_count, /*shift=*/ 1); return res->createWithOffsets(offsets_data, (*res)[0], input_rows_count, /*shift=*/ 1);

View File

@ -0,0 +1,4 @@
(0,0)
(0,0)
(0,1)
(0,NULL)

View File

@ -0,0 +1,14 @@
drop table if exists t_tuple_sparse;
create table t_tuple_sparse (a UInt64, b UInt64)
ENGINE = MergeTree ORDER BY tuple()
SETTINGS ratio_of_defaults_for_sparse_serialization = 0.0;
insert into t_tuple_sparse values (0, 0);
select (a, b) from t_tuple_sparse;
select (a, 0) from t_tuple_sparse;
select (a, 1) from t_tuple_sparse;
select (a, NULL) from t_tuple_sparse;
drop table if exists t_tuple_sparse;