From 16eca75d9635d30acc8e33cda491efed819faeec Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 6 Feb 2025 10:44:31 +0100 Subject: [PATCH 1/2] EXP: [C++] Require C++20 --- .github/workflows/cpp.yml | 4 +- .github/workflows/r.yml | 3 +- .github/workflows/ruby.yml | 2 +- c_glib/meson.build | 2 +- ci/appveyor-cpp-build.bat | 2 +- ci/docker/centos-7-cpp.dockerfile | 5 +- ci/scripts/cpp_build.sh | 4 +- ci/scripts/r_windows_build.sh | 2 +- cpp/CMakeLists.txt | 6 +- cpp/cmake_modules/GandivaAddBitcode.cmake | 2 +- cpp/cmake_modules/SetupCxxFlags.cmake | 8 +- cpp/examples/minimal_build/CMakeLists.txt | 4 +- cpp/examples/minimal_build/run_static.sh | 2 +- .../parquet/parquet_arrow/CMakeLists.txt | 4 +- cpp/examples/tutorial_examples/CMakeLists.txt | 2 +- cpp/meson.build | 2 +- cpp/src/arrow/array/array_nested.cc | 102 +++++++++++------- cpp/src/arrow/array/array_nested.h | 22 +++- .../compute/kernels/hash_aggregate_numeric.cc | 44 +++++--- cpp/src/arrow/filesystem/s3fs.cc | 24 ++--- cpp/src/arrow/record_batch.cc | 23 ++-- cpp/src/arrow/util/range.h | 5 +- cpp/src/arrow/util/string.h | 6 +- cpp/src/arrow/util/vector.h | 9 +- dev/release/verify-apt.sh | 2 +- dev/release/verify-yum.sh | 2 +- dev/tasks/homebrew-formulae/apache-arrow.rb | 2 +- .../apache-arrow/yum/almalinux-8/Dockerfile | 5 +- .../apache-arrow/yum/almalinux-9/Dockerfile | 1 - .../apache-arrow/yum/arrow.spec.in | 21 ++++ .../apache-arrow/yum/centos-7/Dockerfile | 3 +- .../yum/centos-8-stream/Dockerfile | 9 +- dev/tasks/linux-packages/yum/build.sh | 11 ++ dev/tasks/r/github.packages.yml | 2 + dev/tasks/tasks.yml | 7 +- docker-compose.yml | 2 +- docs/source/java/cdata.rst | 4 +- docs/source/python/integration/extending.rst | 2 +- matlab/CMakeLists.txt | 2 +- python/CMakeLists.txt | 2 +- python/pyarrow/tests/test_cython.py | 4 +- 41 files changed, 232 insertions(+), 138 deletions(-) diff --git a/.github/workflows/cpp.yml b/.github/workflows/cpp.yml index fee0cbf23d5..dda68487f64 100644 --- a/.github/workflows/cpp.yml +++ b/.github/workflows/cpp.yml @@ -290,7 +290,7 @@ jobs: include: - os: windows-2022 simd-level: AVX2 - title: AMD64 Windows 2022 AVX2 + title: AMD64 Windows 2022 C++20 AVX2 env: ARROW_BOOST_USE_SHARED: OFF ARROW_BUILD_BENCHMARKS: ON @@ -317,7 +317,7 @@ jobs: ARROW_WITH_ZLIB: ON ARROW_WITH_ZSTD: ON BOOST_SOURCE: BUNDLED - CMAKE_CXX_STANDARD: "17" + CMAKE_CXX_STANDARD: "20" CMAKE_GENERATOR: Ninja CMAKE_INSTALL_LIBDIR: bin CMAKE_INSTALL_PREFIX: /usr diff --git a/.github/workflows/r.yml b/.github/workflows/r.yml index 01cd2b1250d..0b121b6aea2 100644 --- a/.github/workflows/r.yml +++ b/.github/workflows/r.yml @@ -286,12 +286,13 @@ jobs: # static library. The R is not used here but R 4.1 was the last R to use # Rtools40. r-version: "4.1" - rtools-version: 40 + rtools-version: ${{ matrix.config.rtools }} Ncpus: 2 - name: Build Arrow C++ shell: bash env: MINGW_ARCH: ${{ matrix.config.arch }} + RTOOLS_VERSION: ${{ matrix.config.rtools }} run: ci/scripts/r_windows_build.sh - name: Rename libarrow.zip # So that they're unique when multiple are downloaded in the next step diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index b1ef66e921c..2b44f2d88eb 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -349,7 +349,7 @@ jobs: ARROW_WITH_SNAPPY: ON ARROW_WITH_ZLIB: ON ARROW_WITH_ZSTD: ON - CMAKE_CXX_STANDARD: "17" + CMAKE_CXX_STANDARD: "20" CMAKE_GENERATOR: Ninja CMAKE_INSTALL_PREFIX: "${{ github.workspace }}/dist" VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite' diff --git a/c_glib/meson.build b/c_glib/meson.build index d783cb399e8..f467b5ddc5b 100644 --- a/c_glib/meson.build +++ b/c_glib/meson.build @@ -21,7 +21,7 @@ project( 'arrow-glib', 'c', 'cpp', - default_options: ['c_std=c99', 'cpp_std=c++17'], + default_options: ['c_std=c99', 'cpp_std=c++20'], license: 'Apache-2.0', # Debian: # https://packages.debian.org/search?keywords=meson diff --git a/ci/appveyor-cpp-build.bat b/ci/appveyor-cpp-build.bat index eb6a2cb7201..428b1454779 100644 --- a/ci/appveyor-cpp-build.bat +++ b/ci/appveyor-cpp-build.bat @@ -93,7 +93,7 @@ cmake -G "%GENERATOR%" %ARROW_CMAKE_ARGS% ^ -DARROW_WITH_ZSTD=ON ^ -DCMAKE_BUILD_TYPE="Release" ^ -DCMAKE_CXX_FLAGS_RELEASE="/MD /Od /UNDEBUG" ^ - -DCMAKE_CXX_STANDARD=17 ^ + -DCMAKE_CXX_STANDARD=20 ^ -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%\Library ^ -DCMAKE_UNITY_BUILD=ON ^ -DCMAKE_VERBOSE_MAKEFILE=OFF ^ diff --git a/ci/docker/centos-7-cpp.dockerfile b/ci/docker/centos-7-cpp.dockerfile index b012a5abed2..e0e3a73fad3 100644 --- a/ci/docker/centos-7-cpp.dockerfile +++ b/ci/docker/centos-7-cpp.dockerfile @@ -25,7 +25,7 @@ RUN sed -i \ -e 's/mirror\.centos\.org/vault.centos.org/' \ /etc/yum.repos.d/*.repo -# devtoolset is required for C++17 +# devtoolset is required for C++20 RUN \ yum install -y \ centos-release-scl \ @@ -38,7 +38,8 @@ RUN \ /etc/yum.repos.d/CentOS-SCLo-scl*.repo && \ yum install -y \ curl \ - devtoolset-8 \ + devtoolset-11-gcc-c++ \ + devtoolset-11-make \ diffutils \ gcc-c++ \ libcurl-devel \ diff --git a/ci/scripts/cpp_build.sh b/ci/scripts/cpp_build.sh index e6e921b475b..7f17b5add7a 100755 --- a/ci/scripts/cpp_build.sh +++ b/ci/scripts/cpp_build.sh @@ -167,7 +167,7 @@ elif [ "${ARROW_EMSCRIPTEN:-OFF}" = "ON" ]; then -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE:-OFF} \ -DCMAKE_C_FLAGS="${CFLAGS:-}" \ -DCMAKE_CXX_FLAGS="${CXXFLAGS:-}" \ - -DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-17}" \ + -DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-20}" \ -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR:-lib} \ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX:-${ARROW_HOME}} \ -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD:-OFF} \ @@ -255,7 +255,7 @@ else -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE:-OFF} \ -DCMAKE_C_FLAGS="${CFLAGS:-}" \ -DCMAKE_CXX_FLAGS="${CXXFLAGS:-}" \ - -DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-17}" \ + -DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-20}" \ -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR:-lib} \ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX:-${ARROW_HOME}} \ -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD:-OFF} \ diff --git a/ci/scripts/r_windows_build.sh b/ci/scripts/r_windows_build.sh index de92addf083..ab84ed46647 100755 --- a/ci/scripts/r_windows_build.sh +++ b/ci/scripts/r_windows_build.sh @@ -44,7 +44,7 @@ mv mingw* build cd build # This may vary by system/CI provider -MSYS_LIB_DIR="/c/rtools40" +MSYS_LIB_DIR="/c/rtools${RTOOLS_VERSION}" # Untar the builds we made ls *.xz | xargs -n 1 tar -xJf diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 9854ac4a32c..5e660141156 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -625,10 +625,10 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARROW_CXXFLAGS}") # C++ specific flags. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CXX_COMMON_FLAGS} ${ARROW_CXXFLAGS}") -# Remove --std=c++17 to avoid errors from C compilers -string(REPLACE "-std=c++17" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) +# Remove -std=c++20 to avoid errors from C compilers +string(REPLACE "-std=c++20" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) -# Add C++-only flags, like -std=c++17 +# Add C++-only flags, like -std=c++20 set(CMAKE_CXX_FLAGS "${CXX_ONLY_FLAGS} ${CMAKE_CXX_FLAGS}") # ASAN / TSAN / UBSAN diff --git a/cpp/cmake_modules/GandivaAddBitcode.cmake b/cpp/cmake_modules/GandivaAddBitcode.cmake index 98847f8a186..5daf05f9e52 100644 --- a/cpp/cmake_modules/GandivaAddBitcode.cmake +++ b/cpp/cmake_modules/GandivaAddBitcode.cmake @@ -17,7 +17,7 @@ # Create bitcode for the given source file. function(gandiva_add_bitcode SOURCE) - set(CLANG_OPTIONS -std=c++17) + set(CLANG_OPTIONS -std=c++20) if(MSVC) # "19.20" means that it's compatible with Visual Studio 16 2019. # We can update this to "19.30" when we dropped support for Visual diff --git a/cpp/cmake_modules/SetupCxxFlags.cmake b/cpp/cmake_modules/SetupCxxFlags.cmake index fdb28b540e2..b5a0b48e8b8 100644 --- a/cpp/cmake_modules/SetupCxxFlags.cmake +++ b/cpp/cmake_modules/SetupCxxFlags.cmake @@ -137,12 +137,12 @@ endif() # This ensures that things like c++17 get passed correctly if(NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) -elseif(${CMAKE_CXX_STANDARD} VERSION_LESS 17) - message(FATAL_ERROR "Cannot set a CMAKE_CXX_STANDARD smaller than 17") + set(CMAKE_CXX_STANDARD 20) +elseif(${CMAKE_CXX_STANDARD} VERSION_LESS 20) + message(FATAL_ERROR "Cannot set a CMAKE_CXX_STANDARD smaller than 20") endif() -# We require a C++17 compliant compiler +# We require a C++20 compliant compiler set(CMAKE_CXX_STANDARD_REQUIRED ON) # ARROW-6848: Do not use GNU (or other CXX) extensions diff --git a/cpp/examples/minimal_build/CMakeLists.txt b/cpp/examples/minimal_build/CMakeLists.txt index 95dad34221a..463bbce48ea 100644 --- a/cpp/examples/minimal_build/CMakeLists.txt +++ b/cpp/examples/minimal_build/CMakeLists.txt @@ -24,10 +24,10 @@ option(ARROW_LINK_SHARED "Link to the Arrow shared library" ON) find_package(Arrow REQUIRED) if(NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD 20) endif() -# We require a C++17 compliant compiler +# We require a C++20 compliant compiler set(CMAKE_CXX_STANDARD_REQUIRED ON) if(NOT CMAKE_BUILD_TYPE) diff --git a/cpp/examples/minimal_build/run_static.sh b/cpp/examples/minimal_build/run_static.sh index 189f59a007b..26019227a7b 100755 --- a/cpp/examples/minimal_build/run_static.sh +++ b/cpp/examples/minimal_build/run_static.sh @@ -86,7 +86,7 @@ echo rm -rf $EXAMPLE_BUILD_DIR mkdir -p $EXAMPLE_BUILD_DIR -${CXX:-c++} -std=c++17 \ +${CXX:-c++} -std=c++20 \ -o $EXAMPLE_BUILD_DIR/arrow-example \ $EXAMPLE_DIR/example.cc \ $(PKG_CONFIG_PATH=$ARROW_BUILD_DIR/lib/pkgconfig \ diff --git a/cpp/examples/parquet/parquet_arrow/CMakeLists.txt b/cpp/examples/parquet/parquet_arrow/CMakeLists.txt index 189d17914d6..6c3dac8f2ce 100644 --- a/cpp/examples/parquet/parquet_arrow/CMakeLists.txt +++ b/cpp/examples/parquet/parquet_arrow/CMakeLists.txt @@ -28,10 +28,10 @@ option(PARQUET_LINK_SHARED "Link to the Parquet shared library" ON) # This ensures that things like -std=gnu++... get passed correctly if(NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD 20) endif() -# We require a C++17 compliant compiler +# We require a C++20 compliant compiler set(CMAKE_CXX_STANDARD_REQUIRED ON) # Look for installed packages the system diff --git a/cpp/examples/tutorial_examples/CMakeLists.txt b/cpp/examples/tutorial_examples/CMakeLists.txt index a6f8350c41d..ac25dea2b05 100644 --- a/cpp/examples/tutorial_examples/CMakeLists.txt +++ b/cpp/examples/tutorial_examples/CMakeLists.txt @@ -21,7 +21,7 @@ project(ArrowTutorialExamples) find_package(ArrowDataset) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra") set(CMAKE_BUILD_TYPE Release) diff --git a/cpp/meson.build b/cpp/meson.build index f4d006d31f4..89791d3a01c 100644 --- a/cpp/meson.build +++ b/cpp/meson.build @@ -26,7 +26,7 @@ project( 'buildtype=release', 'c_std=c99', 'warning_level=2', - 'cpp_std=c++17', + 'cpp_std=c++20', ], ) diff --git a/cpp/src/arrow/array/array_nested.cc b/cpp/src/arrow/array/array_nested.cc index 924d8b7e29a..987e402cd79 100644 --- a/cpp/src/arrow/array/array_nested.cc +++ b/cpp/src/arrow/array/array_nested.cc @@ -17,10 +17,10 @@ #include "arrow/array/array_nested.h" -#include #include #include #include +#include #include #include #include @@ -1004,10 +1004,18 @@ Result> FixedSizeListArray::Flatten( // ---------------------------------------------------------------------- // Struct +struct StructArray::Impl { + std::mutex mutex; + ArrayVector boxed_fields; +}; + +StructArray::~StructArray() = default; + StructArray::StructArray(const std::shared_ptr& data) { ARROW_CHECK_EQ(data->type->id(), Type::STRUCT); SetData(data); - boxed_fields_.resize(data->child_data.size()); + impl_ = std::make_unique(); + impl_->boxed_fields.resize(data_->child_data.size()); } StructArray::StructArray(const std::shared_ptr& type, int64_t length, @@ -1016,10 +1024,12 @@ StructArray::StructArray(const std::shared_ptr& type, int64_t length, int64_t offset) { ARROW_CHECK_EQ(type->id(), Type::STRUCT); SetData(ArrayData::Make(type, length, {std::move(null_bitmap)}, null_count, offset)); + data_->child_data.reserve(children.size()); for (const auto& child : children) { data_->child_data.push_back(child->data()); } - boxed_fields_.resize(children.size()); + impl_ = std::make_unique(); + impl_->boxed_fields.resize(data_->child_data.size()); } Result> StructArray::Make( @@ -1069,27 +1079,32 @@ const StructType* StructArray::struct_type() const { return checked_cast(data_->type.get()); } +std::shared_ptr StructArray::MakeBoxedField(int i) const { + std::shared_ptr field_data; + if (data_->offset != 0 || data_->child_data[i]->length != data_->length) { + field_data = data_->child_data[i]->Slice(data_->offset, data_->length); + } else { + field_data = data_->child_data[i]; + } + return MakeArray(field_data); +} + const ArrayVector& StructArray::fields() const { + std::lock_guard lock(impl_->mutex); for (int i = 0; i < num_fields(); ++i) { - (void)field(i); + if (impl_->boxed_fields[i] == nullptr) { + impl_->boxed_fields[i] = MakeBoxedField(i); + } } - return boxed_fields_; + return impl_->boxed_fields; } const std::shared_ptr& StructArray::field(int i) const { - std::shared_ptr result = std::atomic_load(&boxed_fields_[i]); - if (!result) { - std::shared_ptr field_data; - if (data_->offset != 0 || data_->child_data[i]->length != data_->length) { - field_data = data_->child_data[i]->Slice(data_->offset, data_->length); - } else { - field_data = data_->child_data[i]; - } - result = MakeArray(field_data); - std::atomic_store(&boxed_fields_[i], std::move(result)); - return boxed_fields_[i]; + std::lock_guard lock(impl_->mutex); + if (impl_->boxed_fields[i] == nullptr) { + impl_->boxed_fields[i] = MakeBoxedField(i); } - return boxed_fields_[i]; + return impl_->boxed_fields[i]; } std::shared_ptr StructArray::GetFieldByName(const std::string& name) const { @@ -1177,6 +1192,14 @@ Result> StructArray::GetFlattenedField(int index, // ---------------------------------------------------------------------- // UnionArray +struct UnionArray::Impl { + std::mutex mutex; + ArrayVector boxed_fields; +}; + +UnionArray::UnionArray() = default; +UnionArray::~UnionArray() = default; + void UnionArray::SetData(std::shared_ptr data) { this->Array::SetData(std::move(data)); @@ -1184,7 +1207,9 @@ void UnionArray::SetData(std::shared_ptr data) { ARROW_CHECK_GE(data_->buffers.size(), 2); raw_type_codes_ = data->GetValuesSafe(1); - boxed_fields_.resize(data_->child_data.size()); + + impl_ = std::make_unique(); + impl_->boxed_fields.resize(data_->child_data.size()); } void SparseUnionArray::SetData(std::shared_ptr data) { @@ -1198,16 +1223,16 @@ void SparseUnionArray::SetData(std::shared_ptr data) { void DenseUnionArray::SetData(const std::shared_ptr& data) { this->UnionArray::SetData(data); - ARROW_CHECK_EQ(data_->type->id(), Type::DENSE_UNION); ARROW_CHECK_EQ(data_->buffers.size(), 3); // No validity bitmap ARROW_CHECK_EQ(data_->buffers[0], nullptr); - raw_value_offsets_ = data->GetValuesSafe(2); } +SparseUnionArray::~SparseUnionArray() = default; + SparseUnionArray::SparseUnionArray(std::shared_ptr data) { SetData(std::move(data)); } @@ -1261,6 +1286,8 @@ Result> SparseUnionArray::GetFlattenedField( return MakeArray(child_data); } +DenseUnionArray::~DenseUnionArray() = default; + DenseUnionArray::DenseUnionArray(const std::shared_ptr& data) { SetData(data); } @@ -1352,26 +1379,29 @@ Result> SparseUnionArray::Make( return std::make_shared(std::move(internal_data)); } +std::shared_ptr UnionArray::MakeBoxedField(int i) const { + std::shared_ptr child_data = data_->child_data[i]->Copy(); + if (mode() == UnionMode::SPARSE) { + // Sparse union: need to adjust child if union is sliced + // (for dense unions, the need to lookup through the offsets + // makes this unnecessary) + if (data_->offset != 0 || child_data->length > data_->length) { + child_data = child_data->Slice(data_->offset, data_->length); + } + } + return MakeArray(child_data); +} + std::shared_ptr UnionArray::field(int i) const { - if (i < 0 || - static_cast(i) >= boxed_fields_.size()) { + if (i < 0 || i >= num_fields()) { return nullptr; } - std::shared_ptr result = std::atomic_load(&boxed_fields_[i]); - if (!result) { - std::shared_ptr child_data = data_->child_data[i]->Copy(); - if (mode() == UnionMode::SPARSE) { - // Sparse union: need to adjust child if union is sliced - // (for dense unions, the need to lookup through the offsets - // makes this unnecessary) - if (data_->offset != 0 || child_data->length > data_->length) { - child_data = child_data->Slice(data_->offset, data_->length); - } - } - result = MakeArray(child_data); - std::atomic_store(&boxed_fields_[i], result); + + std::lock_guard lock(impl_->mutex); + if (impl_->boxed_fields[i] == nullptr) { + impl_->boxed_fields[i] = MakeBoxedField(i); } - return result; + return impl_->boxed_fields[i]; } } // namespace arrow diff --git a/cpp/src/arrow/array/array_nested.h b/cpp/src/arrow/array/array_nested.h index f122f9378b5..91aa09786c9 100644 --- a/cpp/src/arrow/array/array_nested.h +++ b/cpp/src/arrow/array/array_nested.h @@ -661,6 +661,8 @@ class ARROW_EXPORT StructArray : public Array { public: using TypeClass = StructType; + ~StructArray() override; + explicit StructArray(const std::shared_ptr& data); StructArray(const std::shared_ptr& type, int64_t length, @@ -720,8 +722,10 @@ class ARROW_EXPORT StructArray : public Array { private: // For caching boxed child data - // XXX This is not handled in a thread-safe manner. - mutable ArrayVector boxed_fields_; + struct ARROW_NO_EXPORT Impl; + std::unique_ptr impl_; + + std::shared_ptr MakeBoxedField(int pos) const; }; // ---------------------------------------------------------------------- @@ -732,6 +736,8 @@ class ARROW_EXPORT UnionArray : public Array { public: using type_code_t = int8_t; + ~UnionArray() override; + /// Note that this buffer does not account for any slice offset const std::shared_ptr& type_codes() const { return data_->buffers[1]; } @@ -754,13 +760,19 @@ class ARROW_EXPORT UnionArray : public Array { std::shared_ptr field(int pos) const; protected: + UnionArray(); + void SetData(std::shared_ptr data); const type_code_t* raw_type_codes_; const UnionType* union_type_; + private: // For caching boxed child data - mutable std::vector> boxed_fields_; + struct ARROW_NO_EXPORT Impl; + std::unique_ptr impl_; + + std::shared_ptr MakeBoxedField(int pos) const; }; /// Concrete Array class for sparse union data @@ -768,6 +780,8 @@ class ARROW_EXPORT SparseUnionArray : public UnionArray { public: using TypeClass = SparseUnionType; + ~SparseUnionArray() override; + explicit SparseUnionArray(std::shared_ptr data); SparseUnionArray(std::shared_ptr type, int64_t length, ArrayVector children, @@ -821,6 +835,8 @@ class ARROW_EXPORT DenseUnionArray : public UnionArray { public: using TypeClass = DenseUnionType; + ~DenseUnionArray() override; + explicit DenseUnionArray(const std::shared_ptr& data); DenseUnionArray(std::shared_ptr type, int64_t length, ArrayVector children, diff --git a/cpp/src/arrow/compute/kernels/hash_aggregate_numeric.cc b/cpp/src/arrow/compute/kernels/hash_aggregate_numeric.cc index 4a318942af6..b15f831cf3c 100644 --- a/cpp/src/arrow/compute/kernels/hash_aggregate_numeric.cc +++ b/cpp/src/arrow/compute/kernels/hash_aggregate_numeric.cc @@ -849,21 +849,41 @@ using GroupedKurtosisImpl = ConcreteGroupedStatisticImpl; template