Repository: apache/arrow
File: cpp/src/arrow/array/array_run_end_test.cc (C++)

Code before:
      ASSERT_EQ(builder->length(), 516);
      ASSERT_OK(BuilderEquals(
          *builder, 516, "[1, 3, 105, 165, 205, 305, 405, 505, 515, 516]",
          R"(["unique", null, "common", "common", "appended", "common", "common", "appended", "", null])"));
      continue;
    }
    if (step == 13) {
      ASSERT_EQ(builder->length(), 516);
      ASSERT_EQ(*builder->type(), *run_end_encoded(run_end_type, utf8()));

      auto expected_run_ends =
          ArrayFromJSON(run_end_type, "[1, 3, 105, 165, 205, 305, 405, 505, 515, 516]");
      auto expected_values = ArrayFromJSON(
          value_type,
          R"(["unique", null, "common", "common", "appended", "common", "common", "appended", "", null])");

      ASSERT_OK_AND_ASSIGN(auto array, builder->Finish());
      auto ree_array = std::dynamic_pointer_cast<RunEndEncodedArray>(array);
      ASSERT_NE(ree_array, NULLPTR);
      ASSERT_ARRAYS_EQUAL(*expected_run_ends, *ree_array->run_ends());
      ASSERT_ARRAYS_EQUAL(*expected_values, *ree_array->values());
      ASSERT_EQ(array->length(), 516);
      ASSERT_EQ(array->offset(), 0);
      continue;
    }
    // Ensure builder->Finish() properly resets the builder state and is idempotent
    if (step == 14) {
      ASSERT_EQ(builder->length(), 516);
      ASSERT_OK(builder->Finish());
      ASSERT_EQ(builder->length(), 0);
      ASSERT_EQ(*builder->type(), *run_end_encoded(run_end_type, utf8()));

      ASSERT_OK(builder->Finish());
      ASSERT_OK(builder->Finish());
      ASSERT_EQ(builder->length(), 0);
      break;
    }
  }
}

TEST_P(TestRunEndEncodedArray, Validate) {
  auto run_ends_good = ArrayFromJSON(run_end_type, "[10, 20, 30, 40]");
  auto values = ArrayFromJSON(utf8(), R"(["A", "B", "C", null])");
  auto run_ends_with_zero = ArrayFromJSON(run_end_type, "[0, 20, 30, 40]");
  auto run_ends_with_null = ArrayFromJSON(run_end_type, "[0, 20, 30, null]");
  auto run_ends_not_ordered = ArrayFromJSON(run_end_type, "[10, 20, 40, 40]");
  auto run_ends_too_low = ArrayFromJSON(run_end_type, "[10, 20, 40, 39]");
  auto empty_ints = ArrayFromJSON(run_end_type, "[]");
  auto run_ends_require64 = ArrayFromJSON(int64(), "[10, 9223372036854775807]");
  int64_t long_length = 0;
  if (run_end_type->id() == Type::INT16) {

Review comment (suggestion):
maybe adding a new test without reuse prev?

```
// GH-45532: description...
TEST_P(TestRunEndEncodedArray, ReuseAfterFinish) {} 
```

Code after:
      ASSERT_EQ(builder->length(), 516);
      ASSERT_OK(BuilderEquals(
          *builder, 516, "[1, 3, 105, 165, 205, 305, 405, 505, 515, 516]",
          R"(["unique", null, "common", "common", "appended", "common", "common", "appended", "", null])"));
      continue;
    }
    if (step == 13) {
      ASSERT_EQ(builder->length(), 516);
      ASSERT_EQ(*builder->type(), *run_end_encoded(run_end_type, utf8()));

      auto expected_run_ends =
          ArrayFromJSON(run_end_type, "[1, 3, 105, 165, 205, 305, 405, 505, 515, 516]");
      auto expected_values = ArrayFromJSON(
          value_type,
          R"(["unique", null, "common", "common", "appended", "common", "common", "appended", "", null])");

      ASSERT_OK_AND_ASSIGN(auto array, builder->Finish());
      auto ree_array = std::dynamic_pointer_cast<RunEndEncodedArray>(array);
      ASSERT_NE(ree_array, NULLPTR);
      ASSERT_ARRAYS_EQUAL(*expected_run_ends, *ree_array->run_ends());
      ASSERT_ARRAYS_EQUAL(*expected_values, *ree_array->values());
      ASSERT_EQ(array->length(), 516);
      ASSERT_EQ(array->offset(), 0);
      break;
    }
  }
}

TEST_P(TestRunEndEncodedArray, BuilderReuseAfterFinish) {
  // GH-45532: RunEndEncodedBuilder should clear dimensions after a Finish() call
  auto ree_type = run_end_encoded(run_end_type, utf8());
  ASSERT_OK_AND_ASSIGN(std::shared_ptr<ArrayBuilder> builder, MakeBuilder(ree_type));
  ASSERT_OK(builder->AppendScalar(*MakeScalar("test"), 100));
  ASSERT_EQ(builder->length(), 100);
  ASSERT_OK(builder->Finish());
  ASSERT_EQ(builder->length(), 0);
  ASSERT_EQ(*builder->type(), *run_end_encoded(run_end_type, utf8()));
  ASSERT_OK(builder->Finish());
  ASSERT_OK(builder->Finish());
  ASSERT_EQ(builder->length(), 0);
}

TEST_P(TestRunEndEncodedArray, Validate) {
  auto run_ends_good = ArrayFromJSON(run_end_type, "[10, 20, 30, 40]");
  auto values = ArrayFromJSON(utf8(), R"(["A", "B", "C", null])");
  auto run_ends_with_zero = ArrayFromJSON(run_end_type, "[0, 20, 30, 40]");
  auto run_ends_with_null = ArrayFromJSON(run_end_type, "[0, 20, 30, null]");
  auto run_ends_not_ordered = ArrayFromJSON(run_end_type, "[10, 20, 40, 40]");
  auto run_ends_too_low = ArrayFromJSON(run_end_type, "[10, 20, 40, 39]");
  auto empty_ints = ArrayFromJSON(run_end_type, "[]");
  auto run_ends_require64 = ArrayFromJSON(int64(), "[10, 9223372036854775807]");