From 701fdd77b4622ebd83bd52c22cb2229c953a47e9 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 16 Sep 2022 08:12:28 +0200 Subject: [PATCH] Fix wrong implementation of getDataAt for multidimensional arrays --- src/Columns/ColumnArray.cpp | 18 +++++++++++++----- ...ultidimensional_array_get_data_at.reference | 7 +++++++ ...2423_multidimensional_array_get_data_at.sql | 7 +++++++ 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 tests/queries/0_stateless/02423_multidimensional_array_get_data_at.reference create mode 100644 tests/queries/0_stateless/02423_multidimensional_array_get_data_at.sql diff --git a/src/Columns/ColumnArray.cpp b/src/Columns/ColumnArray.cpp index 7bddfc14707..960f0fa183d 100644 --- a/src/Columns/ColumnArray.cpp +++ b/src/Columns/ColumnArray.cpp @@ -151,22 +151,30 @@ void ColumnArray::get(size_t n, Field & res) const StringRef ColumnArray::getDataAt(size_t n) const { + assert(n < size()); + /** Returns the range of memory that covers all elements of the array. * Works for arrays of fixed length values. * For arrays of strings and arrays of arrays, the resulting chunk of memory may not be one-to-one correspondence with the elements, * since it contains only the data laid in succession, but not the offsets. */ - size_t offset_of_first_elem = offsetAt(n); - StringRef first = getData().getDataAtWithTerminatingZero(offset_of_first_elem); - size_t array_size = sizeAt(n); - if (array_size == 0) - return StringRef(first.data, 0); + if (array_size == 0) + return StringRef(nullptr, 0); + + size_t offset_of_first_elem = offsetAt(n); size_t offset_of_last_elem = getOffsets()[n] - 1; + + StringRef first = getData().getDataAtWithTerminatingZero(offset_of_first_elem); StringRef last = getData().getDataAtWithTerminatingZero(offset_of_last_elem); + if (first.empty()) + return last; + if (last.empty()) + return first; + return StringRef(first.data, last.data + last.size - first.data); } diff --git a/tests/queries/0_stateless/02423_multidimensional_array_get_data_at.reference b/tests/queries/0_stateless/02423_multidimensional_array_get_data_at.reference new file mode 100644 index 00000000000..eaf629aa9d9 --- /dev/null +++ b/tests/queries/0_stateless/02423_multidimensional_array_get_data_at.reference @@ -0,0 +1,7 @@ +! + +Hello + +Hello\0 +World\0 + diff --git a/tests/queries/0_stateless/02423_multidimensional_array_get_data_at.sql b/tests/queries/0_stateless/02423_multidimensional_array_get_data_at.sql new file mode 100644 index 00000000000..9bf7c9b49c2 --- /dev/null +++ b/tests/queries/0_stateless/02423_multidimensional_array_get_data_at.sql @@ -0,0 +1,7 @@ +SELECT formatRow('RawBLOB', [[[33]], []]); +SELECT formatRow('RawBLOB', [[[]], []]); +SELECT formatRow('RawBLOB', [[[[[[[0x48, 0x65, 0x6c, 0x6c, 0x6f]]]]]], []]); +SELECT formatRow('RawBLOB', []::Array(Array(Nothing))); +SELECT formatRow('RawBLOB', [[], [['Hello']]]); +SELECT formatRow('RawBLOB', [[['World']], []]); +SELECT formatRow('RawBLOB', []::Array(String));