This is an automated email from the ASF dual-hosted git repository.
pitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 9c37a70022e GH-50508: [C++] Support scalar values in AppendScalars
(#50584)
9c37a70022e is described below
commit 9c37a70022e30b219a7688f1aece585fecf63d78
Author: Mohamed mahmoud <[email protected]>
AuthorDate: Mon Jul 27 17:41:54 2026 +0300
GH-50508: [C++] Support scalar values in AppendScalars (#50584)
# Rationale for this change
`RunEndEncodedBuilder::AppendScalar` accepts regular scalar values, such as
`float32` directly. However, `RunEndEncodedBuilder::AppendScalars` only handled
`RunEndEncodedScalar` values.
This made the two APIs inconsistent. This PR updates `AppendScalars` to
support regular scalar values consistently with `AppendScalar`.
# What changes are included in this PR?
- Updated `RunEndEncodedBuilder::AppendScalars` to process each scalar
through `AppendScalar`.
- Added tests covering regular scalar values and nested
`RunEndEncodedScalar` values.
- Added tests verifying the expected run ends and values.
# Are these changes tested?
Yes. The relevant Run-End Encoded tests pass successfully.
# Are there any user-facing changes?
Yes. `RunEndEncodedBuilder::AppendScalars` now accepts regular scalar
values, such as `float32`, consistently with `AppendScalar`.
# Breaking changes
No
# Critical Fix
No.
* GitHub Issue: #50508
Authored-by: Moemen Mahmoud <[email protected]>
Signed-off-by: Antoine Pitrou <[email protected]>
---
cpp/src/arrow/array/array_run_end_test.cc | 53 +++++++++++++++++++++++++++++++
cpp/src/arrow/array/builder_run_end.cc | 5 ++-
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/cpp/src/arrow/array/array_run_end_test.cc
b/cpp/src/arrow/array/array_run_end_test.cc
index f2c493fb3a3..6cf50ccade1 100644
--- a/cpp/src/arrow/array/array_run_end_test.cc
+++ b/cpp/src/arrow/array/array_run_end_test.cc
@@ -366,6 +366,59 @@ TEST_P(TestRunEndEncodedArray, Builder) {
}
}
}
+TEST_P(TestRunEndEncodedArray, BuilderAppendScalarsPrimitiveScalar) {
+ auto value_type = float32();
+ auto ree_type = run_end_encoded(run_end_type, value_type);
+
+ ASSERT_OK_AND_ASSIGN(std::shared_ptr<ArrayBuilder> builder,
MakeBuilder(ree_type));
+
+ ASSERT_OK_AND_ASSIGN(auto v1, MakeScalar(float32(), 1.0f));
+ ASSERT_OK_AND_ASSIGN(auto v2, MakeScalar(float32(), 1.0f));
+ ASSERT_OK_AND_ASSIGN(auto v3, MakeScalar(float32(), 2.0f));
+ ASSERT_OK_AND_ASSIGN(auto v4, MakeScalar(float32(), 2.0f));
+ ASSERT_OK_AND_ASSIGN(auto v5, MakeScalar(float32(), 3.0f));
+
+ ScalarVector scalars = {v1, v2, v3, v4, v5};
+
+ ASSERT_OK(builder->AppendScalars(scalars));
+ ASSERT_EQ(builder->length(), 5);
+ ASSERT_OK_AND_ASSIGN(auto array, builder->Finish());
+ ASSERT_OK(array->ValidateFull());
+
+ auto ree_array = std::dynamic_pointer_cast<RunEndEncodedArray>(array);
+ ASSERT_NE(ree_array, NULLPTR);
+ auto expected_run_ends = ArrayFromJSON(run_end_type, "[2,4,5]");
+ auto expected_values = ArrayFromJSON(float32(), "[1,2,3]");
+ ASSERT_ARRAYS_EQUAL(*expected_run_ends, *ree_array->run_ends());
+ ASSERT_ARRAYS_EQUAL(*expected_values, *ree_array->values());
+}
+
+TEST_P(TestRunEndEncodedArray, BuilderAppendScalarsRunEndEncodedScalar) {
+ auto value_type = float32();
+ auto ree_type = run_end_encoded(run_end_type, value_type);
+
+ ASSERT_OK_AND_ASSIGN(std::shared_ptr<ArrayBuilder> builder,
MakeBuilder(ree_type));
+
+ ASSERT_OK_AND_ASSIGN(auto s1, MakeScalar(ree_type, *MakeScalar(float32(),
1.0f)));
+ ASSERT_OK_AND_ASSIGN(auto s2, MakeScalar(ree_type, *MakeScalar(float32(),
1.0f)));
+ ASSERT_OK_AND_ASSIGN(auto s3, MakeScalar(ree_type, *MakeScalar(float32(),
2.0f)));
+ ASSERT_OK_AND_ASSIGN(auto s4, MakeScalar(ree_type, *MakeScalar(float32(),
2.0f)));
+ ASSERT_OK_AND_ASSIGN(auto s5, MakeScalar(ree_type, *MakeScalar(float32(),
3.0f)));
+
+ ScalarVector scalars = {s1, s2, s3, s4, s5};
+
+ ASSERT_OK(builder->AppendScalars(scalars));
+ ASSERT_EQ(builder->length(), 5);
+ ASSERT_OK_AND_ASSIGN(auto array, builder->Finish());
+ ASSERT_OK(array->ValidateFull());
+
+ auto ree_array = std::dynamic_pointer_cast<RunEndEncodedArray>(array);
+ ASSERT_NE(ree_array, NULLPTR);
+ auto expected_run_ends = ArrayFromJSON(run_end_type, "[2,4,5]");
+ auto expected_values = ArrayFromJSON(float32(), "[1,2,3]");
+ ASSERT_ARRAYS_EQUAL(*expected_run_ends, *ree_array->run_ends());
+ ASSERT_ARRAYS_EQUAL(*expected_values, *ree_array->values());
+}
TEST_P(TestRunEndEncodedArray, BuilderReuseAfterFinish) {
// GH-45532: RunEndEncodedBuilder should clear dimensions after a Finish()
call
diff --git a/cpp/src/arrow/array/builder_run_end.cc
b/cpp/src/arrow/array/builder_run_end.cc
index 9199b5ab498..2edeaff504d 100644
--- a/cpp/src/arrow/array/builder_run_end.cc
+++ b/cpp/src/arrow/array/builder_run_end.cc
@@ -213,7 +213,10 @@ Status RunEndEncodedBuilder::AppendScalar(const Scalar&
scalar, int64_t n_repeat
}
Status RunEndEncodedBuilder::AppendScalars(const ScalarVector& scalars) {
- RETURN_NOT_OK(this->ArrayBuilder::AppendScalars(scalars));
+ if (scalars.empty()) return Status::OK();
+ for (const auto& scalar : scalars) {
+ RETURN_NOT_OK(AppendScalar(*scalar, 1));
+ }
UpdateDimensions(committed_logical_length_,
value_run_builder_->open_run_length());
return Status::OK();
}