Describe the enhancement requested
ArrayBuilder::AppendEmptyValue() was introduced and implemented in ARROW-25393 to write an arbitrary, well-defined value during StructBuilder::AppendNull(), as discussed here. In that context, the value written to the child builder is irrelevant because the parent entry is null.
At that time, RunEndEncodedBuilder did not yet exist; it was implemented about three years later in ARROW-32688. As a result, the current implementation does not appear to consider that the value written by AppendEmptyValue() may later become part of the value stream observed by RunEndEncodedBuilder.
this can be problematic for RunEndEncodedBuilder with floating-point values, as it can produce a zero value, which cannot be considered an empty value (Case 1). Even worse, it can be mistakenly confused with actual floating-point values (see the example below).
Case 1
auto ree_type = run_end_encoded(int32(), float32());
auto int32_builder = std::make_shared<Int32Builder>(pool_);
auto float_builder = std::make_shared<FloatBuilder>(pool_);
RunEndEncodedBuilder builder(pool_, int32_builder, float_builder, ree_type);
ASSERT_OK(builder.AppendEmptyValues(3));
ASSERT_OK(builder.AppendScalar(**MakeScalar(float32(), 3), 3));
ASSERT_OK_AND_ASSIGN(auto array, builder.Finish());
ARROW_LOGGER_INFO("", array->ToString());
Output:
-- run_ends:
[
3,
6
]
-- values:
[
0,
3
]
Case 2
auto ree_type = run_end_encoded(int32(), float32());
auto int32_builder = std::make_shared<Int32Builder>(pool_);
auto float_builder = std::make_shared<FloatBuilder>(pool_);
RunEndEncodedBuilder builder(pool_, int32_builder, float_builder, ree_type);
ASSERT_OK(builder.AppendEmptyValues(3));
ASSERT_OK(builder.AppendScalar(**MakeScalar(float32(), 0), 3));
ASSERT_OK_AND_ASSIGN(auto array, builder.Finish());
ARROW_LOGGER_INFO("", array->ToString());
Output:
-- run_ends:
[
3,
6
]
-- values:
[
0,
0
]
One possible solution would be to use NaN as the placeholder value for floating-point builders instead of 0.0f.
Component(s)
C++
Describe the enhancement requested
ArrayBuilder::AppendEmptyValue()was introduced and implemented in ARROW-25393 to write an arbitrary, well-defined value duringStructBuilder::AppendNull(), as discussed here. In that context, the value written to the child builder is irrelevant because the parent entry is null.At that time,
RunEndEncodedBuilderdid not yet exist; it was implemented about three years later in ARROW-32688. As a result, the current implementation does not appear to consider that the value written byAppendEmptyValue()may later become part of the value stream observed byRunEndEncodedBuilder.this can be problematic for RunEndEncodedBuilder with floating-point values, as it can produce a zero value, which cannot be considered an empty value (Case 1). Even worse, it can be mistakenly confused with actual floating-point values (see the example below).
Case 1
Output:
Case 2
Output:
One possible solution would be to use
NaNas the placeholder value for floating-point builders instead of0.0f.Component(s)
C++