diff --git a/docs/code-style.md b/docs/code-style.md index 672cda51..cb8c648e 100644 --- a/docs/code-style.md +++ b/docs/code-style.md @@ -237,6 +237,47 @@ virtual ~ClassName() = default; - Use `std::optional` for optional values. - Use `ScopeGuard` (in `src/paimon/common/utils/`) for RAII cleanup. +### Checked Class-Pointer Casts + +Include `paimon/common/utils/checked_cast.h` and use the Paimon cast helpers for conversions +between class pointers: + +- Use `checked_pointer_cast` instead of `std::static_pointer_cast` for `std::shared_ptr` + and `std::unique_ptr` conversions. +- Use `checked_cast` instead of `static_cast` for raw-pointer casts within a polymorphic + class hierarchy. +- Do not call `arrow::internal::checked_cast` or + `arrow::internal::checked_pointer_cast` directly. + +```cpp +#include "paimon/common/utils/checked_cast.h" + +std::shared_ptr struct_array = + checked_pointer_cast(array); +arrow::StringBuilder* string_builder = checked_cast(builder); +``` + +The helpers use Arrow's debug-checked implementation: casts are dynamic in debug builds and +static in release builds. They therefore express an internal type invariant; they do not validate +recoverable runtime input. For data originating from files, schemas, C Data Interface imports, or +other external boundaries, check for null and validate the Arrow type before casting: + +```cpp +if (!array || array->type_id() != arrow::Type::STRUCT) { + return Status::Invalid("expected a struct array"); +} +auto struct_array = checked_pointer_cast(array); +``` + +Do not add a null check after `checked_pointer_cast` as a substitute for runtime type validation; +such a check detects a mismatched type only in debug builds. Use `dynamic_cast` and check its +result when cast failure is an expected runtime branch and no explicit type discriminator is +available. + +These helpers do not apply to non-polymorphic pointer conversions such as `void*` callback +contexts, raw byte buffers, C FFI handles, or other opaque storage. Keep the appropriate explicit +cast for those cases. + --- ## Comments & Documentation diff --git a/src/paimon/common/data/binary_array_test.cpp b/src/paimon/common/data/binary_array_test.cpp index 83b8da2c..26d66792 100644 --- a/src/paimon/common/data/binary_array_test.cpp +++ b/src/paimon/common/data/binary_array_test.cpp @@ -26,11 +26,11 @@ #include "arrow/api.h" #include "arrow/array/array_nested.h" #include "arrow/ipc/json_simple.h" -#include "arrow/util/checked_cast.h" #include "gtest/gtest.h" #include "paimon/common/data/binary_array_writer.h" #include "paimon/common/data/binary_map.h" #include "paimon/common/data/columnar/columnar_array.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/testing/utils/binary_row_generator.h" #include "paimon/testing/utils/testharness.h" @@ -334,7 +334,7 @@ TEST(BinaryArrayTest, TestFromLongArray) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::int64()), R"([[123, null], [789], [12345], [12]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 2); BinaryArray ret = BinaryArray::FromLongArray(&array, pool.get()); @@ -365,7 +365,7 @@ TEST(BinaryArrayTest, TestFromAllNullLongArray) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::int64()), R"([[null, null], [789], [12345], [12]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 2); BinaryArray ret = BinaryArray::FromLongArray(&array, pool.get()); diff --git a/src/paimon/common/data/binary_row_writer.cpp b/src/paimon/common/data/binary_row_writer.cpp index 462a8561..6f002083 100644 --- a/src/paimon/common/data/binary_row_writer.cpp +++ b/src/paimon/common/data/binary_row_writer.cpp @@ -26,9 +26,9 @@ #include #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/binary_string.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/data/decimal.h" #include "paimon/data/timestamp.h" @@ -125,8 +125,7 @@ Result BinaryRowWriter::CreateFieldSetter( break; } case arrow::Type::type::TIMESTAMP: { - auto timestamp_type = - arrow::internal::checked_pointer_cast(field_type); + auto timestamp_type = checked_pointer_cast(field_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); field_setter = [field_idx, precision](const VariantType& field, BinaryRowWriter* writer) -> void { @@ -144,9 +143,7 @@ Result BinaryRowWriter::CreateFieldSetter( return field_setter; } case arrow::Type::type::DECIMAL128: { - auto* decimal_type = - arrow::internal::checked_cast(field_type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(field_type.get()); auto precision = decimal_type->precision(); auto scale = decimal_type->scale(); field_setter = [field_idx, precision, scale](const VariantType& field, diff --git a/src/paimon/common/data/blob_utils.cpp b/src/paimon/common/data/blob_utils.cpp index 41df10b9..ad2ad315 100644 --- a/src/paimon/common/data/blob_utils.cpp +++ b/src/paimon/common/data/blob_utils.cpp @@ -32,6 +32,7 @@ #include "paimon/common/data/blob_view_struct.h" #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/string_utils.h" namespace arrow { class Array; @@ -62,7 +63,7 @@ Result BlobUtils::SeparateBlobArray( const std::shared_ptr& struct_array, const std::set& inline_fields) { std::shared_ptr old_type = - std::static_pointer_cast(struct_array->type()); + checked_pointer_cast(struct_array->type()); const auto& old_fields = old_type->fields(); const auto& old_arrays = struct_array->fields(); @@ -146,12 +147,11 @@ Status BlobUtils::ValidateBlobInlineFields(const std::shared_ptr(field_array.get()); - if (!binary_array) { + if (field_array->type_id() != arrow::Type::LARGE_BINARY) { return Status::Invalid( fmt::format("cannot cast array for field {} to LargeBinaryArray", field_name)); } + const auto* binary_array = checked_cast(field_array.get()); for (int64_t row = 0; row < binary_array->length(); ++row) { if (binary_array->IsNull(row)) { continue; diff --git a/src/paimon/common/data/blob_utils_test.cpp b/src/paimon/common/data/blob_utils_test.cpp index d699d555..7309c575 100644 --- a/src/paimon/common/data/blob_utils_test.cpp +++ b/src/paimon/common/data/blob_utils_test.cpp @@ -27,6 +27,7 @@ #include "paimon/common/data/blob_descriptor.h" #include "paimon/common/data/blob_view_struct.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/data/blob.h" #include "paimon/memory/memory_pool.h" #include "paimon/testing/utils/testharness.h" @@ -164,7 +165,7 @@ TEST_F(BlobUtilsTest, SeparateBlobArray) { .ValueOrDie(); std::shared_ptr struct_array = - std::static_pointer_cast(raw_struct_array); + checked_pointer_cast(raw_struct_array); ASSERT_OK_AND_ASSIGN(auto separated, BlobUtils::SeparateBlobArray(struct_array, /*inline_fields=*/{})); @@ -217,7 +218,7 @@ TEST_F(BlobUtilsTest, SeparateBlobArrayWithPartialInline) { auto raw_struct_array = arrow::StructArray::Make({int_array, blob_array_1, blob_array_2}, schema->fields()) .ValueOrDie(); - auto struct_array = std::static_pointer_cast(raw_struct_array); + auto struct_array = checked_pointer_cast(raw_struct_array); // f2_blob_1 is inline, f3_blob_2 goes to blob ASSERT_OK_AND_ASSIGN(auto separated, BlobUtils::SeparateBlobArray( diff --git a/src/paimon/common/data/columnar/columnar_array.cpp b/src/paimon/common/data/columnar/columnar_array.cpp index 7a961067..6566aea9 100644 --- a/src/paimon/common/data/columnar/columnar_array.cpp +++ b/src/paimon/common/data/columnar/columnar_array.cpp @@ -24,12 +24,12 @@ #include "arrow/array/array_nested.h" #include "arrow/array/array_primitive.h" #include "arrow/type_traits.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "fmt/format.h" #include "paimon/common/data/columnar/columnar_batch_context.h" #include "paimon/common/data/columnar/columnar_map.h" #include "paimon/common/data/columnar/columnar_row_ref.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" namespace paimon { @@ -44,8 +44,7 @@ Status ColumnarArray::CheckNoNull() const { Decimal ColumnarArray::GetDecimal(int32_t pos, int32_t precision, int32_t scale) const { using ArrayType = typename arrow::TypeTraits::ArrayType; - auto array = arrow::internal::checked_cast(array_); - assert(array); + auto array = checked_cast(array_); arrow::Decimal128 decimal(array->GetValue(offset_ + pos)); return Decimal( precision, scale, @@ -56,11 +55,9 @@ Decimal ColumnarArray::GetDecimal(int32_t pos, int32_t precision, int32_t scale) Timestamp ColumnarArray::GetTimestamp(int32_t pos, int32_t precision) const { using ArrayType = typename arrow::TypeTraits::ArrayType; - auto array = arrow::internal::checked_cast(array_); - assert(array); + auto array = checked_cast(array_); int64_t data = array->Value(offset_ + pos); - auto timestamp_type = - arrow::internal::checked_pointer_cast(array->type()); + auto timestamp_type = checked_pointer_cast(array->type()); // for orc format, data is saved as nano, therefore, Timestamp convert should consider precision // in arrow array rather than input precision DateTimeUtils::TimeType time_type = DateTimeUtils::GetTimeTypeFromArrowType(timestamp_type); @@ -70,16 +67,14 @@ Timestamp ColumnarArray::GetTimestamp(int32_t pos, int32_t precision) const { } std::shared_ptr ColumnarArray::GetArray(int32_t pos) const { - auto list_array = arrow::internal::checked_cast(array_); - assert(list_array); + auto list_array = checked_cast(array_); int32_t offset = list_array->value_offset(offset_ + pos); int32_t length = list_array->value_length(offset_ + pos); return std::make_shared(list_array->values().get(), pool_, offset, length); } std::shared_ptr ColumnarArray::GetMap(int32_t pos) const { - auto map_array = arrow::internal::checked_cast(array_); - assert(map_array); + auto map_array = checked_cast(array_); int32_t offset = map_array->value_offset(offset_ + pos); int32_t length = map_array->value_length(offset_ + pos); return std::make_shared(map_array->keys(), map_array->items(), pool_, offset, @@ -87,8 +82,7 @@ std::shared_ptr ColumnarArray::GetMap(int32_t pos) const { } std::shared_ptr ColumnarArray::GetRow(int32_t pos, int32_t num_fields) const { - auto struct_array = arrow::internal::checked_cast(array_); - assert(struct_array); + auto struct_array = checked_cast(array_); auto row_ctx = std::make_shared(struct_array->fields(), pool_); return std::make_shared(std::move(row_ctx), offset_ + pos); } diff --git a/src/paimon/common/data/columnar/columnar_array_test.cpp b/src/paimon/common/data/columnar/columnar_array_test.cpp index 650d7eb2..c36b7edd 100644 --- a/src/paimon/common/data/columnar/columnar_array_test.cpp +++ b/src/paimon/common/data/columnar/columnar_array_test.cpp @@ -23,10 +23,10 @@ #include "arrow/api.h" #include "arrow/array/array_nested.h" #include "arrow/ipc/json_simple.h" -#include "arrow/util/checked_cast.h" #include "gtest/gtest.h" #include "paimon/common/data/internal_map.h" #include "paimon/common/data/internal_row.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/memory/bytes.h" #include "paimon/memory/memory_pool.h" @@ -40,7 +40,7 @@ TEST(ColumnarArrayTest, TestSimple) { arrow::ipc::internal::json::ArrayFromJSON( arrow::list(arrow::boolean()), "[[true, false], [true], [false], [false, true]]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/2, 1); ASSERT_EQ(array.Size(), 1); ASSERT_EQ(array.GetBoolean(0), true); @@ -51,7 +51,7 @@ TEST(ColumnarArrayTest, TestSimple) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::int8()), "[[1, 1, 2], [3], [2], [2]]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/5, 1); ASSERT_EQ(array.GetByte(0), 2); std::vector expected_array = {static_cast(2)}; @@ -61,7 +61,7 @@ TEST(ColumnarArrayTest, TestSimple) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::int16()), "[[1, 1, 2], [3], [2], [-4]]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 3); ASSERT_EQ(array.GetShort(0), 1); ASSERT_EQ(array.GetShort(1), 1); @@ -73,7 +73,7 @@ TEST(ColumnarArrayTest, TestSimple) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::int32()), "[[1, 1, 2], [3], [2], [-4]]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/3, 1); ASSERT_EQ(array.GetInt(0), 3); std::vector expected_array = {3}; @@ -83,7 +83,7 @@ TEST(ColumnarArrayTest, TestSimple) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::int64()), "[[1, 1, 2], [3], [2], [-4]]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/4, 1); ASSERT_EQ(array.GetLong(0), 2); std::vector expected_array = {2}; @@ -93,7 +93,7 @@ TEST(ColumnarArrayTest, TestSimple) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::int64()), "[[1, 1, 2], [3], [null], null]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/4, 1); ASSERT_NOK_WITH_MSG(array.ToLongArray(), "is null"); } @@ -101,7 +101,7 @@ TEST(ColumnarArrayTest, TestSimple) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON( arrow::list(arrow::float32()), "[[0.0, 1.1, 2.2], [3.3], [4.4], [5.5]]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 3); ASSERT_NEAR(array.GetFloat(1), 1.1, 0.001); std::vector expected_array = {0.0, 1.1, 2.2}; @@ -111,7 +111,7 @@ TEST(ColumnarArrayTest, TestSimple) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON( arrow::list(arrow::float64()), "[[0.0, 1.1, 2.2], [3.3], [4.4], [5.5]]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/3, 1); ASSERT_NEAR(array.GetDouble(0), 3.3, 0.001); std::vector expected_array = {3.3}; @@ -121,7 +121,7 @@ TEST(ColumnarArrayTest, TestSimple) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON( arrow::list(arrow::utf8()), R"([["abc", "def"], ["efg"], ["hello"], ["hi"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/4, 1); ASSERT_EQ(array.GetString(0).ToString(), "hi"); ASSERT_EQ(std::string(array.GetStringView(0)), "hi"); @@ -134,7 +134,7 @@ TEST(ColumnarArrayTest, TestComplexAndNestedType) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::date32()), "[[1, 1, 2], [3], [2], [-4]]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/3, 1); ASSERT_EQ(array.GetDate(0), 3); } @@ -143,7 +143,7 @@ TEST(ColumnarArrayTest, TestComplexAndNestedType) { arrow::list(arrow::decimal128(10, 3)), R"([["1.234", "1234.000"], ["-9876.543"], ["666.888"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 2); ASSERT_EQ(array.GetDecimal(0, 10, 3), Decimal(10, 3, 1234)); } @@ -153,7 +153,7 @@ TEST(ColumnarArrayTest, TestComplexAndNestedType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 1); auto ts = array.GetTimestamp(0, 9); ASSERT_EQ(ts, Timestamp(59000, 0)); @@ -162,7 +162,7 @@ TEST(ColumnarArrayTest, TestComplexAndNestedType) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON(arrow::list(arrow::binary()), R"([["aaa", "bb"], ["ccc"], ["bbb"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 2); ASSERT_EQ(*array.GetBinary(1), Bytes("bb", pool.get())); ASSERT_EQ(std::string(array.GetStringView(1)), "bb"); @@ -181,7 +181,7 @@ TEST(ColumnarArrayTest, TestComplexAndNestedType) { [[4, 1, 0, 2]] ])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 2); auto result_row = array.GetRow(1, 4); ASSERT_EQ(result_row->GetLong(0), 2); @@ -193,7 +193,7 @@ TEST(ColumnarArrayTest, TestComplexAndNestedType) { auto f1 = arrow::ipc::internal::json::ArrayFromJSON( arrow::list(arrow::list(arrow::int64())), "[[[1, 2, 3], [4, 5, 6]], []]") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 1); auto result_array = array.GetArray(0); auto inner_result_array = array.GetArray(0); @@ -207,7 +207,7 @@ TEST(ColumnarArrayTest, TestComplexAndNestedType) { [[[1, 3], [4, 4]]], [] ])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); ASSERT_TRUE(list_array); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/0, 1); auto result_key = array.GetMap(0)->KeyArray(); @@ -225,7 +225,7 @@ TEST(ColumnarArrayTest, TestTimestampType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/1, 2); auto ts = array.GetTimestamp(0, 0); ASSERT_EQ(ts, Timestamp(951866603000, 0)) << ts.GetMillisecond(); @@ -236,7 +236,7 @@ TEST(ColumnarArrayTest, TestTimestampType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23.001", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/1, 2); auto ts = array.GetTimestamp(0, 3); ASSERT_EQ(ts, Timestamp(951866603001, 0)) << ts.GetMillisecond(); @@ -247,7 +247,7 @@ TEST(ColumnarArrayTest, TestTimestampType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23.001001", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/1, 2); auto ts = array.GetTimestamp(0, 6); ASSERT_EQ(ts, Timestamp(951866603001, 1000)) << ts.GetMillisecond(); @@ -258,7 +258,7 @@ TEST(ColumnarArrayTest, TestTimestampType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23.001001001", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/1, 2); auto ts = array.GetTimestamp(0, 9); ASSERT_EQ(ts, Timestamp(951866603001, 1001)) << ts.GetMillisecond(); @@ -269,7 +269,7 @@ TEST(ColumnarArrayTest, TestTimestampType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/1, 2); auto ts = array.GetTimestamp(0, 0); ASSERT_EQ(ts, Timestamp(951866603000, 0)) << ts.GetMillisecond(); @@ -280,7 +280,7 @@ TEST(ColumnarArrayTest, TestTimestampType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23.001", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/1, 2); auto ts = array.GetTimestamp(0, 3); ASSERT_EQ(ts, Timestamp(951866603001, 0)) << ts.GetMillisecond(); @@ -291,7 +291,7 @@ TEST(ColumnarArrayTest, TestTimestampType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23.001001", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/1, 2); auto ts = array.GetTimestamp(0, 6); ASSERT_EQ(ts, Timestamp(951866603001, 1000)) << ts.GetMillisecond(); @@ -302,7 +302,7 @@ TEST(ColumnarArrayTest, TestTimestampType) { R"([["1970-01-01T00:00:59"],["2000-02-29T23:23:23.001001001", "1899-01-01T00:59:20"],["2033-05-18T03:33:20"]])") .ValueOrDie(); - auto list_array = arrow::internal::checked_pointer_cast(f1); + auto list_array = checked_pointer_cast(f1); auto array = ColumnarArray(list_array->values().get(), pool, /*offset=*/1, 2); auto ts = array.GetTimestamp(0, 9); ASSERT_EQ(ts, Timestamp(951866603001, 1001)) << ts.GetMillisecond(); diff --git a/src/paimon/common/data/columnar/columnar_row.cpp b/src/paimon/common/data/columnar/columnar_row.cpp index bc7b1505..5099b42b 100644 --- a/src/paimon/common/data/columnar/columnar_row.cpp +++ b/src/paimon/common/data/columnar/columnar_row.cpp @@ -24,19 +24,18 @@ #include "arrow/array/array_nested.h" #include "arrow/array/array_primitive.h" #include "arrow/type_traits.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "paimon/common/data/columnar/columnar_array.h" #include "paimon/common/data/columnar/columnar_batch_context.h" #include "paimon/common/data/columnar/columnar_map.h" #include "paimon/common/data/columnar/columnar_row_ref.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" namespace paimon { Decimal ColumnarRow::GetDecimal(int32_t pos, int32_t precision, int32_t scale) const { using ArrayType = typename arrow::TypeTraits::ArrayType; - auto array = arrow::internal::checked_cast(array_vec_[pos]); - assert(array); + auto array = checked_cast(array_vec_[pos]); arrow::Decimal128 decimal(array->GetValue(row_id_)); return Decimal( precision, scale, @@ -47,11 +46,9 @@ Decimal ColumnarRow::GetDecimal(int32_t pos, int32_t precision, int32_t scale) c Timestamp ColumnarRow::GetTimestamp(int32_t pos, int32_t precision) const { using ArrayType = typename arrow::TypeTraits::ArrayType; - auto array = arrow::internal::checked_cast(array_vec_[pos]); - assert(array); + auto array = checked_cast(array_vec_[pos]); int64_t data = array->Value(row_id_); - auto timestamp_type = - arrow::internal::checked_pointer_cast(array->type()); + auto timestamp_type = checked_pointer_cast(array->type()); // for orc format, data is saved as nano, therefore, Timestamp convert should consider precision // in arrow array rather than input precision DateTimeUtils::TimeType time_type = DateTimeUtils::GetTimeTypeFromArrowType(timestamp_type); @@ -61,8 +58,7 @@ Timestamp ColumnarRow::GetTimestamp(int32_t pos, int32_t precision) const { } std::shared_ptr ColumnarRow::GetRow(int32_t pos, int32_t num_fields) const { - auto struct_array = arrow::internal::checked_cast(array_vec_[pos]); - assert(struct_array); + auto struct_array = checked_cast(array_vec_[pos]); // NOTE: For performance, the returned nested row does NOT hold shared ownership of the parent // StructArray. Callers must ensure the parent ColumnarRow (or its underlying RecordBatch) // outlives the returned row to avoid dangling pointers. @@ -70,16 +66,14 @@ std::shared_ptr ColumnarRow::GetRow(int32_t pos, int32_t num_fields } std::shared_ptr ColumnarRow::GetArray(int32_t pos) const { - auto list_array = arrow::internal::checked_cast(array_vec_[pos]); - assert(list_array); + auto list_array = checked_cast(array_vec_[pos]); int32_t offset = list_array->value_offset(row_id_); int32_t length = list_array->value_length(row_id_); return std::make_shared(list_array->values().get(), pool_, offset, length); } std::shared_ptr ColumnarRow::GetMap(int32_t pos) const { - auto map_array = arrow::internal::checked_cast(array_vec_[pos]); - assert(map_array); + auto map_array = checked_cast(array_vec_[pos]); int32_t offset = map_array->value_offset(row_id_); int32_t length = map_array->value_length(row_id_); return std::make_shared(map_array->keys(), map_array->items(), pool_, offset, diff --git a/src/paimon/common/data/columnar/columnar_row_ref.cpp b/src/paimon/common/data/columnar/columnar_row_ref.cpp index 9aaba461..d73e6b77 100644 --- a/src/paimon/common/data/columnar/columnar_row_ref.cpp +++ b/src/paimon/common/data/columnar/columnar_row_ref.cpp @@ -23,17 +23,16 @@ #include "arrow/array/array_nested.h" #include "arrow/array/array_primitive.h" #include "arrow/type_traits.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "paimon/common/data/columnar/columnar_array.h" #include "paimon/common/data/columnar/columnar_map.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" namespace paimon { Decimal ColumnarRowRef::GetDecimal(int32_t pos, int32_t precision, int32_t scale) const { using ArrayType = typename arrow::TypeTraits::ArrayType; - auto array = arrow::internal::checked_cast(ctx_->array_vec[pos].get()); - assert(array); + auto array = checked_cast(ctx_->array_vec[pos].get()); arrow::Decimal128 decimal(array->GetValue(row_id_)); return Decimal( precision, scale, @@ -44,11 +43,9 @@ Decimal ColumnarRowRef::GetDecimal(int32_t pos, int32_t precision, int32_t scale Timestamp ColumnarRowRef::GetTimestamp(int32_t pos, int32_t precision) const { using ArrayType = typename arrow::TypeTraits::ArrayType; - auto array = arrow::internal::checked_cast(ctx_->array_vec[pos].get()); - assert(array); + auto array = checked_cast(ctx_->array_vec[pos].get()); int64_t data = array->Value(row_id_); - auto timestamp_type = - arrow::internal::checked_pointer_cast(array->type()); + auto timestamp_type = checked_pointer_cast(array->type()); // for orc format, data is saved as nano, therefore, Timestamp convert should consider precision // in arrow array rather than input precision DateTimeUtils::TimeType time_type = DateTimeUtils::GetTimeTypeFromArrowType(timestamp_type); @@ -58,26 +55,20 @@ Timestamp ColumnarRowRef::GetTimestamp(int32_t pos, int32_t precision) const { } std::shared_ptr ColumnarRowRef::GetRow(int32_t pos, int32_t num_fields) const { - auto struct_array = - arrow::internal::checked_cast(ctx_->array_vec[pos].get()); - assert(struct_array); + auto struct_array = checked_cast(ctx_->array_vec[pos].get()); auto nested_ctx = std::make_shared(struct_array->fields(), ctx_->pool); return std::make_shared(std::move(nested_ctx), row_id_); } std::shared_ptr ColumnarRowRef::GetArray(int32_t pos) const { - auto list_array = - arrow::internal::checked_cast(ctx_->array_vec[pos].get()); - assert(list_array); + auto list_array = checked_cast(ctx_->array_vec[pos].get()); int32_t offset = list_array->value_offset(row_id_); int32_t length = list_array->value_length(row_id_); return std::make_shared(list_array->values().get(), ctx_->pool, offset, length); } std::shared_ptr ColumnarRowRef::GetMap(int32_t pos) const { - auto map_array = - arrow::internal::checked_cast(ctx_->array_vec[pos].get()); - assert(map_array); + auto map_array = checked_cast(ctx_->array_vec[pos].get()); int32_t offset = map_array->value_offset(row_id_); int32_t length = map_array->value_length(row_id_); return std::make_shared(map_array->keys(), map_array->items(), ctx_->pool, offset, diff --git a/src/paimon/common/data/columnar/columnar_utils.h b/src/paimon/common/data/columnar/columnar_utils.h index c1270ed5..ede3155b 100644 --- a/src/paimon/common/data/columnar/columnar_utils.h +++ b/src/paimon/common/data/columnar/columnar_utils.h @@ -29,7 +29,7 @@ #include "arrow/array/array_dict.h" #include "arrow/array/array_primitive.h" #include "arrow/type_traits.h" -#include "arrow/util/checked_cast.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/memory/bytes.h" namespace paimon { @@ -43,8 +43,7 @@ class ColumnarUtils { template static ValueType GetGenericValue(const arrow::Array* array, int32_t pos) { using ArrayType = typename arrow::TypeTraits::ArrayType; - const auto* typed_array = arrow::internal::checked_cast(array); - assert(typed_array); + const auto* typed_array = checked_cast(array); return typed_array->Value(pos); } @@ -52,51 +51,35 @@ class ColumnarUtils { auto type_id = array->type_id(); bool is_dict = (type_id == arrow::Type::type::DICTIONARY); if (!is_dict) { - const auto* typed_array = - arrow::internal::checked_cast(array); - assert(typed_array); + const auto* typed_array = checked_cast(array); return typed_array->GetView(pos); } else { - const auto* typed_array = - arrow::internal::checked_cast(array); - assert(typed_array); - auto dict_type = - arrow::internal::checked_pointer_cast(array->type()); - assert(dict_type); + const auto* typed_array = checked_cast(array); + auto dict_type = checked_pointer_cast(array->type()); auto value_type_id = dict_type->value_type()->id(); auto index_type_id = dict_type->index_type()->id(); int64_t dict_index = -1; if (index_type_id == arrow::Type::type::INT8) { - auto indices = - arrow::internal::checked_cast(typed_array->indices().get()); - assert(indices); + auto indices = checked_cast(typed_array->indices().get()); dict_index = indices->Value(pos); } else if (index_type_id == arrow::Type::type::INT16) { - auto indices = - arrow::internal::checked_cast(typed_array->indices().get()); - assert(indices); + auto indices = checked_cast(typed_array->indices().get()); dict_index = indices->Value(pos); } else if (index_type_id == arrow::Type::type::INT32) { - auto indices = - arrow::internal::checked_cast(typed_array->indices().get()); - assert(indices); + auto indices = checked_cast(typed_array->indices().get()); dict_index = indices->Value(pos); } else if (index_type_id == arrow::Type::type::INT64) { - auto indices = - arrow::internal::checked_cast(typed_array->indices().get()); - assert(indices); + auto indices = checked_cast(typed_array->indices().get()); dict_index = indices->Value(pos); } assert(dict_index >= 0); if (value_type_id == arrow::Type::type::STRING) { - auto dictionary = arrow::internal::checked_cast( - typed_array->dictionary().get()); - assert(dictionary); + auto dictionary = + checked_cast(typed_array->dictionary().get()); return dictionary->GetView(dict_index); } else if (value_type_id == arrow::Type::type::LARGE_STRING) { - auto dictionary = arrow::internal::checked_cast( - typed_array->dictionary().get()); - assert(dictionary); + auto dictionary = + checked_cast(typed_array->dictionary().get()); return dictionary->GetView(dict_index); } assert(false); diff --git a/src/paimon/common/data/internal_row.cpp b/src/paimon/common/data/internal_row.cpp index abc54e7c..24b6b5be 100644 --- a/src/paimon/common/data/internal_row.cpp +++ b/src/paimon/common/data/internal_row.cpp @@ -24,8 +24,8 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/status.h" @@ -104,9 +104,7 @@ Result InternalRow::CreateFieldGetter( break; } case arrow::Type::type::TIMESTAMP: { - auto timestamp_type = - arrow::internal::checked_pointer_cast(field_type); - assert(timestamp_type); + auto timestamp_type = checked_pointer_cast(field_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); field_getter = [field_idx, precision](const InternalRow& row) -> VariantType { return row.GetTimestamp(field_idx, precision); @@ -114,9 +112,7 @@ Result InternalRow::CreateFieldGetter( break; } case arrow::Type::type::DECIMAL128: { - auto* decimal_type = - arrow::internal::checked_cast(field_type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(field_type.get()); auto precision = decimal_type->precision(); auto scale = decimal_type->scale(); field_getter = [field_idx, precision, scale](const InternalRow& row) -> VariantType { @@ -125,8 +121,7 @@ Result InternalRow::CreateFieldGetter( break; } case arrow::Type::type::STRUCT: { - auto* struct_type = arrow::internal::checked_cast(field_type.get()); - assert(struct_type); + auto* struct_type = checked_cast(field_type.get()); auto num_fields = struct_type->num_fields(); field_getter = [field_idx, num_fields](const InternalRow& row) -> VariantType { return row.GetRow(field_idx, num_fields); diff --git a/src/paimon/common/data/record_batch_test.cpp b/src/paimon/common/data/record_batch_test.cpp index 4b503228..9fdb2146 100644 --- a/src/paimon/common/data/record_batch_test.cpp +++ b/src/paimon/common/data/record_batch_test.cpp @@ -33,6 +33,7 @@ #include "arrow/status.h" #include "arrow/type.h" #include "gtest/gtest.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/result.h" #include "paimon/status.h" #include "paimon/testing/utils/testharness.h" @@ -53,10 +54,10 @@ TEST(RecordBatchTest, TestSimple) { struct_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto int_builder = static_cast(struct_builder.field_builder(1)); - auto long_builder = static_cast(struct_builder.field_builder(2)); - auto bool_builder = static_cast(struct_builder.field_builder(3)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(1)); + auto long_builder = checked_cast(struct_builder.field_builder(2)); + auto bool_builder = checked_cast(struct_builder.field_builder(3)); for (int32_t i = 0; i < 10; ++i) { ASSERT_TRUE(struct_builder.Append().ok()); ASSERT_TRUE(string_builder->Append("20240813").ok()); diff --git a/src/paimon/common/data/serializer/binary_serializer_utils.cpp b/src/paimon/common/data/serializer/binary_serializer_utils.cpp index 544e0ca2..c0248cd6 100644 --- a/src/paimon/common/data/serializer/binary_serializer_utils.cpp +++ b/src/paimon/common/data/serializer/binary_serializer_utils.cpp @@ -21,6 +21,7 @@ #include "paimon/common/data/binary_array_writer.h" #include "paimon/common/data/binary_row_writer.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" namespace paimon { Result> BinarySerializerUtils::WriteBinaryArray( @@ -30,8 +31,7 @@ Result> BinarySerializerUtils::WriteBinaryArray( return binary_array; } auto binary_array = std::make_shared(); - auto list_type = std::dynamic_pointer_cast(type); - assert(list_type); + auto list_type = checked_pointer_cast(type); auto value_type = list_type->value_type(); // TODO(xinyu.lxy): reuse BinaryWriter BinaryArrayWriter binary_writer(binary_array.get(), value->Size(), @@ -49,8 +49,7 @@ Result> BinarySerializerUtils::WriteBinaryMap( if (auto binary_map = std::dynamic_pointer_cast(value)) { return binary_map; } - auto map_type = std::dynamic_pointer_cast(type); - assert(map_type); + auto map_type = checked_pointer_cast(type); auto key_type = map_type->key_type(); auto value_type = map_type->item_type(); auto key_array = value->KeyArray(); @@ -82,8 +81,7 @@ Result> BinarySerializerUtils::WriteBinaryRow( return binary_row; } - auto struct_type = std::dynamic_pointer_cast(type); - assert(struct_type); + auto struct_type = checked_pointer_cast(type); auto field_count = struct_type->num_fields(); auto binary_row = std::make_shared(field_count); BinaryRowWriter binary_writer(binary_row.get(), /*initial_size=*/1024, pool); @@ -155,8 +153,7 @@ Status BinarySerializerUtils::WriteBinaryData(const std::shared_ptr(type); - assert(timestamp_type); + auto timestamp_type = checked_pointer_cast(type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); if (getter->IsNullAt(pos)) { // compatible with Java Paimon @@ -171,8 +168,7 @@ Status BinarySerializerUtils::WriteBinaryData(const std::shared_ptr(type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(type.get()); auto precision = decimal_type->precision(); auto scale = decimal_type->scale(); if (getter->IsNullAt(pos)) { diff --git a/src/paimon/common/data/serializer/row_compacted_serializer.cpp b/src/paimon/common/data/serializer/row_compacted_serializer.cpp index 491f3a65..411dae68 100644 --- a/src/paimon/common/data/serializer/row_compacted_serializer.cpp +++ b/src/paimon/common/data/serializer/row_compacted_serializer.cpp @@ -25,6 +25,7 @@ #include "paimon/common/data/data_define.h" #include "paimon/common/data/generic_row.h" #include "paimon/common/data/serializer/binary_serializer_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/fields_comparator.h" @@ -123,14 +124,10 @@ Result RowCompactedSerializer::CreateSliceComparat auto field_type = schema->field(i)->type(); field_infos[i].type_id = field_type->id(); if (field_type->id() == arrow::Type::type::TIMESTAMP) { - auto timestamp_type = - arrow::internal::checked_pointer_cast(field_type); - assert(timestamp_type); + auto timestamp_type = checked_pointer_cast(field_type); field_infos[i].precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); } else if (field_type->id() == arrow::Type::type::DECIMAL128) { - auto decimal_type = - arrow::internal::checked_pointer_cast(field_type); - assert(decimal_type); + auto decimal_type = checked_pointer_cast(field_type); field_infos[i].precision = decimal_type->precision(); field_infos[i].scale = decimal_type->scale(); } @@ -269,8 +266,7 @@ Result RowCompactedSerializer::CreateFieldR break; } case arrow::Type::type::TIMESTAMP: { - auto timestamp_type = - arrow::internal::checked_pointer_cast(field_type); + auto timestamp_type = checked_pointer_cast(field_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); field_reader = [precision](int32_t pos, RowReader* reader) -> Result { PAIMON_ASSIGN_OR_RAISE(VariantType value, reader->ReadTimestamp(precision)); @@ -279,9 +275,7 @@ Result RowCompactedSerializer::CreateFieldR break; } case arrow::Type::type::DECIMAL128: { - auto* decimal_type = - arrow::internal::checked_cast(field_type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(field_type.get()); auto precision = decimal_type->precision(); auto scale = decimal_type->scale(); field_reader = [precision, scale](int32_t pos, @@ -306,8 +300,7 @@ Result RowCompactedSerializer::CreateFieldR break; } case arrow::Type::type::STRUCT: { - auto* struct_type = arrow::internal::checked_cast(field_type.get()); - assert(struct_type); + auto* struct_type = checked_cast(field_type.get()); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr serializer, RowCompactedSerializer::Create(arrow::schema(struct_type->fields()), pool)); @@ -403,8 +396,7 @@ Result RowCompactedSerializer::CreateFieldW break; } case arrow::Type::type::TIMESTAMP: { - auto timestamp_type = - arrow::internal::checked_pointer_cast(field_type); + auto timestamp_type = checked_pointer_cast(field_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); field_writer = [precision](int32_t pos, const VariantType& field, RowWriter* writer) -> Status { @@ -414,9 +406,7 @@ Result RowCompactedSerializer::CreateFieldW break; } case arrow::Type::type::DECIMAL128: { - auto* decimal_type = - arrow::internal::checked_cast(field_type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(field_type.get()); auto precision = decimal_type->precision(); field_writer = [precision](int32_t pos, const VariantType& field, RowWriter* writer) -> Status { @@ -441,8 +431,7 @@ Result RowCompactedSerializer::CreateFieldW break; } case arrow::Type::type::STRUCT: { - auto struct_type = arrow::internal::checked_pointer_cast(field_type); - assert(struct_type); + auto struct_type = checked_pointer_cast(field_type); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr serializer, RowCompactedSerializer::Create(arrow::schema(struct_type->fields()), pool)); diff --git a/src/paimon/common/data/shredding/map_shared_shredding_file_reader.cpp b/src/paimon/common/data/shredding/map_shared_shredding_file_reader.cpp index 342c6adb..b7c84095 100644 --- a/src/paimon/common/data/shredding/map_shared_shredding_file_reader.cpp +++ b/src/paimon/common/data/shredding/map_shared_shredding_file_reader.cpp @@ -31,6 +31,7 @@ #include "paimon/common/reader/reader_utils.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/casting/casting_utils.h" #include "paimon/core/utils/nested_projection_utils.h" @@ -61,8 +62,8 @@ void CollectPhysicalColumns( continue; } if (sub_field->name() == MapSharedShreddingDefine::kOverflow) { - *overflow_array = arrow::internal::checked_pointer_cast( - physical_struct_array->field(i)); + *overflow_array = + checked_pointer_cast(physical_struct_array->field(i)); continue; } (*physical_column_name_to_array)[sub_field->name()] = physical_struct_array->field(i); @@ -76,8 +77,7 @@ class FullMapReadPlan : public MapFieldReadPlan { std::vector>&& selected_key_ids) : MapFieldReadPlan(logical_field, physical_read_field), selected_key_ids_(std::move(selected_key_ids)), - logical_map_type_( - arrow::internal::checked_pointer_cast(logical_field->type())) {} + logical_map_type_(checked_pointer_cast(logical_field->type())) {} Result> Materialize( const std::shared_ptr& physical_array, @@ -135,8 +135,7 @@ Result> MapFieldReadPlanFactory::CreateMapRead logical_map_field->name(), logical_map_field->type()->ToString())); } - auto logical_map_type = - arrow::internal::checked_pointer_cast(logical_map_field->type()); + auto logical_map_type = checked_pointer_cast(logical_map_field->type()); PAIMON_ASSIGN_OR_RAISE(std::vector selected_keys, NestedProjectionUtils::GetMapSelectedKeys(logical_map_field)); if (selected_keys.empty()) { @@ -176,8 +175,7 @@ Result> MapFieldReadPlanFactory::CreateSharedS PAIMON_ASSIGN_OR_RAISE( std::vector selected_keys, NestedProjectionUtils::ValidateMapSharedShreddingAccessField(selected_keys_field)); - auto selected_keys_type = - arrow::internal::checked_pointer_cast(selected_keys_field->type()); + auto selected_keys_type = checked_pointer_cast(selected_keys_field->type()); const auto& value_field = selected_keys_type->field(0); std::set selected_physical_column_ids; @@ -262,12 +260,12 @@ Result> MapSharedShreddingFileReader::GetFileSche Result> MapSharedShreddingFileReader::ToLogicalMapField( const std::shared_ptr& physical_field) { - auto physical_type = - arrow::internal::checked_pointer_cast(physical_field->type()); - if (!physical_type) { + if (!physical_field || !physical_field->type() || + physical_field->type()->id() != arrow::Type::STRUCT) { return Status::Invalid(fmt::format("shared-shredding field {} is not a physical struct", - physical_field->name())); + physical_field ? physical_field->name() : "")); } + auto physical_type = checked_pointer_cast(physical_field->type()); std::shared_ptr value_type; bool value_nullable = true; for (const auto& child : physical_type->fields()) { @@ -334,10 +332,10 @@ Result MapSharedShreddingFileReader::NextBatch auto& [c_array, c_schema] = batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto struct_array = arrow::internal::checked_pointer_cast(arrow_array); - if (!struct_array) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("cannot cast batch to StructArray in MapSharedShreddingFileReader"); } + auto struct_array = checked_pointer_cast(arrow_array); arrow::ArrayVector resolved_arrays = struct_array->fields(); arrow::FieldVector resolved_fields = struct_array->struct_type()->fields(); @@ -364,25 +362,25 @@ Result MapSharedShreddingFileReader::NextBatch Result> FullMapReadPlan::Materialize( const std::shared_ptr& physical_array, arrow::MemoryPool* arrow_pool) const { - auto physical_struct_array = - arrow::internal::checked_pointer_cast(physical_array); - if (!physical_struct_array) { + if (!physical_array || physical_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid(fmt::format("cannot cast physical shredding field {} to StructArray", LogicalField()->name())); } + auto physical_struct_array = checked_pointer_cast(physical_array); const std::string& shredding_field_name = LogicalField()->name(); - auto field_mapping_array = arrow::internal::checked_pointer_cast( - physical_struct_array->GetFieldByName(MapSharedShreddingDefine::kFieldMapping)); - if (!field_mapping_array) { + auto field_mapping = + physical_struct_array->GetFieldByName(MapSharedShreddingDefine::kFieldMapping); + if (!field_mapping || field_mapping->type_id() != arrow::Type::LIST) { return Status::Invalid( fmt::format("cannot find __field_mapping for field {}", shredding_field_name)); } - auto field_mapping_values = - arrow::internal::checked_pointer_cast(field_mapping_array->values()); - if (!field_mapping_values) { + auto field_mapping_array = checked_pointer_cast(field_mapping); + auto mapping_values = field_mapping_array->values(); + if (!mapping_values || mapping_values->type_id() != arrow::Type::INT32) { return Status::Invalid("__field_mapping values is not an Int32Array"); } + auto field_mapping_values = checked_pointer_cast(mapping_values); std::map> physical_column_name_to_array; std::shared_ptr overflow_array; @@ -399,11 +397,14 @@ Result> FullMapReadPlan::Materialize( std::shared_ptr overflow_keys; std::shared_ptr overflow_items; if (overflow_array) { - overflow_keys = - arrow::internal::checked_pointer_cast(overflow_array->keys()); + auto overflow_key_array = overflow_array->keys(); + if (!overflow_key_array || overflow_key_array->type_id() != arrow::Type::INT32) { + return Status::Invalid("__overflow map keys is not an Int32Array"); + } + overflow_keys = checked_pointer_cast(overflow_key_array); overflow_items = overflow_array->items(); - if (!overflow_keys || !overflow_items) { - return Status::Invalid("__overflow map has invalid key or item array"); + if (!overflow_items) { + return Status::Invalid("__overflow map item array is null"); } if (overflow_items->type_id() == arrow::Type::DICTIONARY) { PAIMON_ASSIGN_OR_RAISE( @@ -415,16 +416,19 @@ Result> FullMapReadPlan::Materialize( PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::unique_ptr map_builder_base, arrow::MakeBuilder(logical_map_type_, arrow_pool)); - auto* map_builder = dynamic_cast(map_builder_base.get()); - if (!map_builder) { + if (!map_builder_base || !map_builder_base->type() || + map_builder_base->type()->id() != arrow::Type::MAP) { return Status::Invalid( fmt::format("cannot create MapBuilder for field {}", shredding_field_name)); } - auto* key_builder = dynamic_cast(map_builder->key_builder()); - if (!key_builder) { + auto* map_builder = checked_cast(map_builder_base.get()); + auto* key_builder_base = map_builder->key_builder(); + if (!key_builder_base || !key_builder_base->type() || + key_builder_base->type()->id() != arrow::Type::STRING) { return Status::Invalid(fmt::format("map key builder is not a StringBuilder for field {}", shredding_field_name)); } + auto* key_builder = checked_cast(key_builder_base); arrow::ArrayBuilder* item_builder = map_builder->item_builder(); if (!item_builder) { return Status::Invalid( @@ -501,26 +505,25 @@ Result> FullMapReadPlan::Materialize( Result> SharedSelectedKeysReadPlan::Materialize( const std::shared_ptr& physical_array, arrow::MemoryPool* arrow_pool) const { - auto physical_struct_array = - arrow::internal::checked_pointer_cast(physical_array); - if (!physical_struct_array) { + if (!physical_array || physical_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid(fmt::format("cannot cast physical shredding field {} to StructArray", LogicalField()->name())); } - auto selected_keys_type = - arrow::internal::checked_pointer_cast(LogicalField()->type()); + auto physical_struct_array = checked_pointer_cast(physical_array); + auto selected_keys_type = checked_pointer_cast(LogicalField()->type()); - auto field_mapping_array = arrow::internal::checked_pointer_cast( - physical_struct_array->GetFieldByName(MapSharedShreddingDefine::kFieldMapping)); - if (!field_mapping_array) { + auto field_mapping = + physical_struct_array->GetFieldByName(MapSharedShreddingDefine::kFieldMapping); + if (!field_mapping || field_mapping->type_id() != arrow::Type::LIST) { return Status::Invalid( fmt::format("cannot find __field_mapping for field {}", LogicalField()->name())); } - auto field_mapping_values = - arrow::internal::checked_pointer_cast(field_mapping_array->values()); - if (!field_mapping_values) { + auto field_mapping_array = checked_pointer_cast(field_mapping); + auto mapping_values = field_mapping_array->values(); + if (!mapping_values || mapping_values->type_id() != arrow::Type::INT32) { return Status::Invalid("__field_mapping values is not an Int32Array"); } + auto field_mapping_values = checked_pointer_cast(mapping_values); std::shared_ptr value_type = selected_keys_type->field(0)->type(); std::map> physical_column_name_to_array; @@ -538,11 +541,14 @@ Result> SharedSelectedKeysReadPlan::Materialize( std::shared_ptr overflow_keys; std::shared_ptr overflow_items; if (overflow_array) { - overflow_keys = - arrow::internal::checked_pointer_cast(overflow_array->keys()); + auto overflow_key_array = overflow_array->keys(); + if (!overflow_key_array || overflow_key_array->type_id() != arrow::Type::INT32) { + return Status::Invalid("__overflow map keys is not an Int32Array"); + } + overflow_keys = checked_pointer_cast(overflow_key_array); overflow_items = overflow_array->items(); - if (!overflow_keys || !overflow_items) { - return Status::Invalid("__overflow map has invalid key or item array"); + if (!overflow_items) { + return Status::Invalid("__overflow map item array is null"); } if (overflow_items->type_id() == arrow::Type::DICTIONARY) { PAIMON_ASSIGN_OR_RAISE( @@ -555,11 +561,12 @@ Result> SharedSelectedKeysReadPlan::Materialize( std::unique_ptr access_builder_base; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(access_builder_base, arrow::MakeBuilder(LogicalField()->type(), arrow_pool)); - auto* access_builder = dynamic_cast(access_builder_base.get()); - if (!access_builder) { + if (!access_builder_base || !access_builder_base->type() || + access_builder_base->type()->id() != arrow::Type::STRUCT) { return Status::Invalid( fmt::format("selected-key MAP field {} is not a STRUCT", LogicalField()->name())); } + auto* access_builder = checked_cast(access_builder_base.get()); PAIMON_RETURN_NOT_OK_FROM_ARROW(access_builder->Reserve(physical_struct_array->length())); for (int64_t row = 0; row < physical_struct_array->length(); ++row) { @@ -631,17 +638,15 @@ Result> SharedSelectedKeysReadPlan::Materialize( Result> DefaultSelectedKeysReadPlan::Materialize( const std::shared_ptr& physical_array, arrow::MemoryPool* arrow_pool) const { - auto map_array = arrow::internal::checked_pointer_cast(physical_array); - if (!map_array) { + if (!physical_array || physical_array->type_id() != arrow::Type::MAP) { return Status::Invalid( fmt::format("cannot cast default-layout selected-key field {} to " "MapArray", LogicalField()->name())); } - auto selected_keys_type = - arrow::internal::checked_pointer_cast(LogicalField()->type()); - auto physical_map_type = - arrow::internal::checked_pointer_cast(PhysicalReadField()->type()); + auto map_array = checked_pointer_cast(physical_array); + auto selected_keys_type = checked_pointer_cast(LogicalField()->type()); + auto physical_map_type = checked_pointer_cast(PhysicalReadField()->type()); std::shared_ptr items = map_array->items(); if (items->type_id() == arrow::Type::DICTIONARY) { @@ -653,11 +658,12 @@ Result> DefaultSelectedKeysReadPlan::Materialize( std::unique_ptr access_builder_base; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(access_builder_base, arrow::MakeBuilder(LogicalField()->type(), arrow_pool)); - auto* access_builder = dynamic_cast(access_builder_base.get()); - if (!access_builder) { + if (!access_builder_base || !access_builder_base->type() || + access_builder_base->type()->id() != arrow::Type::STRUCT) { return Status::Invalid( fmt::format("selected-key MAP field {} is not a STRUCT", LogicalField()->name())); } + auto* access_builder = checked_cast(access_builder_base.get()); PAIMON_RETURN_NOT_OK_FROM_ARROW(access_builder->Reserve(map_array->length())); for (int64_t row = 0; row < map_array->length(); ++row) { diff --git a/src/paimon/common/data/shredding/map_shared_shredding_file_reader_test.cpp b/src/paimon/common/data/shredding/map_shared_shredding_file_reader_test.cpp index 408469e3..80f5046b 100644 --- a/src/paimon/common/data/shredding/map_shared_shredding_file_reader_test.cpp +++ b/src/paimon/common/data/shredding/map_shared_shredding_file_reader_test.cpp @@ -34,6 +34,7 @@ #include "paimon/common/data/shredding/map_shared_shredding_utils.h" #include "paimon/common/data/shredding/map_shredding_defs.h" #include "paimon/common/fs/external_path_provider.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/append/append_only_writer.h" #include "paimon/core/compact/noop_compact_manager.h" #include "paimon/core/core_options.h" @@ -111,8 +112,7 @@ class MapSharedShreddingFileReaderTest : public ::testing::Test { continue; } EXPECT_OK_AND_ASSIGN(auto meta, MapSharedShreddingUtils::DeserializeMetadata(metadata)); - auto physical_type = - arrow::internal::checked_pointer_cast(field->type()); + auto physical_type = checked_pointer_cast(field->type()); std::shared_ptr item_field; for (const auto& child : physical_type->fields()) { if (child->name() != MapSharedShreddingDefine::kFieldMapping && @@ -122,7 +122,7 @@ class MapSharedShreddingFileReaderTest : public ::testing::Test { } } EXPECT_TRUE(item_field); - auto map_type = arrow::internal::checked_pointer_cast(arrow::map( + auto map_type = checked_pointer_cast(arrow::map( arrow::utf8(), arrow::field("value", item_field->type(), item_field->nullable()))); std::shared_ptr logical_map_field = field->WithType(map_type); if (selected_keys_str.has_value()) { @@ -334,7 +334,7 @@ TEST_F(MapSharedShreddingFileReaderTest, TestSelectedKeysStructProjection) { } TEST_F(MapSharedShreddingFileReaderTest, TestSelectedKeysStructProjectionFromDefaultMap) { - auto map_type = arrow::internal::checked_pointer_cast( + auto map_type = checked_pointer_cast( arrow::map(arrow::utf8(), arrow::field("value", arrow::int64()))); auto file_schema = arrow::schema({arrow::field("id", arrow::int32()), arrow::field("tags", map_type)}); diff --git a/src/paimon/common/data/shredding/map_shared_shredding_schema_utils.cpp b/src/paimon/common/data/shredding/map_shared_shredding_schema_utils.cpp index 36978d04..e15a4ac5 100644 --- a/src/paimon/common/data/shredding/map_shared_shredding_schema_utils.cpp +++ b/src/paimon/common/data/shredding/map_shared_shredding_schema_utils.cpp @@ -30,6 +30,7 @@ #include "paimon/common/data/shredding/map_shared_shredding_utils.h" #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -62,7 +63,7 @@ Result> MapSharedShreddingAcces fmt::format("MapSharedShreddingAccessBuilder requires MAP field, got {}", field->type()->ToString())); } - auto map_type = arrow::internal::checked_pointer_cast(field->type()); + auto map_type = checked_pointer_cast(field->type()); if (map_type->key_type()->id() != arrow::Type::STRING) { return Status::Invalid(fmt::format( "MapSharedShreddingAccessBuilder only supports MAP with STRING keys, got {}", diff --git a/src/paimon/common/data/shredding/map_shared_shredding_schema_utils_test.cpp b/src/paimon/common/data/shredding/map_shared_shredding_schema_utils_test.cpp index bfe26a37..194acb29 100644 --- a/src/paimon/common/data/shredding/map_shared_shredding_schema_utils_test.cpp +++ b/src/paimon/common/data/shredding/map_shared_shredding_schema_utils_test.cpp @@ -28,6 +28,7 @@ #include "gtest/gtest.h" #include "paimon/common/data/shredding/map_shared_shredding_utils.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/testing/utils/testharness.h" namespace paimon::test { @@ -60,7 +61,7 @@ TEST(MapSharedShreddingAccessBuilderTest, BuildSelectedKeysField) { ASSERT_EQ(field->type()->id(), arrow::Type::STRUCT); ASSERT_FALSE(field->nullable()); - auto struct_type = arrow::internal::checked_pointer_cast(field->type()); + auto struct_type = checked_pointer_cast(field->type()); ASSERT_EQ(struct_type->num_fields(), 2); ASSERT_EQ(struct_type->field(0)->name(), "age"); ASSERT_EQ(struct_type->field(1)->name(), "score"); diff --git a/src/paimon/common/data/shredding/map_shared_shredding_utils.cpp b/src/paimon/common/data/shredding/map_shared_shredding_utils.cpp index 6ba2b43c..c345f314 100644 --- a/src/paimon/common/data/shredding/map_shared_shredding_utils.cpp +++ b/src/paimon/common/data/shredding/map_shared_shredding_utils.cpp @@ -30,6 +30,7 @@ #include "paimon/common/compression/block_decompressor.h" #include "paimon/common/data/shredding/map_shared_shredding_batch_converter.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/string_utils.h" #include "paimon/core/core_options.h" #include "paimon/core/options/map_storage_layout.h" @@ -60,7 +61,7 @@ bool MapSharedShreddingUtils::IsShreddingKeyMap( if (arrow_type->id() != arrow::Type::MAP) { return false; } - auto map_type = std::static_pointer_cast(arrow_type); + auto map_type = checked_pointer_cast(arrow_type); return map_type->key_type()->id() == arrow::Type::STRING; } @@ -131,7 +132,7 @@ Result> MapSharedShreddingUtils::LogicalToPhysica fmt::format("Field '{}' is expected to be MAP type, but got '{}'.", field->name(), field->type()->name())); } - auto map_type = std::static_pointer_cast(field->type()); + auto map_type = checked_pointer_cast(field->type()); auto value_type = map_type->item_type(); bool value_nullable = map_type->item_field()->nullable(); auto physical_type = BuildPhysicalStructType(value_type, it->second, value_nullable); diff --git a/src/paimon/common/data/shredding/map_shared_shredding_write_plan_factory.cpp b/src/paimon/common/data/shredding/map_shared_shredding_write_plan_factory.cpp index 04c821a7..acf44d52 100644 --- a/src/paimon/common/data/shredding/map_shared_shredding_write_plan_factory.cpp +++ b/src/paimon/common/data/shredding/map_shared_shredding_write_plan_factory.cpp @@ -25,6 +25,7 @@ #include "paimon/common/data/shredding/map_shared_shredding_context.h" #include "paimon/common/data/shredding/map_shared_shredding_utils.h" #include "paimon/common/data/shredding/map_shredding_defs.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -81,7 +82,7 @@ MapSharedShreddingWritePlanFactory::CreateMetadataFinalizer( const std::shared_ptr& converter, const std::string& compression) const { // The converter is created by CreateConverter above; the concrete type is guaranteed. - auto map_converter = std::static_pointer_cast(converter); + auto map_converter = checked_pointer_cast(converter); return MapSharedShreddingUtils::BuildMetadataFinalizer(map_converter, compression, map_converter->GetPhysicalSchema()); } diff --git a/src/paimon/common/data/shredding/shredding_file_reader.cpp b/src/paimon/common/data/shredding/shredding_file_reader.cpp index cb0eaa28..0f47350d 100644 --- a/src/paimon/common/data/shredding/shredding_file_reader.cpp +++ b/src/paimon/common/data/shredding/shredding_file_reader.cpp @@ -26,6 +26,7 @@ #include "fmt/format.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -86,7 +87,7 @@ Result ShreddingFileReader::NextBatchWithBitma if (arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("cannot cast batch to StructArray in ShreddingFileReader"); } - auto struct_array = std::static_pointer_cast(arrow_array); + auto struct_array = checked_pointer_cast(arrow_array); arrow::ArrayVector resolved_arrays = struct_array->fields(); arrow::FieldVector resolved_fields = struct_array->struct_type()->fields(); diff --git a/src/paimon/common/data/variant/infer_variant_shredding_schema.cpp b/src/paimon/common/data/variant/infer_variant_shredding_schema.cpp index c1aee113..0fdfb34f 100644 --- a/src/paimon/common/data/variant/infer_variant_shredding_schema.cpp +++ b/src/paimon/common/data/variant/infer_variant_shredding_schema.cpp @@ -27,11 +27,11 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/data/variant/variant_binary_util.h" #include "paimon/common/data/variant/variant_defs.h" #include "paimon/common/data/variant/variant_shredding_write_plan.h" #include "paimon/common/data/variant/variant_type_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -90,7 +90,7 @@ std::shared_ptr MergeDecimalWithLong(const arrow::Decimal128Type& return SimpleSchema::Scalar(arrow::int64()); } // A long can always fit in a decimal(19, 0). - auto long_decimal = std::static_pointer_cast(arrow::decimal128(19, 0)); + auto long_decimal = checked_pointer_cast(arrow::decimal128(19, 0)); return MergeDecimal(d, *long_decimal); } @@ -381,7 +381,7 @@ std::shared_ptr FindArrowField(const std::shared_ptrid() != arrow::Type::STRUCT) { return nullptr; } - return std::static_pointer_cast(type)->GetFieldByName(name); + return checked_pointer_cast(type)->GetFieldByName(name); } bool IsUntyped(const std::shared_ptr& schema) { @@ -464,7 +464,7 @@ std::shared_ptr SelectedSchemaToSimpleSchema( auto result = std::make_shared(); result->is_array = true; result->element = SelectedSchemaToSimpleSchema( - std::static_pointer_cast(selected)->value_type(), field_count); + checked_pointer_cast(selected)->value_type(), field_count); return result; } return SimpleSchema::Scalar(selected); @@ -552,7 +552,7 @@ std::shared_ptr FinalizeAdaptiveSchema( std::shared_ptr previous_element; if (previous_selected != nullptr && previous_selected->id() == arrow::Type::LIST) { previous_element = - std::static_pointer_cast(previous_selected)->value_type(); + checked_pointer_cast(previous_selected)->value_type(); } return arrow::list(FinalizeAdaptiveSchema(combined->element, current_element, previous_element, root_value_count, @@ -616,17 +616,15 @@ InferVariantShreddingSchema::CollectSamplesAtPath(const SampleBatches& sample_ba if (column != sample_batch) { ancestors.push_back(column); } - column = arrow::internal::checked_cast(*column).field(index); + column = checked_cast(*column).field(index); } if (column == nullptr) { return Status::Invalid("sample batch misses the planned variant column"); } - const auto& variant_array = - arrow::internal::checked_cast(*column); - const auto& value_array = - arrow::internal::checked_cast(*variant_array.field(0)); + const auto& variant_array = checked_cast(*column); + const auto& value_array = checked_cast(*variant_array.field(0)); const auto& metadata_array = - arrow::internal::checked_cast(*variant_array.field(1)); + checked_cast(*variant_array.field(1)); for (int64_t row = 0; row < variant_array.length(); ++row) { bool row_is_null = variant_array.IsNull(row); for (const std::shared_ptr& ancestor : ancestors) { diff --git a/src/paimon/common/data/variant/variant_get.cpp b/src/paimon/common/data/variant/variant_get.cpp index 9bb8bab5..e7b0a564 100644 --- a/src/paimon/common/data/variant/variant_get.cpp +++ b/src/paimon/common/data/variant/variant_get.cpp @@ -31,6 +31,7 @@ #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/core/casting/cast_executor_factory.h" #include "paimon/data/decimal.h" @@ -206,34 +207,34 @@ Status AppendLiteralToBuilder(const Literal& literal, switch (target_type->id()) { case arrow::Type::type::BOOL: return ToPaimonStatus( - static_cast(builder)->Append(literal.GetValue())); + checked_cast(builder)->Append(literal.GetValue())); case arrow::Type::type::INT8: return ToPaimonStatus( - static_cast(builder)->Append(literal.GetValue())); + checked_cast(builder)->Append(literal.GetValue())); case arrow::Type::type::INT16: return ToPaimonStatus( - static_cast(builder)->Append(literal.GetValue())); + checked_cast(builder)->Append(literal.GetValue())); case arrow::Type::type::INT32: return ToPaimonStatus( - static_cast(builder)->Append(literal.GetValue())); + checked_cast(builder)->Append(literal.GetValue())); case arrow::Type::type::INT64: return ToPaimonStatus( - static_cast(builder)->Append(literal.GetValue())); + checked_cast(builder)->Append(literal.GetValue())); case arrow::Type::type::FLOAT: return ToPaimonStatus( - static_cast(builder)->Append(literal.GetValue())); + checked_cast(builder)->Append(literal.GetValue())); case arrow::Type::type::DOUBLE: return ToPaimonStatus( - static_cast(builder)->Append(literal.GetValue())); + checked_cast(builder)->Append(literal.GetValue())); case arrow::Type::type::STRING: - return ToPaimonStatus(static_cast(builder)->Append( + return ToPaimonStatus(checked_cast(builder)->Append( literal.GetValue())); case arrow::Type::type::BINARY: - return ToPaimonStatus(static_cast(builder)->Append( + return ToPaimonStatus(checked_cast(builder)->Append( literal.GetValue())); case arrow::Type::type::DATE32: return ToPaimonStatus( - static_cast(builder)->Append(literal.GetValue())); + checked_cast(builder)->Append(literal.GetValue())); case arrow::Type::type::TIMESTAMP: { auto timestamp = literal.GetValue(); const auto& timestamp_type = static_cast(*target_type); @@ -254,12 +255,12 @@ Status AppendLiteralToBuilder(const Literal& literal, default: return Status::Invalid("Unsupported timestamp unit"); } - return ToPaimonStatus(static_cast(builder)->Append(value)); + return ToPaimonStatus(checked_cast(builder)->Append(value)); } case arrow::Type::type::DECIMAL128: { auto decimal = literal.GetValue(); arrow::Decimal128 value(static_cast(decimal.HighBits()), decimal.LowBits()); - return ToPaimonStatus(static_cast(builder)->Append(value)); + return ToPaimonStatus(checked_cast(builder)->Append(value)); } default: return Status::Invalid( @@ -291,12 +292,12 @@ Status VariantGetExecutor::CastToBuilder(const std::shared_ptr& VariantBuilder variant_builder(/*allow_duplicate_keys=*/false); PAIMON_RETURN_NOT_OK(variant_builder.AppendVariant(*variant)); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr copied, variant_builder.Build(pool)); - auto* struct_builder = static_cast(builder); + auto* struct_builder = checked_cast(builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder->Append()); PAIMON_ASSIGN_OR_RAISE(std::string_view value, copied->Value()); PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(struct_builder->field_builder(0))->Append(value)); - return ToPaimonStatus(static_cast(struct_builder->field_builder(1)) + checked_cast(struct_builder->field_builder(0))->Append(value)); + return ToPaimonStatus(checked_cast(struct_builder->field_builder(1)) ->Append(copied->Metadata())); } @@ -310,7 +311,7 @@ Status VariantGetExecutor::CastToBuilder(const std::shared_ptr& if (variant_type != VariantValueType::kObject) { return invalid_cast(); } - auto* struct_builder = static_cast(builder); + auto* struct_builder = checked_cast(builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder->Append()); const auto& struct_type = static_cast(*target_field->type()); for (int i = 0; i < struct_type.num_fields(); ++i) { @@ -328,7 +329,7 @@ Status VariantGetExecutor::CastToBuilder(const std::shared_ptr& variant_type != VariantValueType::kObject) { return invalid_cast(); } - auto* map_builder = static_cast(builder); + auto* map_builder = checked_cast(builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(map_builder->Append()); PAIMON_ASSIGN_OR_RAISE(int32_t object_size, variant->ObjectSize()); for (int32_t i = 0; i < object_size; ++i) { @@ -338,7 +339,7 @@ Status VariantGetExecutor::CastToBuilder(const std::shared_ptr& return Status::Invalid(fmt::format("Malformed variant object at index {}", i)); } PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(map_builder->key_builder()) + checked_cast(map_builder->key_builder()) ->Append(field->key)); PAIMON_RETURN_NOT_OK(CastToBuilder(field->value, map_type.item_field(), cast_args, pool, map_builder->item_builder())); @@ -349,7 +350,7 @@ Status VariantGetExecutor::CastToBuilder(const std::shared_ptr& if (variant_type != VariantValueType::kArray) { return invalid_cast(); } - auto* list_builder = static_cast(builder); + auto* list_builder = checked_cast(builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(list_builder->Append()); const auto& list_type = static_cast(*target_field->type()); PAIMON_ASSIGN_OR_RAISE(int32_t array_size, variant->ArraySize()); diff --git a/src/paimon/common/data/variant/variant_reassembler.cpp b/src/paimon/common/data/variant/variant_reassembler.cpp index 7d301ff7..ab50fcdc 100644 --- a/src/paimon/common/data/variant/variant_reassembler.cpp +++ b/src/paimon/common/data/variant/variant_reassembler.cpp @@ -28,12 +28,12 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/variant/generic_variant.h" #include "paimon/common/data/variant/variant_builder.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/memory/memory_pool.h" namespace paimon { @@ -229,9 +229,9 @@ Result> VariantReassembler::AssembleVariantArray( auto output_type = VariantTypeUtils::UnshreddedStructType(); std::unique_ptr output_builder; PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::MakeBuilder(arrow_pool, output_type, &output_builder)); - auto* struct_builder = static_cast(output_builder.get()); - auto* value_builder = static_cast(struct_builder->field_builder(0)); - auto* metadata_builder = static_cast(struct_builder->field_builder(1)); + auto* struct_builder = checked_cast(output_builder.get()); + auto* value_builder = checked_cast(struct_builder->field_builder(0)); + auto* metadata_builder = checked_cast(struct_builder->field_builder(1)); bool unshredded = schema->IsUnshredded(); for (int64_t row = 0; row < shredded->length(); ++row) { diff --git a/src/paimon/common/data/variant/variant_shredding_batch_converter.cpp b/src/paimon/common/data/variant/variant_shredding_batch_converter.cpp index a2cb234e..8a677b26 100644 --- a/src/paimon/common/data/variant/variant_shredding_batch_converter.cpp +++ b/src/paimon/common/data/variant/variant_shredding_batch_converter.cpp @@ -25,12 +25,12 @@ #include "arrow/api.h" #include "arrow/c/bridge.h" #include "arrow/util/bitmap_ops.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/variant/generic_variant.h" #include "paimon/common/data/variant/variant_shredding_writer.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -58,15 +58,13 @@ Result> ShredVariantColumn( return Status::Invalid( fmt::format("variant column {} is not a struct column", field_name)); } - const auto& variant_column = arrow::internal::checked_cast(column); + const auto& variant_column = checked_cast(column); if (variant_column.num_fields() != 2) { return Status::Invalid( fmt::format("variant column {} is not a struct column", field_name)); } - const auto& value_column = - arrow::internal::checked_cast(*variant_column.field(0)); - const auto& metadata_column = - arrow::internal::checked_cast(*variant_column.field(1)); + const auto& value_column = checked_cast(*variant_column.field(0)); + const auto& metadata_column = checked_cast(*variant_column.field(1)); PAIMON_ASSIGN_OR_RAISE( std::unique_ptr writer, VariantShreddedColumnWriter::Create(variant_schema, physical_type, arrow_pool)); @@ -124,11 +122,9 @@ Result> VariantShreddingBatchConverter::ConvertFie return Status::Invalid(fmt::format("variant shredding cannot convert non-struct field {}", logical_field->name())); } - const auto& logical_struct = arrow::internal::checked_cast(*logical); - const auto& logical_type = - arrow::internal::checked_cast(*logical_field->type()); - const auto& physical_type = - arrow::internal::checked_cast(*physical_field->type()); + const auto& logical_struct = checked_cast(*logical); + const auto& logical_type = checked_cast(*logical_field->type()); + const auto& physical_type = checked_cast(*physical_field->type()); if (logical_type.num_fields() != physical_type.num_fields()) { return Status::Invalid(fmt::format("variant shredding physical struct {} does not match", physical_field->name())); @@ -161,7 +157,7 @@ Result> VariantShreddingBatchConverter::Convert( auto logical_struct_type = arrow::struct_(plan_->LogicalSchema()->fields()); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr logical_array, arrow::ImportArray(logical_batch, logical_struct_type)); - const auto& logical_struct = std::static_pointer_cast(logical_array); + const auto& logical_struct = checked_pointer_cast(logical_array); const auto& logical_fields = plan_->LogicalSchema()->fields(); const auto& physical_fields = plan_->PhysicalSchema()->fields(); diff --git a/src/paimon/common/data/variant/variant_shredding_read_plan_factory.cpp b/src/paimon/common/data/variant/variant_shredding_read_plan_factory.cpp index b1e14b1a..acaabeea 100644 --- a/src/paimon/common/data/variant/variant_shredding_read_plan_factory.cpp +++ b/src/paimon/common/data/variant/variant_shredding_read_plan_factory.cpp @@ -23,7 +23,6 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/variant/generic_variant.h" #include "paimon/common/data/variant/variant_access_utils.h" @@ -35,6 +34,7 @@ #include "paimon/common/data/variant/variant_shredding_utils.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -67,7 +67,7 @@ class FullVariantColumnReadPlan : public ShreddingColumnReadPlan { return Status::Invalid(fmt::format("cannot cast shredded variant field {} to a struct", physical_field_->name())); } - auto physical_struct = std::static_pointer_cast(physical); + auto physical_struct = checked_pointer_cast(physical); return VariantReassembler::AssembleVariantArray(physical_struct, schema_, pool_, pool); } @@ -296,10 +296,9 @@ Result BuildNestedVariantPlan(const std::shared_ptr& read_fi for (int32_t i = 0; i < read_type.num_fields(); ++i) { const std::shared_ptr& read_child = read_type.field(i); std::shared_ptr file_child = - in_repeated_subtree - ? file_type.field(i) - : arrow::internal::checked_cast(file_type).GetFieldByName( - read_child->name()); + in_repeated_subtree ? file_type.field(i) + : checked_cast(file_type).GetFieldByName( + read_child->name()); if (file_child == nullptr) { // The nested column is absent in the file (schema evolution); it is filled with // nulls downstream. @@ -405,7 +404,7 @@ class VariantAccessColumnReadPlan : public ShreddingColumnReadPlan { std::unique_ptr builder; PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::MakeBuilder(pool, logical_field_->type(), &builder)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Reserve(physical_struct.length())); - auto* struct_builder = static_cast(builder.get()); + auto* struct_builder = checked_cast(builder.get()); for (int64_t row = 0; row < physical_struct.length(); ++row) { if (physical_struct.IsNull(row)) { PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder->AppendNull()); diff --git a/src/paimon/common/data/variant/variant_shredding_read_plan_factory_test.cpp b/src/paimon/common/data/variant/variant_shredding_read_plan_factory_test.cpp index 61107e7d..c515fd71 100644 --- a/src/paimon/common/data/variant/variant_shredding_read_plan_factory_test.cpp +++ b/src/paimon/common/data/variant/variant_shredding_read_plan_factory_test.cpp @@ -34,6 +34,7 @@ #include "paimon/common/data/variant/variant_shredding_writer.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/memory/memory_pool.h" #include "paimon/testing/utils/testharness.h" @@ -62,7 +63,7 @@ class VariantShreddingReadPlanFactoryTest : public ::testing::Test { arrow::default_memory_pool())); ASSERT_OK(writer->Append(*variant)); ASSERT_OK_AND_ASSIGN(std::shared_ptr arr, writer->Finish()); - *array = std::static_pointer_cast(arr); + *array = checked_pointer_cast(arr); } // The unshredded physical StructArray (struct{value, metadata}) for one variant. @@ -141,9 +142,9 @@ TEST_F(VariantShreddingReadPlanFactoryTest, FullVariantReadOfShreddedFile) { ASSERT_OK_AND_ASSIGN(std::shared_ptr assembled, plan->Assemble(shredded, arrow::default_memory_pool())); - auto assembled_struct = std::static_pointer_cast(assembled); - auto value_column = std::static_pointer_cast(assembled_struct->field(0)); - auto metadata_column = std::static_pointer_cast(assembled_struct->field(1)); + auto assembled_struct = checked_pointer_cast(assembled); + auto value_column = checked_pointer_cast(assembled_struct->field(0)); + auto metadata_column = checked_pointer_cast(assembled_struct->field(1)); ASSERT_OK_AND_ASSIGN( std::shared_ptr rebuilt, GenericVariant::Create(value_column->GetView(0), metadata_column->GetView(0), pool_)); @@ -176,11 +177,11 @@ TEST_F(VariantShreddingReadPlanFactoryTest, FullVariantReadOfUntypedPhysicalFile ASSERT_OK_AND_ASSIGN(std::shared_ptr assembled, plan->Assemble(shredded, arrow::default_memory_pool())); - auto assembled_struct = std::static_pointer_cast(assembled); + auto assembled_struct = checked_pointer_cast(assembled); ASSERT_EQ(assembled_struct->data()->child_data[0], shredded->data()->child_data[1]); ASSERT_EQ(assembled_struct->data()->child_data[1], shredded->data()->child_data[0]); - auto value_column = std::static_pointer_cast(assembled_struct->field(0)); - auto metadata_column = std::static_pointer_cast(assembled_struct->field(1)); + auto value_column = checked_pointer_cast(assembled_struct->field(0)); + auto metadata_column = checked_pointer_cast(assembled_struct->field(1)); ASSERT_OK_AND_ASSIGN( std::shared_ptr rebuilt, GenericVariant::Create(value_column->GetView(0), metadata_column->GetView(0), pool_)); @@ -205,7 +206,7 @@ TEST_F(VariantShreddingReadPlanFactoryTest, AccessProjectionOnUnshreddedFile) { ASSERT_OK_AND_ASSIGN(std::shared_ptr assembled, plan->Assemble(unshredded, arrow::default_memory_pool())); - auto row = std::static_pointer_cast(assembled); + auto row = checked_pointer_cast(assembled); ASSERT_EQ(row->length(), 1); EXPECT_EQ(static_cast(*row->field(0)).Value(0), 5); EXPECT_EQ(static_cast(*row->field(1)).GetString(0), "hi"); @@ -255,7 +256,7 @@ TEST_F(VariantShreddingReadPlanFactoryTest, AccessProjectionOnShreddedFile) { ASSERT_TRUE(made.ok()) << made.status().ToString(); ASSERT_OK_AND_ASSIGN(std::shared_ptr assembled, plan->Assemble(made.ValueOrDie(), arrow::default_memory_pool())); - auto row = std::static_pointer_cast(assembled); + auto row = checked_pointer_cast(assembled); EXPECT_EQ(static_cast(*row->field(0)).Value(0), 5); EXPECT_EQ(static_cast(*row->field(1)).GetString(0), "hi"); } @@ -288,7 +289,7 @@ TEST_F(VariantShreddingReadPlanFactoryTest, NestedVariantColumnAndTypeMismatch) ASSERT_TRUE(made.ok()) << made.status().ToString(); ASSERT_OK_AND_ASSIGN(std::shared_ptr assembled, plan->Assemble(made.ValueOrDie(), arrow::default_memory_pool())); - auto row = std::static_pointer_cast(assembled); + auto row = checked_pointer_cast(assembled); EXPECT_EQ(static_cast(*row->field(0)).Value(0), 7); ASSERT_EQ(row->field(1)->type_id(), arrow::Type::STRUCT); diff --git a/src/paimon/common/data/variant/variant_shredding_test.cpp b/src/paimon/common/data/variant/variant_shredding_test.cpp index 632223a9..cbf71f78 100644 --- a/src/paimon/common/data/variant/variant_shredding_test.cpp +++ b/src/paimon/common/data/variant/variant_shredding_test.cpp @@ -31,6 +31,7 @@ #include "paimon/common/data/variant/variant_schema.h" #include "paimon/common/data/variant/variant_shredding_utils.h" #include "paimon/common/data/variant/variant_shredding_writer.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/memory/memory_pool.h" #include "paimon/testing/utils/testharness.h" @@ -66,15 +67,15 @@ class VariantShreddingTest : public ::testing::Test { EXPECT_OK(writer->Append(*variant)); } EXPECT_OK_AND_ASSIGN(std::shared_ptr shredded_array, writer->Finish()); - auto shredded = std::static_pointer_cast(shredded_array); + auto shredded = checked_pointer_cast(shredded_array); EXPECT_OK_AND_ASSIGN(std::shared_ptr assembled_array, VariantReassembler::AssembleVariantArray( shredded, schema, pool_, arrow::default_memory_pool())); - auto assembled = std::static_pointer_cast(assembled_array); + auto assembled = checked_pointer_cast(assembled_array); EXPECT_EQ(assembled->length(), static_cast(jsons.size())); - auto value_column = std::static_pointer_cast(assembled->field(0)); - auto metadata_column = std::static_pointer_cast(assembled->field(1)); + auto value_column = checked_pointer_cast(assembled->field(0)); + auto metadata_column = checked_pointer_cast(assembled->field(1)); for (size_t i = 0; i < jsons.size(); ++i) { SCOPED_TRACE("row " + std::to_string(i)); if (jsons[i] == nullptr) { @@ -140,14 +141,14 @@ class VariantShreddingTest : public ::testing::Test { EXPECT_OK(writer->Append(*variant)); } EXPECT_OK_AND_ASSIGN(std::shared_ptr shredded_array, writer->Finish()); - auto shredded = std::static_pointer_cast(shredded_array); + auto shredded = checked_pointer_cast(shredded_array); EXPECT_OK_AND_ASSIGN(std::shared_ptr assembled_array, VariantReassembler::AssembleVariantArray( shredded, schema, pool_, arrow::default_memory_pool())); - auto assembled = std::static_pointer_cast(assembled_array); - auto value_column = std::static_pointer_cast(assembled->field(0)); - auto metadata_column = std::static_pointer_cast(assembled->field(1)); + auto assembled = checked_pointer_cast(assembled_array); + auto value_column = checked_pointer_cast(assembled->field(0)); + auto metadata_column = checked_pointer_cast(assembled->field(1)); for (size_t i = 0; i < variants.size(); ++i) { SCOPED_TRACE("row " + std::to_string(i)); if (variants[i] == nullptr) { @@ -233,8 +234,8 @@ TEST_F(VariantShreddingTest, ShredObject) { arrow::struct_({arrow::field("a", arrow::int32()), arrow::field("c", arrow::utf8()), arrow::field("b", arrow::utf8())}), {variant_json}); - auto typed = std::static_pointer_cast(shredded->field(2)); - auto c_group = std::static_pointer_cast(typed->field(1)); + auto typed = checked_pointer_cast(shredded->field(2)); + auto c_group = checked_pointer_cast(typed->field(1)); ASSERT_FALSE(c_group->IsNull(0)); ASSERT_TRUE(c_group->field(0)->IsNull(0)); ASSERT_TRUE(c_group->field(1)->IsNull(0)); @@ -244,7 +245,7 @@ TEST_F(VariantShreddingTest, ShredObject) { auto shredded = RoundTrip( arrow::struct_({arrow::field("b", arrow::utf8()), arrow::field("c", arrow::utf8())}), {variant_json}); - auto value_column = std::static_pointer_cast(shredded->field(1)); + auto value_column = checked_pointer_cast(shredded->field(1)); ASSERT_FALSE(value_column->IsNull(0)); // The residual must equal the standalone encoding of {"a": 1}. ASSERT_OK_AND_ASSIGN(std::shared_ptr residual_expected, @@ -277,10 +278,10 @@ TEST_F(VariantShreddingTest, ShredAllTypes) { auto shredded = RoundTrip(shredding_type, {json, nullptr, json}); // c6 is a variant null: it stays in the field's value column ("00"), typed_value is null. - auto typed = std::static_pointer_cast(shredded->field(2)); - auto c6_group = std::static_pointer_cast(typed->field(5)); + auto typed = checked_pointer_cast(shredded->field(2)); + auto c6_group = checked_pointer_cast(typed->field(5)); ASSERT_FALSE(c6_group->IsNull(0)); - auto c6_value = std::static_pointer_cast(c6_group->field(0)); + auto c6_value = checked_pointer_cast(c6_group->field(0)); ASSERT_FALSE(c6_value->IsNull(0)); ASSERT_EQ(c6_value->GetView(0), std::string_view("\x00", 1)); ASSERT_TRUE(c6_group->field(1)->IsNull(0)); @@ -291,7 +292,7 @@ TEST_F(VariantShreddingTest, ShredAllTypes) { // No shredding at all: everything stays in the top-level value. auto no_match_type = arrow::struct_({arrow::field("other", arrow::utf8())}); auto unshredded = RoundTrip(no_match_type, {json}); - auto value_column = std::static_pointer_cast(unshredded->field(1)); + auto value_column = checked_pointer_cast(unshredded->field(1)); ASSERT_FALSE(value_column->IsNull(0)); ASSERT_OK_AND_ASSIGN(std::shared_ptr expected, GenericVariant::FromJson(json, pool_)); @@ -409,9 +410,9 @@ TEST_F(VariantShreddingTest, TimestampReassembly) { ASSERT_OK_AND_ASSIGN(std::shared_ptr assembled_array, VariantReassembler::AssembleVariantArray( shredded, schema, pool_, arrow::default_memory_pool())); - auto assembled = std::static_pointer_cast(assembled_array); - auto value_column = std::static_pointer_cast(assembled->field(0)); - auto metadata_column = std::static_pointer_cast(assembled->field(1)); + auto assembled = checked_pointer_cast(assembled_array); + auto value_column = checked_pointer_cast(assembled->field(0)); + auto metadata_column = checked_pointer_cast(assembled->field(1)); ASSERT_OK_AND_ASSIGN( std::shared_ptr variant, GenericVariant::Create(value_column->GetView(0), metadata_column->GetView(0), pool_)); diff --git a/src/paimon/common/data/variant/variant_shredding_utils.cpp b/src/paimon/common/data/variant/variant_shredding_utils.cpp index bbb23135..4d5c7dda 100644 --- a/src/paimon/common/data/variant/variant_shredding_utils.cpp +++ b/src/paimon/common/data/variant/variant_shredding_utils.cpp @@ -28,10 +28,10 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/variant/variant_defs.h" #include "paimon/common/data/variant/variant_type_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -53,7 +53,7 @@ Result> VariantShreddingSchemaImpl( } switch (data_type->id()) { case arrow::Type::LIST: { - const auto& list_type = std::static_pointer_cast(data_type); + const auto& list_type = checked_pointer_cast(data_type); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr element_type, VariantShreddingSchemaImpl(list_type->value_type(), /*is_top_level=*/false, @@ -68,7 +68,7 @@ Result> VariantShreddingSchemaImpl( // The field name level is always non-nullable: Variant null values are represented in // the "value" column as "00", and missing values are represented by setting both // "value" and "typed_value" to null. - const auto& struct_type = std::static_pointer_cast(data_type); + const auto& struct_type = checked_pointer_cast(data_type); arrow::FieldVector shredded_fields; for (const auto& field : struct_type->fields()) { PAIMON_ASSIGN_OR_RAISE(std::shared_ptr field_type, @@ -120,7 +120,7 @@ Result> BuildVariantSchemaImpl( if (type->id() != arrow::Type::STRUCT) { return InvalidVariantShreddingSchema(type); } - const auto& struct_type = std::static_pointer_cast(type); + const auto& struct_type = checked_pointer_cast(type); // The struct must not be empty or contain duplicate field names. The latter is enforced in // the loop below. if (struct_type->num_fields() == 0) { @@ -140,8 +140,7 @@ Result> BuildVariantSchemaImpl( schema->typed_idx = i; switch (field_type->id()) { case arrow::Type::STRUCT: { - const auto& object_type = - std::static_pointer_cast(field_type); + const auto& object_type = checked_pointer_cast(field_type); schema->has_object_schema = true; schema->object_schema.reserve(object_type->num_fields()); for (int32_t index = 0; index < object_type->num_fields(); ++index) { @@ -160,7 +159,7 @@ Result> BuildVariantSchemaImpl( break; } case arrow::Type::LIST: { - const auto& list_type = std::static_pointer_cast(field_type); + const auto& list_type = checked_pointer_cast(field_type); PAIMON_ASSIGN_OR_RAISE( schema->array_schema, BuildVariantSchemaImpl(list_type->value_type(), /*top_level=*/false)); @@ -208,7 +207,7 @@ Result> BuildVariantSchemaImpl( break; case arrow::Type::DECIMAL128: { const auto& decimal_type = - std::static_pointer_cast(field_type); + checked_pointer_cast(field_type); schema->scalar_schema = VariantSchema::ScalarType{VariantSchema::ScalarKind::kDecimal, decimal_type->precision(), decimal_type->scale()}; @@ -216,7 +215,7 @@ Result> BuildVariantSchemaImpl( } case arrow::Type::TIMESTAMP: { const auto& timestamp_type = - std::static_pointer_cast(field_type); + checked_pointer_cast(field_type); // The variant binary stores timestamps as microseconds since the epoch; a // typed_value column of any other precision would misinterpret the values. if (timestamp_type->unit() != arrow::TimeUnit::MICRO) { @@ -305,7 +304,7 @@ bool VariantShreddingUtils::IsShreddedFileType( if (!file_variant_type || file_variant_type->id() != arrow::Type::STRUCT) { return false; } - const auto& struct_type = std::static_pointer_cast(file_variant_type); + const auto& struct_type = checked_pointer_cast(file_variant_type); return struct_type->GetFieldByName(VariantDefs::kTypedValueFieldName) != nullptr; } @@ -314,7 +313,7 @@ bool VariantShreddingUtils::IsUntypedPhysicalVariantType( if (!file_variant_type || file_variant_type->id() != arrow::Type::STRUCT) { return false; } - const auto& struct_type = std::static_pointer_cast(file_variant_type); + const auto& struct_type = checked_pointer_cast(file_variant_type); if (struct_type->num_fields() != 2) { return false; } diff --git a/src/paimon/common/data/variant/variant_shredding_write_plan.cpp b/src/paimon/common/data/variant/variant_shredding_write_plan.cpp index 7fccc4ff..fbf575ad 100644 --- a/src/paimon/common/data/variant/variant_shredding_write_plan.cpp +++ b/src/paimon/common/data/variant/variant_shredding_write_plan.cpp @@ -22,11 +22,11 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/variant/variant_shredding_utils.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/types/data_type_json_parser.h" +#include "paimon/common/utils/checked_cast.h" #include "rapidjson/document.h" namespace paimon { @@ -39,8 +39,7 @@ Result> ReplacePlannedFields( const std::shared_ptr& field, const std::map, std::shared_ptr>& paths, size_t depth, std::vector* columns) { - const auto& struct_type = - arrow::internal::checked_cast(*field->type()); + const auto& struct_type = checked_cast(*field->type()); arrow::FieldVector new_fields = struct_type.fields(); bool changed = false; auto it = paths.begin(); @@ -119,10 +118,8 @@ Status CollectPlannedColumns(const std::shared_ptr& logical_field, "variant shredding physical type of field '{}' differs outside a Variant column", logical_field->name())); } - const auto& logical_type = - arrow::internal::checked_cast(*logical_field->type()); - const auto& physical_type = - arrow::internal::checked_cast(*physical_field->type()); + const auto& logical_type = checked_cast(*logical_field->type()); + const auto& physical_type = checked_cast(*physical_field->type()); if (logical_type.num_fields() != physical_type.num_fields()) { return Status::Invalid( fmt::format("variant shredding physical struct '{}' has a different field count", diff --git a/src/paimon/common/data/variant/variant_shredding_write_plan_factory_test.cpp b/src/paimon/common/data/variant/variant_shredding_write_plan_factory_test.cpp index a3d3c6c5..6dbb8d79 100644 --- a/src/paimon/common/data/variant/variant_shredding_write_plan_factory_test.cpp +++ b/src/paimon/common/data/variant/variant_shredding_write_plan_factory_test.cpp @@ -30,6 +30,7 @@ #include "paimon/common/data/variant/variant_shredding_utils.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/core_options.h" #include "paimon/testing/utils/testharness.h" #include "paimon/testing/utils/variant_test_data.h" @@ -64,7 +65,7 @@ class VariantShreddingWritePlanFactoryTest : public ::testing::Test { if (field == nullptr || field->type()->id() != arrow::Type::STRUCT) { return nullptr; } - return std::static_pointer_cast(field->type()) + return checked_pointer_cast(field->type()) ->GetFieldByName("typed_value") ->type(); } @@ -346,7 +347,7 @@ TEST_F(VariantShreddingWritePlanFactoryTest, AdaptiveInferenceWithNestedVariant) *converter->GetPhysicalSchema()->GetFieldByName("nested")->type()); const auto& physical_variant = static_cast( *physical_nested.GetFieldByName("payload")->type()); - return std::static_pointer_cast( + return checked_pointer_cast( physical_variant.GetFieldByName("typed_value")->type()); }; diff --git a/src/paimon/common/data/variant/variant_shredding_writer.cpp b/src/paimon/common/data/variant/variant_shredding_writer.cpp index bb7c412e..6142ddbb 100644 --- a/src/paimon/common/data/variant/variant_shredding_writer.cpp +++ b/src/paimon/common/data/variant/variant_shredding_writer.cpp @@ -27,11 +27,11 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/variant/variant_builder.h" #include "paimon/common/data/variant/variant_defs.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -53,7 +53,7 @@ Result<__int128_t> ScaleUpUnscaled(__int128_t unscaled, int32_t power) { } Status AppendDecimalTo(__int128_t unscaled, arrow::ArrayBuilder* builder) { - auto* decimal_builder = static_cast(builder); + auto* decimal_builder = checked_cast(builder); arrow::Decimal128 value(static_cast(unscaled >> 64), static_cast(static_cast<__uint128_t>(unscaled))); PAIMON_RETURN_NOT_OK_FROM_ARROW(decimal_builder->Append(value)); @@ -81,7 +81,7 @@ Result> VariantShreddedColumnWriter auto writer = std::unique_ptr( new VariantShreddedColumnWriter(schema, std::move(root_builder))); PAIMON_RETURN_NOT_OK(BuildNode( - schema, static_cast(writer->root_builder_.get()), &writer->root_)); + schema, checked_cast(writer->root_builder_.get()), &writer->root_)); return writer; } @@ -95,28 +95,29 @@ Status VariantShreddedColumnWriter::BuildNode(const std::shared_ptrnum_children(), schema->num_fields)); } if (schema->top_level_metadata_idx >= 0) { - node->metadata = static_cast( + node->metadata = checked_cast( group->field_builder(schema->top_level_metadata_idx)); } if (schema->variant_idx >= 0) { - node->value = static_cast(group->field_builder(schema->variant_idx)); + node->value = + checked_cast(group->field_builder(schema->variant_idx)); } if (schema->typed_idx >= 0) { arrow::ArrayBuilder* typed_builder = group->field_builder(schema->typed_idx); if (schema->has_object_schema) { - node->typed_object = static_cast(typed_builder); + node->typed_object = checked_cast(typed_builder); node->object_children.resize(schema->object_schema.size()); for (size_t i = 0; i < schema->object_schema.size(); ++i) { - auto* child_group = static_cast( + auto* child_group = checked_cast( node->typed_object->field_builder(static_cast(i))); PAIMON_RETURN_NOT_OK(BuildNode(schema->object_schema[i].schema, child_group, &node->object_children[i])); } } else if (schema->array_schema) { - node->typed_list = static_cast(typed_builder); + node->typed_list = checked_cast(typed_builder); node->array_element = std::make_unique(); auto* element_group = - static_cast(node->typed_list->value_builder()); + checked_cast(node->typed_list->value_builder()); PAIMON_RETURN_NOT_OK( BuildNode(schema->array_schema, element_group, node->array_element.get())); } else if (schema->scalar_schema) { @@ -272,7 +273,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, case VariantSchema::ScalarKind::kByte: if (value == static_cast(value)) { PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar) + checked_cast(node->typed_scalar) ->Append(static_cast(value))); *shredded = true; } @@ -280,7 +281,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, case VariantSchema::ScalarKind::kShort: if (value == static_cast(value)) { PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar) + checked_cast(node->typed_scalar) ->Append(static_cast(value))); *shredded = true; } @@ -288,14 +289,14 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, case VariantSchema::ScalarKind::kInt: if (value == static_cast(value)) { PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar) + checked_cast(node->typed_scalar) ->Append(static_cast(value))); *shredded = true; } break; case VariantSchema::ScalarKind::kLong: PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar)->Append(value)); + checked_cast(node->typed_scalar)->Append(value)); *shredded = true; break; case VariantSchema::ScalarKind::kDecimal: { @@ -376,7 +377,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, case VariantSchema::ScalarKind::kByte: if (long_value == static_cast(long_value)) { PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar) + checked_cast(node->typed_scalar) ->Append(static_cast(long_value))); *shredded = true; } @@ -384,7 +385,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, case VariantSchema::ScalarKind::kShort: if (long_value == static_cast(long_value)) { PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar) + checked_cast(node->typed_scalar) ->Append(static_cast(long_value))); *shredded = true; } @@ -392,14 +393,14 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, case VariantSchema::ScalarKind::kInt: if (long_value == static_cast(long_value)) { PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar) + checked_cast(node->typed_scalar) ->Append(static_cast(long_value))); *shredded = true; } break; default: PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar) + checked_cast(node->typed_scalar) ->Append(long_value)); *shredded = true; break; @@ -411,7 +412,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, if (target.kind == VariantSchema::ScalarKind::kBoolean) { PAIMON_ASSIGN_OR_RAISE(bool value, variant.GetBoolean()); PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar)->Append(value)); + checked_cast(node->typed_scalar)->Append(value)); *shredded = true; } break; @@ -420,7 +421,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, if (target.kind == VariantSchema::ScalarKind::kString) { PAIMON_ASSIGN_OR_RAISE(std::string_view value, variant.GetString()); PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar)->Append(value)); + checked_cast(node->typed_scalar)->Append(value)); *shredded = true; } break; @@ -429,7 +430,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, if (target.kind == VariantSchema::ScalarKind::kDouble) { PAIMON_ASSIGN_OR_RAISE(double value, variant.GetDouble()); PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar)->Append(value)); + checked_cast(node->typed_scalar)->Append(value)); *shredded = true; } break; @@ -438,7 +439,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, if (target.kind == VariantSchema::ScalarKind::kFloat) { PAIMON_ASSIGN_OR_RAISE(float value, variant.GetFloat()); PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar)->Append(value)); + checked_cast(node->typed_scalar)->Append(value)); *shredded = true; } break; @@ -447,7 +448,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, if (target.kind == VariantSchema::ScalarKind::kDate) { PAIMON_ASSIGN_OR_RAISE(int64_t value, variant.GetLong()); PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar) + checked_cast(node->typed_scalar) ->Append(static_cast(value))); *shredded = true; } @@ -457,7 +458,7 @@ Status VariantShreddedColumnWriter::TryTypedShred(const GenericVariant& variant, if (target.kind == VariantSchema::ScalarKind::kBinary) { PAIMON_ASSIGN_OR_RAISE(std::string_view value, variant.GetBinary()); PAIMON_RETURN_NOT_OK_FROM_ARROW( - static_cast(node->typed_scalar)->Append(value)); + checked_cast(node->typed_scalar)->Append(value)); *shredded = true; } break; diff --git a/src/paimon/common/data/variant/variant_type_utils.cpp b/src/paimon/common/data/variant/variant_type_utils.cpp index 6bb494e1..63b5eff1 100644 --- a/src/paimon/common/data/variant/variant_type_utils.cpp +++ b/src/paimon/common/data/variant/variant_type_utils.cpp @@ -23,6 +23,7 @@ #include "fmt/format.h" #include "paimon/common/data/variant/variant_defs.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -83,7 +84,7 @@ Status VariantTypeUtils::ValidateVariantShape(const std::shared_ptrname(), type->ToString())); } - const auto& struct_type = std::static_pointer_cast(type); + const auto& struct_type = checked_pointer_cast(type); if (struct_type->num_fields() != 2) { return Status::Invalid( fmt::format("Variant field '{}' must be a struct, " diff --git a/src/paimon/common/data/variant/variant_type_utils_test.cpp b/src/paimon/common/data/variant/variant_type_utils_test.cpp index ba6fc4ac..b4c33576 100644 --- a/src/paimon/common/data/variant/variant_type_utils_test.cpp +++ b/src/paimon/common/data/variant/variant_type_utils_test.cpp @@ -22,6 +22,7 @@ #include "arrow/api.h" #include "gtest/gtest.h" #include "paimon/common/data/variant/variant_defs.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/testing/utils/testharness.h" @@ -35,7 +36,7 @@ TEST(VariantTypeUtilsTest, ToArrowFieldAndDetection) { ASSERT_TRUE(VariantTypeUtils::IsVariantMetadata(field->metadata())); ASSERT_OK(VariantTypeUtils::ValidateVariantShape(field)); - auto struct_type = std::static_pointer_cast(field->type()); + auto struct_type = checked_pointer_cast(field->type()); ASSERT_EQ(struct_type->num_fields(), 2); ASSERT_EQ(struct_type->field(0)->name(), VariantDefs::kValueFieldName); ASSERT_EQ(struct_type->field(0)->type()->id(), arrow::Type::BINARY); diff --git a/src/paimon/common/factories/factory_creator_test.cpp b/src/paimon/common/factories/factory_creator_test.cpp index 96ed1dd7..d011d334 100644 --- a/src/paimon/common/factories/factory_creator_test.cpp +++ b/src/paimon/common/factories/factory_creator_test.cpp @@ -23,6 +23,7 @@ #include #include "gtest/gtest.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/factories/factory.h" namespace paimon::test { @@ -68,8 +69,8 @@ TEST_F(FactoryCreatorTest, RegisterAndCreateFactory) { ASSERT_NE(created_factory1, nullptr); ASSERT_NE(created_factory2, nullptr); - EXPECT_EQ(static_cast(created_factory1)->GetName(), "Factory1"); - EXPECT_EQ(static_cast(created_factory2)->GetName(), "Factory2"); + EXPECT_EQ(checked_cast(created_factory1)->GetName(), "Factory1"); + EXPECT_EQ(checked_cast(created_factory2)->GetName(), "Factory2"); } TEST_F(FactoryCreatorTest, GetRegisteredType) { diff --git a/src/paimon/common/file_index/bitmap/bitmap_file_index.cpp b/src/paimon/common/file_index/bitmap/bitmap_file_index.cpp index a9542a0d..6df16143 100644 --- a/src/paimon/common/file_index/bitmap/bitmap_file_index.cpp +++ b/src/paimon/common/file_index/bitmap/bitmap_file_index.cpp @@ -27,6 +27,7 @@ #include "paimon/common/file_index/bitmap/bitmap_file_index_meta_v2.h" #include "paimon/common/memory/memory_segment_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/common/utils/options_utils.h" @@ -52,11 +53,11 @@ Result BitmapFileIndex::ConvertLiteral( if (literal.IsNull()) { return Literal(FieldType::BIGINT); } else { - auto ts_type = std::dynamic_pointer_cast(arrow_type); - if (!ts_type) { + if (!arrow_type || arrow_type->id() != arrow::Type::TIMESTAMP) { return Status::Invalid(fmt::format("literal type TIMESTAMP mismatch arrow type {}", - arrow_type->ToString())); + arrow_type ? arrow_type->ToString() : "null")); } + auto ts_type = checked_pointer_cast(arrow_type); int64_t precision = DateTimeUtils::GetPrecisionFromType(ts_type); int64_t value = 0; if (precision <= Timestamp::MILLIS_PRECISION) { @@ -136,11 +137,14 @@ BitmapFileIndexWriter::BitmapFileIndexWriter(int8_t version, Status BitmapFileIndexWriter::AddBatch(::ArrowArray* batch) { PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(batch, struct_type_)); - auto struct_array = std::dynamic_pointer_cast(arrow_array); - if (!struct_array || struct_array->num_fields() != 1) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { + return Status::Invalid("invalid batch for BitmapFileIndexWriter, expected a struct array"); + } + auto struct_array = checked_pointer_cast(arrow_array); + if (struct_array->num_fields() != 1) { return Status::Invalid( - "invalid batch for BitmapFileIndexWriter, supposed to be struct array with single " - "field."); + "invalid batch for BitmapFileIndexWriter, expected a struct array with exactly one " + "field"); } PAIMON_ASSIGN_OR_RAISE( std::vector array_values, diff --git a/src/paimon/common/file_index/bitmap/bitmap_file_index_test.cpp b/src/paimon/common/file_index/bitmap/bitmap_file_index_test.cpp index eccbb1f3..42a888a8 100644 --- a/src/paimon/common/file_index/bitmap/bitmap_file_index_test.cpp +++ b/src/paimon/common/file_index/bitmap/bitmap_file_index_test.cpp @@ -25,6 +25,7 @@ #include "arrow/ipc/json_simple.h" #include "gtest/gtest.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/data/timestamp.h" #include "paimon/defs.h" @@ -671,7 +672,7 @@ TEST_F(BitmapIndexTest, TestHighCardinalityForWriteAndRead) { arrow::StructBuilder struct_builder(arrow::struct_({arrow::field("f0", type)}), arrow::default_memory_pool(), {std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); for (int32_t i = 0; i < 100000; i++) { EXPECT_TRUE(struct_builder.Append().ok()); diff --git a/src/paimon/common/file_index/bloomfilter/fast_hash.cpp b/src/paimon/common/file_index/bloomfilter/fast_hash.cpp index ed9738ec..d98dc476 100644 --- a/src/paimon/common/file_index/bloomfilter/fast_hash.cpp +++ b/src/paimon/common/file_index/bloomfilter/fast_hash.cpp @@ -24,6 +24,7 @@ #include #include "fmt/format.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/data/timestamp.h" @@ -70,7 +71,7 @@ Result FastHash::GetHashFunction( return GetLongHash(bits); }); case FieldType::TIMESTAMP: { - auto ts_type = arrow::internal::checked_pointer_cast(arrow_type); + auto ts_type = checked_pointer_cast(arrow_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(ts_type); assert(precision >= 0); return HashFunction([precision](const Literal& literal) -> int64_t { diff --git a/src/paimon/common/file_index/bsi/bit_slice_index_bitmap_file_index.cpp b/src/paimon/common/file_index/bsi/bit_slice_index_bitmap_file_index.cpp index aca978bd..7ce53e9a 100644 --- a/src/paimon/common/file_index/bsi/bit_slice_index_bitmap_file_index.cpp +++ b/src/paimon/common/file_index/bsi/bit_slice_index_bitmap_file_index.cpp @@ -25,6 +25,7 @@ #include "fmt/format.h" #include "paimon/common/file_index/bsi/bit_slice_index_roaring_bitmap.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/data/timestamp.h" @@ -131,7 +132,7 @@ Result BitSliceIndexBitmapFileInd return GetValueFromLiteral(literal); }); case FieldType::TIMESTAMP: { - auto ts_type = arrow::internal::checked_pointer_cast(arrow_type); + auto ts_type = checked_pointer_cast(arrow_type); int64_t precision = DateTimeUtils::GetPrecisionFromType(ts_type); assert(precision >= 0); return BitSliceIndexBitmapFileIndex::ValueMapperType( diff --git a/src/paimon/common/file_index/rangebitmap/range_bitmap_file_index.cpp b/src/paimon/common/file_index/rangebitmap/range_bitmap_file_index.cpp index 17f27009..5d0543be 100644 --- a/src/paimon/common/file_index/rangebitmap/range_bitmap_file_index.cpp +++ b/src/paimon/common/file_index/rangebitmap/range_bitmap_file_index.cpp @@ -26,6 +26,7 @@ #include "paimon/common/options/memory_size.h" #include "paimon/common/predicate/literal_converter.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/file_index/bitmap_index_result.h" #include "paimon/predicate/literal.h" @@ -92,11 +93,15 @@ Result> RangeBitmapFileIndexWriter:: Status RangeBitmapFileIndexWriter::AddBatch(::ArrowArray* batch) { PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr array, arrow::ImportArray(batch, struct_type_)); - auto struct_array = std::dynamic_pointer_cast(array); - if (!struct_array || struct_array->num_fields() != 1) { + if (!array || array->type_id() != arrow::Type::STRUCT) { return Status::Invalid( - "invalid batch for RangeBitmapFileIndexWriter, supposed to be struct array with single " - "field."); + "invalid batch for RangeBitmapFileIndexWriter, expected a struct array"); + } + auto struct_array = checked_pointer_cast(array); + if (struct_array->num_fields() != 1) { + return Status::Invalid( + "invalid batch for RangeBitmapFileIndexWriter, expected a struct array with exactly " + "one field"); } PAIMON_ASSIGN_OR_RAISE(std::vector array_values, LiteralConverter::ConvertLiteralsFromArray(*(struct_array->field(0)), diff --git a/src/paimon/common/global_index/bitmap/bitmap_global_index_test.cpp b/src/paimon/common/global_index/bitmap/bitmap_global_index_test.cpp index f19c294c..80e023f9 100644 --- a/src/paimon/common/global_index/bitmap/bitmap_global_index_test.cpp +++ b/src/paimon/common/global_index/bitmap/bitmap_global_index_test.cpp @@ -29,6 +29,7 @@ #include "paimon/common/file_index/bitmap/bitmap_file_index.h" #include "paimon/common/global_index/wrap/file_index_writer_wrapper.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/path_util.h" #include "paimon/common/utils/string_utils.h" @@ -325,7 +326,7 @@ TEST_F(BitmapGlobalIndexTest, TestHighCardinality) { arrow::StructBuilder struct_builder(arrow::struct_({arrow::field("f0", type)}), arrow::default_memory_pool(), {std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); for (int32_t i = 0; i < 100000; i++) { EXPECT_TRUE(struct_builder.Append().ok()); diff --git a/src/paimon/common/global_index/btree/btree_global_index_writer.cpp b/src/paimon/common/global_index/btree/btree_global_index_writer.cpp index 2e3c99aa..37b81c41 100644 --- a/src/paimon/common/global_index/btree/btree_global_index_writer.cpp +++ b/src/paimon/common/global_index/btree/btree_global_index_writer.cpp @@ -31,6 +31,7 @@ #include "paimon/common/memory/memory_slice_output.h" #include "paimon/common/predicate/literal_converter.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/crc32c.h" #include "paimon/common/utils/preconditions.h" #include "paimon/memory/bytes.h" @@ -76,9 +77,11 @@ Status BTreeGlobalIndexWriter::AddBatch(::ArrowArray* arrow_array, arrow_array, relative_row_ids, /*expected_next_row_id=*/std::nullopt)); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr array, arrow::ImportArray(arrow_array, arrow_type_)); - auto struct_array = std::dynamic_pointer_cast(array); - PAIMON_RETURN_NOT_OK(Preconditions::CheckNotNull( - struct_array, "arrow array must be struct array when AddBatch to BTreeGlobalIndexWriter")); + if (!array || array->type_id() != arrow::Type::STRUCT) { + return Status::Invalid( + "arrow array must be struct array when AddBatch to BTreeGlobalIndexWriter"); + } + auto struct_array = checked_pointer_cast(array); auto value_array = struct_array->GetFieldByName(field_name_); PAIMON_RETURN_NOT_OK(Preconditions::CheckNotNull( value_array, diff --git a/src/paimon/common/global_index/btree/btree_global_indexer.cpp b/src/paimon/common/global_index/btree/btree_global_indexer.cpp index 29bffe9f..e554985d 100644 --- a/src/paimon/common/global_index/btree/btree_global_indexer.cpp +++ b/src/paimon/common/global_index/btree/btree_global_indexer.cpp @@ -32,6 +32,7 @@ #include "paimon/common/memory/memory_slice_input.h" #include "paimon/common/options/memory_size.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/crc32c.h" #include "paimon/common/utils/options_utils.h" #include "paimon/common/utils/preconditions.h" @@ -68,9 +69,11 @@ Result> BTreeGlobalIndexer::CreateWriter( PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_type, arrow::ImportType(arrow_schema)); // check data type - auto struct_type = std::dynamic_pointer_cast(arrow_type); - PAIMON_RETURN_NOT_OK(Preconditions::CheckNotNull( - struct_type, "arrow schema must be struct type when create BTreeGlobalIndexWriter")); + if (!arrow_type || arrow_type->id() != arrow::Type::STRUCT) { + return Status::Invalid( + "arrow schema must be struct type when create BTreeGlobalIndexWriter"); + } + auto struct_type = checked_pointer_cast(arrow_type); // parse options PAIMON_ASSIGN_OR_RAISE( diff --git a/src/paimon/common/global_index/btree/key_serializer.cpp b/src/paimon/common/global_index/btree/key_serializer.cpp index d6d71751..1ce1f6b4 100644 --- a/src/paimon/common/global_index/btree/key_serializer.cpp +++ b/src/paimon/common/global_index/btree/key_serializer.cpp @@ -22,6 +22,7 @@ #include "fmt/format.h" #include "paimon/common/memory/memory_slice_input.h" #include "paimon/common/memory/memory_slice_output.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/common/utils/fields_comparator.h" @@ -92,9 +93,11 @@ Result> KeySerializer::SerializeKey( return bytes; } case FieldType::TIMESTAMP: { - auto ts_type = std::dynamic_pointer_cast(type); - PAIMON_RETURN_NOT_OK(Preconditions::CheckNotNull( - ts_type, "ts type cannot cast to arrow::TimestampType in BTreeGlobalIndex")); + if (!type || type->id() != arrow::Type::TIMESTAMP) { + return Status::Invalid( + "ts type cannot cast to arrow::TimestampType in BTreeGlobalIndex"); + } + auto ts_type = checked_pointer_cast(type); MemorySliceOutput output(8, pool); output.Reset(); auto ts = literal.GetValue(); @@ -107,10 +110,11 @@ Result> KeySerializer::SerializeKey( return output.ToSlice().CopyBytes(pool); } case FieldType::DECIMAL: { - auto decimal_type = std::dynamic_pointer_cast(type); - PAIMON_RETURN_NOT_OK(Preconditions::CheckNotNull( - decimal_type, - "decimal type cannot cast to arrow::Decimal128Type in BTreeGlobalIndex")); + if (!type || type->id() != arrow::Type::DECIMAL128) { + return Status::Invalid( + "decimal type cannot cast to arrow::Decimal128Type in BTreeGlobalIndex"); + } + auto decimal_type = checked_pointer_cast(type); auto decimal = literal.GetValue(); if (Decimal::IsCompact(decimal_type->precision())) { @@ -165,9 +169,7 @@ Result KeySerializer::DeserializeKey(const MemorySlice& slice, return Literal(FieldType::STRING, bytes->data(), bytes->size()); } case arrow::Type::type::TIMESTAMP: { - auto ts_type = std::dynamic_pointer_cast(type); - PAIMON_RETURN_NOT_OK(Preconditions::CheckNotNull( - ts_type, "ts type cannot cast to arrow::TimestampType in BTreeGlobalIndex")); + auto ts_type = checked_pointer_cast(type); if (Timestamp::IsCompact(DateTimeUtils::GetPrecisionFromType(ts_type))) { return Literal(Timestamp::FromEpochMillis(slice.ReadLong(0))); } else { @@ -178,10 +180,7 @@ Result KeySerializer::DeserializeKey(const MemorySlice& slice, } } case arrow::Type::type::DECIMAL128: { - auto decimal_type = std::dynamic_pointer_cast(type); - PAIMON_RETURN_NOT_OK(Preconditions::CheckNotNull( - decimal_type, - "decimal type cannot cast to arrow::Decimal128Type in BTreeGlobalIndex")); + auto decimal_type = checked_pointer_cast(type); if (Decimal::IsCompact(decimal_type->precision())) { return Literal(Decimal::FromUnscaledLong( slice.ReadLong(0), decimal_type->precision(), decimal_type->scale())); diff --git a/src/paimon/common/global_index/complete_index_score_batch_reader.cpp b/src/paimon/common/global_index/complete_index_score_batch_reader.cpp index 15cdc8fe..c4626322 100644 --- a/src/paimon/common/global_index/complete_index_score_batch_reader.cpp +++ b/src/paimon/common/global_index/complete_index_score_batch_reader.cpp @@ -33,6 +33,7 @@ #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/status.h" namespace paimon { CompleteIndexScoreBatchReader::CompleteIndexScoreBatchReader( @@ -71,10 +72,10 @@ Result CompleteIndexScoreBatchReader::NextBatc auto& [c_array, c_schema] = batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto struct_array = std::dynamic_pointer_cast(arrow_array); - if (!struct_array) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("cannot cast array to StructArray in CompleteIndexScoreBatchReader"); } + auto struct_array = checked_pointer_cast(arrow_array); auto struct_type = struct_array->struct_type(); UpdateScoreFieldIndex(struct_type); @@ -82,8 +83,11 @@ Result CompleteIndexScoreBatchReader::NextBatc std::unique_ptr index_score_builder; PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::MakeBuilder( arrow_pool_.get(), SpecialFields::IndexScore().Type(), &index_score_builder)); - auto typed_builder = dynamic_cast(index_score_builder.get()); - assert(typed_builder); + if (!index_score_builder || !index_score_builder->type() || + index_score_builder->type()->id() != arrow::Type::FLOAT) { + return Status::Invalid("cannot cast index score builder to FloatBuilder"); + } + auto* typed_builder = checked_cast(index_score_builder.get()); PAIMON_RETURN_NOT_OK_FROM_ARROW(typed_builder->Reserve(struct_array->length())); bool all_not_null = (struct_array->length() == bitmap.Cardinality()); for (int64_t i = 0; i < struct_array->length(); i++) { diff --git a/src/paimon/common/global_index/rangebitmap/range_bitmap_global_index_test.cpp b/src/paimon/common/global_index/rangebitmap/range_bitmap_global_index_test.cpp index 01a1f842..d19622ad 100644 --- a/src/paimon/common/global_index/rangebitmap/range_bitmap_global_index_test.cpp +++ b/src/paimon/common/global_index/rangebitmap/range_bitmap_global_index_test.cpp @@ -30,6 +30,7 @@ #include "paimon/common/file_index/rangebitmap/range_bitmap_file_index.h" #include "paimon/common/global_index/wrap/file_index_writer_wrapper.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/path_util.h" #include "paimon/common/utils/scope_guard.h" @@ -237,7 +238,7 @@ TEST_F(RangeBitmapGlobalIndexTest, TestHighCardinality) { arrow::StructBuilder struct_builder(arrow::struct_({arrow::field("f0", type)}), arrow::default_memory_pool(), {std::make_shared()}); - auto int_builder = static_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(0)); for (int32_t i = 0; i < 100000; i++) { ASSERT_TRUE(struct_builder.Append().ok()); diff --git a/src/paimon/common/predicate/leaf_predicate_impl.h b/src/paimon/common/predicate/leaf_predicate_impl.h index 856fd467..c9a8758f 100644 --- a/src/paimon/common/predicate/leaf_predicate_impl.h +++ b/src/paimon/common/predicate/leaf_predicate_impl.h @@ -27,6 +27,7 @@ #include "paimon/common/predicate/leaf_function.h" #include "paimon/common/predicate/literal_converter.h" #include "paimon/common/predicate/predicate_filter.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/predicate/leaf_predicate.h" namespace paimon { class LeafPredicateImpl : public LeafPredicate, public PredicateFilter { @@ -41,7 +42,7 @@ class LeafPredicateImpl : public LeafPredicate, public PredicateFilter { } Result> Test(const arrow::Array& array) const override { - const auto& struct_array = arrow::internal::checked_cast(array); + const auto& struct_array = checked_cast(array); if (field_index_ >= static_cast(struct_array.fields().size())) { return Status::Invalid( fmt::format("field index {} exceed field count {} in struct array", field_index_, diff --git a/src/paimon/common/predicate/leaf_unary_function.h b/src/paimon/common/predicate/leaf_unary_function.h index b260bd36..544ce673 100644 --- a/src/paimon/common/predicate/leaf_unary_function.h +++ b/src/paimon/common/predicate/leaf_unary_function.h @@ -22,7 +22,6 @@ #include "arrow/array/array_nested.h" #include "arrow/c/bridge.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/predicate/leaf_function.h" #include "paimon/common/predicate/literal_converter.h" #include "paimon/common/utils/arrow/status_utils.h" diff --git a/src/paimon/common/predicate/literal_converter.cpp b/src/paimon/common/predicate/literal_converter.cpp index dafedc16..19410768 100644 --- a/src/paimon/common/predicate/literal_converter.cpp +++ b/src/paimon/common/predicate/literal_converter.cpp @@ -27,11 +27,11 @@ #include "arrow/array/array_primitive.h" #include "arrow/type.h" #include "arrow/type_traits.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "fmt/format.h" #include "paimon/common/data/binary_string.h" #include "paimon/common/data/internal_row.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/common/utils/string_utils.h" @@ -139,25 +139,25 @@ Result LiteralConverter::ConvertLiteralsFromRow( return Literal(type, field->data(), field->size()); } case FieldType::TIMESTAMP: { - auto timestamp_type = arrow::internal::checked_pointer_cast( - schema->field(field_idx)->type()); - if (!timestamp_type) { + const std::shared_ptr& field_type = schema->field(field_idx)->type(); + if (!field_type || field_type->id() != arrow::Type::TIMESTAMP) { return Status::Invalid( fmt::format("Convert literal from row not valid for schema {}, field_idx {}", schema->ToString(), field_idx)); } + auto timestamp_type = checked_pointer_cast(field_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); Timestamp field = row.GetTimestamp(field_idx, precision); return Literal(field); } case FieldType::DECIMAL: { - auto* decimal_type = arrow::internal::checked_cast( - schema->field(field_idx)->type().get()); - if (!decimal_type) { + const std::shared_ptr& field_type = schema->field(field_idx)->type(); + if (!field_type || field_type->id() != arrow::Type::DECIMAL128) { return Status::Invalid( fmt::format("Convert literal from row not valid for schema {}, field_idx {}", schema->ToString(), field_idx)); } + auto* decimal_type = checked_cast(field_type.get()); auto precision = decimal_type->precision(); auto scale = decimal_type->scale(); Decimal field = row.GetDecimal(field_idx, precision, scale); @@ -203,10 +203,8 @@ Result> LiteralConverter::ConvertLiteralsFromArray(const ar case arrow::Type::type::DATE32: return GetLiteralFromDateArray(array); case arrow::Type::type::DICTIONARY: { - const auto& dict_array = - arrow::internal::checked_cast(array); - auto* dict_type = - arrow::internal::checked_cast(dict_array.type().get()); + const auto& dict_array = checked_cast(array); + auto* dict_type = checked_cast(dict_array.type().get()); auto value_type_id = dict_type->value_type()->id(); auto index_type_id = dict_type->index_type()->id(); if (value_type_id == arrow::Type::type::STRING && @@ -230,8 +228,8 @@ Result> LiteralConverter::ConvertLiteralsFromArray(const ar std::vector LiteralConverter::GetLiteralFromDecimalArray(const arrow::Array& array) { using ArrayType = typename arrow::TypeTraits::ArrayType; - const auto& array_(arrow::internal::checked_cast(array)); - auto* arrow_type = arrow::internal::checked_cast(array.type().get()); + const auto& array_(checked_cast(array)); + auto* arrow_type = checked_cast(array.type().get()); int32_t precision = arrow_type->precision(); int32_t scale = arrow_type->scale(); std::vector literals; @@ -252,7 +250,7 @@ std::vector LiteralConverter::GetLiteralFromDecimalArray(const arrow::A std::vector LiteralConverter::GetLiteralFromDateArray(const arrow::Array& array) { using ArrayType = typename arrow::TypeTraits::ArrayType; - const auto& array_(arrow::internal::checked_cast(array)); + const auto& array_(checked_cast(array)); std::vector literals; literals.reserve(array_.length()); for (int64_t i = 0; i < array_.length(); i++) { @@ -267,10 +265,8 @@ std::vector LiteralConverter::GetLiteralFromDateArray(const arrow::Arra std::vector LiteralConverter::GetLiteralFromTimestampArray(const arrow::Array& array) { using ArrayType = typename arrow::TypeTraits::ArrayType; - const auto& array_(arrow::internal::checked_cast(array)); - auto timestamp_type = - arrow::internal::checked_pointer_cast(array_.type()); - assert(timestamp_type); + const auto& array_(checked_cast(array)); + auto timestamp_type = checked_pointer_cast(array_.type()); DateTimeUtils::TimeType time_type = DateTimeUtils::GetTimeTypeFromArrowType(timestamp_type); std::vector literals; literals.reserve(array_.length()); diff --git a/src/paimon/common/predicate/literal_converter.h b/src/paimon/common/predicate/literal_converter.h index 7b990a22..09739533 100644 --- a/src/paimon/common/predicate/literal_converter.h +++ b/src/paimon/common/predicate/literal_converter.h @@ -28,7 +28,7 @@ #include "arrow/array/array_dict.h" #include "arrow/type_traits.h" -#include "arrow/util/checked_cast.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/predicate/literal.h" #include "paimon/result.h" #include "paimon/visibility.h" @@ -63,7 +63,7 @@ class PAIMON_EXPORT LiteralConverter { const FieldType& literal_type) { using ArrayType = typename arrow::TypeTraits::ArrayType; using ValueType = typename arrow::TypeTraits::CType; - const ArrayType& array_(arrow::internal::checked_cast(array)); + const ArrayType& array_(checked_cast(array)); std::vector literals; literals.reserve(array_.length()); for (int64_t i = 0; i < array_.length(); i++) { @@ -82,7 +82,7 @@ class PAIMON_EXPORT LiteralConverter { bool own_data) { using ArrayType = typename arrow::TypeTraits::ArrayType; using OffsetType = typename ArrayType::offset_type; - const ArrayType& array_(arrow::internal::checked_cast(array)); + const ArrayType& array_(checked_cast(array)); std::vector literals; literals.reserve(array_.length()); for (int64_t i = 0; i < array_.length(); i++) { @@ -101,12 +101,8 @@ class PAIMON_EXPORT LiteralConverter { template static std::vector GetLiteralFromDictionaryArray( const arrow::DictionaryArray& dict_array, const FieldType& literal_type, bool own_data) { - auto* dictionary = - arrow::internal::checked_cast(dict_array.dictionary().get()); - auto* indices = - arrow::internal::checked_cast(dict_array.indices().get()); - assert(dictionary); - assert(indices); + auto* dictionary = checked_cast(dict_array.dictionary().get()); + auto* indices = checked_cast(dict_array.indices().get()); std::vector literals; literals.reserve(dict_array.length()); for (int64_t i = 0; i < dict_array.length(); ++i) { diff --git a/src/paimon/common/predicate/multi_literals_leaf_function.h b/src/paimon/common/predicate/multi_literals_leaf_function.h index 93c057ea..80446647 100644 --- a/src/paimon/common/predicate/multi_literals_leaf_function.h +++ b/src/paimon/common/predicate/multi_literals_leaf_function.h @@ -22,7 +22,6 @@ #include "arrow/array/array_nested.h" #include "arrow/c/bridge.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/predicate/leaf_function.h" #include "paimon/common/predicate/literal_converter.h" #include "paimon/common/utils/arrow/status_utils.h" diff --git a/src/paimon/common/predicate/null_false_leaf_binary_function.h b/src/paimon/common/predicate/null_false_leaf_binary_function.h index 56fc6ca5..87de3249 100644 --- a/src/paimon/common/predicate/null_false_leaf_binary_function.h +++ b/src/paimon/common/predicate/null_false_leaf_binary_function.h @@ -22,7 +22,6 @@ #include "arrow/array/array_nested.h" #include "arrow/c/bridge.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/predicate/leaf_function.h" #include "paimon/common/predicate/literal_converter.h" diff --git a/src/paimon/common/reader/blob_fallback_batch_reader.cpp b/src/paimon/common/reader/blob_fallback_batch_reader.cpp index 68d45c11..6ca3106b 100644 --- a/src/paimon/common/reader/blob_fallback_batch_reader.cpp +++ b/src/paimon/common/reader/blob_fallback_batch_reader.cpp @@ -33,6 +33,7 @@ #include "paimon/common/table/special_fields.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -168,10 +169,10 @@ Result BlobFallbackBatchReader::FillWindow(size_t group_idx, int64_t wa if (selected_array->length() == 0) { continue; } - auto struct_array = std::dynamic_pointer_cast(selected_array); - if (struct_array == nullptr) { + if (!selected_array || selected_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("Blob fallback expects file readers to emit struct arrays."); } + auto struct_array = checked_pointer_cast(selected_array); cursor.pending.push_back(std::move(struct_array)); } } @@ -188,12 +189,12 @@ Result> BlobFallbackBatchReader::ComputePlaceholderFlags( std::fill(flags.begin() + pos, flags.begin() + pos + chunk.length, true); } else { std::shared_ptr blob_col = chunk.array->field(blob_field_idx_); - auto binary_col = std::dynamic_pointer_cast(blob_col); - if (binary_col == nullptr) { + if (!blob_col || blob_col->type_id() != arrow::Type::LARGE_BINARY) { return Status::Invalid(fmt::format( "Blob fallback expects the blob column to be large binary, but got {}", - blob_col->type()->ToString())); + blob_col ? blob_col->type()->ToString() : "null")); } + auto binary_col = checked_pointer_cast(blob_col); for (int64_t k = 0; k < chunk.length; k++) { int64_t idx = chunk.offset + k; if (binary_col->IsNull(idx)) { diff --git a/src/paimon/common/reader/blob_fallback_batch_reader_test.cpp b/src/paimon/common/reader/blob_fallback_batch_reader_test.cpp index 29dd754c..a1ddf962 100644 --- a/src/paimon/common/reader/blob_fallback_batch_reader_test.cpp +++ b/src/paimon/common/reader/blob_fallback_batch_reader_test.cpp @@ -29,6 +29,7 @@ #include "paimon/common/data/blob_defs.h" #include "paimon/common/data/blob_utils.h" #include "paimon/common/table/special_fields.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/memory/memory_pool.h" #include "paimon/testing/mock/mock_file_batch_reader.h" #include "paimon/testing/utils/read_result_collector.h" @@ -56,7 +57,7 @@ class BlobFallbackBatchReaderTest : public ::testing::Test { arrow::StructBuilder struct_builder(struct_type_, arrow::default_memory_pool(), {std::make_shared()}); auto blob_builder = - static_cast(struct_builder.field_builder(0)); + checked_cast(struct_builder.field_builder(0)); for (const auto& row : rows) { EXPECT_TRUE(struct_builder.Append().ok()); if (!row) { @@ -241,7 +242,7 @@ TEST_F(BlobFallbackBatchReaderTest, TestRowTrackingFieldsPreserved) { arrow::StructBuilder struct_builder(struct_type, arrow::default_memory_pool(), std::move(field_builders)); auto blob_builder = - static_cast(struct_builder.field_builder(0)); + checked_cast(struct_builder.field_builder(0)); for (const auto& row : rows) { EXPECT_TRUE(struct_builder.Append().ok()); if (!row.blob) { @@ -254,12 +255,12 @@ TEST_F(BlobFallbackBatchReaderTest, TestRowTrackingFieldsPreserved) { } int32_t next_field = 1; if (with_row_id) { - auto builder = static_cast( + auto builder = checked_cast( struct_builder.field_builder(next_field++)); EXPECT_TRUE(builder->Append(row.row_id).ok()); } if (with_seq_num) { - auto builder = static_cast( + auto builder = checked_cast( struct_builder.field_builder(next_field)); EXPECT_TRUE(builder->Append(row.seq_num).ok()); } diff --git a/src/paimon/common/reader/blob_view_resolving_batch_reader.cpp b/src/paimon/common/reader/blob_view_resolving_batch_reader.cpp index a2714a31..29adedcd 100644 --- a/src/paimon/common/reader/blob_view_resolving_batch_reader.cpp +++ b/src/paimon/common/reader/blob_view_resolving_batch_reader.cpp @@ -34,6 +34,7 @@ #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/memory/bytes.h" #include "paimon/status.h" @@ -60,11 +61,11 @@ Result BlobViewResolvingBatchReader::NextBatch() { auto& [c_array, c_schema] = batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto struct_array = std::dynamic_pointer_cast(arrow_array); - if (struct_array == nullptr) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid( "invalid batch, BlobViewResolvingBatchReader expects a StructArray batch."); } + auto struct_array = checked_pointer_cast(arrow_array); const auto struct_type = struct_array->struct_type(); arrow::ArrayVector new_fields = struct_array->fields(); @@ -78,13 +79,13 @@ Result BlobViewResolvingBatchReader::NextBatch() { continue; } const auto& column = struct_array->field(field_idx); - if (auto large_binary_array = std::dynamic_pointer_cast(column)) { - PAIMON_ASSIGN_OR_RAISE(new_fields[field_idx], ResolveBinaryColumn(large_binary_array)); - } else { + if (!column || column->type_id() != arrow::Type::LARGE_BINARY) { return Status::Invalid(fmt::format( "BlobViewResolvingBatchReader expects blob-view column {} to be LargeBinaryArray.", field->name())); } + auto large_binary_array = checked_pointer_cast(column); + PAIMON_ASSIGN_OR_RAISE(new_fields[field_idx], ResolveBinaryColumn(large_binary_array)); } PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr resolved_struct_array, arrow::StructArray::Make(new_fields, field_names)); diff --git a/src/paimon/common/reader/complete_row_kind_batch_reader.cpp b/src/paimon/common/reader/complete_row_kind_batch_reader.cpp index 732f9b28..b613514e 100644 --- a/src/paimon/common/reader/complete_row_kind_batch_reader.cpp +++ b/src/paimon/common/reader/complete_row_kind_batch_reader.cpp @@ -33,6 +33,7 @@ #include "paimon/common/types/data_field.h" #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/status.h" namespace paimon { @@ -53,10 +54,10 @@ Result CompleteRowKindBatchReader::NextBatchWi auto& [c_array, c_schema] = batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto struct_array = std::dynamic_pointer_cast(arrow_array); - if (!struct_array) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("cannot cast array to StructArray in CompleteRowKindBatchReader"); } + auto struct_array = checked_pointer_cast(arrow_array); if (struct_array->GetFieldByName(SpecialFields::ValueKind().Name())) { // batch returned by reader_ has value kind, just return PAIMON_RETURN_NOT_OK_FROM_ARROW( diff --git a/src/paimon/common/reader/data_evolution_file_reader.cpp b/src/paimon/common/reader/data_evolution_file_reader.cpp index 296a56c6..6f2e12d4 100644 --- a/src/paimon/common/reader/data_evolution_file_reader.cpp +++ b/src/paimon/common/reader/data_evolution_file_reader.cpp @@ -28,6 +28,7 @@ #include "paimon/common/reader/reader_utils.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -77,8 +78,7 @@ Result DataEvolutionFileReader::NextBatchWithB } else if (array_length != array->length()) { return Status::Invalid("array for single reader length mismatch others"); } - auto struct_array = arrow::internal::checked_pointer_cast(array); - assert(struct_array); + auto struct_array = checked_pointer_cast(array); array_for_each_reader.push_back(struct_array); } int32_t read_field_count = read_schema_->num_fields(); diff --git a/src/paimon/common/reader/predicate_batch_reader.cpp b/src/paimon/common/reader/predicate_batch_reader.cpp index 7949811b..b4d6b91d 100644 --- a/src/paimon/common/reader/predicate_batch_reader.cpp +++ b/src/paimon/common/reader/predicate_batch_reader.cpp @@ -38,6 +38,7 @@ #include "paimon/common/reader/reader_utils.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/predicate/predicate.h" #include "paimon/predicate/predicate_utils.h" #include "paimon/status.h" @@ -96,8 +97,7 @@ Status PredicateBatchReader::BindPredicateToArray(const arrow::Array& array) { if (array.type_id() != arrow::Type::STRUCT) { return Status::Invalid("predicate batch reader requires a struct array"); } - const auto& struct_type = - arrow::internal::checked_cast(*array.type()); + const auto& struct_type = checked_cast(*array.type()); std::shared_ptr schema = arrow::schema(struct_type.fields()); PAIMON_RETURN_NOT_OK(PredicateValidator::ValidatePredicateWithSchema( *schema, predicate_, /*validate_field_idx=*/false)); diff --git a/src/paimon/common/reader/predicate_batch_reader_test.cpp b/src/paimon/common/reader/predicate_batch_reader_test.cpp index d934bfc2..8bcc53af 100644 --- a/src/paimon/common/reader/predicate_batch_reader_test.cpp +++ b/src/paimon/common/reader/predicate_batch_reader_test.cpp @@ -31,6 +31,7 @@ #include "arrow/array/builder_primitive.h" #include "arrow/ipc/json_simple.h" #include "gtest/gtest.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/defs.h" #include "paimon/memory/memory_pool.h" #include "paimon/predicate/literal.h" @@ -60,9 +61,9 @@ class PredicateBatchReaderTest : public ::testing::Test { data_type_, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto big_int_builder = static_cast(struct_builder.field_builder(1)); - auto bool_builder = static_cast(struct_builder.field_builder(2)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto big_int_builder = checked_cast(struct_builder.field_builder(1)); + auto bool_builder = checked_cast(struct_builder.field_builder(2)); for (int32_t i = 0 + offset; i < length + offset; ++i) { EXPECT_TRUE(struct_builder.Append().ok()); EXPECT_TRUE(string_builder->Append("str_" + std::to_string(i)).ok()); diff --git a/src/paimon/common/reader/prefetch_file_batch_reader_impl_test.cpp b/src/paimon/common/reader/prefetch_file_batch_reader_impl_test.cpp index e1514ada..ed840a24 100644 --- a/src/paimon/common/reader/prefetch_file_batch_reader_impl_test.cpp +++ b/src/paimon/common/reader/prefetch_file_batch_reader_impl_test.cpp @@ -25,6 +25,7 @@ #include "arrow/compute/api.h" #include "arrow/ipc/api.h" #include "gtest/gtest.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/executor.h" #include "paimon/format/file_format.h" @@ -137,9 +138,9 @@ class PrefetchFileBatchReaderImplTest : public ::testing::Test, data_type_, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto big_int_builder = static_cast(struct_builder.field_builder(1)); - auto bool_builder = static_cast(struct_builder.field_builder(2)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto big_int_builder = checked_cast(struct_builder.field_builder(1)); + auto bool_builder = checked_cast(struct_builder.field_builder(2)); for (int32_t i = 0 + offset; i < length + offset; ++i) { EXPECT_TRUE(struct_builder.Append().ok()); EXPECT_TRUE(string_builder->Append("str_" + std::to_string(i)).ok()); diff --git a/src/paimon/common/types/array_type.h b/src/paimon/common/types/array_type.h index cecd5bc2..1bd9324a 100644 --- a/src/paimon/common/types/array_type.h +++ b/src/paimon/common/types/array_type.h @@ -24,6 +24,7 @@ #include "arrow/api.h" #include "paimon/common/types/data_type.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/rapidjson_util.h" namespace paimon { @@ -43,7 +44,7 @@ class ArrayType : public DataType { rapidjson::StringRef("type"), RapidJsonUtil::SerializeValue(WithNullable(std::string(TYPE)), allocator).Move(), *allocator); - auto type = arrow::internal::checked_cast(type_.get()); + auto type = checked_cast(type_.get()); auto value_field = type->value_field(); // The element metadata is load-bearing: it is what marks an extension type such as diff --git a/src/paimon/common/types/data_type.cpp b/src/paimon/common/types/data_type.cpp index 623d4ca2..9b6d3c90 100644 --- a/src/paimon/common/types/data_type.cpp +++ b/src/paimon/common/types/data_type.cpp @@ -23,13 +23,13 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/blob_utils.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/types/array_type.h" #include "paimon/common/types/map_type.h" #include "paimon/common/types/row_type.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/decimal_utils.h" #include "paimon/common/utils/rapidjson_util.h" @@ -115,14 +115,13 @@ std::string DataType::DataTypeToString(const std::shared_ptr& t throw std::invalid_argument(status.ToString()); } const uint64_t precision = static_cast( - arrow::internal::checked_pointer_cast(type)->precision()); - const uint64_t scale = static_cast( - arrow::internal::checked_pointer_cast(type)->scale()); + checked_pointer_cast(type)->precision()); + const uint64_t scale = + static_cast(checked_pointer_cast(type)->scale()); return fmt::format("DECIMAL({}, {})", precision, scale); } case arrow::Type::type::TIMESTAMP: { - const auto& timestamp_type = - arrow::internal::checked_pointer_cast(type); + const auto& timestamp_type = checked_pointer_cast(type); return TimestampToString(timestamp_type); } case arrow::Type::type::STRUCT: { diff --git a/src/paimon/common/types/data_type_json_parser_test.cpp b/src/paimon/common/types/data_type_json_parser_test.cpp index bfa69c32..5026db02 100644 --- a/src/paimon/common/types/data_type_json_parser_test.cpp +++ b/src/paimon/common/types/data_type_json_parser_test.cpp @@ -24,6 +24,7 @@ #include "gtest/gtest.h" #include "paimon/common/data/variant/variant_type_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/status.h" #include "paimon/testing/utils/testharness.h" @@ -60,7 +61,7 @@ TEST(DataTypeJsonParserTest, ParseTypeMapTypeSuccess) { ASSERT_OK_AND_ASSIGN(std::shared_ptr field, DataTypeJsonParser::ParseType(name, doc)); ASSERT_NE(field, nullptr); - auto map_type = std::static_pointer_cast(field->type()); + auto map_type = checked_pointer_cast(field->type()); ASSERT_FALSE(map_type->key_field()->nullable()); } diff --git a/src/paimon/common/types/map_type.h b/src/paimon/common/types/map_type.h index 29fd8bbd..3e9cd01a 100644 --- a/src/paimon/common/types/map_type.h +++ b/src/paimon/common/types/map_type.h @@ -24,6 +24,7 @@ #include "arrow/api.h" #include "paimon/common/types/data_type.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/rapidjson_util.h" namespace paimon { @@ -50,7 +51,7 @@ class MapType : public DataType { rapidjson::StringRef("type"), RapidJsonUtil::SerializeValue(WithNullable(std::string(TYPE)), allocator).Move(), *allocator); - auto type = arrow::internal::checked_cast(type_.get()); + auto type = checked_cast(type_.get()); auto key_field = type->key_field(); // The key and value metadata is load-bearing: it is what marks an extension type such as // VARIANT. diff --git a/src/paimon/common/types/row_type.cpp b/src/paimon/common/types/row_type.cpp index f497cdf0..2cc239f3 100644 --- a/src/paimon/common/types/row_type.cpp +++ b/src/paimon/common/types/row_type.cpp @@ -27,8 +27,8 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/rapidjson_util.h" #include "paimon/common/utils/string_utils.h" #include "rapidjson/allocators.h" @@ -46,10 +46,10 @@ rapidjson::Value RowType::ToJson(rapidjson::Document::AllocatorType* allocator) rapidjson::Value obj(rapidjson::kObjectType); obj.AddMember(rapidjson::StringRef("type"), RapidJsonUtil::SerializeValue(WithNullable(TYPE), allocator).Move(), *allocator); - auto type = arrow::internal::checked_cast(type_.get()); - if (type == nullptr) { + if (!type_ || type_->id() != arrow::Type::STRUCT) { throw std::invalid_argument("type failed to cast to StructType"); } + auto type = checked_cast(type_.get()); std::vector fields; for (const auto& field : type->fields()) { diff --git a/src/paimon/common/utils/arrow/arrow_utils.cpp b/src/paimon/common/utils/arrow/arrow_utils.cpp index 04ce7216..707e888f 100644 --- a/src/paimon/common/utils/arrow/arrow_utils.cpp +++ b/src/paimon/common/utils/arrow/arrow_utils.cpp @@ -27,10 +27,10 @@ #include "arrow/type_traits.h" #include "arrow/util/bit_util.h" #include "arrow/util/bitmap_ops.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/compression.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/string_utils.h" namespace paimon { @@ -191,8 +191,7 @@ Result> RebaseFixedWidth( data->buffers[1] == nullptr || !data->child_data.empty() || data->dictionary != nullptr) { return std::shared_ptr(); } - const int32_t bit_width = - arrow::internal::checked_cast(*data->type).bit_width(); + const int32_t bit_width = checked_cast(*data->type).bit_width(); if (bit_width <= 0 || bit_width % 8 != 0) { return std::shared_ptr(); } @@ -255,11 +254,11 @@ const char* ArrowUtils::kArrowSchemaMetadataKey = "ARROW:schema"; Result> ArrowUtils::DataTypeToSchema( const std::shared_ptr& data_type) { - if (data_type->id() != arrow::Type::STRUCT) { - return Status::Invalid( - fmt::format("Expected struct data type, actual data type: {}", data_type->ToString())); + if (!data_type || data_type->id() != arrow::Type::STRUCT) { + return Status::Invalid(fmt::format("Expected struct data type, actual data type: {}", + data_type ? data_type->ToString() : "null")); } - const auto& struct_type = std::static_pointer_cast(data_type); + const auto& struct_type = checked_pointer_cast(data_type); return std::make_shared(struct_type->fields()); } @@ -280,7 +279,10 @@ Result> ArrowUtils::CreateProjection( Status ArrowUtils::CheckNullabilityMatch(const std::shared_ptr& schema, const std::shared_ptr& data) { - auto struct_array = arrow::internal::checked_pointer_cast(data); + if (!schema || !data || data->type_id() != arrow::Type::STRUCT) { + return Status::Invalid("CheckNullabilityMatch requires a schema and a struct array"); + } + auto struct_array = checked_pointer_cast(data); if (struct_array->num_fields() != schema->num_fields()) { return Status::Invalid(fmt::format( "CheckNullabilityMatch failed, data field count {} mismatch schema field count {}", @@ -296,25 +298,25 @@ void ArrowUtils::TraverseArray(const std::shared_ptr& array) { arrow::Type::type type = array->type()->id(); switch (type) { case arrow::Type::type::DICTIONARY: { - auto* dict_array = arrow::internal::checked_cast(array.get()); + auto* dict_array = checked_cast(array.get()); [[maybe_unused]] auto dict = dict_array->dictionary(); return; } case arrow::Type::type::STRUCT: { - auto* struct_array = arrow::internal::checked_cast(array.get()); + auto* struct_array = checked_cast(array.get()); for (const auto& field : struct_array->fields()) { TraverseArray(field); } return; } case arrow::Type::type::MAP: { - auto* map_array = arrow::internal::checked_cast(array.get()); + auto* map_array = checked_cast(array.get()); TraverseArray(map_array->keys()); TraverseArray(map_array->items()); return; } case arrow::Type::type::LIST: { - auto* list_array = arrow::internal::checked_cast(array.get()); + auto* list_array = checked_cast(array.get()); TraverseArray(list_array->values()); return; } @@ -350,20 +352,20 @@ Status ArrowUtils::InnerCheckNullabilityMatch(const std::shared_ptrtype(); if (type->id() == arrow::Type::STRUCT) { - auto struct_type = arrow::internal::checked_pointer_cast(field->type()); - auto struct_array = arrow::internal::checked_pointer_cast(data); + auto struct_type = checked_pointer_cast(field->type()); + auto struct_array = checked_pointer_cast(data); for (int32_t i = 0; i < struct_type->num_fields(); ++i) { PAIMON_RETURN_NOT_OK( InnerCheckNullabilityMatch(struct_type->field(i), struct_array->field(i))); } } else if (type->id() == arrow::Type::LIST) { - auto list_type = arrow::internal::checked_pointer_cast(field->type()); - auto list_array = arrow::internal::checked_pointer_cast(data); + auto list_type = checked_pointer_cast(field->type()); + auto list_array = checked_pointer_cast(data); PAIMON_RETURN_NOT_OK( InnerCheckNullabilityMatch(list_type->value_field(), list_array->values())); } else if (type->id() == arrow::Type::MAP) { - auto map_type = arrow::internal::checked_pointer_cast(field->type()); - auto map_array = arrow::internal::checked_pointer_cast(data); + auto map_type = checked_pointer_cast(field->type()); + auto map_array = checked_pointer_cast(data); PAIMON_RETURN_NOT_OK(InnerCheckNullabilityMatch(map_type->key_field(), map_array->keys())); PAIMON_RETURN_NOT_OK( InnerCheckNullabilityMatch(map_type->item_field(), map_array->items())); @@ -373,7 +375,7 @@ Status ArrowUtils::InnerCheckNullabilityMatch(const std::shared_ptr> ArrowUtils::RemoveFieldFromStructArray( const std::shared_ptr& struct_array, const std::string& field_name) { - auto struct_type = std::static_pointer_cast(struct_array->type()); + auto struct_type = checked_pointer_cast(struct_array->type()); int32_t field_idx = struct_type->GetFieldIndex(field_name); if (field_idx == -1) { return struct_array; diff --git a/src/paimon/common/utils/arrow/arrow_utils_test.cpp b/src/paimon/common/utils/arrow/arrow_utils_test.cpp index 032e8b4b..3680291c 100644 --- a/src/paimon/common/utils/arrow/arrow_utils_test.cpp +++ b/src/paimon/common/utils/arrow/arrow_utils_test.cpp @@ -23,10 +23,45 @@ #include "arrow/ipc/api.h" #include "gtest/gtest.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/testing/utils/testharness.h" namespace paimon::test { +namespace { + +class CastBase { + public: + virtual ~CastBase() = default; +}; + +class CastDerived : public CastBase {}; + +} // namespace + +TEST(CheckedCastTest, DelegatesToArrowCheckedCast) { + std::shared_ptr shared_base = std::make_shared(); + std::shared_ptr shared_derived = checked_pointer_cast(shared_base); + ASSERT_NE(shared_derived, nullptr); + + std::unique_ptr unique_base = std::make_unique(); + std::unique_ptr unique_derived = + checked_pointer_cast(std::move(unique_base)); + ASSERT_NE(unique_derived, nullptr); + + CastBase* raw_base = shared_base.get(); + ASSERT_EQ(checked_cast(raw_base), shared_derived.get()); + + std::shared_ptr null_base; + ASSERT_EQ(checked_pointer_cast(null_base), nullptr); + +#ifndef NDEBUG + std::shared_ptr wrong_type = std::make_shared(); + ASSERT_EQ(checked_pointer_cast(wrong_type), nullptr); + ASSERT_EQ(checked_cast(wrong_type.get()), nullptr); +#endif +} + TEST(ArrowUtilsTest, TestCreateProjection) { arrow::FieldVector file_fields = { arrow::field("k0", arrow::int32()), arrow::field("k1", arrow::int32()), @@ -346,7 +381,7 @@ TEST(ArrowUtilsTest, TestRemoveFieldFromStructArrayFieldNotFound) { auto src_array = arrow::ipc::internal::json::ArrayFromJSON( struct_type, R"([{"a":1,"b":"x"},{"a":2,"b":"y"},{"a":3,"b":"z"}])") .ValueOrDie(); - auto src_struct_array = std::static_pointer_cast(src_array); + auto src_struct_array = checked_pointer_cast(src_array); ASSERT_OK_AND_ASSIGN(auto result, ArrowUtils::RemoveFieldFromStructArray(src_struct_array, "missing")); @@ -364,7 +399,7 @@ TEST(ArrowUtilsTest, TestRemoveFieldFromStructArraySuccess) { struct_type, R"([{"a":1,"b":"x","c":10},{"a":2,"b":"y","c":20},{"a":3,"b":"z","c":30}])") .ValueOrDie(); - auto src_struct_array = std::static_pointer_cast(src_array); + auto src_struct_array = checked_pointer_cast(src_array); ASSERT_OK_AND_ASSIGN(auto result, ArrowUtils::RemoveFieldFromStructArray(src_struct_array, "b")); @@ -374,7 +409,7 @@ TEST(ArrowUtilsTest, TestRemoveFieldFromStructArraySuccess) { auto expected_array = arrow::ipc::internal::json::ArrayFromJSON( expected_type, R"([{"a":1,"c":10},{"a":2,"c":20},{"a":3,"c":30}])") .ValueOrDie(); - auto expected_struct_array = std::static_pointer_cast(expected_array); + auto expected_struct_array = checked_pointer_cast(expected_array); ASSERT_EQ(result->type()->num_fields(), 2); ASSERT_EQ(result->type()->field(0)->name(), "a"); @@ -415,7 +450,7 @@ TEST(ArrowUtilsTest, TestNormalizeRecordBatchOffsets) { ASSERT_NE(normalized_batch.get(), record_batch.get()); ASSERT_TRUE(normalized_batch->Equals(*record_batch)); std::shared_ptr normalized_nested = - std::static_pointer_cast(normalized_batch->column(0)); + checked_pointer_cast(normalized_batch->column(0)); ASSERT_EQ(normalized_nested->offset(), 0); ASSERT_EQ(normalized_nested->field(0)->offset(), 0); ASSERT_EQ(normalized_batch->column(1)->offset(), 0); diff --git a/src/paimon/common/utils/checked_cast.h b/src/paimon/common/utils/checked_cast.h new file mode 100644 index 00000000..bf3eb1aa --- /dev/null +++ b/src/paimon/common/utils/checked_cast.h @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include +#include + +#include "arrow/util/checked_cast.h" + +namespace paimon { + +/// Casts using Arrow's debug-checked cast implementation. In release builds this is a static +/// cast, so callers must validate any recoverable runtime type mismatch before calling it. +template +inline OutputType checked_cast(InputType&& value) { + return arrow::internal::checked_cast(std::forward(value)); +} + +template +inline std::shared_ptr checked_pointer_cast(std::shared_ptr value) noexcept { + return arrow::internal::checked_pointer_cast(std::move(value)); +} + +template +inline std::unique_ptr checked_pointer_cast(std::unique_ptr value) noexcept { + return arrow::internal::checked_pointer_cast(std::move(value)); +} + +} // namespace paimon diff --git a/src/paimon/common/utils/date_time_utils.h b/src/paimon/common/utils/date_time_utils.h index 652c312d..49d8f2d4 100644 --- a/src/paimon/common/utils/date_time_utils.h +++ b/src/paimon/common/utils/date_time_utils.h @@ -34,6 +34,7 @@ #include "arrow/vendored/datetime.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/data/timestamp.h" #include "paimon/result.h" namespace paimon { @@ -114,8 +115,12 @@ class DateTimeUtils { utc_micro, arrow::TimeUnit::MICRO, GetLocalTimezoneName()); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW( arrow::Datum local_micro, arrow::compute::LocalTimestamp(arrow::Datum(utc_ts_scalar))); - auto local_ts_scalar = - std::dynamic_pointer_cast(local_micro.scalar()); + auto local_scalar = local_micro.scalar(); + if (!local_scalar || !local_scalar->type || + local_scalar->type->id() != arrow::Type::TIMESTAMP) { + return Status::Invalid("LocalTimestamp did not return a TimestampScalar"); + } + auto local_ts_scalar = checked_pointer_cast(local_scalar); auto [millisecond, nano_of_millisecond] = DateTimeUtils::TimestampConverter( *(static_cast(local_ts_scalar->data())), DateTimeUtils::TimeType::MICROSECOND, DateTimeUtils::TimeType::MILLISECOND, @@ -216,8 +221,11 @@ class DateTimeUtils { PAIMON_ASSIGN_OR_RAISE_FROM_ARROW( arrow::Datum target_scalar, arrow::compute::AssumeTimezone(arrow::Datum(local_ts_scalar), options)); - auto utc_ts_scalar = - std::dynamic_pointer_cast(target_scalar.scalar()); + auto utc_scalar = target_scalar.scalar(); + if (!utc_scalar || !utc_scalar->type || utc_scalar->type->id() != arrow::Type::TIMESTAMP) { + return Status::Invalid("AssumeTimezone did not return a TimestampScalar"); + } + auto utc_ts_scalar = checked_pointer_cast(utc_scalar); auto [milli, nano] = DateTimeUtils::TimestampConverter( *(static_cast(utc_ts_scalar->data())), DateTimeUtils::TimeType::MICROSECOND, DateTimeUtils::TimeType::MILLISECOND, diff --git a/src/paimon/common/utils/date_time_utils_test.cpp b/src/paimon/common/utils/date_time_utils_test.cpp index e0121721..7d32c6d9 100644 --- a/src/paimon/common/utils/date_time_utils_test.cpp +++ b/src/paimon/common/utils/date_time_utils_test.cpp @@ -22,6 +22,7 @@ #include #include "gtest/gtest.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/testing/utils/testharness.h" #include "paimon/testing/utils/timezone_guard.h" @@ -182,39 +183,39 @@ TEST(DateTimeUtilsTest, TestTimestampToInteger) { TEST(DateTimeUtilsTest, TestGetPrecisionFromType) { auto ts_sec_type = arrow::timestamp(arrow::TimeUnit::type::SECOND); - auto ts_type = arrow::internal::checked_pointer_cast(ts_sec_type); + auto ts_type = checked_pointer_cast(ts_sec_type); ASSERT_EQ(DateTimeUtils::GetPrecisionFromType(ts_type), 0); auto ts_milli_type = arrow::timestamp(arrow::TimeUnit::type::MILLI); - ts_type = arrow::internal::checked_pointer_cast(ts_milli_type); + ts_type = checked_pointer_cast(ts_milli_type); ASSERT_EQ(DateTimeUtils::GetPrecisionFromType(ts_type), 3); auto ts_micro_type = arrow::timestamp(arrow::TimeUnit::type::MICRO); - ts_type = arrow::internal::checked_pointer_cast(ts_micro_type); + ts_type = checked_pointer_cast(ts_micro_type); ASSERT_EQ(DateTimeUtils::GetPrecisionFromType(ts_type), 6); auto ts_nano_type = arrow::timestamp(arrow::TimeUnit::type::NANO); - ts_type = arrow::internal::checked_pointer_cast(ts_nano_type); + ts_type = checked_pointer_cast(ts_nano_type); ASSERT_EQ(DateTimeUtils::GetPrecisionFromType(ts_type), 9); } TEST(DateTimeUtilsTest, TestGetTimeTypeFromArrowType) { auto ts_sec_type = arrow::timestamp(arrow::TimeUnit::type::SECOND); - auto ts_type = arrow::internal::checked_pointer_cast(ts_sec_type); + auto ts_type = checked_pointer_cast(ts_sec_type); ASSERT_EQ(DateTimeUtils::GetTimeTypeFromArrowType(ts_type), DateTimeUtils::TimeType::SECOND); auto ts_milli_type = arrow::timestamp(arrow::TimeUnit::type::MILLI); - ts_type = arrow::internal::checked_pointer_cast(ts_milli_type); + ts_type = checked_pointer_cast(ts_milli_type); ASSERT_EQ(DateTimeUtils::GetTimeTypeFromArrowType(ts_type), DateTimeUtils::TimeType::MILLISECOND); auto ts_micro_type = arrow::timestamp(arrow::TimeUnit::type::MICRO); - ts_type = arrow::internal::checked_pointer_cast(ts_micro_type); + ts_type = checked_pointer_cast(ts_micro_type); ASSERT_EQ(DateTimeUtils::GetTimeTypeFromArrowType(ts_type), DateTimeUtils::TimeType::MICROSECOND); auto ts_nano_type = arrow::timestamp(arrow::TimeUnit::type::NANO); - ts_type = arrow::internal::checked_pointer_cast(ts_nano_type); + ts_type = checked_pointer_cast(ts_nano_type); ASSERT_EQ(DateTimeUtils::GetTimeTypeFromArrowType(ts_type), DateTimeUtils::TimeType::NANOSECOND); } diff --git a/src/paimon/common/utils/decimal_utils.cpp b/src/paimon/common/utils/decimal_utils.cpp index 2cee2561..8e4522e5 100644 --- a/src/paimon/common/utils/decimal_utils.cpp +++ b/src/paimon/common/utils/decimal_utils.cpp @@ -26,16 +26,16 @@ #include "arrow/api.h" #include "arrow/util/basic_decimal.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "fmt/format.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { Status DecimalUtils::CheckDecimalType(const arrow::DataType& type) { - auto* decimal_type = dynamic_cast(&type); - if (!decimal_type) { + if (type.id() != arrow::Type::DECIMAL128) { return Status::Invalid(fmt::format("Invalid decimal type: {}", type.ToString())); } + auto* decimal_type = checked_cast(&type); if (decimal_type->precision() > Decimal::MAX_PRECISION || decimal_type->precision() < Decimal::MIN_PRECISION) { return Status::Invalid(fmt::format("Invalid decimal type, precision must in range [{}, {}]", diff --git a/src/paimon/common/utils/fields_comparator.cpp b/src/paimon/common/utils/fields_comparator.cpp index bb6f9f2f..224ec131 100644 --- a/src/paimon/common/utils/fields_comparator.cpp +++ b/src/paimon/common/utils/fields_comparator.cpp @@ -23,10 +23,10 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/binary_string.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/data/decimal.h" #include "paimon/data/timestamp.h" @@ -155,9 +155,7 @@ Result FieldsComparator::CompareField( }); } case arrow::Type::type::TIMESTAMP: { - auto timestamp_type = - arrow::internal::checked_pointer_cast(input_type); - assert(timestamp_type); + auto timestamp_type = checked_pointer_cast(input_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); return FieldsComparator::FieldComparatorFunc( [field_idx, precision](const InternalRow& lhs, const InternalRow& rhs) -> int32_t { @@ -167,9 +165,7 @@ Result FieldsComparator::CompareField( }); } case arrow::Type::type::DECIMAL128: { - auto* decimal_type = - arrow::internal::checked_cast(input_type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(input_type.get()); auto precision = decimal_type->precision(); auto scale = decimal_type->scale(); return FieldsComparator::FieldComparatorFunc( diff --git a/src/paimon/core/append/append_compact_task.cpp b/src/paimon/core/append/append_compact_task.cpp index d7e0e836..75fa524a 100644 --- a/src/paimon/core/append/append_compact_task.cpp +++ b/src/paimon/core/append/append_compact_task.cpp @@ -24,6 +24,7 @@ #include "fmt/format.h" #include "fmt/ranges.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/object_utils.h" #include "paimon/core/compact/cancellation_controller.h" #include "paimon/core/io/compact_increment.h" @@ -73,7 +74,7 @@ Result> AppendCompactTask::DoCompact( /*total_buckets=*/options.GetBucket(), data_increment, compact_increment); - return std::static_pointer_cast(commit_message); + return checked_pointer_cast(commit_message); } std::string AppendCompactTask::ToString() const { diff --git a/src/paimon/core/append/append_only_writer.cpp b/src/paimon/core/append/append_only_writer.cpp index feea29c5..d70611d5 100644 --- a/src/paimon/core/append/append_only_writer.cpp +++ b/src/paimon/core/append/append_only_writer.cpp @@ -33,6 +33,7 @@ #include "paimon/common/metrics/metrics_impl.h" #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/long_counter.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/core/io/append_data_file_writer_factory.h" @@ -90,7 +91,10 @@ Status AppendOnlyWriter::Write(std::unique_ptr&& batch) { auto data_type = arrow::struct_(write_schema_->fields()); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(batch->GetData(), data_type)); - auto struct_array = std::dynamic_pointer_cast(arrow_array); + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { + return Status::Invalid("AppendOnlyWriter: input is not a StructArray"); + } + auto struct_array = checked_pointer_cast(arrow_array); PAIMON_RETURN_NOT_OK(BlobUtils::ValidateBlobInlineFields( struct_array, inline_descriptor_fields_, "blob-descriptor-field")); PAIMON_RETURN_NOT_OK(BlobUtils::ValidateBlobInlineFields(struct_array, inline_view_fields_, diff --git a/src/paimon/core/append/append_only_writer_test.cpp b/src/paimon/core/append/append_only_writer_test.cpp index 068398b3..fdde9a9c 100644 --- a/src/paimon/core/append/append_only_writer_test.cpp +++ b/src/paimon/core/append/append_only_writer_test.cpp @@ -44,6 +44,7 @@ #include "paimon/common/data/shredding/map_shredding_defs.h" #include "paimon/common/fs/external_path_provider.h" #include "paimon/common/utils/arrow/arrow_input_stream_adapter.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/compact/compact_deletion_file.h" #include "paimon/core/compact/compact_result.h" #include "paimon/core/compact/noop_compact_manager.h" @@ -220,7 +221,7 @@ class AppendOnlyWriterTest : public testing::Test { auto struct_type = arrow::struct_(fields); arrow::StructBuilder struct_builder(struct_type, arrow::default_memory_pool(), {std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); for (const auto& value : values) { EXPECT_TRUE(struct_builder.Append().ok()); EXPECT_TRUE(string_builder->Append(value).ok()); @@ -425,7 +426,7 @@ TEST_F(AppendOnlyWriterTest, TestWriteAndClose) { auto struct_type = arrow::struct_(fields); arrow::StructBuilder struct_builder(struct_type, arrow::default_memory_pool(), {std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); for (size_t j = 0; j < 100; j++) { ASSERT_TRUE(struct_builder.Append().ok()); ASSERT_TRUE(string_builder->Append(std::to_string(j)).ok()); @@ -470,7 +471,7 @@ TEST_F(AppendOnlyWriterTest, TestInvalidRowKind) { auto struct_type = arrow::struct_(fields); arrow::StructBuilder struct_builder(struct_type, arrow::default_memory_pool(), {std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); ASSERT_TRUE(struct_builder.Append().ok()); ASSERT_TRUE(string_builder->Append("row0").ok()); std::shared_ptr array; diff --git a/src/paimon/core/bucket/bucket_id_calculator.cpp b/src/paimon/core/bucket/bucket_id_calculator.cpp index c3dcb79e..21a98b99 100644 --- a/src/paimon/core/bucket/bucket_id_calculator.cpp +++ b/src/paimon/core/bucket/bucket_id_calculator.cpp @@ -38,12 +38,12 @@ #include "arrow/c/abi.h" #include "arrow/c/bridge.h" #include "arrow/c/helpers.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "fmt/format.h" #include "paimon/common/data/binary_row.h" #include "paimon/common/data/binary_row_writer.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/core/bucket/bucket_function.h" @@ -69,9 +69,7 @@ static Result WriteBucketRow(int32_t col_id, arrow::Type::type type = field->type()->id(); switch (type) { case arrow::Type::type::BOOL: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -80,9 +78,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::INT8: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -91,9 +87,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::INT16: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -102,9 +96,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::INT32: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -113,9 +105,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::INT64: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -124,9 +114,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::FLOAT: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -135,9 +123,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::DOUBLE: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -146,9 +132,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::DATE32: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -157,9 +141,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::STRING: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -169,9 +151,7 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::BINARY: { - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array](int32_t row_id, BinaryRowWriter* row_writer) { CHECK_AND_SET_NULL(typed_array, row_writer, row_id, col_id); @@ -181,15 +161,11 @@ static Result WriteBucketRow(int32_t col_id, return writer_func; } case arrow::Type::type::TIMESTAMP: { - auto timestamp_type = - arrow::internal::checked_pointer_cast(field->type()); - assert(timestamp_type); + auto timestamp_type = checked_pointer_cast(field->type()); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); DateTimeUtils::TimeType time_type = DateTimeUtils::GetTimeTypeFromArrowType(timestamp_type); - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [typed_array, col_id, precision, time_type]( int32_t row_id, BinaryRowWriter* row_writer) { if (typed_array->IsNull(row_id)) { @@ -210,13 +186,10 @@ static Result WriteBucketRow(int32_t col_id, } case arrow::Type::type::DECIMAL128: { const auto* decimal_type = - arrow::internal::checked_cast(field->type().get()); - assert(decimal_type); + checked_cast(field->type().get()); auto precision = decimal_type->precision(); auto scale = decimal_type->scale(); - const auto* typed_array = - arrow::internal::checked_cast(field.get()); - assert(typed_array); + const auto* typed_array = checked_cast(field.get()); WriteFunction writer_func = [col_id, typed_array, precision, scale]( int32_t row_id, BinaryRowWriter* row_writer) { if (typed_array->IsNull(row_id)) { @@ -308,11 +281,10 @@ Status BucketIdCalculator::CalculateBucketIds(ArrowArray* bucket_keys, ArrowSche PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr bucket_array, arrow::ImportArray(bucket_keys, bucket_schema)); - const auto* struct_array = - arrow::internal::checked_cast(bucket_array.get()); - if (!struct_array) { + if (!bucket_array || bucket_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("bucket keys is not a struct array"); } + const auto* struct_array = checked_cast(bucket_array.get()); std::vector write_functions; int32_t num_fields = struct_array->num_fields(); write_functions.reserve(num_fields); diff --git a/src/paimon/core/bucket/bucket_id_calculator_test.cpp b/src/paimon/core/bucket/bucket_id_calculator_test.cpp index 97284a6f..2c3061d1 100644 --- a/src/paimon/core/bucket/bucket_id_calculator_test.cpp +++ b/src/paimon/core/bucket/bucket_id_calculator_test.cpp @@ -29,9 +29,9 @@ #include "arrow/c/abi.h" #include "arrow/c/bridge.h" #include "arrow/ipc/json_simple.h" -#include "arrow/util/checked_cast.h" #include "gtest/gtest.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/core/bucket/default_bucket_function.h" #include "paimon/core/bucket/mod_bucket_function.h" @@ -138,7 +138,7 @@ TEST_F(BucketIdCalculatorTest, TestCompatibleWithJava) { CalculateBucketIds(/*is_pk_table=*/true, /*num_buckets=*/12345, bucket_schema, bucket_array)); - auto bucket_id_array = arrow::internal::checked_cast( + auto bucket_id_array = checked_cast( bucket_array_with_id->field(bucket_schema->num_fields()).get()); ASSERT_TRUE(bucket_id_array); // test compatible with java @@ -189,7 +189,7 @@ TEST_F(BucketIdCalculatorTest, TestCompatibleWithJavaWithNull) { CalculateBucketIds(/*is_pk_table=*/false, /*num_buckets=*/12345, bucket_schema, bucket_array)); - auto bucket_id_array = arrow::internal::checked_cast( + auto bucket_id_array = checked_cast( bucket_array_with_id->field(bucket_schema->num_fields()).get()); ASSERT_TRUE(bucket_id_array); // test compatible with java @@ -236,7 +236,7 @@ TEST_F(BucketIdCalculatorTest, TestCompatibleWithJavaWithTimestamp) { CalculateBucketIds(/*is_pk_table=*/false, /*num_buckets=*/12345, bucket_schema, bucket_array)); - auto bucket_id_array = arrow::internal::checked_cast( + auto bucket_id_array = checked_cast( bucket_array_with_id->field(bucket_schema->num_fields()).get()); ASSERT_TRUE(bucket_id_array); // test compatible with java diff --git a/src/paimon/core/bucket/bucket_select_converter.cpp b/src/paimon/core/bucket/bucket_select_converter.cpp index 01bf860a..3e8aa17e 100644 --- a/src/paimon/core/bucket/bucket_select_converter.cpp +++ b/src/paimon/core/bucket/bucket_select_converter.cpp @@ -24,10 +24,10 @@ #include #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/binary_row.h" #include "paimon/common/data/binary_row_writer.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/core/bucket/bucket_function.h" @@ -166,16 +166,14 @@ Status BucketSelectConverter::WriteLiteralToRow(int32_t pos, const Literal& lite } case FieldType::TIMESTAMP: { auto ts = literal.GetValue(); - auto timestamp_type = - arrow::internal::checked_pointer_cast(arrow_type); + auto timestamp_type = checked_pointer_cast(arrow_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); writer->WriteTimestamp(pos, ts, precision); break; } case FieldType::DECIMAL: { auto dec = literal.GetValue(); - const auto* decimal_type = - arrow::internal::checked_cast(arrow_type.get()); + const auto* decimal_type = checked_cast(arrow_type.get()); int32_t precision = decimal_type->precision(); writer->WriteDecimal(pos, dec, precision); break; @@ -206,8 +204,7 @@ Result> BucketSelectConverter::CreateBucketFunct for (size_t i = 0; i < bucket_key_types.size(); i++) { if (bucket_key_types[i] == FieldType::DECIMAL) { const auto* decimal_type = - arrow::internal::checked_cast( - bucket_key_arrow_types[i].get()); + checked_cast(bucket_key_arrow_types[i].get()); field_infos.emplace_back(bucket_key_types[i], decimal_type->precision(), decimal_type->scale()); } else { diff --git a/src/paimon/core/casting/binary_to_blob_cast_executor.cpp b/src/paimon/core/casting/binary_to_blob_cast_executor.cpp index 5642e62b..77ee39e8 100644 --- a/src/paimon/core/casting/binary_to_blob_cast_executor.cpp +++ b/src/paimon/core/casting/binary_to_blob_cast_executor.cpp @@ -27,6 +27,7 @@ #include "arrow/type.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/status.h" namespace arrow { @@ -55,7 +56,7 @@ Result> BinaryToBlobCastExecutor::Cast( target_type->ToString())); } - auto binary_array = std::static_pointer_cast(array); + auto binary_array = checked_pointer_cast(array); if (binary_array->offset() != 0) { return Status::Invalid("BinaryToBlobCastExecutor only supports arrays with zero offset"); } diff --git a/src/paimon/core/casting/boolean_to_decimal_cast_executor.cpp b/src/paimon/core/casting/boolean_to_decimal_cast_executor.cpp index 81884f8f..cf9a24b9 100644 --- a/src/paimon/core/casting/boolean_to_decimal_cast_executor.cpp +++ b/src/paimon/core/casting/boolean_to_decimal_cast_executor.cpp @@ -27,9 +27,9 @@ #include "arrow/array/array_primitive.h" #include "arrow/array/builder_decimal.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/decimal_utils.h" #include "paimon/data/decimal.h" #include "paimon/defs.h" @@ -46,8 +46,7 @@ Result BooleanToDecimalCastExecutor::Cast( const Literal& literal, const std::shared_ptr& target_type) const { assert(literal.GetType() == FieldType::BOOLEAN); PAIMON_RETURN_NOT_OK(DecimalUtils::CheckDecimalType(*target_type)); - auto* decimal_type = arrow::internal::checked_cast(target_type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(target_type.get()); if (literal.IsNull()) { return Literal(FieldType::DECIMAL); } @@ -70,10 +69,8 @@ Result> BooleanToDecimalCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { PAIMON_RETURN_NOT_OK(DecimalUtils::CheckDecimalType(*target_type)); - auto* boolean_array = arrow::internal::checked_cast(array.get()); - assert(boolean_array); - auto* decimal_type = arrow::internal::checked_cast(target_type.get()); - assert(decimal_type); + auto* boolean_array = checked_cast(array.get()); + auto* decimal_type = checked_cast(target_type.get()); auto decimal_builder = std::make_shared(target_type, pool); for (int64_t i = 0; i < boolean_array->length(); ++i) { if (boolean_array->IsNull(i)) { diff --git a/src/paimon/core/casting/casting_utils.cpp b/src/paimon/core/casting/casting_utils.cpp index c5820f9d..d17b475c 100644 --- a/src/paimon/core/casting/casting_utils.cpp +++ b/src/paimon/core/casting/casting_utils.cpp @@ -20,6 +20,8 @@ #include +#include "paimon/common/utils/checked_cast.h" + namespace paimon { Result> CastingUtils::Cast( const std::shared_ptr& src_array, @@ -40,9 +42,7 @@ Result> CastingUtils::Cast( Result> CastingUtils::TimestampToTimestampWithTimezone( const std::shared_ptr& src_array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) { - auto src_ts_type = - arrow::internal::checked_pointer_cast(src_array->type()); - assert(src_ts_type); + auto src_ts_type = checked_pointer_cast(src_array->type()); if (src_ts_type->unit() != target_type->unit()) { return Status::Invalid("in timezone converter, time unit of src and target type mismatch"); } @@ -62,9 +62,7 @@ Result> CastingUtils::TimestampToTimestampWithTime Result> CastingUtils::TimestampWithTimezoneToTimestamp( const std::shared_ptr& src_array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) { - auto src_ts_type = - arrow::internal::checked_pointer_cast(src_array->type()); - assert(src_ts_type); + auto src_ts_type = checked_pointer_cast(src_array->type()); if (src_ts_type->unit() != target_type->unit()) { return Status::Invalid("in timezone converter, time unit of src and target type mismatch"); } diff --git a/src/paimon/core/casting/casting_utils.h b/src/paimon/core/casting/casting_utils.h index 453abf8a..d28ff3cc 100644 --- a/src/paimon/core/casting/casting_utils.h +++ b/src/paimon/core/casting/casting_utils.h @@ -73,8 +73,7 @@ class CastingUtils { PAIMON_ASSIGN_OR_RAISE_FROM_ARROW( arrow::Datum casted_result, arrow::compute::Cast(arrow::Datum(src_scalar), type_holder, options)); - auto* casted_scalar = - arrow::internal::checked_cast(casted_result.scalar().get()); + auto* casted_scalar = dynamic_cast(casted_result.scalar().get()); if (!casted_scalar) { return Status::Invalid(fmt::format("cast literal failed: cannot cast to {} scalar", target_type->ToString())); diff --git a/src/paimon/core/casting/casting_utils_test.cpp b/src/paimon/core/casting/casting_utils_test.cpp index 861789c6..0c66c662 100644 --- a/src/paimon/core/casting/casting_utils_test.cpp +++ b/src/paimon/core/casting/casting_utils_test.cpp @@ -24,6 +24,7 @@ #include "arrow/ipc/api.h" #include "gtest/gtest.h" #include "paimon/common/utils/arrow/mem_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/testing/utils/testharness.h" namespace paimon::test { @@ -59,7 +60,7 @@ TEST_F(CastingUtilsTest, TestTimestampToTimestampWithTimezone) { .ValueOr(nullptr); ASSERT_TRUE(src_array); auto target_type = arrow::timestamp(arrow::TimeUnit::SECOND, "Asia/Shanghai"); - auto target_ts_type = arrow::internal::checked_pointer_cast(target_type); + auto target_ts_type = checked_pointer_cast(target_type); auto target_array = arrow::ipc::internal::json::ArrayFromJSON(target_type, R"(["1969-12-31 16:00:01"])") .ValueOr(nullptr); @@ -78,8 +79,7 @@ TEST_F(CastingUtilsTest, TestTimestampToTimestampWithTimezoneInvalid) { .ValueOr(nullptr); ASSERT_TRUE(src_array); auto target_type = arrow::timestamp(arrow::TimeUnit::NANO, "Asia/Shanghai"); - auto target_ts_type = - arrow::internal::checked_pointer_cast(target_type); + auto target_ts_type = checked_pointer_cast(target_type); ASSERT_NOK_WITH_MSG(CastingUtils::TimestampToTimestampWithTimezone( src_array, target_ts_type, arrow_pool_.get()), "time unit of src and target type mismatch"); @@ -91,8 +91,7 @@ TEST_F(CastingUtilsTest, TestTimestampToTimestampWithTimezoneInvalid) { .ValueOr(nullptr); ASSERT_TRUE(src_array); auto target_type = arrow::timestamp(arrow::TimeUnit::SECOND); - auto target_ts_type = - arrow::internal::checked_pointer_cast(target_type); + auto target_ts_type = checked_pointer_cast(target_type); ASSERT_NOK_WITH_MSG( CastingUtils::TimestampToTimestampWithTimezone(src_array, target_ts_type, arrow_pool_.get()), @@ -105,8 +104,7 @@ TEST_F(CastingUtilsTest, TestTimestampToTimestampWithTimezoneInvalid) { .ValueOr(nullptr); ASSERT_TRUE(src_array); auto target_type = arrow::timestamp(arrow::TimeUnit::SECOND, "Europe/Warsaw"); - auto target_ts_type = - arrow::internal::checked_pointer_cast(target_type); + auto target_ts_type = checked_pointer_cast(target_type); ASSERT_NOK_WITH_MSG(CastingUtils::TimestampToTimestampWithTimezone( src_array, target_ts_type, arrow_pool_.get()), "Timestamp doesn't exist in timezone 'Europe/Warsaw': 2015-03-29 " @@ -122,7 +120,7 @@ TEST_F(CastingUtilsTest, TestTimestampWithTimezoneToTimestamp) { .ValueOr(nullptr); ASSERT_TRUE(src_array); auto target_type = arrow::timestamp(arrow::TimeUnit::SECOND); - auto target_ts_type = arrow::internal::checked_pointer_cast(target_type); + auto target_ts_type = checked_pointer_cast(target_type); auto target_array = arrow::ipc::internal::json::ArrayFromJSON(target_type, R"(["1970-01-01 08:00:01"])") .ValueOr(nullptr); @@ -141,8 +139,7 @@ TEST_F(CastingUtilsTest, TestTimestampWithTimezoneToTimestampInvalid) { .ValueOr(nullptr); ASSERT_TRUE(src_array); auto target_type = arrow::timestamp(arrow::TimeUnit::SECOND); - auto target_ts_type = - arrow::internal::checked_pointer_cast(target_type); + auto target_ts_type = checked_pointer_cast(target_type); ASSERT_NOK_WITH_MSG(CastingUtils::TimestampWithTimezoneToTimestamp( src_array, target_ts_type, arrow_pool_.get()), "in timezone converter, time unit of src and target type mismatch"); @@ -154,8 +151,7 @@ TEST_F(CastingUtilsTest, TestTimestampWithTimezoneToTimestampInvalid) { .ValueOr(nullptr); ASSERT_TRUE(src_array); auto target_type = arrow::timestamp(arrow::TimeUnit::SECOND, "Asia/Tokyo"); - auto target_ts_type = - arrow::internal::checked_pointer_cast(target_type); + auto target_ts_type = checked_pointer_cast(target_type); ASSERT_NOK_WITH_MSG(CastingUtils::TimestampWithTimezoneToTimestamp( src_array, target_ts_type, arrow_pool_.get()), "target value must be local time (no tz)"); diff --git a/src/paimon/core/casting/date_to_timestamp_cast_executor.cpp b/src/paimon/core/casting/date_to_timestamp_cast_executor.cpp index 33d911f9..594615f2 100644 --- a/src/paimon/core/casting/date_to_timestamp_cast_executor.cpp +++ b/src/paimon/core/casting/date_to_timestamp_cast_executor.cpp @@ -25,7 +25,7 @@ #include "arrow/compute/cast.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/casting/casting_utils.h" #include "paimon/status.h" @@ -44,8 +44,7 @@ Result DateToTimestampCastExecutor::Cast( Result> DateToTimestampCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { - auto target_ts_type = arrow::internal::checked_pointer_cast(target_type); - assert(target_ts_type); + auto target_ts_type = checked_pointer_cast(target_type); arrow::compute::CastOptions options = arrow::compute::CastOptions::Safe(); auto target_ts_type_no_tz = arrow::timestamp(target_ts_type->unit()); diff --git a/src/paimon/core/casting/decimal_to_decimal_cast_executor.cpp b/src/paimon/core/casting/decimal_to_decimal_cast_executor.cpp index 34dabded..d1845ded 100644 --- a/src/paimon/core/casting/decimal_to_decimal_cast_executor.cpp +++ b/src/paimon/core/casting/decimal_to_decimal_cast_executor.cpp @@ -28,9 +28,9 @@ #include "arrow/array/array_decimal.h" #include "arrow/array/builder_decimal.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/decimal_utils.h" #include "paimon/data/decimal.h" #include "paimon/defs.h" @@ -48,9 +48,7 @@ Result DecimalToDecimalCastExecutor::Cast( if (literal.IsNull()) { return Literal(FieldType::DECIMAL); } - auto* target_decimal_type = - arrow::internal::checked_cast(target_type.get()); - assert(target_decimal_type); + auto* target_decimal_type = checked_cast(target_type.get()); auto src_value = literal.GetValue(); arrow::Decimal128 src_decimal(src_value.HighBits(), src_value.LowBits()); auto scaled_decimal = DecimalUtils::RescaleDecimalWithOverflowCheck( @@ -71,14 +69,9 @@ Result> DecimalToDecimalCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { PAIMON_RETURN_NOT_OK(DecimalUtils::CheckDecimalType(*target_type)); - auto* src_array = arrow::internal::checked_cast(array.get()); - assert(src_array); - auto* src_decimal_type = - arrow::internal::checked_cast(array->type().get()); - assert(src_decimal_type); - auto* target_decimal_type = - arrow::internal::checked_cast(target_type.get()); - assert(target_decimal_type); + auto* src_array = checked_cast(array.get()); + auto* src_decimal_type = checked_cast(array->type().get()); + auto* target_decimal_type = checked_cast(target_type.get()); auto decimal_builder = std::make_shared(target_type, pool); for (int64_t i = 0; i < src_array->length(); ++i) { if (src_array->IsNull(i)) { diff --git a/src/paimon/core/casting/numeric_primitive_to_decimal_cast_executor.cpp b/src/paimon/core/casting/numeric_primitive_to_decimal_cast_executor.cpp index b950dbc6..ade60d45 100644 --- a/src/paimon/core/casting/numeric_primitive_to_decimal_cast_executor.cpp +++ b/src/paimon/core/casting/numeric_primitive_to_decimal_cast_executor.cpp @@ -30,10 +30,10 @@ #include "arrow/array/array_primitive.h" #include "arrow/array/builder_decimal.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/decimal_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/data/decimal.h" @@ -49,8 +49,7 @@ namespace paimon { template Result NumericPrimitiveToDecimalCastExecutor::Cast( const Literal& literal, const std::shared_ptr& target_type) { - auto* decimal_type = arrow::internal::checked_cast(target_type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(target_type.get()); if (literal.IsNull()) { return Literal(FieldType::DECIMAL); } @@ -113,9 +112,8 @@ Result> NumericPrimitiveToDecimalCastExecutor::Cas const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) { using SrcValueType = typename arrow::NumericArray::value_type; - auto* typed_array = arrow::internal::checked_cast*>(array.get()); - assert(typed_array); - auto* decimal_type = arrow::internal::checked_cast(target_type.get()); + auto* typed_array = checked_cast*>(array.get()); + auto* decimal_type = checked_cast(target_type.get()); auto decimal_builder = std::make_shared(target_type, pool); for (int64_t i = 0; i < typed_array->length(); ++i) { if (typed_array->IsNull(i)) { diff --git a/src/paimon/core/casting/numeric_primitive_to_timestamp_cast_executor.cpp b/src/paimon/core/casting/numeric_primitive_to_timestamp_cast_executor.cpp index 33f5ca61..be283d16 100644 --- a/src/paimon/core/casting/numeric_primitive_to_timestamp_cast_executor.cpp +++ b/src/paimon/core/casting/numeric_primitive_to_timestamp_cast_executor.cpp @@ -27,7 +27,6 @@ #include "arrow/array/array_base.h" #include "arrow/array/builder_dict.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/status_utils.h" #include "paimon/common/utils/date_time_utils.h" diff --git a/src/paimon/core/casting/string_to_boolean_cast_executor.cpp b/src/paimon/core/casting/string_to_boolean_cast_executor.cpp index 58632781..951682f3 100644 --- a/src/paimon/core/casting/string_to_boolean_cast_executor.cpp +++ b/src/paimon/core/casting/string_to_boolean_cast_executor.cpp @@ -28,9 +28,9 @@ #include "arrow/array/array_binary.h" #include "arrow/array/builder_primitive.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/common/utils/string_utils.h" #include "paimon/defs.h" @@ -63,8 +63,7 @@ Result StringToBooleanCastExecutor::Cast( Result> StringToBooleanCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { - auto* string_array = arrow::internal::checked_cast(array.get()); - assert(string_array); + auto* string_array = checked_cast(array.get()); auto bool_builder = std::make_shared(pool); for (int64_t i = 0; i < string_array->length(); ++i) { if (string_array->IsNull(i)) { diff --git a/src/paimon/core/casting/string_to_date_cast_executor.cpp b/src/paimon/core/casting/string_to_date_cast_executor.cpp index 06089205..66c4cbbe 100644 --- a/src/paimon/core/casting/string_to_date_cast_executor.cpp +++ b/src/paimon/core/casting/string_to_date_cast_executor.cpp @@ -27,8 +27,8 @@ #include "arrow/array/array_binary.h" #include "arrow/array/builder_primitive.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/common/utils/string_utils.h" #include "paimon/defs.h" @@ -56,8 +56,7 @@ Result StringToDateCastExecutor::Cast( Result> StringToDateCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { - auto* string_array = arrow::internal::checked_cast(array.get()); - assert(string_array); + auto* string_array = checked_cast(array.get()); auto date_builder = std::make_shared(pool); for (int64_t i = 0; i < string_array->length(); ++i) { if (string_array->IsNull(i)) { diff --git a/src/paimon/core/casting/string_to_decimal_cast_executor.cpp b/src/paimon/core/casting/string_to_decimal_cast_executor.cpp index 1f8af8b5..7b7554d9 100644 --- a/src/paimon/core/casting/string_to_decimal_cast_executor.cpp +++ b/src/paimon/core/casting/string_to_decimal_cast_executor.cpp @@ -25,9 +25,9 @@ #include "arrow/array/array_binary.h" #include "arrow/array/builder_decimal.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/decimal_utils.h" #include "paimon/data/decimal.h" #include "paimon/defs.h" @@ -58,8 +58,7 @@ Result StringToDecimalCastExecutor::Cast( const Literal& literal, const std::shared_ptr& target_type) const { assert(literal.GetType() == FieldType::STRING); PAIMON_RETURN_NOT_OK(DecimalUtils::CheckDecimalType(*target_type)); - auto* decimal_type = arrow::internal::checked_cast(target_type.get()); - assert(decimal_type); + auto* decimal_type = checked_cast(target_type.get()); if (literal.IsNull()) { return Literal(FieldType::DECIMAL); } @@ -82,9 +81,8 @@ Result> StringToDecimalCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { PAIMON_RETURN_NOT_OK(DecimalUtils::CheckDecimalType(*target_type)); - auto* string_array = arrow::internal::checked_cast(array.get()); - assert(string_array); - auto* decimal_type = arrow::internal::checked_cast(target_type.get()); + auto* string_array = checked_cast(array.get()); + auto* decimal_type = checked_cast(target_type.get()); auto decimal_builder = std::make_shared(target_type, pool); for (int64_t i = 0; i < string_array->length(); ++i) { if (string_array->IsNull(i)) { diff --git a/src/paimon/core/casting/string_to_timestamp_cast_executor.cpp b/src/paimon/core/casting/string_to_timestamp_cast_executor.cpp index 09b06235..288c221c 100644 --- a/src/paimon/core/casting/string_to_timestamp_cast_executor.cpp +++ b/src/paimon/core/casting/string_to_timestamp_cast_executor.cpp @@ -25,7 +25,7 @@ #include "arrow/compute/cast.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/casting/casting_utils.h" #include "paimon/status.h" @@ -44,8 +44,7 @@ Result StringToTimestampCastExecutor::Cast( Result> StringToTimestampCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { - auto timestamp_type = arrow::internal::checked_pointer_cast(target_type); - assert(timestamp_type); + auto timestamp_type = checked_pointer_cast(target_type); auto target_type_no_tz = arrow::timestamp(timestamp_type->unit()); arrow::compute::CastOptions options = arrow::compute::CastOptions::Safe(); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr target_array, diff --git a/src/paimon/core/casting/timestamp_to_date_cast_executor.cpp b/src/paimon/core/casting/timestamp_to_date_cast_executor.cpp index a629fb06..47a7357a 100644 --- a/src/paimon/core/casting/timestamp_to_date_cast_executor.cpp +++ b/src/paimon/core/casting/timestamp_to_date_cast_executor.cpp @@ -25,6 +25,7 @@ #include "arrow/compute/cast.h" #include "arrow/type.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/core/casting/casting_utils.h" @@ -46,7 +47,7 @@ Result> TimestampToDateCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { auto target_array = array; - auto src_ts_type = arrow::internal::checked_pointer_cast(array->type()); + auto src_ts_type = checked_pointer_cast(array->type()); if (!src_ts_type->timezone().empty()) { auto target_type_no_tz = std::make_shared(src_ts_type->unit()); PAIMON_ASSIGN_OR_RAISE(target_array, CastingUtils::TimestampWithTimezoneToTimestamp( diff --git a/src/paimon/core/casting/timestamp_to_numeric_primitive_cast_executor.cpp b/src/paimon/core/casting/timestamp_to_numeric_primitive_cast_executor.cpp index c8ba9743..d546f501 100644 --- a/src/paimon/core/casting/timestamp_to_numeric_primitive_cast_executor.cpp +++ b/src/paimon/core/casting/timestamp_to_numeric_primitive_cast_executor.cpp @@ -27,8 +27,8 @@ #include "arrow/array/array_primitive.h" #include "arrow/array/builder_base.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/core/casting/casting_utils.h" @@ -52,9 +52,7 @@ Result TimestampToNumericPrimitiveCastExecutor::Cast( Result> TimestampToNumericPrimitiveCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { - auto timestamp_type = - arrow::internal::checked_pointer_cast(array->type()); - assert(timestamp_type); + auto timestamp_type = checked_pointer_cast(array->type()); assert(target_type->id() == arrow::Type::type::INT32 || target_type->id() == arrow::Type::type::INT64); auto timestamp_to_timestamp_cast_executor = diff --git a/src/paimon/core/casting/timestamp_to_string_cast_executor.cpp b/src/paimon/core/casting/timestamp_to_string_cast_executor.cpp index 7fbdfe24..6841ade6 100644 --- a/src/paimon/core/casting/timestamp_to_string_cast_executor.cpp +++ b/src/paimon/core/casting/timestamp_to_string_cast_executor.cpp @@ -24,7 +24,7 @@ #include "arrow/array/array_base.h" #include "arrow/compute/cast.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/casting/casting_utils.h" #include "paimon/status.h" @@ -42,7 +42,7 @@ Result> TimestampToStringCastExecutor::Cast( const std::shared_ptr& array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) const { auto target_array = array; - auto src_ts_type = arrow::internal::checked_pointer_cast(array->type()); + auto src_ts_type = checked_pointer_cast(array->type()); if (!src_ts_type->timezone().empty()) { auto target_type_no_tz = std::make_shared(src_ts_type->unit()); PAIMON_ASSIGN_OR_RAISE(target_array, CastingUtils::TimestampWithTimezoneToTimestamp( diff --git a/src/paimon/core/casting/timestamp_to_timestamp_cast_executor.cpp b/src/paimon/core/casting/timestamp_to_timestamp_cast_executor.cpp index ff9bdec7..b982750b 100644 --- a/src/paimon/core/casting/timestamp_to_timestamp_cast_executor.cpp +++ b/src/paimon/core/casting/timestamp_to_timestamp_cast_executor.cpp @@ -21,6 +21,7 @@ #include +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/core/casting/casting_utils.h" @@ -35,9 +36,8 @@ Result> TimestampToTimestampCastExecutor::Cast( arrow::MemoryPool* pool) const { arrow::compute::CastOptions options = arrow::compute::CastOptions::Safe(); options.allow_time_truncate = true; - auto src_ts_type = arrow::internal::checked_pointer_cast(array->type()); - auto target_ts_type = arrow::internal::checked_pointer_cast(target_type); - assert(src_ts_type && target_ts_type); + auto src_ts_type = checked_pointer_cast(array->type()); + auto target_ts_type = checked_pointer_cast(target_type); std::shared_ptr target_array = array; // first, handle timezone if (src_ts_type->timezone() != target_ts_type->timezone()) { diff --git a/src/paimon/core/catalog/file_system_catalog.cpp b/src/paimon/core/catalog/file_system_catalog.cpp index a036c080..3c587709 100644 --- a/src/paimon/core/catalog/file_system_catalog.cpp +++ b/src/paimon/core/catalog/file_system_catalog.cpp @@ -29,6 +29,7 @@ #include "fmt/ranges.h" #include "paimon/catalog/identifier.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/common/utils/string_utils.h" #include "paimon/core/catalog/catalog_utils.h" @@ -315,7 +316,7 @@ Result> FileSystemCatalog::LoadTableSchema( if (!latest_schema) { return Status::NotExist(fmt::format("{} not exist", identifier.ToString())); } - return std::static_pointer_cast(*latest_schema); + return checked_pointer_cast(*latest_schema); } Result> FileSystemCatalog::GetTable(const Identifier& identifier) const { diff --git a/src/paimon/core/global_index/global_index_write_task.cpp b/src/paimon/core/global_index/global_index_write_task.cpp index f0e35050..6ff92955 100644 --- a/src/paimon/core/global_index/global_index_write_task.cpp +++ b/src/paimon/core/global_index/global_index_write_task.cpp @@ -29,6 +29,7 @@ #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/core/casting/casting_utils.h" #include "paimon/core/core_options.h" @@ -174,7 +175,7 @@ Result> CastDictionaryArrayToString( arrow::Type::type type_id = array->type_id(); if (type_id == arrow::Type::DICTIONARY) { const auto* dictionary_type = - static_cast(array->type().get()); + checked_cast(array->type().get()); arrow::Type::type value_type = dictionary_type->value_type()->id(); if (value_type != arrow::Type::STRING && value_type != arrow::Type::LARGE_STRING) { return Status::Invalid(fmt::format( @@ -193,7 +194,7 @@ Result> CastDictionaryArrayToString( if (type_id == arrow::Type::STRUCT) { std::shared_ptr struct_array = - std::static_pointer_cast(array); + checked_pointer_cast(array); arrow::ArrayVector children; for (int32_t i = 0; i < struct_array->num_fields(); i++) { std::shared_ptr child = struct_array->field(i); @@ -222,8 +223,7 @@ Result> CastDictionaryArrayToString( } if (type_id == arrow::Type::MAP) { - std::shared_ptr map_array = - std::static_pointer_cast(array); + std::shared_ptr map_array = checked_pointer_cast(array); std::shared_ptr original_keys = map_array->keys(); std::shared_ptr original_items = map_array->items(); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr keys, @@ -233,7 +233,7 @@ Result> CastDictionaryArrayToString( if (keys == original_keys && items == original_items) { return array; } - const auto* map_type = static_cast(map_array->type().get()); + const auto* map_type = checked_cast(map_array->type().get()); std::shared_ptr casted_type = std::make_shared( map_type->key_field()->WithType(keys->type()), map_type->item_field()->WithType(items->type()), map_type->keys_sorted()); @@ -242,15 +242,14 @@ Result> CastDictionaryArrayToString( map_array->null_bitmap(), map_array->null_count(), map_array->offset()); } - std::shared_ptr list_array = - std::static_pointer_cast(array); + std::shared_ptr list_array = checked_pointer_cast(array); std::shared_ptr original_values = list_array->values(); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr values, CastDictionaryArrayToString(original_values, pool)); if (values == original_values) { return array; } - const auto* list_type = static_cast(list_array->type().get()); + const auto* list_type = checked_cast(list_array->type().get()); std::shared_ptr casted_type = arrow::list(list_type->value_field()->WithType(values->type())); return std::make_shared( @@ -270,19 +269,19 @@ Result> BuildIndex( auto& [c_array, c_schema] = read_batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto struct_array = std::dynamic_pointer_cast(array); - if (!struct_array) { + if (!array || array->type_id() != arrow::Type::STRUCT) { return Status::Invalid( "array read from batch reader is not a struct array in GlobalIndexWriteTask"); } + auto struct_array = checked_pointer_cast(array); auto row_id_array = struct_array->GetFieldByName(SpecialFields::RowId().Name()); - auto typed_row_id_array = std::dynamic_pointer_cast(row_id_array); - if (!typed_row_id_array) { + if (!row_id_array || row_id_array->type_id() != arrow::Type::INT64) { return Status::Invalid( fmt::format("read array does not contain {} field, or it cannot be casted to " "Int64Array in GlobalIndexWriteTask", SpecialFields::RowId().Name())); } + auto typed_row_id_array = checked_pointer_cast(row_id_array); std::vector relative_row_ids; relative_row_ids.reserve(typed_row_id_array->length()); for (int64_t i = 0; i < typed_row_id_array->length(); i++) { diff --git a/src/paimon/core/io/complete_row_tracking_fields_reader.cpp b/src/paimon/core/io/complete_row_tracking_fields_reader.cpp index 53749b83..f43ffcc0 100644 --- a/src/paimon/core/io/complete_row_tracking_fields_reader.cpp +++ b/src/paimon/core/io/complete_row_tracking_fields_reader.cpp @@ -28,6 +28,7 @@ #include "paimon/common/table/special_fields.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/object_utils.h" namespace paimon { @@ -92,8 +93,7 @@ CompleteRowTrackingFieldsBatchReader::NextBatchWithBitmap() { auto& [c_array, c_schema] = read_batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr src_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto src_struct_array = arrow::internal::checked_pointer_cast(src_array); - assert(src_struct_array); + auto src_struct_array = checked_pointer_cast(src_array); // complete row id array std::shared_ptr row_id_array; @@ -164,9 +164,7 @@ Status CompleteRowTrackingFieldsBatchReader::ConvertRowTrackingField( PAIMON_ASSIGN_OR_RAISE_FROM_ARROW( special_array, arrow::MakeArrayFromScalar(*scalar, array_length, arrow_pool_.get())); auto typed_special_array = - arrow::internal::checked_pointer_cast>( - special_array); - assert(typed_special_array); + checked_pointer_cast>(special_array); if (convert_func) { auto raw_value_ptr = const_cast(typed_special_array->raw_values()); assert(raw_value_ptr); @@ -178,8 +176,7 @@ Status CompleteRowTrackingFieldsBatchReader::ConvertRowTrackingField( } else if (special_array->null_count() > 0) { // condition3: special field exist, has null auto typed_special_array = - arrow::internal::checked_pointer_cast>( - special_array); + checked_pointer_cast>(special_array); auto raw_value_ptr = const_cast(typed_special_array->raw_values()); // row id = first_row_id_ + previous_batch_first_row_number + idx in batch // sequence number = init_value diff --git a/src/paimon/core/io/field_mapping_reader.cpp b/src/paimon/core/io/field_mapping_reader.cpp index 947853c3..2d07cef2 100644 --- a/src/paimon/core/io/field_mapping_reader.cpp +++ b/src/paimon/core/io/field_mapping_reader.cpp @@ -29,12 +29,12 @@ #include "arrow/c/abi.h" #include "arrow/c/bridge.h" #include "arrow/scalar.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/binary_string.h" #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/casting/cast_executor.h" #include "paimon/core/casting/casting_utils.h" #include "paimon/core/utils/field_mapping.h" @@ -54,8 +54,7 @@ Result FieldMappingReader::HasMapSelectedKeysRecursively( if (NestedProjectionUtils::IsMapSharedShreddingAccessField(read_field)) { PAIMON_ASSIGN_OR_RAISE(std::vector selected_keys, NestedProjectionUtils::GetMapSelectedKeys(read_field)); - auto read_struct = - arrow::internal::checked_pointer_cast(read_field->type()); + auto read_struct = checked_pointer_cast(read_field->type()); if (selected_keys.size() != static_cast(read_struct->num_fields())) { return Status::Invalid(fmt::format( "selected-key metadata size {} does not match STRUCT field count {} for {}", @@ -109,8 +108,8 @@ Result> FieldMappingReader::FilterMapSelectedKeysR "field '{}', got {}", read_field->name(), array->type()->ToString())); } - auto struct_array = std::static_pointer_cast(array); - auto read_struct_type = std::static_pointer_cast(read_field->type()); + auto struct_array = checked_pointer_cast(array); + auto read_struct_type = checked_pointer_cast(read_field->type()); if (struct_array->num_fields() != read_struct_type->num_fields()) { return Status::Invalid(fmt::format( "FilterMapSelectedKeysRecursively struct field count mismatch for '{}': " @@ -217,7 +216,7 @@ Result> FieldMappingReader::CastNonPartitionArrayI if (!need_casting_) { return src_array; } - auto* struct_array = arrow::internal::checked_cast(src_array.get()); + auto* struct_array = checked_cast(src_array.get()); int32_t field_count = struct_array->num_fields(); assert(static_cast(field_count) == non_partition_info_.cast_executors.size()); arrow::ArrayVector casted_array; @@ -434,8 +433,7 @@ Status FieldMappingReader::MappingFields(const std::shared_ptr& da const std::vector& idx_in_target_schema, arrow::ArrayVector* target_array, std::vector* target_field_names) { - auto* struct_array = arrow::internal::checked_cast(data_array.get()); - assert(struct_array); + auto* struct_array = checked_cast(data_array.get()); assert(struct_array->fields().size() == idx_in_target_schema.size()); for (size_t i = 0; i < idx_in_target_schema.size(); i++) { std::shared_ptr field_array = struct_array->field(i); diff --git a/src/paimon/core/io/field_mapping_reader_test.cpp b/src/paimon/core/io/field_mapping_reader_test.cpp index 233a8587..5375a250 100644 --- a/src/paimon/core/io/field_mapping_reader_test.cpp +++ b/src/paimon/core/io/field_mapping_reader_test.cpp @@ -32,10 +32,10 @@ #include "arrow/c/abi.h" #include "arrow/c/bridge.h" #include "arrow/ipc/json_simple.h" -#include "arrow/util/checked_cast.h" #include "gtest/gtest.h" #include "paimon/common/data/blob_utils.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/utils/field_mapping.h" #include "paimon/defs.h" #include "paimon/format/file_format.h" @@ -248,60 +248,48 @@ TEST_F(FieldMappingReaderTest, TestGenerateSinglePartitionArray) { ASSERT_OK_AND_ASSIGN(auto p7_array, mapping_reader->GenerateSinglePartitionArray( /*idx=*/0, /*batch_size=*/2)); ASSERT_EQ(p7_array->length(), 2); - ASSERT_EQ(arrow::internal::checked_cast(p7_array.get())->Value(0), - 100); + ASSERT_EQ(checked_cast(p7_array.get())->Value(0), 100); } { ASSERT_OK_AND_ASSIGN(auto p6_array, mapping_reader->GenerateSinglePartitionArray( /*idx=*/1, /*batch_size=*/2)); ASSERT_EQ(p6_array->length(), 2); - ASSERT_EQ(arrow::internal::checked_cast(p6_array.get())->Value(0), - "6"); + ASSERT_EQ(checked_cast(p6_array.get())->Value(0), "6"); } { ASSERT_OK_AND_ASSIGN(auto p5_array, mapping_reader->GenerateSinglePartitionArray( /*idx=*/2, /*batch_size=*/1)); ASSERT_EQ(p5_array->length(), 1); - ASSERT_EQ(arrow::internal::checked_cast(p5_array.get())->Value(0), - "5"); + ASSERT_EQ(checked_cast(p5_array.get())->Value(0), "5"); } { ASSERT_OK_AND_ASSIGN(auto p4_array, mapping_reader->GenerateSinglePartitionArray( /*idx=*/3, /*batch_size=*/1)); - ASSERT_EQ( - arrow::internal::checked_cast*>(p4_array.get()) - ->Value(0), - static_cast(4)); + ASSERT_EQ(checked_cast*>(p4_array.get())->Value(0), + static_cast(4)); } { ASSERT_OK_AND_ASSIGN(auto p3_array, mapping_reader->GenerateSinglePartitionArray( /*idx=*/4, /*batch_size=*/1)); - ASSERT_EQ( - arrow::internal::checked_cast*>(p3_array.get()) - ->Value(0), - static_cast(3)); + ASSERT_EQ(checked_cast*>(p3_array.get())->Value(0), + static_cast(3)); } { ASSERT_OK_AND_ASSIGN(auto p2_array, mapping_reader->GenerateSinglePartitionArray( /*idx=*/5, /*batch_size=*/1)); - ASSERT_EQ( - arrow::internal::checked_cast*>(p2_array.get()) - ->Value(0), - static_cast(2)); + ASSERT_EQ(checked_cast*>(p2_array.get())->Value(0), + static_cast(2)); } { ASSERT_OK_AND_ASSIGN(auto p1_array, mapping_reader->GenerateSinglePartitionArray( /*idx=*/6, /*batch_size=*/1)); - ASSERT_EQ( - arrow::internal::checked_cast*>(p1_array.get()) - ->Value(0), - static_cast(1)); + ASSERT_EQ(checked_cast*>(p1_array.get())->Value(0), + static_cast(1)); } { ASSERT_OK_AND_ASSIGN(auto p0_array, mapping_reader->GenerateSinglePartitionArray( /*idx=*/7, /*batch_size=*/1)); - ASSERT_EQ(arrow::internal::checked_cast(p0_array.get())->Value(0), - false); + ASSERT_EQ(checked_cast(p0_array.get())->Value(0), false); } } diff --git a/src/paimon/core/io/generic_row_to_arrow_array_converter.cpp b/src/paimon/core/io/generic_row_to_arrow_array_converter.cpp index 253db982..ee442e64 100644 --- a/src/paimon/core/io/generic_row_to_arrow_array_converter.cpp +++ b/src/paimon/core/io/generic_row_to_arrow_array_converter.cpp @@ -26,8 +26,8 @@ #include "arrow/array/builder_nested.h" #include "arrow/memory_pool.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -37,9 +37,7 @@ Result> GenericRowToArrowArrayC PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::MakeBuilder( pool, std::make_shared(schema->fields()), &array_builder)); - auto struct_builder = - arrow::internal::checked_pointer_cast(std::move(array_builder)); - assert(struct_builder); + auto struct_builder = checked_pointer_cast(std::move(array_builder)); std::vector appenders; appenders.reserve(schema->num_fields()); int32_t reserve_count = 1; diff --git a/src/paimon/core/io/key_value_data_file_record_reader.cpp b/src/paimon/core/io/key_value_data_file_record_reader.cpp index 18e27679..4a66aa20 100644 --- a/src/paimon/core/io/key_value_data_file_record_reader.cpp +++ b/src/paimon/core/io/key_value_data_file_record_reader.cpp @@ -28,13 +28,13 @@ #include "arrow/c/abi.h" #include "arrow/c/bridge.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/columnar/columnar_row_ref.h" #include "paimon/common/table/special_fields.h" #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/arrow_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/status.h" namespace paimon { class MemoryPool; @@ -103,20 +103,25 @@ Result> KeyValueDataFileRecordRe } PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto data_batch = arrow::internal::checked_pointer_cast(arrow_array); - assert(data_batch); - // do not use arrow::checked_pointer_cast as in release compile, checked_pointer_cast is - // static_cast without check - sequence_number_array_ = - std::dynamic_pointer_cast>(data_batch->field(0)); - if (!sequence_number_array_) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { + return Status::Invalid("cannot cast data batch to StructArray"); + } + auto data_batch = checked_pointer_cast(arrow_array); + if (data_batch->num_fields() < SpecialFields::KEY_VALUE_SPECIAL_FIELD_COUNT) { + return Status::Invalid( + fmt::format("data batch field count {} is less than required special field count {}", + data_batch->num_fields(), SpecialFields::KEY_VALUE_SPECIAL_FIELD_COUNT)); + } + if (!data_batch->field(0) || data_batch->field(0)->type_id() != arrow::Type::INT64) { return Status::Invalid("cannot cast SEQUENCE_NUMBER column to int64 arrow array"); } - row_kind_array_ = - std::dynamic_pointer_cast>(data_batch->field(1)); - if (!row_kind_array_) { + sequence_number_array_ = + checked_pointer_cast>(data_batch->field(0)); + if (!data_batch->field(1) || data_batch->field(1)->type_id() != arrow::Type::INT8) { return Status::Invalid("cannot cast VALUE_KIND column to int8 arrow array"); } + row_kind_array_ = + checked_pointer_cast>(data_batch->field(1)); arrow::ArrayVector key_fields; key_fields.reserve(key_schema_->num_fields()); for (const auto& key_field : key_schema_->fields()) { diff --git a/src/paimon/core/io/key_value_in_memory_record_reader.cpp b/src/paimon/core/io/key_value_in_memory_record_reader.cpp index 43af1b54..9918b328 100644 --- a/src/paimon/core/io/key_value_in_memory_record_reader.cpp +++ b/src/paimon/core/io/key_value_in_memory_record_reader.cpp @@ -26,13 +26,13 @@ #include "arrow/array/array_primitive.h" #include "arrow/compute/api.h" #include "arrow/compute/ordering.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/columnar/columnar_row_ref.h" #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/arrow_utils.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/fields_comparator.h" #include "paimon/status.h" namespace paimon { @@ -127,12 +127,11 @@ KeyValueInMemoryRecordReader::SortBatch() const { PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr sorted_indices, arrow::compute::SortIndices(arrow::Datum(value_struct_array_), sort_options, &exec_context)); - auto typed_indices = - arrow::internal::checked_pointer_cast>( - sorted_indices); - if (!typed_indices) { + if (!sorted_indices || sorted_indices->type_id() != arrow::Type::UINT64) { return Status::Invalid("cannot cast sorted indices to UInt64Array"); } + auto typed_indices = + checked_pointer_cast>(sorted_indices); return typed_indices; } diff --git a/src/paimon/core/io/key_value_meta_projection_consumer.cpp b/src/paimon/core/io/key_value_meta_projection_consumer.cpp index c07fb2eb..e7e5b854 100644 --- a/src/paimon/core/io/key_value_meta_projection_consumer.cpp +++ b/src/paimon/core/io/key_value_meta_projection_consumer.cpp @@ -29,12 +29,12 @@ #include "arrow/array/builder_nested.h" #include "arrow/c/abi.h" #include "arrow/c/helpers.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/data/internal_row.h" #include "paimon/common/table/special_fields.h" #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/reader/batch_reader.h" #include "paimon/status.h" @@ -66,19 +66,19 @@ Result> KeyValueMetaProjectionCo PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::MakeBuilder( arrow_pool.get(), arrow::struct_(target_schema->fields()), &array_builder)); - auto struct_builder = - arrow::internal::checked_pointer_cast(std::move(array_builder)); - assert(struct_builder); - auto* sequence_appender = - arrow::internal::checked_cast(struct_builder->field_builder(0)); - if (sequence_appender == nullptr) { + auto struct_builder = checked_pointer_cast(std::move(array_builder)); + auto* sequence_builder = struct_builder->field_builder(0); + if (!sequence_builder || !sequence_builder->type() || + sequence_builder->type()->id() != arrow::Type::INT64) { return Status::Invalid("sequence_appender cannot cast to Int64Builder"); } - auto* value_kind_appender = - arrow::internal::checked_cast(struct_builder->field_builder(1)); - if (value_kind_appender == nullptr) { + auto* sequence_appender = checked_cast(sequence_builder); + auto* value_kind_builder = struct_builder->field_builder(1); + if (!value_kind_builder || !value_kind_builder->type() || + value_kind_builder->type()->id() != arrow::Type::INT8) { return Status::Invalid("value_kind_appender cannot cast to Int8Builder"); } + auto* value_kind_appender = checked_cast(value_kind_builder); // appenders only contains array_builder of value schema, sequence_appender and // value_kind_appender are not in appenders std::vector appenders; diff --git a/src/paimon/core/io/key_value_projection_consumer.cpp b/src/paimon/core/io/key_value_projection_consumer.cpp index fe6f9471..53cbe0db 100644 --- a/src/paimon/core/io/key_value_projection_consumer.cpp +++ b/src/paimon/core/io/key_value_projection_consumer.cpp @@ -26,10 +26,10 @@ #include "arrow/array/builder_base.h" #include "arrow/array/builder_nested.h" #include "arrow/c/abi.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/data/internal_row.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/key_value.h" #include "paimon/status.h" @@ -49,9 +49,7 @@ Result> KeyValueProjectionConsumer:: arrow_pool.get(), std::make_shared(target_schema->fields()), &array_builder)); - auto struct_builder = - arrow::internal::checked_pointer_cast(std::move(array_builder)); - assert(struct_builder); + auto struct_builder = checked_pointer_cast(std::move(array_builder)); std::vector appenders; appenders.reserve(target_to_src_mapping.size()); // first is the root struct array @@ -75,19 +73,22 @@ Result KeyValueProjectionConsumer::NextBatch( for (int32_t i = 0; i < static_cast(target_to_src_mapping_.size()); i++) { for (const auto& row : key_value_vec) { if (target_to_src_mapping_[i] == kSequenceNumberProjection) { - auto* builder = - dynamic_cast(array_builder_->field_builder(i)); - if (builder == nullptr) { + auto* field_builder = array_builder_->field_builder(i); + if (!field_builder || !field_builder->type() || + field_builder->type()->id() != arrow::Type::INT64) { return Status::Invalid("cannot append sequence number to non-int64 field"); } + auto* builder = checked_cast(field_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.sequence_number)); continue; } if (target_to_src_mapping_[i] == kValueKindProjection) { - auto* builder = dynamic_cast(array_builder_->field_builder(i)); - if (builder == nullptr) { + auto* field_builder = array_builder_->field_builder(i); + if (!field_builder || !field_builder->type() || + field_builder->type()->id() != arrow::Type::INT8) { return Status::Invalid("cannot append value kind to non-int8 field"); } + auto* builder = checked_cast(field_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.value_kind->ToByteValue())); continue; } diff --git a/src/paimon/core/io/key_value_projection_reader_test.cpp b/src/paimon/core/io/key_value_projection_reader_test.cpp index 8954ae3a..a37711ed 100644 --- a/src/paimon/core/io/key_value_projection_reader_test.cpp +++ b/src/paimon/core/io/key_value_projection_reader_test.cpp @@ -32,10 +32,10 @@ #include "arrow/array/builder_nested.h" #include "arrow/c/abi.h" #include "arrow/ipc/json_simple.h" -#include "arrow/util/checked_cast.h" #include "gtest/gtest.h" #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/mem_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/fields_comparator.h" #include "paimon/core/io/async_key_value_projection_reader.h" @@ -175,14 +175,13 @@ TEST_P(KeyValueProjectionReaderTest, TestBulkData) { std::unique_ptr array_builder; ASSERT_TRUE(arrow::MakeBuilder(arrow_pool.get(), src_type, &array_builder).ok()); - auto struct_builder = - arrow::internal::checked_pointer_cast(std::move(array_builder)); - auto seq_builder = static_cast(struct_builder->field_builder(0)); - auto kind_builder = static_cast(struct_builder->field_builder(1)); - auto int_builder = static_cast(struct_builder->field_builder(2)); - auto short_builder = static_cast(struct_builder->field_builder(3)); - auto float_builder = static_cast(struct_builder->field_builder(4)); - auto string_builder = static_cast(struct_builder->field_builder(5)); + auto struct_builder = checked_pointer_cast(std::move(array_builder)); + auto seq_builder = checked_cast(struct_builder->field_builder(0)); + auto kind_builder = checked_cast(struct_builder->field_builder(1)); + auto int_builder = checked_cast(struct_builder->field_builder(2)); + auto short_builder = checked_cast(struct_builder->field_builder(3)); + auto float_builder = checked_cast(struct_builder->field_builder(4)); + auto string_builder = checked_cast(struct_builder->field_builder(5)); for (int32_t i = 0; i < 2000; ++i) { ASSERT_TRUE(struct_builder->Append().ok()); ASSERT_TRUE(int_builder->Append(i).ok()); @@ -202,7 +201,7 @@ TEST_P(KeyValueProjectionReaderTest, TestBulkData) { } std::shared_ptr src_array; ASSERT_TRUE(struct_builder->Finish(&src_array).ok()); - auto typed_array = arrow::internal::checked_pointer_cast(src_array); + auto typed_array = checked_pointer_cast(src_array); auto target_type = std::dynamic_pointer_cast( arrow::struct_({fields[2], fields[3], fields[4], fields[5]})); diff --git a/src/paimon/core/io/meta_to_arrow_array_converter.cpp b/src/paimon/core/io/meta_to_arrow_array_converter.cpp index 5493db6f..c149a0e6 100644 --- a/src/paimon/core/io/meta_to_arrow_array_converter.cpp +++ b/src/paimon/core/io/meta_to_arrow_array_converter.cpp @@ -17,22 +17,22 @@ */ #include "paimon/core/io/meta_to_arrow_array_converter.h" +#include "paimon/common/utils/checked_cast.h" + namespace paimon { Result> MetaToArrowArrayConverter::Create( const std::shared_ptr& meta_data_type, const std::shared_ptr& pool) { - auto struct_type = std::dynamic_pointer_cast(meta_data_type); - if (!struct_type) { + if (!meta_data_type || meta_data_type->id() != arrow::Type::STRUCT) { return Status::Invalid("meta_data_type in MetaToArrowArrayConverter must be struct type"); } + auto struct_type = checked_pointer_cast(meta_data_type); auto arrow_pool = GetArrowPool(pool); std::unique_ptr array_builder; PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::MakeBuilder( arrow_pool.get(), arrow::struct_(struct_type->fields()), &array_builder)); - auto struct_builder = - arrow::internal::checked_pointer_cast(std::move(array_builder)); - assert(struct_builder); + auto struct_builder = checked_pointer_cast(std::move(array_builder)); std::vector appenders; appenders.reserve(struct_type->num_fields()); // first is the root struct array diff --git a/src/paimon/core/io/multiple_blob_file_writer.cpp b/src/paimon/core/io/multiple_blob_file_writer.cpp index 915c115d..7c62c574 100644 --- a/src/paimon/core/io/multiple_blob_file_writer.cpp +++ b/src/paimon/core/io/multiple_blob_file_writer.cpp @@ -29,6 +29,7 @@ #include "arrow/c/helpers.h" #include "arrow/type.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/macros.h" @@ -55,11 +56,11 @@ Status MultipleBlobFileWriter::Write(::ArrowArray* record) { std::shared_ptr data_type = arrow::struct_(blob_schema_->fields()); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(record, data_type)); - std::shared_ptr struct_array = - std::dynamic_pointer_cast(arrow_array); - if (!struct_array) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("MultipleBlobFileWriter: input is not a StructArray"); } + std::shared_ptr struct_array = + checked_pointer_cast(arrow_array); // TODO(xinyu.lxy): support write parallel // For each blob field, extract the column and write row by row to its dedicated writer diff --git a/src/paimon/core/io/rolling_blob_file_writer.cpp b/src/paimon/core/io/rolling_blob_file_writer.cpp index 36336eef..0044ea68 100644 --- a/src/paimon/core/io/rolling_blob_file_writer.cpp +++ b/src/paimon/core/io/rolling_blob_file_writer.cpp @@ -32,6 +32,7 @@ #include "fmt/format.h" #include "paimon/common/data/blob_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/macros.h" @@ -67,7 +68,10 @@ Status RollingBlobFileWriter::Write(::ArrowArray* record) { int64_t record_count = record->length; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(record, data_type_)); - auto struct_array = std::dynamic_pointer_cast(arrow_array); + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { + return Status::Invalid("RollingBlobFileWriter: input is not a StructArray"); + } + auto struct_array = checked_pointer_cast(arrow_array); PAIMON_ASSIGN_OR_RAISE(BlobUtils::SeparatedStructArrays separated_arrays, BlobUtils::SeparateBlobArray(struct_array, inline_fields_)); diff --git a/src/paimon/core/io/row_to_arrow_array_converter.h b/src/paimon/core/io/row_to_arrow_array_converter.h index 43c97afd..24533685 100644 --- a/src/paimon/core/io/row_to_arrow_array_converter.h +++ b/src/paimon/core/io/row_to_arrow_array_converter.h @@ -28,6 +28,7 @@ #include "paimon/common/data/internal_map.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/core/key_value.h" #include "paimon/memory/memory_pool.h" @@ -206,35 +207,30 @@ Status RowToArrowArrayConverter::Accumulate(const arrow::Array* array, int case arrow::Type::type::DECIMAL128: break; case arrow::Type::type::STRING: { - auto string_array = arrow::internal::checked_cast(array); - assert(string_array); + auto string_array = checked_cast(array); // accumulate the bytes buffer size of binary UpdateAccumulatedVec(string_array->value_data()->size(), idx); break; } case arrow::Type::type::BINARY: { - auto binary_array = arrow::internal::checked_cast(array); - assert(binary_array); + auto binary_array = checked_cast(array); // accumulate the bytes buffer size of binary UpdateAccumulatedVec(binary_array->value_data()->size(), idx); break; } case arrow::Type::type::LIST: { - auto list_array = arrow::internal::checked_cast(array); - assert(list_array); + auto list_array = checked_cast(array); PAIMON_RETURN_NOT_OK(Accumulate(list_array->values().get(), idx)); break; } case arrow::Type::type::MAP: { - auto map_array = arrow::internal::checked_cast(array); - assert(map_array); + auto map_array = checked_cast(array); PAIMON_RETURN_NOT_OK(Accumulate(map_array->keys().get(), idx)); PAIMON_RETURN_NOT_OK(Accumulate(map_array->items().get(), idx)); break; } case arrow::Type::type::STRUCT: { - auto struct_array = arrow::internal::checked_cast(array); - assert(struct_array); + auto struct_array = checked_cast(array); for (const auto& field : struct_array->fields()) { PAIMON_RETURN_NOT_OK(Accumulate(field.get(), idx)); } @@ -252,7 +248,7 @@ template template Result RowToArrowArrayConverter::CastToTypedBuilder( arrow::ArrayBuilder* array_builder) { - auto field_builder = arrow::internal::checked_cast(array_builder); + auto field_builder = dynamic_cast(array_builder); if (field_builder == nullptr) { return Status::Invalid("field builder is nullptr"); } @@ -389,11 +385,7 @@ RowToArrowArrayConverter::AppendField(bool use_view, arrow::ArrayBuilder* case arrow::Type::type::TIMESTAMP: { PAIMON_ASSIGN_OR_RAISE(auto* field_builder, CastToTypedBuilder(array_builder)); - auto ts_type = - arrow::internal::checked_pointer_cast(field_builder->type()); - if (!ts_type) { - return Status::Invalid("cannot cast to timestamp type"); - } + auto ts_type = checked_pointer_cast(field_builder->type()); DateTimeUtils::TimeType time_type = DateTimeUtils::GetTimeTypeFromArrowType(ts_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(ts_type); return RowToArrowArrayConverter::AppendValueFunc( @@ -408,11 +400,7 @@ RowToArrowArrayConverter::AppendField(bool use_view, arrow::ArrayBuilder* case arrow::Type::type::DECIMAL128: { PAIMON_ASSIGN_OR_RAISE(auto* field_builder, CastToTypedBuilder(array_builder)); - auto decimal_type = - arrow::internal::checked_cast(field_builder->type().get()); - if (!decimal_type) { - return Status::Invalid("cannot cast to decimal type"); - } + auto decimal_type = checked_cast(field_builder->type().get()); auto precision = decimal_type->precision(); auto scale = decimal_type->scale(); return RowToArrowArrayConverter::AppendValueFunc( diff --git a/src/paimon/core/mergetree/compact/aggregate/field_aggregate_utils.cpp b/src/paimon/core/mergetree/compact/aggregate/field_aggregate_utils.cpp index ad81dccb..9397ca4e 100644 --- a/src/paimon/core/mergetree/compact/aggregate/field_aggregate_utils.cpp +++ b/src/paimon/core/mergetree/compact/aggregate/field_aggregate_utils.cpp @@ -25,13 +25,13 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/data_getters.h" #include "paimon/common/data/internal_array.h" #include "paimon/common/data/internal_map.h" #include "paimon/common/data/internal_row.h" #include "paimon/common/types/row_kind.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/fields_comparator.h" #include "paimon/memory/bytes.h" @@ -164,13 +164,12 @@ Result FieldAggregateUtils::GetValue(const DataGetters& getters, in return VariantType(getters.GetStringView(pos)); case arrow::Type::TIMESTAMP: { std::shared_ptr timestamp_type = - arrow::internal::checked_pointer_cast(type); + checked_pointer_cast(type); return VariantType( getters.GetTimestamp(pos, DateTimeUtils::GetPrecisionFromType(timestamp_type))); } case arrow::Type::DECIMAL128: { - const auto* decimal_type = - arrow::internal::checked_cast(type.get()); + const auto* decimal_type = checked_cast(type.get()); return VariantType( getters.GetDecimal(pos, decimal_type->precision(), decimal_type->scale())); } @@ -228,15 +227,15 @@ Result FieldAggregateUtils::Equals(const VariantType& lhs, const VariantTy case arrow::Type::STRUCT: return EqualRows(DataDefine::GetVariantValue>(lhs), DataDefine::GetVariantValue>(rhs), - arrow::internal::checked_pointer_cast(type)); + checked_pointer_cast(type)); case arrow::Type::LIST: return EqualArrays(DataDefine::GetVariantValue>(lhs), DataDefine::GetVariantValue>(rhs), - arrow::internal::checked_pointer_cast(type)); + checked_pointer_cast(type)); case arrow::Type::MAP: return EqualMaps(DataDefine::GetVariantValue>(lhs), DataDefine::GetVariantValue>(rhs), - arrow::internal::checked_pointer_cast(type)); + checked_pointer_cast(type)); default: return Status::Invalid( fmt::format("type {} is not supported by field aggregation", type->ToString())); diff --git a/src/paimon/core/mergetree/compact/aggregate/field_collect_agg.cpp b/src/paimon/core/mergetree/compact/aggregate/field_collect_agg.cpp index 4e1c7b44..ff938b73 100644 --- a/src/paimon/core/mergetree/compact/aggregate/field_collect_agg.cpp +++ b/src/paimon/core/mergetree/compact/aggregate/field_collect_agg.cpp @@ -22,10 +22,10 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/generic_array.h" #include "paimon/common/data/internal_array.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/core_options.h" #include "paimon/core/mergetree/compact/aggregate/field_aggregate_utils.h" #include "paimon/status.h" @@ -78,8 +78,7 @@ Result> FieldCollectAgg::Create( fmt::format("invalid field type {} for field '{}' of {}, supposed to be array", field_type->ToString(), field_name, NAME)); } - std::shared_ptr list_type = - arrow::internal::checked_pointer_cast(field_type); + std::shared_ptr list_type = checked_pointer_cast(field_type); PAIMON_ASSIGN_OR_RAISE(bool distinct, options.FieldCollectAggDistinct(field_name)); return std::unique_ptr( new FieldCollectAgg(field_type, list_type->value_type(), distinct, pool)); @@ -125,7 +124,7 @@ Result FieldCollectAgg::AggImpl(const VariantType& accumulator, if (input_array) { holders.push_back(input_array); } - return VariantType(std::static_pointer_cast( + return VariantType(checked_pointer_cast( std::make_shared(std::move(values), std::move(holders)))); } @@ -163,7 +162,7 @@ Result FieldCollectAgg::Retract(const VariantType& accumulator, result_values.push_back(std::move(candidate)); } } - return VariantType(std::static_pointer_cast(std::make_shared( + return VariantType(checked_pointer_cast(std::make_shared( std::move(result_values), std::vector>{accumulator_array, retract_array}))); } diff --git a/src/paimon/core/mergetree/compact/aggregate/field_collect_agg_test.cpp b/src/paimon/core/mergetree/compact/aggregate/field_collect_agg_test.cpp index 5d574a0e..33804567 100644 --- a/src/paimon/core/mergetree/compact/aggregate/field_collect_agg_test.cpp +++ b/src/paimon/core/mergetree/compact/aggregate/field_collect_agg_test.cpp @@ -31,6 +31,7 @@ #include "paimon/common/data/generic_map.h" #include "paimon/common/data/generic_row.h" #include "paimon/common/data/serializer/binary_serializer_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/core_options.h" #include "paimon/memory/memory_pool.h" #include "paimon/testing/utils/testharness.h" @@ -40,7 +41,7 @@ namespace { VariantType IntArray(std::vector values) { return VariantType( - std::static_pointer_cast(std::make_shared(std::move(values)))); + checked_pointer_cast(std::make_shared(std::move(values)))); } std::vector Values(const VariantType& value) { @@ -111,14 +112,14 @@ Result> MakeDistinctAgg( VariantType Array(std::vector values) { return VariantType( - std::static_pointer_cast(std::make_shared(std::move(values)))); + checked_pointer_cast(std::make_shared(std::move(values)))); } VariantType IntStringRow(int32_t id, std::string_view name) { std::shared_ptr row = std::make_shared(2); row->SetField(0, id); row->SetField(1, name); - return VariantType(std::static_pointer_cast(row)); + return VariantType(checked_pointer_cast(row)); } VariantType IntStringMap(std::vector> entries) { @@ -128,7 +129,7 @@ VariantType IntStringMap(std::vector> entri keys.emplace_back(entry.first); values.emplace_back(entry.second); } - return VariantType(std::static_pointer_cast( + return VariantType(checked_pointer_cast( std::make_shared(std::make_shared(std::move(keys)), std::make_shared(std::move(values))))); } diff --git a/src/paimon/core/mergetree/compact/aggregate/field_ignore_retract_agg_test.cpp b/src/paimon/core/mergetree/compact/aggregate/field_ignore_retract_agg_test.cpp index e6da2487..80348d64 100644 --- a/src/paimon/core/mergetree/compact/aggregate/field_ignore_retract_agg_test.cpp +++ b/src/paimon/core/mergetree/compact/aggregate/field_ignore_retract_agg_test.cpp @@ -27,6 +27,7 @@ #include "arrow/type_fwd.h" #include "gtest/gtest.h" #include "paimon/common/data/generic_array.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/core_options.h" #include "paimon/core/mergetree/compact/aggregate/field_collect_agg.h" #include "paimon/core/mergetree/compact/aggregate/field_sum_agg.h" @@ -83,9 +84,9 @@ TEST(FieldIgnoreRetractAggTest, ReversedAggBypassesWrappedOverride) { FieldCollectAgg::Create(arrow::list(arrow::int32()), options, "f0", GetDefaultPool())); auto agg = std::make_unique(std::move(collect_agg)); - VariantType accumulator = VariantType(std::static_pointer_cast( + VariantType accumulator = VariantType(checked_pointer_cast( std::make_shared(std::vector{int32_t{1}, int32_t{2}}))); - VariantType input = VariantType(std::static_pointer_cast( + VariantType input = VariantType(checked_pointer_cast( std::make_shared(std::vector{int32_t{3}, int32_t{4}}))); ASSERT_OK_AND_ASSIGN(VariantType result, agg->AggReversed(accumulator, input)); diff --git a/src/paimon/core/mergetree/compact/aggregate/field_merge_map_agg.cpp b/src/paimon/core/mergetree/compact/aggregate/field_merge_map_agg.cpp index 496149be..2cd48bab 100644 --- a/src/paimon/core/mergetree/compact/aggregate/field_merge_map_agg.cpp +++ b/src/paimon/core/mergetree/compact/aggregate/field_merge_map_agg.cpp @@ -23,10 +23,10 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/generic_array.h" #include "paimon/common/data/generic_map.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/mergetree/compact/aggregate/field_aggregate_utils.h" #include "paimon/status.h" @@ -84,7 +84,7 @@ VariantType MakeMap(std::vector entries, std::make_shared(std::move(keys), std::move(key_holders)); std::shared_ptr value_array = std::make_shared(std::move(values), std::move(value_holders)); - return std::static_pointer_cast( + return checked_pointer_cast( std::make_shared(std::move(key_array), std::move(value_array))); } @@ -98,8 +98,7 @@ Result> FieldMergeMapAgg::Create( fmt::format("invalid field type {} for field '{}' of {}, supposed to be map", field_type->ToString(), field_name, NAME)); } - std::shared_ptr map_type = - arrow::internal::checked_pointer_cast(field_type); + std::shared_ptr map_type = checked_pointer_cast(field_type); return std::unique_ptr( new FieldMergeMapAgg(field_type, map_type->key_type(), map_type->item_type(), pool)); } diff --git a/src/paimon/core/mergetree/compact/aggregate/field_merge_map_agg_test.cpp b/src/paimon/core/mergetree/compact/aggregate/field_merge_map_agg_test.cpp index b3b29ea4..1dcbd304 100644 --- a/src/paimon/core/mergetree/compact/aggregate/field_merge_map_agg_test.cpp +++ b/src/paimon/core/mergetree/compact/aggregate/field_merge_map_agg_test.cpp @@ -28,6 +28,7 @@ #include "paimon/common/data/generic_array.h" #include "paimon/common/data/generic_map.h" #include "paimon/common/data/serializer/binary_serializer_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/memory/memory_pool.h" #include "paimon/testing/utils/testharness.h" @@ -37,7 +38,7 @@ namespace { VariantType IntMap(std::vector keys, std::vector values) { std::shared_ptr key_array = std::make_shared(std::move(keys)); std::shared_ptr value_array = std::make_shared(std::move(values)); - return VariantType(std::static_pointer_cast( + return VariantType(checked_pointer_cast( std::make_shared(std::move(key_array), std::move(value_array)))); } diff --git a/src/paimon/core/mergetree/compact/aggregate/field_nested_update_agg.cpp b/src/paimon/core/mergetree/compact/aggregate/field_nested_update_agg.cpp index 99aea1e1..54676432 100644 --- a/src/paimon/core/mergetree/compact/aggregate/field_nested_update_agg.cpp +++ b/src/paimon/core/mergetree/compact/aggregate/field_nested_update_agg.cpp @@ -23,12 +23,12 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/generic_array.h" #include "paimon/common/data/internal_row.h" #include "paimon/common/types/data_field.h" #include "paimon/common/types/row_kind.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/fields_comparator.h" #include "paimon/core/mergetree/compact/aggregate/field_aggregate_utils.h" #include "paimon/defs.h" @@ -104,15 +104,14 @@ Result> FieldNestedUpdateAgg::Create( fmt::format("invalid field type {} for field '{}' of {}, supposed to be array", field_type->ToString(), field_name, NAME)); } - std::shared_ptr list_type = - arrow::internal::checked_pointer_cast(field_type); + std::shared_ptr list_type = checked_pointer_cast(field_type); if (list_type->value_type()->id() != arrow::Type::STRUCT) { return Status::Invalid( fmt::format("invalid field type {} for field '{}' of {}, supposed to be array", field_type->ToString(), field_name, NAME)); } std::shared_ptr row_type = - arrow::internal::checked_pointer_cast(list_type->value_type()); + checked_pointer_cast(list_type->value_type()); PAIMON_ASSIGN_OR_RAISE(std::vector key_names, options.FieldNestedUpdateAggNestedKey(field_name)); @@ -220,7 +219,7 @@ Result FieldNestedUpdateAgg::AggImpl(const VariantType& accumulator } holders.push_back(input); return VariantType( - std::static_pointer_cast(MakeRows(std::move(rows), std::move(holders)))); + checked_pointer_cast(MakeRows(std::move(rows), std::move(holders)))); } std::vector> rows; @@ -265,7 +264,7 @@ Result FieldNestedUpdateAgg::AggImpl(const VariantType& accumulator } holders.push_back(input); return VariantType( - std::static_pointer_cast(MakeRows(std::move(rows), std::move(holders)))); + checked_pointer_cast(MakeRows(std::move(rows), std::move(holders)))); } Result FieldNestedUpdateAgg::Retract(const VariantType& accumulator, @@ -295,7 +294,7 @@ Result FieldNestedUpdateAgg::Retract(const VariantType& accumulator } } } - return VariantType(std::static_pointer_cast( + return VariantType(checked_pointer_cast( MakeRows(std::move(rows), std::vector>{acc, retract}))); } @@ -341,7 +340,7 @@ Result FieldNestedUpdateAgg::Retract(const VariantType& accumulator } } } - return VariantType(std::static_pointer_cast( + return VariantType(checked_pointer_cast( MakeRows(std::move(rows), std::vector>{acc, retract}))); } diff --git a/src/paimon/core/mergetree/compact/aggregate/field_nested_update_agg_test.cpp b/src/paimon/core/mergetree/compact/aggregate/field_nested_update_agg_test.cpp index c40ffab2..805850d4 100644 --- a/src/paimon/core/mergetree/compact/aggregate/field_nested_update_agg_test.cpp +++ b/src/paimon/core/mergetree/compact/aggregate/field_nested_update_agg_test.cpp @@ -32,6 +32,7 @@ #include "paimon/common/data/generic_row.h" #include "paimon/common/data/serializer/binary_serializer_utils.h" #include "paimon/common/types/row_kind.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/core_options.h" #include "paimon/memory/memory_pool.h" #include "paimon/testing/utils/testharness.h" @@ -55,7 +56,7 @@ std::shared_ptr Row(VariantType id, int32_t sequence, int32_t value VariantType Rows(std::vector rows) { return VariantType( - std::static_pointer_cast(std::make_shared(std::move(rows)))); + checked_pointer_cast(std::make_shared(std::move(rows)))); } std::shared_ptr GetRows(const VariantType& value) { @@ -159,7 +160,7 @@ TEST(FieldNestedUpdateAggTest, RetractRequiresMatchingRowKind) { ASSERT_OK_AND_ASSIGN( VariantType kept, agg->Retract(Rows({Row(int32_t{1}, 1, 10)}), - Rows({VariantType(std::static_pointer_cast(retract_row))}))); + Rows({VariantType(checked_pointer_cast(retract_row))}))); ASSERT_EQ(1, GetRows(kept)->Size()); ASSERT_TRUE(FindRow(kept, 1)); } @@ -236,7 +237,7 @@ VariantType KeyedRow(VariantType k0, VariantType k1, std::string_view v, int32_t row->SetField(2, v); row->SetField(3, seq); row->SetField(4, seq2); - return VariantType(std::static_pointer_cast(row)); + return VariantType(checked_pointer_cast(row)); } Result> MakeKeyedAgg( diff --git a/src/paimon/core/mergetree/compact/merge_tree_compact_manager_factory_test.cpp b/src/paimon/core/mergetree/compact/merge_tree_compact_manager_factory_test.cpp index ad20b3ea..7473b7c0 100644 --- a/src/paimon/core/mergetree/compact/merge_tree_compact_manager_factory_test.cpp +++ b/src/paimon/core/mergetree/compact/merge_tree_compact_manager_factory_test.cpp @@ -32,6 +32,7 @@ #include "paimon/catalog/catalog.h" #include "paimon/catalog/identifier.h" #include "paimon/common/data/binary_row.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/core/compact/noop_compact_manager.h" #include "paimon/core/core_options.h" @@ -148,7 +149,7 @@ class MergeTreeCompactManagerFactoryWriteTest : public ::testing::Test { auto struct_type = arrow::struct_(fields); arrow::StructBuilder struct_builder(struct_type, arrow::default_memory_pool(), {std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder.Append()); PAIMON_RETURN_NOT_OK_FROM_ARROW(string_builder->Append(value)); @@ -175,8 +176,8 @@ class MergeTreeCompactManagerFactoryWriteTest : public ::testing::Test { arrow::StructBuilder struct_builder( struct_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto int64_builder = static_cast(struct_builder.field_builder(1)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto int64_builder = checked_cast(struct_builder.field_builder(1)); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder.Append()); PAIMON_RETURN_NOT_OK_FROM_ARROW(string_builder->Append(key)); PAIMON_RETURN_NOT_OK_FROM_ARROW(int64_builder->Append(sequence)); diff --git a/src/paimon/core/mergetree/in_memory_sort_buffer.cpp b/src/paimon/core/mergetree/in_memory_sort_buffer.cpp index cf1174f8..5f53d598 100644 --- a/src/paimon/core/mergetree/in_memory_sort_buffer.cpp +++ b/src/paimon/core/mergetree/in_memory_sort_buffer.cpp @@ -26,9 +26,9 @@ #include "arrow/array/array_nested.h" #include "arrow/c/bridge.h" #include "arrow/c/helpers.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/io/key_value_in_memory_record_reader.h" #include "paimon/core/io/key_value_record_reader.h" #include "paimon/data/decimal.h" @@ -73,10 +73,10 @@ Result InMemorySortBuffer::Write(std::unique_ptr&& moved_batc std::unique_ptr batch = std::move(moved_batch); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(batch->GetData(), value_type_)); - auto value_struct_array = std::dynamic_pointer_cast(arrow_array); - if (value_struct_array == nullptr) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("invalid RecordBatch: cannot cast to StructArray"); } + auto value_struct_array = checked_pointer_cast(arrow_array); PAIMON_ASSIGN_OR_RAISE(int64_t memory_in_bytes, EstimateMemoryUse(value_struct_array)); current_memory_in_bytes_ += static_cast(memory_in_bytes); @@ -146,30 +146,24 @@ Result InMemorySortBuffer::EstimateMemoryUse(const std::shared_ptrlength() * sizeof(Decimal::int128_t); case arrow::Type::type::STRING: case arrow::Type::type::BINARY: { - auto binary_array = - arrow::internal::checked_cast(array.get()); - assert(binary_array); + auto binary_array = checked_cast(array.get()); int64_t value_length = binary_array->total_values_length(); int64_t offset_length = array->length() * sizeof(int32_t); return null_bits_size_in_bytes + value_length + offset_length; } case arrow::Type::type::LIST: { - auto list_array = arrow::internal::checked_cast(array.get()); - assert(list_array); + auto list_array = checked_cast(array.get()); PAIMON_ASSIGN_OR_RAISE(int64_t value_mem, EstimateMemoryUse(list_array->values())); return null_bits_size_in_bytes + value_mem; } case arrow::Type::type::MAP: { - auto map_array = arrow::internal::checked_cast(array.get()); - assert(map_array); + auto map_array = checked_cast(array.get()); PAIMON_ASSIGN_OR_RAISE(int64_t key_mem, EstimateMemoryUse(map_array->keys())); PAIMON_ASSIGN_OR_RAISE(int64_t item_mem, EstimateMemoryUse(map_array->items())); return null_bits_size_in_bytes + key_mem + item_mem; } case arrow::Type::type::STRUCT: { - auto struct_array = - arrow::internal::checked_cast(array.get()); - assert(struct_array); + auto struct_array = checked_cast(array.get()); int64_t struct_mem = 0; for (const auto& field : struct_array->fields()) { PAIMON_ASSIGN_OR_RAISE(int64_t field_mem, EstimateMemoryUse(field)); diff --git a/src/paimon/core/mergetree/spill_reader.cpp b/src/paimon/core/mergetree/spill_reader.cpp index e1ed9004..cb2598e5 100644 --- a/src/paimon/core/mergetree/spill_reader.cpp +++ b/src/paimon/core/mergetree/spill_reader.cpp @@ -25,6 +25,7 @@ #include "paimon/common/utils/arrow/arrow_input_stream_adapter.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon { @@ -101,21 +102,20 @@ Result> SpillReader::NextBatch() if (!sequence_number_col) { return Status::Invalid("cannot find _SEQUENCE_NUMBER column in spill file"); } - sequence_number_array_ = - std::dynamic_pointer_cast>(sequence_number_col); - if (!sequence_number_array_) { + if (sequence_number_col->type_id() != arrow::Type::INT64) { return Status::Invalid("cannot cast _SEQUENCE_NUMBER column to int64 arrow array"); } + sequence_number_array_ = + checked_pointer_cast>(sequence_number_col); auto value_kind_col = record_batch->GetColumnByName(SpecialFields::ValueKind().Name()); if (!value_kind_col) { return Status::Invalid("cannot find _VALUE_KIND column in spill file"); } - row_kind_array_ = - std::dynamic_pointer_cast>(value_kind_col); - if (!row_kind_array_) { + if (value_kind_col->type_id() != arrow::Type::INT8) { return Status::Invalid("cannot cast _VALUE_KIND column to int8 arrow array"); } + row_kind_array_ = checked_pointer_cast>(value_kind_col); arrow::ArrayVector key_fields; key_fields.reserve(key_schema_->num_fields()); diff --git a/src/paimon/core/operation/append_only_file_store_write.cpp b/src/paimon/core/operation/append_only_file_store_write.cpp index f0dd32c9..c0cd6a3c 100644 --- a/src/paimon/core/operation/append_only_file_store_write.cpp +++ b/src/paimon/core/operation/append_only_file_store_write.cpp @@ -29,6 +29,7 @@ #include "paimon/common/data/shredding/shredding_write_plan_factories.h" #include "paimon/common/table/special_fields.h" #include "paimon/common/utils/arrow/arrow_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/append/append_only_writer.h" #include "paimon/core/append/bucketed_append_compact_manager.h" #include "paimon/core/compact/noop_compact_manager.h" @@ -176,11 +177,11 @@ Result>> AppendOnlyFileStoreWrite::Com auto& [c_array, c_schema] = batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto struct_array = std::dynamic_pointer_cast(arrow_array); - if (!struct_array) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid( "cannot cast array to StructArray in CompleteRowKindBatchReader"); } + auto struct_array = checked_pointer_cast(arrow_array); PAIMON_ASSIGN_OR_RAISE(struct_array, ArrowUtils::RemoveFieldFromStructArray( struct_array, SpecialFields::ValueKind().Name())); PAIMON_RETURN_NOT_OK_FROM_ARROW( diff --git a/src/paimon/core/operation/append_only_file_store_write_test.cpp b/src/paimon/core/operation/append_only_file_store_write_test.cpp index bb2496a2..2090a004 100644 --- a/src/paimon/core/operation/append_only_file_store_write_test.cpp +++ b/src/paimon/core/operation/append_only_file_store_write_test.cpp @@ -41,6 +41,7 @@ #include "paimon/common/data/binary_row_writer.h" #include "paimon/common/data/shredding/map_shared_shredding_utils.h" #include "paimon/common/data/shredding/map_shredding_defs.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/core/io/data_file_meta.h" #include "paimon/core/operation/restore_files.h" @@ -194,7 +195,7 @@ class AppendOnlyFileStoreWriteTest : public testing::Test { } std::shared_ptr array = arrow::Concatenate(result->chunks(), arrow::default_memory_pool()).ValueOrDie(); - return std::static_pointer_cast(array); + return checked_pointer_cast(array); } MapSharedShreddingFieldMeta ShreddingMeta(const std::shared_ptr& file_schema, diff --git a/src/paimon/core/operation/data_evolution_split_read.cpp b/src/paimon/core/operation/data_evolution_split_read.cpp index e6658f7b..52a1bb51 100644 --- a/src/paimon/core/operation/data_evolution_split_read.cpp +++ b/src/paimon/core/operation/data_evolution_split_read.cpp @@ -46,6 +46,7 @@ #include "paimon/common/table/special_fields.h" #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/object_utils.h" #include "paimon/common/utils/path_util.h" #include "paimon/common/utils/range_helper.h" @@ -340,20 +341,20 @@ Result> DataEvolutionSplitRead::ExtractBlobVi auto& [c_array, c_schema] = batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto struct_array = std::dynamic_pointer_cast(arrow_array); - if (struct_array == nullptr) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid( "invalid array in ExtractBlobViewStructs, batch array is not a StructArray."); } + auto struct_array = checked_pointer_cast(arrow_array); for (int32_t field_idx = 0; field_idx < struct_array->num_fields(); ++field_idx) { - auto binary_array = - std::dynamic_pointer_cast(struct_array->field(field_idx)); - if (binary_array == nullptr) { + auto field_array = struct_array->field(field_idx); + if (!field_array || field_array->type_id() != arrow::Type::LARGE_BINARY) { return Status::Invalid( "invalid array in ExtractBlobViewStructs, blob view column is not a " "LargeBinaryArray."); } + auto binary_array = checked_pointer_cast(field_array); for (int64_t row = 0; row < binary_array->length(); ++row) { if (binary_array->IsNull(row)) { continue; diff --git a/src/paimon/core/operation/internal_read_context.cpp b/src/paimon/core/operation/internal_read_context.cpp index 7c4e2ecd..ecd70e0c 100644 --- a/src/paimon/core/operation/internal_read_context.cpp +++ b/src/paimon/core/operation/internal_read_context.cpp @@ -31,6 +31,7 @@ #include "paimon/common/table/special_fields.h" #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/options/map_storage_layout.h" #include "paimon/core/schema/arrow_schema_validator.h" #include "paimon/core/utils/nested_projection_utils.h" @@ -53,7 +54,7 @@ Result> InternalReadContext::AlignReadFieldWithTab if (table_field->type()->id() == arrow::Type::MAP && NestedProjectionUtils::IsMapSharedShreddingAccessField(read_field)) { - auto table_map = arrow::internal::checked_pointer_cast(table_field->type()); + auto table_map = checked_pointer_cast(table_field->type()); if (table_map->key_type()->id() != arrow::Type::STRING) { return Status::Invalid(fmt::format( "Selected-key MAP pushdown only supports string MAP keys for field '{}'", @@ -61,8 +62,7 @@ Result> InternalReadContext::AlignReadFieldWithTab } PAIMON_RETURN_NOT_OK( NestedProjectionUtils::ValidateMapSharedShreddingAccessField(read_field).status()); - auto read_struct = - arrow::internal::checked_pointer_cast(read_field->type()); + auto read_struct = checked_pointer_cast(read_field->type()); const auto& selected_value_type = read_struct->field(0)->type(); if (!selected_value_type->Equals(table_map->item_type())) { return Status::Invalid(fmt::format( @@ -84,8 +84,8 @@ Result> InternalReadContext::AlignReadFieldWithTab auto type_id = read_field->type()->id(); if (type_id == arrow::Type::STRUCT) { - auto read_struct = std::static_pointer_cast(read_field->type()); - auto table_struct = std::static_pointer_cast(table_field->type()); + auto read_struct = checked_pointer_cast(read_field->type()); + auto table_struct = checked_pointer_cast(table_field->type()); arrow::FieldVector rebased_children; rebased_children.reserve(read_struct->num_fields()); for (const auto& read_child : read_struct->fields()) { @@ -108,8 +108,8 @@ Result> InternalReadContext::AlignReadFieldWithTab } if (type_id == arrow::Type::LIST) { - auto read_list = std::static_pointer_cast(read_field->type()); - auto table_list = std::static_pointer_cast(table_field->type()); + auto read_list = checked_pointer_cast(read_field->type()); + auto table_list = checked_pointer_cast(table_field->type()); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr rebased_value_field, AlignReadFieldWithTableFieldIds(read_list->value_field(), table_list->value_field())); @@ -120,8 +120,8 @@ Result> InternalReadContext::AlignReadFieldWithTab } if (type_id == arrow::Type::MAP) { - auto read_map = std::static_pointer_cast(read_field->type()); - auto table_map = std::static_pointer_cast(table_field->type()); + auto read_map = checked_pointer_cast(read_field->type()); + auto table_map = checked_pointer_cast(table_field->type()); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr rebased_key_field, AlignReadFieldWithTableFieldIds(read_map->key_field(), table_map->key_field())); diff --git a/src/paimon/core/operation/key_value_file_store_write_test.cpp b/src/paimon/core/operation/key_value_file_store_write_test.cpp index 62dfd716..35d938af 100644 --- a/src/paimon/core/operation/key_value_file_store_write_test.cpp +++ b/src/paimon/core/operation/key_value_file_store_write_test.cpp @@ -40,6 +40,7 @@ #include "paimon/common/data/shredding/map_shared_shredding_utils.h" #include "paimon/common/data/shredding/map_shredding_defs.h" #include "paimon/common/table/special_fields.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/core/io/data_file_meta.h" #include "paimon/core/operation/restore_files.h" @@ -96,7 +97,7 @@ class KeyValueFileStoreWriteTest : public ::testing::Test { auto struct_type = arrow::struct_(fields); arrow::StructBuilder struct_builder(struct_type, arrow::default_memory_pool(), {std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder.Append()); PAIMON_RETURN_NOT_OK_FROM_ARROW(string_builder->Append(value)); diff --git a/src/paimon/core/postpone/postpone_bucket_writer.cpp b/src/paimon/core/postpone/postpone_bucket_writer.cpp index fb27d001..47fd3bcb 100644 --- a/src/paimon/core/postpone/postpone_bucket_writer.cpp +++ b/src/paimon/core/postpone/postpone_bucket_writer.cpp @@ -30,7 +30,6 @@ #include "arrow/c/bridge.h" #include "arrow/c/helpers.h" #include "arrow/scalar.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/shredding/shredding_write_plan_factories.h" #include "paimon/common/metrics/metrics_impl.h" @@ -39,6 +38,7 @@ #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/core/io/compact_increment.h" #include "paimon/core/io/data_file_path_factory.h" @@ -157,11 +157,10 @@ Result> PostponeBucketWriter::CheckAndCastVa } PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(value_array, value_type_)); - auto value_struct_array = - arrow::internal::checked_pointer_cast(arrow_array); - if (value_struct_array == nullptr) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("invalid RecordBatch: cannot cast to StructArray"); } + auto value_struct_array = checked_pointer_cast(arrow_array); return value_struct_array; } @@ -190,17 +189,13 @@ Result> PostponeBucketWriter::PrepareRowKindArray( std::shared_ptr scalar_array, arrow::MakeArrayFromScalar(*row_kind_scalar, value_array_length, arrow_pool_.get())); auto typed_row_kind_array = - arrow::internal::checked_pointer_cast>( - scalar_array); - assert(typed_row_kind_array); + checked_pointer_cast>(scalar_array); row_kind_array_ = std::move(typed_row_kind_array); row_kind_array = row_kind_array_; } else { assert(row_kind_array_->length() >= value_array_length); - row_kind_array = - arrow::internal::checked_pointer_cast>( - row_kind_array_->Slice(0, value_array_length)); - assert(row_kind_array); + row_kind_array = checked_pointer_cast>( + row_kind_array_->Slice(0, value_array_length)); } if (!row_kind_vec.empty()) { diff --git a/src/paimon/core/realtime/arrow_mem_indexer.cpp b/src/paimon/core/realtime/arrow_mem_indexer.cpp index c8769df5..8dc054c1 100644 --- a/src/paimon/core/realtime/arrow_mem_indexer.cpp +++ b/src/paimon/core/realtime/arrow_mem_indexer.cpp @@ -30,6 +30,7 @@ #include "paimon/common/table/special_fields.h" #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/utils/nested_projection_utils.h" #include "paimon/macros.h" @@ -218,11 +219,11 @@ class ArrowMemIndexer::QueryBatchReader : public BatchReader { std::shared_ptr projected, NestedProjectionUtils::AlignArrayToReadType( stored.data, arrow::struct_(read_schema_->fields()), arrow_pool_.get())); - std::shared_ptr projected_struct = - std::dynamic_pointer_cast(projected); - if (!projected_struct) { + if (!projected || projected->type_id() != arrow::Type::STRUCT) { return Status::Invalid("memory query projection did not produce a StructArray"); } + std::shared_ptr projected_struct = + checked_pointer_cast(projected); return projected_struct; } @@ -256,11 +257,11 @@ Status ArrowMemIndexer::Write(RealtimeWriteBatch&& write_batch) { PAIMON_ASSIGN_OR_RAISE_FROM_ARROW( std::shared_ptr data, arrow::ImportArray(write_batch.batch->GetData(), arrow::struct_(write_schema_->fields()))); - std::shared_ptr struct_array = - std::dynamic_pointer_cast(data); - if (!struct_array) { + if (!data || data->type_id() != arrow::Type::STRUCT) { return Status::Invalid("real-time write data is not a StructArray"); } + std::shared_ptr struct_array = + checked_pointer_cast(data); std::lock_guard lock(mutex_); if (building_range_ && write_batch.offset_range.from != building_range_->to + 1) { diff --git a/src/paimon/core/realtime/realtime_append_only_writer.cpp b/src/paimon/core/realtime/realtime_append_only_writer.cpp index 794cc394..009f8597 100644 --- a/src/paimon/core/realtime/realtime_append_only_writer.cpp +++ b/src/paimon/core/realtime/realtime_append_only_writer.cpp @@ -32,6 +32,7 @@ #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/arrow_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/core/append/append_only_writer.h" #include "paimon/core/utils/commit_increment.h" @@ -130,11 +131,11 @@ Status RealtimeAppendOnlyWriter::FlushSegment( auto& [c_array, c_schema] = batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr imported, arrow::ImportArray(c_array.get(), c_schema.get())); - std::shared_ptr struct_array = - std::dynamic_pointer_cast(imported); - if (!struct_array) { + if (!imported || imported->type_id() != arrow::Type::STRUCT) { return Status::Invalid("mem indexer commit reader returned a non-StructArray"); } + std::shared_ptr struct_array = + checked_pointer_cast(imported); std::shared_ptr value_kind = struct_array->GetFieldByName(SpecialFields::ValueKind().Name()); if (!value_kind || value_kind->type_id() != arrow::Type::INT8) { @@ -142,7 +143,7 @@ Status RealtimeAppendOnlyWriter::FlushSegment( "mem indexer commit reader must return an INT8 _VALUE_KIND field"); } std::shared_ptr row_kinds = - std::static_pointer_cast(value_kind); + checked_pointer_cast(value_kind); for (int64_t i = 0; i < row_kinds->length(); ++i) { if (row_kinds->IsNull(i) || row_kinds->Value(i) != static_cast(RecordBatch::RowKind::INSERT)) { diff --git a/src/paimon/core/schema/arrow_schema_validator.cpp b/src/paimon/core/schema/arrow_schema_validator.cpp index e01afe01..f78e1550 100644 --- a/src/paimon/core/schema/arrow_schema_validator.cpp +++ b/src/paimon/core/schema/arrow_schema_validator.cpp @@ -23,12 +23,12 @@ #include #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/blob_utils.h" #include "paimon/common/data/variant/variant_access_utils.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/decimal_utils.h" #include "paimon/common/utils/string_utils.h" #include "paimon/result.h" @@ -123,8 +123,7 @@ Status ArrowSchemaValidator::ValidateDataTypeWithFieldId( case arrow::Type::type::TIMESTAMP: return Status::OK(); case arrow::Type::type::LIST: { - const auto& value_field = - arrow::internal::checked_cast(type.get())->value_field(); + const auto& value_field = checked_cast(type.get())->value_field(); PAIMON_RETURN_NOT_OK(ValidateDataTypeWithFieldId( value_field->type(), value_field->metadata(), /*allow_blob=*/false, field_id_set)); break; @@ -135,8 +134,7 @@ Status ArrowSchemaValidator::ValidateDataTypeWithFieldId( // paimon field ids 0/1 which must not join the global field id uniqueness check. break; } - arrow::FieldVector sub_fields = - arrow::internal::checked_cast(type.get())->fields(); + arrow::FieldVector sub_fields = checked_cast(type.get())->fields(); for (const auto& sub_field : sub_fields) { PAIMON_ASSIGN_OR_RAISE(DataField data_field, DataField::ConvertArrowFieldToDataField(sub_field)); @@ -152,10 +150,8 @@ Status ArrowSchemaValidator::ValidateDataTypeWithFieldId( break; } case arrow::Type::type::MAP: { - const auto& key_field = - arrow::internal::checked_cast(type.get())->key_field(); - const auto& item_field = - arrow::internal::checked_cast(type.get())->item_field(); + const auto& key_field = checked_cast(type.get())->key_field(); + const auto& item_field = checked_cast(type.get())->item_field(); PAIMON_RETURN_NOT_OK(ValidateDataTypeWithFieldId( key_field->type(), key_field->metadata(), /*allow_blob=*/false, field_id_set)); PAIMON_RETURN_NOT_OK(ValidateDataTypeWithFieldId( @@ -203,8 +199,7 @@ Status ArrowSchemaValidator::ValidateField(const std::shared_ptr& break; case arrow::Type::type::LIST: { const auto& value_field = - arrow::internal::checked_cast(*field->type()) - .value_field(); + checked_cast(*field->type()).value_field(); PAIMON_RETURN_NOT_OK(ValidateField(value_field, /*allow_blob=*/false)); break; } @@ -220,17 +215,16 @@ Status ArrowSchemaValidator::ValidateField(const std::shared_ptr& break; } arrow::FieldVector arrow_fields = - arrow::internal::checked_cast(*field->type()).fields(); + checked_cast(*field->type()).fields(); for (const auto& sub_field : arrow_fields) { PAIMON_RETURN_NOT_OK(ValidateField(sub_field, /*allow_blob=*/false)); } break; } case arrow::Type::type::MAP: { - const auto& key_field = - arrow::internal::checked_cast(*field->type()).key_field(); + const auto& key_field = checked_cast(*field->type()).key_field(); const auto& item_field = - arrow::internal::checked_cast(*field->type()).item_field(); + checked_cast(*field->type()).item_field(); PAIMON_RETURN_NOT_OK(ValidateField(key_field, /*allow_blob=*/false)); PAIMON_RETURN_NOT_OK(ValidateField(item_field, /*allow_blob=*/false)); break; @@ -256,16 +250,14 @@ bool ArrowSchemaValidator::ContainTimestampWithTimezone(const arrow::DataType& t const auto kind = type.id(); switch (kind) { case arrow::Type::type::LIST: { - const auto& value_field = - arrow::internal::checked_cast(type).value_field(); + const auto& value_field = checked_cast(type).value_field(); if (ContainTimestampWithTimezone(*value_field->type())) { return true; } break; } case arrow::Type::type::STRUCT: { - arrow::FieldVector arrow_fields = - arrow::internal::checked_cast(type).fields(); + arrow::FieldVector arrow_fields = checked_cast(type).fields(); for (const auto& sub_field : arrow_fields) { if (ContainTimestampWithTimezone(*sub_field->type())) { return true; @@ -274,10 +266,8 @@ bool ArrowSchemaValidator::ContainTimestampWithTimezone(const arrow::DataType& t break; } case arrow::Type::type::MAP: { - const auto& key_field = - arrow::internal::checked_cast(type).key_field(); - const auto& item_field = - arrow::internal::checked_cast(type).item_field(); + const auto& key_field = checked_cast(type).key_field(); + const auto& item_field = checked_cast(type).item_field(); if (ContainTimestampWithTimezone(*key_field->type())) { return true; } @@ -287,7 +277,7 @@ bool ArrowSchemaValidator::ContainTimestampWithTimezone(const arrow::DataType& t break; } case arrow::Type::type::TIMESTAMP: { - const auto& ts_type = arrow::internal::checked_cast(type); + const auto& ts_type = checked_cast(type); if (!ts_type.timezone().empty()) { return true; } diff --git a/src/paimon/core/schema/arrow_schema_validator.h b/src/paimon/core/schema/arrow_schema_validator.h index f7abf6d8..a2dfa994 100644 --- a/src/paimon/core/schema/arrow_schema_validator.h +++ b/src/paimon/core/schema/arrow_schema_validator.h @@ -24,7 +24,6 @@ #include #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/utils/arrow/status_utils.h" #include "paimon/status.h" #include "paimon/visibility.h" diff --git a/src/paimon/core/schema/schema_validation.cpp b/src/paimon/core/schema/schema_validation.cpp index 3005792e..7b8947ea 100644 --- a/src/paimon/core/schema/schema_validation.cpp +++ b/src/paimon/core/schema/schema_validation.cpp @@ -31,7 +31,6 @@ #include #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "fmt/ranges.h" #include "paimon/common/data/blob_utils.h" @@ -39,6 +38,7 @@ #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/table/special_fields.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/object_utils.h" #include "paimon/common/utils/preconditions.h" #include "paimon/common/utils/string_utils.h" @@ -70,7 +70,7 @@ bool ContainsBlobField(const std::shared_ptr& field) { } else if (type->id() == arrow::Type::LIST) { return ContainsBlobField(type->fields().front()); } else if (type->id() == arrow::Type::MAP) { - const auto& map_type = arrow::internal::checked_cast(*type); + const auto& map_type = checked_cast(*type); return ContainsBlobField(map_type.key_field()) || ContainsBlobField(map_type.item_field()); } return false; @@ -612,7 +612,7 @@ Status SchemaValidation::ValidateMapStorageLayout(const TableSchema& schema, "but its type is not MAP.", field_name)); } - auto map_type = arrow::internal::checked_pointer_cast(field_type); + auto map_type = checked_pointer_cast(field_type); if (map_type->key_field()->nullable()) { return Status::Invalid( fmt::format("Column '{}' is configured with map.storage-layout=shared-shredding " diff --git a/src/paimon/core/schema/table_schema.cpp b/src/paimon/core/schema/table_schema.cpp index e5139478..d7be7f11 100644 --- a/src/paimon/core/schema/table_schema.cpp +++ b/src/paimon/core/schema/table_schema.cpp @@ -26,10 +26,10 @@ #include "arrow/api.h" #include "arrow/c/bridge.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/common/utils/object_utils.h" @@ -103,7 +103,7 @@ Result> TableSchema::AssignFieldIdsRecursively( // paimon field ids 0/1 (mapped to parquet field ids on write). return metadata ? field->WithMergedMetadata(metadata) : field; } - auto struct_type = arrow::internal::checked_pointer_cast(field->type()); + auto struct_type = checked_pointer_cast(field->type()); arrow::FieldVector new_childs; for (const auto& child : struct_type->fields()) { PAIMON_ASSIGN_OR_RAISE( @@ -112,14 +112,14 @@ Result> TableSchema::AssignFieldIdsRecursively( } return arrow::field(field->name(), arrow::struct_(new_childs), field->nullable(), metadata); } else if (type->id() == arrow::Type::LIST) { - auto list_type = arrow::internal::checked_pointer_cast(field->type()); + auto list_type = checked_pointer_cast(field->type()); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr new_value_field, AssignFieldIdsRecursively(list_type->value_field(), /*set_field_id=*/false, field_id)); return arrow::field(field->name(), arrow::list(new_value_field), field->nullable(), metadata); } else if (field->type()->id() == arrow::Type::MAP) { - auto map_type = arrow::internal::checked_pointer_cast(field->type()); + auto map_type = checked_pointer_cast(field->type()); std::shared_ptr key_field = map_type->key_field(); std::shared_ptr value_field = map_type->item_field(); PAIMON_ASSIGN_OR_RAISE( diff --git a/src/paimon/core/schema/table_schema_test.cpp b/src/paimon/core/schema/table_schema_test.cpp index 1a46eaa6..0acbee0b 100644 --- a/src/paimon/core/schema/table_schema_test.cpp +++ b/src/paimon/core/schema/table_schema_test.cpp @@ -22,9 +22,9 @@ #include #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "gtest/gtest.h" #include "paimon/common/data/variant/variant_type_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/string_utils.h" #include "paimon/fs/local/local_file_system.h" @@ -1106,7 +1106,7 @@ TEST_F(TableSchemaTest, SetFieldIdStructType) { ASSERT_OK_AND_ASSIGN( std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(struct_field, /*set_field_id=*/true, &field_id)); - auto struct_type = std::static_pointer_cast(new_field->type()); + auto struct_type = checked_pointer_cast(new_field->type()); ASSERT_EQ(struct_type->num_fields(), 2); ASSERT_EQ(new_field->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); ASSERT_EQ(struct_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "1"); @@ -1118,7 +1118,7 @@ TEST_F(TableSchemaTest, SetFieldIdStructType) { ASSERT_OK_AND_ASSIGN(std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively( struct_field, /*set_field_id=*/false, &field_id)); - auto struct_type = std::static_pointer_cast(new_field->type()); + auto struct_type = checked_pointer_cast(new_field->type()); ASSERT_EQ(struct_type->num_fields(), 2); ASSERT_FALSE(new_field->metadata()); ASSERT_EQ(struct_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); @@ -1136,7 +1136,7 @@ TEST_F(TableSchemaTest, SetFieldIdListType) { std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(list_field, /*set_field_id=*/true, &field_id)); ASSERT_EQ(new_field->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); - auto list_type = arrow::internal::checked_pointer_cast(new_field->type()); + auto list_type = checked_pointer_cast(new_field->type()); ASSERT_FALSE(list_type->value_field()->metadata()); ASSERT_EQ(field_id, 1); } @@ -1146,7 +1146,7 @@ TEST_F(TableSchemaTest, SetFieldIdListType) { std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(list_field, /*set_field_id=*/false, &field_id)); ASSERT_FALSE(new_field->metadata()); - auto list_type = arrow::internal::checked_pointer_cast(new_field->type()); + auto list_type = checked_pointer_cast(new_field->type()); ASSERT_FALSE(list_type->value_field()->metadata()); ASSERT_EQ(field_id, 0); } @@ -1160,7 +1160,7 @@ TEST_F(TableSchemaTest, SetFieldIdMapType) { std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(map_field, /*set_field_id=*/true, &field_id)); ASSERT_EQ(new_field->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); - auto map_type = arrow::internal::checked_pointer_cast(new_field->type()); + auto map_type = checked_pointer_cast(new_field->type()); std::shared_ptr key_field = map_type->key_field(); std::shared_ptr value_field = map_type->item_field(); ASSERT_FALSE(key_field->metadata()); @@ -1173,7 +1173,7 @@ TEST_F(TableSchemaTest, SetFieldIdMapType) { std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(map_field, /*set_field_id=*/false, &field_id)); ASSERT_FALSE(new_field->metadata()); - auto map_type = arrow::internal::checked_pointer_cast(new_field->type()); + auto map_type = checked_pointer_cast(new_field->type()); std::shared_ptr key_field = map_type->key_field(); std::shared_ptr value_field = map_type->item_field(); ASSERT_FALSE(key_field->metadata()); @@ -1194,15 +1194,15 @@ TEST_F(TableSchemaTest, SetFieldIdMapWithStruct) { std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(map_field, /*set_field_id=*/true, &field_id)); ASSERT_EQ(new_field->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); - auto map_type = arrow::internal::checked_pointer_cast(new_field->type()); + auto map_type = checked_pointer_cast(new_field->type()); std::shared_ptr key_field = map_type->key_field(); std::shared_ptr value_field = map_type->item_field(); ASSERT_FALSE(key_field->metadata()); - auto key_inner_type = std::static_pointer_cast(key_field->type()); + auto key_inner_type = checked_pointer_cast(key_field->type()); ASSERT_EQ(key_inner_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "1"); ASSERT_EQ(key_inner_type->field(1)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "2"); ASSERT_FALSE(value_field->metadata()); - auto value_inner_type = std::static_pointer_cast(value_field->type()); + auto value_inner_type = checked_pointer_cast(value_field->type()); ASSERT_EQ(value_inner_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "3"); ASSERT_EQ(value_inner_type->field(1)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), @@ -1215,15 +1215,15 @@ TEST_F(TableSchemaTest, SetFieldIdMapWithStruct) { std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(map_field, /*set_field_id=*/false, &field_id)); ASSERT_FALSE(new_field->metadata()); - auto map_type = arrow::internal::checked_pointer_cast(new_field->type()); + auto map_type = checked_pointer_cast(new_field->type()); std::shared_ptr key_field = map_type->key_field(); std::shared_ptr value_field = map_type->item_field(); ASSERT_FALSE(key_field->metadata()); - auto key_inner_type = std::static_pointer_cast(key_field->type()); + auto key_inner_type = checked_pointer_cast(key_field->type()); ASSERT_EQ(key_inner_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); ASSERT_EQ(key_inner_type->field(1)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "1"); ASSERT_FALSE(value_field->metadata()); - auto value_inner_type = std::static_pointer_cast(value_field->type()); + auto value_inner_type = checked_pointer_cast(value_field->type()); ASSERT_EQ(value_inner_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "2"); ASSERT_EQ(value_inner_type->field(1)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), @@ -1243,9 +1243,9 @@ TEST_F(TableSchemaTest, SetFieldIdNestedStruct) { std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(outer_struct, /*set_field_id=*/true, &field_id)); ASSERT_EQ(new_field->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); - auto outer_type = std::static_pointer_cast(new_field->type()); + auto outer_type = checked_pointer_cast(new_field->type()); ASSERT_EQ(outer_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "1"); - auto inner_type = std::static_pointer_cast(outer_type->field(0)->type()); + auto inner_type = checked_pointer_cast(outer_type->field(0)->type()); ASSERT_EQ(inner_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "2"); ASSERT_EQ(inner_type->field(1)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "3"); ASSERT_EQ(field_id, 4); @@ -1256,9 +1256,9 @@ TEST_F(TableSchemaTest, SetFieldIdNestedStruct) { TableSchema::AssignFieldIdsRecursively( outer_struct, /*set_field_id=*/false, &field_id)); ASSERT_FALSE(new_field->metadata()); - auto outer_type = std::static_pointer_cast(new_field->type()); + auto outer_type = checked_pointer_cast(new_field->type()); ASSERT_EQ(outer_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); - auto inner_type = std::static_pointer_cast(outer_type->field(0)->type()); + auto inner_type = checked_pointer_cast(outer_type->field(0)->type()); ASSERT_EQ(inner_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "1"); ASSERT_EQ(inner_type->field(1)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "2"); ASSERT_EQ(field_id, 3); @@ -1274,11 +1274,10 @@ TEST_F(TableSchemaTest, SetFieldIdNestedListInStruct) { ASSERT_OK_AND_ASSIGN( std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively(struct_field, /*set_field_id=*/true, &field_id)); - auto struct_type = std::static_pointer_cast(new_field->type()); + auto struct_type = checked_pointer_cast(new_field->type()); ASSERT_EQ(new_field->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); ASSERT_EQ(struct_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "1"); - auto list_type = - arrow::internal::checked_pointer_cast(struct_type->field(0)->type()); + auto list_type = checked_pointer_cast(struct_type->field(0)->type()); ASSERT_FALSE(list_type->value_field()->metadata()); ASSERT_EQ(field_id, 2); } @@ -1287,11 +1286,10 @@ TEST_F(TableSchemaTest, SetFieldIdNestedListInStruct) { ASSERT_OK_AND_ASSIGN(std::shared_ptr new_field, TableSchema::AssignFieldIdsRecursively( struct_field, /*set_field_id=*/false, &field_id)); - auto struct_type = std::static_pointer_cast(new_field->type()); + auto struct_type = checked_pointer_cast(new_field->type()); ASSERT_FALSE(new_field->metadata()); ASSERT_EQ(struct_type->field(0)->metadata()->Get(DataField::FIELD_ID).ValueOrDie(), "0"); - auto list_type = - arrow::internal::checked_pointer_cast(struct_type->field(0)->type()); + auto list_type = checked_pointer_cast(struct_type->field(0)->type()); ASSERT_FALSE(list_type->value_field()->metadata()); ASSERT_EQ(field_id, 1); } @@ -1318,7 +1316,7 @@ TEST_F(TableSchemaTest, NullableMapKeySchemaIsSupported) { })"; ASSERT_OK_AND_ASSIGN(std::unique_ptr table_schema, TableSchema::CreateFromJson(table_schema_str)); - auto json_map_type = std::static_pointer_cast(table_schema->Fields()[0].Type()); + auto json_map_type = checked_pointer_cast(table_schema->Fields()[0].Type()); ASSERT_FALSE(json_map_type->key_field()->nullable()); auto nullable_key_map = @@ -1329,7 +1327,7 @@ TEST_F(TableSchemaTest, NullableMapKeySchemaIsSupported) { TableSchema::Create(/*schema_id=*/0, arrow::schema({arrow::field("f0", nullable_key_map)}), /*partition_keys=*/{}, /*primary_keys=*/{}, /*options=*/{})); auto direct_map_type = - std::static_pointer_cast(direct_table_schema->Fields()[0].Type()); + checked_pointer_cast(direct_table_schema->Fields()[0].Type()); ASSERT_TRUE(direct_map_type->key_field()->nullable()); } @@ -1343,12 +1341,12 @@ TEST_F(TableSchemaTest, MapKeysSortedIsNormalized) { TableSchema::Create(/*schema_id=*/0, arrow::schema({arrow::field("f0", sorted_map)}), /*partition_keys=*/{}, /*primary_keys=*/{}, /*options=*/{})); - auto map_type = std::static_pointer_cast(table_schema->Fields()[0].Type()); + auto map_type = checked_pointer_cast(table_schema->Fields()[0].Type()); ASSERT_FALSE(map_type->keys_sorted()); ASSERT_OK_AND_ASSIGN(std::string json, table_schema->ToJsonString()); ASSERT_OK_AND_ASSIGN(std::unique_ptr restored, TableSchema::CreateFromJson(json)); - auto restored_map_type = std::static_pointer_cast(restored->Fields()[0].Type()); + auto restored_map_type = checked_pointer_cast(restored->Fields()[0].Type()); ASSERT_FALSE(restored_map_type->keys_sorted()); ASSERT_TRUE(map_type->Equals(*restored_map_type)); } diff --git a/src/paimon/core/table/source/data_split_test.cpp b/src/paimon/core/table/source/data_split_test.cpp index 22d75d96..b6598852 100644 --- a/src/paimon/core/table/source/data_split_test.cpp +++ b/src/paimon/core/table/source/data_split_test.cpp @@ -28,6 +28,7 @@ #include "gtest/gtest.h" #include "paimon/common/data/binary_row.h" #include "paimon/common/data/data_define.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/deletionvectors/bitmap_deletion_vector.h" #include "paimon/core/deletionvectors/deletion_vector.h" #include "paimon/core/io/data_file_meta.h" @@ -1515,7 +1516,7 @@ TEST(DataSplitTest, TestPartialMergedRowCountResolvesMissingCardinalityViaFactor [&deletion_vector]( const std::string& file_name) -> Result> { if (file_name == "data-1.orc") { - return std::static_pointer_cast(deletion_vector); + return checked_pointer_cast(deletion_vector); } return std::shared_ptr(); }; diff --git a/src/paimon/core/table/system/audit_log_system_table.cpp b/src/paimon/core/table/system/audit_log_system_table.cpp index e77821fe..e384146e 100644 --- a/src/paimon/core/table/system/audit_log_system_table.cpp +++ b/src/paimon/core/table/system/audit_log_system_table.cpp @@ -32,7 +32,6 @@ #include "arrow/array/concatenate.h" #include "arrow/c/abi.h" #include "arrow/c/bridge.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/metrics/metrics_impl.h" #include "paimon/common/reader/concat_batch_reader.h" #include "paimon/common/table/special_fields.h" @@ -40,6 +39,7 @@ #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/core_options.h" #include "paimon/core/schema/table_schema.h" #include "paimon/core/table/source/data_split_impl.h" @@ -94,10 +94,10 @@ class ChangelogBatchReader : public BatchReader { PAIMON_ASSIGN_OR_RAISE_FROM_ARROW( std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - struct_array = std::dynamic_pointer_cast(arrow_array); - if (!struct_array) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid("audit_log system table expects struct batches"); } + struct_array = checked_pointer_cast(arrow_array); PAIMON_ASSIGN_OR_RAISE(struct_array, PrependPendingUpdateBefore(struct_array)); PAIMON_ASSIGN_OR_RAISE(row_group_lengths, BuildRowGroupLengths(struct_array)); } @@ -160,22 +160,22 @@ class ChangelogBatchReader : public BatchReader { std::shared_ptr combined, arrow::Concatenate({pending_update_before_, struct_array}, arrow_pool_)); pending_update_before_.reset(); - std::shared_ptr result = - std::dynamic_pointer_cast(combined); - if (!result) { + if (!combined || combined->type_id() != arrow::Type::STRUCT) { return Status::Invalid("failed to concatenate binlog struct batches"); } + std::shared_ptr result = + checked_pointer_cast(combined); return result; } Result> BuildRowGroupLengths( const std::shared_ptr& struct_array) { - std::shared_ptr value_kind_array = - std::dynamic_pointer_cast( - struct_array->GetFieldByName(SpecialFields::ValueKind().Name())); - if (!value_kind_array) { + auto value_kind = struct_array->GetFieldByName(SpecialFields::ValueKind().Name()); + if (!value_kind || value_kind->type_id() != arrow::Type::INT8) { return Status::Invalid("cannot find _VALUE_KIND in audit_log batch"); } + std::shared_ptr value_kind_array = + checked_pointer_cast(value_kind); std::vector row_group_lengths; row_group_lengths.reserve(struct_array->length()); @@ -191,10 +191,10 @@ class ChangelogBatchReader : public BatchReader { if (i + 1 == value_kind_array->length()) { PAIMON_ASSIGN_OR_RAISE(std::shared_ptr pending, CopyToStablePool(struct_array->Slice(i, /*length=*/1))); - pending_update_before_ = std::dynamic_pointer_cast(pending); - if (!pending_update_before_) { + if (!pending || pending->type_id() != arrow::Type::STRUCT) { return Status::Invalid("failed to cache UPDATE_BEFORE in binlog reader"); } + pending_update_before_ = checked_pointer_cast(pending); break; } if (value_kind_array->IsNull(i + 1) || @@ -220,12 +220,12 @@ class ChangelogBatchReader : public BatchReader { Result> BuildRowKindArray( const std::shared_ptr& struct_array, const std::vector& row_group_lengths) const { - std::shared_ptr value_kind_array = - std::dynamic_pointer_cast( - struct_array->GetFieldByName(SpecialFields::ValueKind().Name())); - if (!value_kind_array) { + auto value_kind = struct_array->GetFieldByName(SpecialFields::ValueKind().Name()); + if (!value_kind || value_kind->type_id() != arrow::Type::INT8) { return Status::Invalid("cannot find _VALUE_KIND in audit_log batch"); } + std::shared_ptr value_kind_array = + checked_pointer_cast(value_kind); arrow::StringBuilder builder(arrow_pool_); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(row_group_lengths.size())); int64_t offset = 0; @@ -251,12 +251,12 @@ class ChangelogBatchReader : public BatchReader { Result> BuildSequenceNumberArray( const std::shared_ptr& struct_array, const std::vector& row_group_lengths) const { - std::shared_ptr sequence_array = - std::dynamic_pointer_cast( - struct_array->GetFieldByName(SpecialFields::SequenceNumber().Name())); - if (!sequence_array) { + auto sequence = struct_array->GetFieldByName(SpecialFields::SequenceNumber().Name()); + if (!sequence || sequence->type_id() != arrow::Type::INT64) { return Status::Invalid("cannot find _SEQUENCE_NUMBER in audit_log batch"); } + std::shared_ptr sequence_array = + checked_pointer_cast(sequence); arrow::Int64Builder builder(arrow_pool_); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(row_group_lengths.size())); int64_t offset = 0; diff --git a/src/paimon/core/table/system/in_memory_system_table.cpp b/src/paimon/core/table/system/in_memory_system_table.cpp index 91cb9eec..f4d1aa67 100644 --- a/src/paimon/core/table/system/in_memory_system_table.cpp +++ b/src/paimon/core/table/system/in_memory_system_table.cpp @@ -26,6 +26,7 @@ #include "paimon/common/metrics/metrics_impl.h" #include "paimon/common/utils/arrow/mem_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/io/generic_row_to_arrow_array_converter.h" #include "paimon/core/table/system/system_table_scan.h" #include "paimon/memory/memory_pool.h" @@ -113,7 +114,7 @@ Result> InMemorySystemTable::NewScan( Result> InMemorySystemTable::NewRead( const std::shared_ptr& context) const { return std::make_unique( - std::static_pointer_cast(shared_from_this()), + checked_pointer_cast(shared_from_this()), context->GetMemoryPool()); } diff --git a/src/paimon/core/table/table.cpp b/src/paimon/core/table/table.cpp index 557c4526..f0c1de2f 100644 --- a/src/paimon/core/table/table.cpp +++ b/src/paimon/core/table/table.cpp @@ -21,6 +21,7 @@ #include #include "fmt/format.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/schema/schema_manager.h" #include "paimon/core/schema/table_schema.h" #include "paimon/fs/file_system.h" @@ -43,7 +44,7 @@ Result> Table::Create(const std::shared_ptr& fmt::format("load table schema for {} failed", identifier.ToString())); } - auto schema = std::static_pointer_cast(*latest_schema); + auto schema = checked_pointer_cast(*latest_schema); return std::make_shared(schema, identifier.GetDatabaseName(), identifier.GetTableName()); } diff --git a/src/paimon/core/utils/blob_view_lookup.cpp b/src/paimon/core/utils/blob_view_lookup.cpp index cf41ca81..d0b2ead7 100644 --- a/src/paimon/core/utils/blob_view_lookup.cpp +++ b/src/paimon/core/utils/blob_view_lookup.cpp @@ -32,6 +32,7 @@ #include "paimon/common/executor/future.h" #include "paimon/common/table/special_fields.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/defs.h" #include "paimon/executor.h" @@ -224,11 +225,11 @@ Status BlobViewLookup::ExtractBlobDescriptors(const Identifier& identifier, auto& [c_array, c_schema] = batch; PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr arrow_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto struct_array = std::dynamic_pointer_cast(arrow_array); - if (struct_array == nullptr) { + if (!arrow_array || arrow_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid( "invalid array in ExtractBlobDescriptors, batch array is not a StructArray."); } + auto struct_array = checked_pointer_cast(arrow_array); // skip the _VALUE_KIND column if (static_cast(struct_array->num_fields()) - 1 != field_ids.size()) { return Status::Invalid( @@ -250,22 +251,22 @@ Status BlobViewLookup::ExtractBlobDescriptors(const Identifier& identifier, "invalid array in ExtractBlobDescriptors, expected _ROW_ID as the last column"); } auto row_id_array = struct_array->field(struct_array->num_fields() - 1); - auto typed_row_id_array = std::dynamic_pointer_cast(row_id_array); - if (!typed_row_id_array) { + if (!row_id_array || row_id_array->type_id() != arrow::Type::INT64) { return Status::Invalid( fmt::format("invalid array does not contain {} field, or it cannot be casted to " "Int64Array in ExtractBlobDescriptors.", SpecialFields::RowId().Name())); } + auto typed_row_id_array = checked_pointer_cast(row_id_array); // skip _VALUE_KIND for (int32_t idx = 1; idx < struct_array->num_fields() - 1; ++idx) { - auto binary_array = - std::dynamic_pointer_cast(struct_array->field(idx)); - if (binary_array == nullptr) { + auto field_array = struct_array->field(idx); + if (!field_array || field_array->type_id() != arrow::Type::LARGE_BINARY) { return Status::Invalid( "invalid array in ExtractBlobDescriptors, column is not a LargeBinaryArray."); } + auto binary_array = checked_pointer_cast(field_array); for (int64_t row = 0; row < binary_array->length(); ++row) { BlobViewStruct blob_view_struct(identifier, field_ids[idx - 1], typed_row_id_array->Value(row)); diff --git a/src/paimon/core/utils/field_mapping.cpp b/src/paimon/core/utils/field_mapping.cpp index c9b70d47..447d8d58 100644 --- a/src/paimon/core/utils/field_mapping.cpp +++ b/src/paimon/core/utils/field_mapping.cpp @@ -26,6 +26,7 @@ #include "fmt/format.h" #include "paimon/common/predicate/compound_predicate_impl.h" #include "paimon/common/predicate/leaf_predicate_impl.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/field_type_utils.h" #include "paimon/common/utils/object_utils.h" #include "paimon/core/casting/cast_executor_factory.h" @@ -156,8 +157,8 @@ std::optional FieldMappingBuilder::CreateNonExistFieldInfo( // cannot be read from data files directly. Materialize it as nulls. if (read_field.Type()->id() == arrow::Type::STRUCT && iter->second.Type()->id() == arrow::Type::STRUCT) { - auto read_struct = std::static_pointer_cast(read_field.Type()); - auto data_struct = std::static_pointer_cast(iter->second.Type()); + auto read_struct = checked_pointer_cast(read_field.Type()); + auto data_struct = checked_pointer_cast(iter->second.Type()); if (read_struct->num_fields() == 0 && data_struct->num_fields() > 0) { non_exist_field_info.non_exist_read_schema.push_back(read_field); non_exist_field_info.idx_in_target_read_schema.push_back(i); diff --git a/src/paimon/core/utils/manifest_meta_reader.cpp b/src/paimon/core/utils/manifest_meta_reader.cpp index 9e160236..52faecae 100644 --- a/src/paimon/core/utils/manifest_meta_reader.cpp +++ b/src/paimon/core/utils/manifest_meta_reader.cpp @@ -32,9 +32,9 @@ #include "arrow/c/bridge.h" #include "arrow/compute/cast.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/status.h" namespace paimon { @@ -68,18 +68,19 @@ Result ManifestMetaReader::NextBatch() { Result> ManifestMetaReader::AlignArrayWithSchema( const std::shared_ptr& src_array, const std::shared_ptr& target_type, arrow::MemoryPool* pool) { + if (!src_array || !target_type) { + return Status::Invalid("Align array with schema failed, array or target type is null"); + } const auto src_kind = src_array->type()->id(); switch (src_kind) { case arrow::Type::type::LIST: { - auto list_src_array = - arrow::internal::checked_pointer_cast(src_array); - auto list_target_type = - arrow::internal::checked_pointer_cast(target_type); - if (!list_target_type) { + auto list_src_array = checked_pointer_cast(src_array); + if (target_type->id() != arrow::Type::LIST) { return Status::Invalid( "Complete non exist field failed, target type cannot cast to a list data " "type"); } + auto list_target_type = checked_pointer_cast(target_type); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr converted, AlignArrayWithSchema(list_src_array->values(), list_target_type->value_type(), pool)); @@ -90,14 +91,13 @@ Result> ManifestMetaReader::AlignArrayWithSchema( list_src_array->offset()); } case arrow::Type::type::MAP: { - auto map_src_array = arrow::internal::checked_pointer_cast(src_array); - auto map_target_type = - arrow::internal::checked_pointer_cast(target_type); - if (!map_target_type) { + auto map_src_array = checked_pointer_cast(src_array); + if (target_type->id() != arrow::Type::MAP) { return Status::Invalid( "Complete non exist field failed, target type cannot cast to a map data " "type"); } + auto map_target_type = checked_pointer_cast(target_type); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr key_converted, AlignArrayWithSchema(map_src_array->keys(), map_target_type->key_type(), pool)); @@ -112,15 +112,13 @@ Result> ManifestMetaReader::AlignArrayWithSchema( map_src_array->null_count(), map_src_array->offset()); } case arrow::Type::type::STRUCT: { - auto struct_src_array = - arrow::internal::checked_pointer_cast(src_array); - auto struct_target_type = - arrow::internal::checked_pointer_cast(target_type); - if (!struct_target_type) { + auto struct_src_array = checked_pointer_cast(src_array); + if (target_type->id() != arrow::Type::STRUCT) { return Status::Invalid( "Complete non exist field failed, target type cannot cast to a struct data " "type"); } + auto struct_target_type = checked_pointer_cast(target_type); std::vector field_names; arrow::ArrayVector converted_array; field_names.reserve(target_type->num_fields()); @@ -156,8 +154,7 @@ Result> ManifestMetaReader::AlignArrayWithSchema( if (src_kind != target_type->id()) { arrow::compute::CastOptions cast_options; cast_options.allow_int_overflow = false; - auto int32_array = - arrow::internal::checked_pointer_cast(src_array); + auto int32_array = checked_pointer_cast(src_array); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW( std::shared_ptr result, arrow::compute::Cast(*int32_array, target_type, cast_options)); diff --git a/src/paimon/core/utils/nested_projection_utils.cpp b/src/paimon/core/utils/nested_projection_utils.cpp index 3826ae81..c786936b 100644 --- a/src/paimon/core/utils/nested_projection_utils.cpp +++ b/src/paimon/core/utils/nested_projection_utils.cpp @@ -35,6 +35,7 @@ #include "fmt/format.h" #include "paimon/common/data/variant/variant_access_utils.h" #include "paimon/common/data/variant/variant_type_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/string_utils.h" #include "paimon/core/casting/casting_utils.h" #include "paimon/status.h" @@ -100,8 +101,8 @@ Result NestedProjectionUtils::HasNestedSubfieldProjectionType( "type is {} and read type is {}", file_type->ToString(), read_type->ToString())); } - auto file_struct = std::static_pointer_cast(file_type); - auto read_struct = std::static_pointer_cast(read_type); + auto file_struct = checked_pointer_cast(file_type); + auto read_struct = checked_pointer_cast(read_type); bool field_count_diff = read_struct->num_fields() != file_struct->num_fields(); for (const auto& read_child : read_struct->fields()) { auto file_child = FindFieldByName(file_struct->fields(), read_child->name()); @@ -127,8 +128,8 @@ Result NestedProjectionUtils::HasNestedSubfieldProjectionType( "type is {} and read type is {}", file_type->ToString(), read_type->ToString())); } - auto file_list = std::static_pointer_cast(file_type); - auto read_list = std::static_pointer_cast(read_type); + auto file_list = checked_pointer_cast(file_type); + auto read_list = checked_pointer_cast(read_type); return HasNestedSubfieldProjectionType(file_list->value_type(), read_list->value_type()); } @@ -139,8 +140,8 @@ Result NestedProjectionUtils::HasNestedSubfieldProjectionType( "type is {} and read type is {}", file_type->ToString(), read_type->ToString())); } - auto file_map = std::static_pointer_cast(file_type); - auto read_map = std::static_pointer_cast(read_type); + auto file_map = checked_pointer_cast(file_type); + auto read_map = checked_pointer_cast(read_type); PAIMON_ASSIGN_OR_RAISE( bool key_has_nested_projection, HasNestedSubfieldProjectionType(file_map->key_type(), read_map->key_type())); @@ -292,15 +293,15 @@ Result> PruneRepeatedItemType( return arrow::list(data_type->field(0)->WithType(item)); } case arrow::Type::MAP: { - auto read_map = std::static_pointer_cast(read_type); - auto data_map = std::static_pointer_cast(data_type); + auto read_map = checked_pointer_cast(read_type); + auto data_map = checked_pointer_cast(data_type); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr key, PruneRepeatedItemType(read_map->key_type(), data_map->key_type(), container)); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr item, PruneRepeatedItemType(read_map->item_type(), data_map->item_type(), container)); - return std::static_pointer_cast(std::make_shared( + return checked_pointer_cast(std::make_shared( data_map->key_field()->WithType(key), data_map->item_field()->WithType(item), data_map->keys_sorted())); } @@ -379,8 +380,8 @@ Result>> NestedProjectionUtils::P if (map_substitution) { return std::optional>(read_type); } - auto read_map = std::static_pointer_cast(read_type); - auto data_map = std::static_pointer_cast(data_type); + auto read_map = checked_pointer_cast(read_type); + auto data_map = checked_pointer_cast(data_type); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr key, PruneRepeatedItemType(read_map->key_type(), data_map->key_type(), "map")); @@ -460,7 +461,7 @@ Result> NestedProjectionUtils::ValidateMapSharedShreddi return Status::Invalid( fmt::format("selected-key MAP field {} is not a STRUCT", field->name())); } - auto struct_type = arrow::internal::checked_pointer_cast(field->type()); + auto struct_type = checked_pointer_cast(field->type()); PAIMON_ASSIGN_OR_RAISE(std::vector selected_keys, GetMapSelectedKeys(field)); if (struct_type->num_fields() == 0 || selected_keys.size() != static_cast(struct_type->num_fields())) { @@ -493,8 +494,8 @@ NestedProjectionUtils::BuildMapSharedShreddingAccessDataType( read_field->name(), data_type->ToString())); } PAIMON_RETURN_NOT_OK(ValidateMapSharedShreddingAccessField(read_field).status()); - auto read_struct = arrow::internal::checked_pointer_cast(read_field->type()); - auto data_map = arrow::internal::checked_pointer_cast(data_type); + auto read_struct = checked_pointer_cast(read_field->type()); + auto data_map = checked_pointer_cast(data_type); arrow::FieldVector data_children; data_children.reserve(read_struct->num_fields()); for (const auto& read_child : read_struct->fields()) { @@ -510,12 +511,10 @@ Result NestedProjectionUtils::GetMapKeyViewAt( std::to_string(entry_idx)); } if (key_array->type_id() == arrow::Type::STRING) { - return arrow::internal::checked_pointer_cast(key_array)->GetView( - entry_idx); + return checked_pointer_cast(key_array)->GetView(entry_idx); } if (key_array->type_id() == arrow::Type::DICTIONARY) { - auto dict_type = - arrow::internal::checked_pointer_cast(key_array->type()); + auto dict_type = checked_pointer_cast(key_array->type()); if (dict_type->value_type()->id() != arrow::Type::STRING && dict_type->value_type()->id() != arrow::Type::LARGE_STRING) { return Status::Invalid( @@ -523,7 +522,7 @@ Result NestedProjectionUtils::GetMapKeyViewAt( "dictionary keys, got {}", key_array->type()->ToString())); } - auto dict_keys = arrow::internal::checked_pointer_cast(key_array); + auto dict_keys = checked_pointer_cast(key_array); int64_t dict_idx = dict_keys->GetValueIndex(entry_idx); const auto& dictionary = dict_keys->dictionary(); if (dictionary->IsNull(dict_idx)) { @@ -532,11 +531,9 @@ Result NestedProjectionUtils::GetMapKeyViewAt( std::to_string(dict_idx)); } if (dict_type->value_type()->id() == arrow::Type::STRING) { - return arrow::internal::checked_pointer_cast(dictionary) - ->GetView(dict_idx); + return checked_pointer_cast(dictionary)->GetView(dict_idx); } - return arrow::internal::checked_pointer_cast(dictionary) - ->GetView(dict_idx); + return checked_pointer_cast(dictionary)->GetView(dict_idx); } return Status::Invalid( fmt::format("selected-key MAP read only supports string keys or " @@ -559,9 +556,8 @@ Result> NestedProjectionUtils::FilterMapArrayBySel "FilterMapArrayBySelectedKeys requires map array, got {}", array->type()->ToString())); } - auto map_array = arrow::internal::checked_pointer_cast(array); - auto map_type = arrow::internal::checked_pointer_cast(array->type()); - assert(map_array && map_type); + auto map_array = checked_pointer_cast(array); + auto map_type = checked_pointer_cast(array->type()); auto key_array = map_array->keys(); @@ -582,7 +578,7 @@ Result> NestedProjectionUtils::FilterMapArrayBySel PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::unique_ptr value_builder_u, arrow::MakeBuilder(values_array->type(), pool)); arrow::MapBuilder map_builder(pool, std::move(key_builder_u), std::move(value_builder_u)); - auto* key_builder = static_cast(map_builder.key_builder()); + auto* key_builder = checked_cast(map_builder.key_builder()); auto* value_builder = map_builder.item_builder(); PAIMON_RETURN_NOT_OK_FROM_ARROW(map_builder.Reserve(num_maps)); @@ -625,7 +621,7 @@ std::shared_ptr NormalizeLeafRepresentation( const std::shared_ptr& type) { auto t = type; if (t->id() == arrow::Type::DICTIONARY) { - t = std::static_pointer_cast(t)->value_type(); + t = checked_pointer_cast(t)->value_type(); } if (t->id() == arrow::Type::LARGE_STRING) { return arrow::utf8(); @@ -695,7 +691,7 @@ Result> NestedProjectionUtils::AlignArrayToReadTyp array->type()->ToString(), read_type->ToString())); } - auto read_list = std::static_pointer_cast(read_type); + auto read_list = checked_pointer_cast(read_type); auto values = arrow::MakeArray(data->child_data[0]); PAIMON_ASSIGN_OR_RAISE(values, AlignArrayToReadType(values, read_list->value_type(), pool)); @@ -710,7 +706,7 @@ Result> NestedProjectionUtils::AlignArrayToReadTyp array->type()->ToString(), read_type->ToString())); } - auto read_map = std::static_pointer_cast(read_type); + auto read_map = checked_pointer_cast(read_type); const auto& entries_data = data->child_data[0]; auto key = arrow::MakeArray(entries_data->child_data[0]); auto value = arrow::MakeArray(entries_data->child_data[1]); diff --git a/src/paimon/core/utils/nested_projection_utils_test.cpp b/src/paimon/core/utils/nested_projection_utils_test.cpp index 570a5321..153d90e1 100644 --- a/src/paimon/core/utils/nested_projection_utils_test.cpp +++ b/src/paimon/core/utils/nested_projection_utils_test.cpp @@ -32,6 +32,7 @@ #include "paimon/common/data/variant/variant_access_utils.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/testing/utils/testharness.h" namespace paimon::test { @@ -301,12 +302,12 @@ TEST(NestedProjectionUtilsTest, AlignArrayToReadTypeNullFillsAddedListStructFiel ASSERT_OK_AND_ASSIGN(std::shared_ptr aligned, NestedProjectionUtils::AlignArrayToReadType(list_arr, read_type, pool)); ASSERT_TRUE(aligned->type()->Equals(*read_type)) << aligned->type()->ToString(); - auto out_struct = std::static_pointer_cast( - std::static_pointer_cast(aligned)->values()); + auto out_struct = checked_pointer_cast( + checked_pointer_cast(aligned)->values()); auto c_col = out_struct->GetFieldByName("c"); ASSERT_NE(c_col, nullptr); ASSERT_EQ(c_col->null_count(), c_col->length()); // added field is all null - auto a_col = std::static_pointer_cast(out_struct->GetFieldByName("a")); + auto a_col = checked_pointer_cast(out_struct->GetFieldByName("a")); ASSERT_EQ(a_col->Value(0), 1); ASSERT_EQ(a_col->Value(2), 3); } @@ -325,8 +326,8 @@ TEST(NestedProjectionUtilsTest, AlignArrayToReadTypeDecodesDictionaryLeafAndNull ASSERT_OK_AND_ASSIGN(std::shared_ptr aligned, NestedProjectionUtils::AlignArrayToReadType(struct_arr, read_type, pool)); ASSERT_TRUE(aligned->type()->Equals(*read_type)) << aligned->type()->ToString(); - auto out = std::static_pointer_cast(aligned); - ASSERT_EQ(std::static_pointer_cast(out->GetFieldByName("a"))->GetString(0), + auto out = checked_pointer_cast(aligned); + ASSERT_EQ(checked_pointer_cast(out->GetFieldByName("a"))->GetString(0), "x"); auto b = out->GetFieldByName("b"); ASSERT_EQ(b->null_count(), b->length()); @@ -361,7 +362,7 @@ TEST(NestedProjectionUtilsTest, AlignArrayToReadTypeFieldIdChangeNullFillsNotLea ASSERT_OK_AND_ASSIGN(std::shared_ptr aligned, NestedProjectionUtils::AlignArrayToReadType(struct_arr, read_type, pool)); - auto a_out = std::static_pointer_cast(aligned)->GetFieldByName("a"); + auto a_out = checked_pointer_cast(aligned)->GetFieldByName("a"); ASSERT_NE(a_out, nullptr); ASSERT_EQ(a_out->null_count(), a_out->length()); } @@ -393,7 +394,7 @@ TEST(NestedProjectionUtilsTest, AlignArrayToReadTypeKeepsNestedLargeBinaryBlob) ASSERT_OK_AND_ASSIGN(std::shared_ptr aligned, NestedProjectionUtils::AlignArrayToReadType(struct_arr, read_type, pool)); - auto blob_out = std::static_pointer_cast(aligned)->GetFieldByName("blob"); + auto blob_out = checked_pointer_cast(aligned)->GetFieldByName("blob"); ASSERT_EQ(blob_out->type_id(), arrow::Type::LARGE_BINARY); ASSERT_TRUE(blob_out->Equals(*blob)); } @@ -575,7 +576,7 @@ TEST(NestedProjectionUtilsTest, BuildMapSharedShreddingAccessDataType) { ASSERT_OK_AND_ASSIGN( std::shared_ptr result, NestedProjectionUtils::BuildMapSharedShreddingAccessDataType(read_field, data_type)); - auto result_struct = arrow::internal::checked_pointer_cast(result); + auto result_struct = checked_pointer_cast(result); ASSERT_EQ(result_struct->num_fields(), 2); ASSERT_EQ(result_struct->field(0)->name(), "a"); ASSERT_EQ(result_struct->field(1)->name(), "b"); @@ -729,8 +730,8 @@ TEST_F(NestedProjectionUtilsMapArrayTest, FilterMapArrayBySelectedKeysDictionary {{"a", 1}, {"b", 2}, {"c", 3}}, {{"c", 30}, {"a", 10}}, }); - auto map = std::static_pointer_cast(map_array); - auto string_keys = std::static_pointer_cast(map->keys()); + auto map = checked_pointer_cast(map_array); + auto string_keys = checked_pointer_cast(map->keys()); arrow::StringDictionaryBuilder dict_builder(arrow::default_memory_pool()); for (int64_t i = 0; i < string_keys->length(); ++i) { @@ -759,7 +760,7 @@ TEST_F(NestedProjectionUtilsMapArrayTest, FilterMapArrayBySelectedKeysDictionary TEST_F(NestedProjectionUtilsMapArrayTest, FilterMapArrayBySelectedKeysDictionaryLargeStringKey) { auto map_array = BuildStringInt32MapArray({{{"a", 1}, {"b", 2}}}); - auto map = std::static_pointer_cast(map_array); + auto map = checked_pointer_cast(map_array); arrow::LargeStringBuilder dict_value_builder(arrow::default_memory_pool()); ASSERT_TRUE(dict_value_builder.Append("a").ok()); diff --git a/src/paimon/core/utils/objects_file.h b/src/paimon/core/utils/objects_file.h index 1e334704..f8509fe2 100644 --- a/src/paimon/core/utils/objects_file.h +++ b/src/paimon/core/utils/objects_file.h @@ -32,6 +32,7 @@ #include "paimon/common/data/columnar/columnar_row.h" #include "paimon/common/utils/arrow/arrow_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/core/io/meta_to_arrow_array_converter.h" @@ -167,10 +168,10 @@ Status ObjectsFile::Read(const std::string& file_name, } PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr typed_array, arrow::ImportArray(c_array.get(), c_schema.get())); - auto* struct_array = dynamic_cast(typed_array.get()); - if (!struct_array) { + if (!typed_array || typed_array->type_id() != arrow::Type::STRUCT) { return Status::Invalid(fmt::format("file {}, cannot cast to struct array", file_name)); } + auto* struct_array = checked_cast(typed_array.get()); result->reserve(struct_array->length()); for (int64_t i = 0; i < struct_array->length(); i++) { ColumnarRow row(struct_array->fields(), pool_, i); diff --git a/src/paimon/core/utils/versioned_object_serializer.h b/src/paimon/core/utils/versioned_object_serializer.h index 92e57b84..1aff6b1a 100644 --- a/src/paimon/core/utils/versioned_object_serializer.h +++ b/src/paimon/core/utils/versioned_object_serializer.h @@ -20,6 +20,7 @@ #include +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/utils/object_serializer.h" #include "paimon/core/utils/offset_row.h" @@ -33,11 +34,11 @@ class PAIMON_EXPORT VersionedObjectSerializer : public ObjectSerializer { static std::shared_ptr VersionType( const std::shared_ptr& data_type) { - auto struct_type = arrow::internal::checked_pointer_cast(data_type); - if (!struct_type) { + if (!data_type || data_type->id() != arrow::Type::STRUCT) { assert(false); return nullptr; } + auto struct_type = checked_pointer_cast(data_type); return struct_type ->AddField(0, arrow::field("_VERSION", arrow::int32(), /*nullable=*/false)) .ValueOr(nullptr); diff --git a/src/paimon/format/avro/avro_direct_decoder.cpp b/src/paimon/format/avro/avro_direct_decoder.cpp index dbc1252a..f837eed0 100644 --- a/src/paimon/format/avro/avro_direct_decoder.cpp +++ b/src/paimon/format/avro/avro_direct_decoder.cpp @@ -23,11 +23,11 @@ #include "paimon/format/avro/avro_direct_decoder.h" #include "arrow/api.h" -#include "arrow/util/checked_cast.h" #include "avro/Decoder.hh" #include "avro/Node.hh" #include "avro/Types.hh" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/format/avro/avro_utils.h" @@ -138,7 +138,7 @@ Status DecodeStructToBuilder(const ::avro::NodePtr& avro_node, fmt::format("Expected Avro record, got type: {}", AvroUtils::ToString(avro_node))); } - auto* struct_builder = arrow::internal::checked_cast(array_builder); + auto* struct_builder = checked_cast(array_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder->Append()); size_t skipped_fields = 0; @@ -168,7 +168,7 @@ Status DecodeListToBuilder(const ::avro::NodePtr& avro_node, ::avro::Decoder* de fmt::format("Expected Avro array, got type: {}", AvroUtils::ToString(avro_node))); } - auto* list_builder = arrow::internal::checked_cast(array_builder); + auto* list_builder = checked_cast(array_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(list_builder->Append()); auto* value_builder = list_builder->value_builder(); @@ -191,7 +191,7 @@ Status DecodeListToBuilder(const ::avro::NodePtr& avro_node, ::avro::Decoder* de Status DecodeMapToBuilder(const ::avro::NodePtr& avro_node, ::avro::Decoder* decoder, arrow::ArrayBuilder* array_builder, AvroDirectDecoder::DecodeContext* ctx) { - auto* map_builder = arrow::internal::checked_cast(array_builder); + auto* map_builder = checked_cast(array_builder); if (avro_node->type() == ::avro::AVRO_MAP) { // Handle regular Avro map: map @@ -258,7 +258,7 @@ Status DecodeAvroValueToBuilder(const ::avro::NodePtr& avro_node, switch (type) { case ::avro::AVRO_BOOL: { - auto* builder = arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); bool value = decoder->decodeBool(); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(value)); return Status::OK(); @@ -269,20 +269,17 @@ Status DecodeAvroValueToBuilder(const ::avro::NodePtr& avro_node, auto arrow_type = array_builder->type(); switch (arrow_type->id()) { case arrow::Type::INT8: { - auto* builder = - arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(value)); return Status::OK(); } case arrow::Type::INT16: { - auto* builder = - arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(value)); return Status::OK(); } case arrow::Type::INT32: { - auto* builder = - arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(value)); return Status::OK(); } @@ -292,8 +289,7 @@ Status DecodeAvroValueToBuilder(const ::avro::NodePtr& avro_node, fmt::format("Unexpected avro type [{}] with arrow type [{}].", ::avro::toString(type), arrow_type->ToString())); } - auto* builder = - arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(value)); return Status::OK(); } @@ -308,8 +304,7 @@ Status DecodeAvroValueToBuilder(const ::avro::NodePtr& avro_node, int64_t value = decoder->decodeLong(); switch (logical_type.type()) { case ::avro::LogicalType::Type::NONE: { - auto* builder = - arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(value)); return Status::OK(); } @@ -319,10 +314,8 @@ Status DecodeAvroValueToBuilder(const ::avro::NodePtr& avro_node, case ::avro::LogicalType::Type::LOCAL_TIMESTAMP_MILLIS: case ::avro::LogicalType::Type::LOCAL_TIMESTAMP_MICROS: case ::avro::LogicalType::Type::LOCAL_TIMESTAMP_NANOS: { - auto* builder = - arrow::internal::checked_cast(array_builder); - auto ts_type = - arrow::internal::checked_cast(builder->type().get()); + auto* builder = checked_cast(array_builder); + auto ts_type = checked_cast(builder->type().get()); // for arrow second, we need to convert it from avro millisecond if (ts_type->unit() == arrow::TimeUnit::type::SECOND) { value /= DateTimeUtils::CONVERSION_FACTORS[DateTimeUtils::MILLISECOND]; @@ -338,19 +331,19 @@ Status DecodeAvroValueToBuilder(const ::avro::NodePtr& avro_node, } case ::avro::AVRO_FLOAT: { - auto* builder = arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); float value = decoder->decodeFloat(); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(value)); return Status::OK(); } case ::avro::AVRO_DOUBLE: { - auto* builder = arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); double value = decoder->decodeDouble(); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(value)); return Status::OK(); } case ::avro::AVRO_STRING: { - auto* builder = arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); decoder->decodeString(ctx->string_scratch); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(ctx->string_scratch)); return Status::OK(); @@ -360,16 +353,14 @@ Status DecodeAvroValueToBuilder(const ::avro::NodePtr& avro_node, decoder->decodeBytes(ctx->bytes_scratch); switch (logical_type.type()) { case ::avro::LogicalType::Type::NONE: { - auto* builder = - arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); PAIMON_RETURN_NOT_OK_FROM_ARROW( builder->Append(ctx->bytes_scratch.data(), static_cast(ctx->bytes_scratch.size()))); return Status::OK(); } case ::avro::LogicalType::Type::DECIMAL: { - auto* builder = - arrow::internal::checked_cast(array_builder); + auto* builder = checked_cast(array_builder); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW( arrow::Decimal128 decimal, arrow::Decimal128::FromBigEndian(ctx->bytes_scratch.data(), diff --git a/src/paimon/format/avro/avro_direct_encoder.cpp b/src/paimon/format/avro/avro_direct_encoder.cpp index b371c27f..46556213 100644 --- a/src/paimon/format/avro/avro_direct_encoder.cpp +++ b/src/paimon/format/avro/avro_direct_encoder.cpp @@ -27,8 +27,8 @@ #include "arrow/api.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/format/avro/avro_utils.h" #include "paimon/result.h" @@ -94,8 +94,7 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, switch (avro_node->type()) { case ::avro::AVRO_BOOL: { - const auto& bool_array = - arrow::internal::checked_cast(array); + const auto& bool_array = checked_cast(array); encoder->encodeBool(bool_array.Value(row_index)); return Status::OK(); } @@ -104,27 +103,23 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, // AVRO_INT can represent: int8, int16, int32, date (days since epoch) switch (array.type()->id()) { case arrow::Type::INT8: { - const auto& int8_array = - arrow::internal::checked_cast(array); + const auto& int8_array = checked_cast(array); encoder->encodeInt(int8_array.Value(row_index)); return Status::OK(); } case arrow::Type::INT16: { - const auto& int16_array = - arrow::internal::checked_cast(array); + const auto& int16_array = checked_cast(array); encoder->encodeInt(int16_array.Value(row_index)); return Status::OK(); } case arrow::Type::INT32: { - const auto& int32_array = - arrow::internal::checked_cast(array); + const auto& int32_array = checked_cast(array); encoder->encodeInt(int32_array.Value(row_index)); return Status::OK(); } case arrow::Type::DATE32: { - const auto& date_array = - arrow::internal::checked_cast(array); + const auto& date_array = checked_cast(array); encoder->encodeInt(date_array.Value(row_index)); return Status::OK(); } @@ -140,18 +135,15 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, // AVRO_LONG can represent: int64, timestamp switch (array.type()->id()) { case arrow::Type::INT64: { - const auto& int64_array = - arrow::internal::checked_cast(array); + const auto& int64_array = checked_cast(array); encoder->encodeLong(int64_array.Value(row_index)); return Status::OK(); } case arrow::Type::TIMESTAMP: { - const auto& timestamp_array = - arrow::internal::checked_cast(array); + const auto& timestamp_array = checked_cast(array); int64_t timestamp = timestamp_array.Value(row_index); - auto ts_type = - arrow::internal::checked_pointer_cast(array.type()); + auto ts_type = checked_pointer_cast(array.type()); arrow::TimeUnit::type unit = ts_type->unit(); const auto& logical_type = avro_node->logicalType().type(); @@ -190,22 +182,19 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, } case ::avro::AVRO_FLOAT: { - const auto& float_array = - arrow::internal::checked_cast(array); + const auto& float_array = checked_cast(array); encoder->encodeFloat(float_array.Value(row_index)); return Status::OK(); } case ::avro::AVRO_DOUBLE: { - const auto& double_array = - arrow::internal::checked_cast(array); + const auto& double_array = checked_cast(array); encoder->encodeDouble(double_array.Value(row_index)); return Status::OK(); } case ::avro::AVRO_STRING: { - const auto& string_array = - arrow::internal::checked_cast(array); + const auto& string_array = checked_cast(array); std::string_view value = string_array.GetView(row_index); encoder->encodeString(std::string(value)); return Status::OK(); @@ -214,8 +203,7 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, case ::avro::AVRO_BYTES: { // Handle DECIMAL if (avro_node->logicalType().type() == ::avro::LogicalType::DECIMAL) { - const auto& decimal_array = - arrow::internal::checked_cast(array); + const auto& decimal_array = checked_cast(array); std::string_view decimal_value = decimal_array.GetView(row_index); ctx->assign(decimal_value.begin(), decimal_value.end()); // Arrow Decimal128 bytes are in little-endian order, Avro requires big-endian @@ -227,13 +215,12 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, // Handle regular BYTES (binary or large_binary) if (array.type()->id() == arrow::Type::LARGE_BINARY) { const auto& large_binary_array = - arrow::internal::checked_cast(array); + checked_cast(array); std::string_view value = large_binary_array.GetView(row_index); encoder->encodeBytes(reinterpret_cast(value.data()), value.size()); return Status::OK(); } - const auto& binary_array = - arrow::internal::checked_cast(array); + const auto& binary_array = checked_cast(array); std::string_view value = binary_array.GetView(row_index); encoder->encodeBytes(reinterpret_cast(value.data()), value.size()); return Status::OK(); @@ -245,8 +232,7 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, array.type()->ToString())); } - const auto& struct_array = - arrow::internal::checked_cast(array); + const auto& struct_array = checked_cast(array); const size_t num_fields = avro_node->leaves(); if (PAIMON_UNLIKELY(struct_array.num_fields() != static_cast(num_fields))) { @@ -270,8 +256,7 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, // Handle ListArray if (array.type()->id() == arrow::Type::LIST) { - const auto& list_array = - arrow::internal::checked_cast(array); + const auto& list_array = checked_cast(array); const auto start = list_array.value_offset(row_index); const auto end = list_array.value_offset(row_index + 1); @@ -300,8 +285,7 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, AvroUtils::ToString(element_node))); } - const auto& map_array = - arrow::internal::checked_cast(array); + const auto& map_array = checked_cast(array); const auto start = map_array.value_offset(row_index); const auto end = map_array.value_offset(row_index + 1); @@ -337,7 +321,7 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, return Status::Invalid( fmt::format("AVRO_MAP expects MapArray, got {}", array.type()->ToString())); } - const auto& map_array = arrow::internal::checked_cast(array); + const auto& map_array = checked_cast(array); const auto start = map_array.value_offset(row_index); const auto end = map_array.value_offset(row_index + 1); @@ -354,8 +338,7 @@ Status AvroDirectEncoder::EncodeArrowToAvro(const ::avro::NodePtr& avro_node, return Status::Invalid(fmt::format("AVRO_MAP keys must be StringArray, got {}", keys->type()->ToString())); } - const auto& string_array = - arrow::internal::checked_cast(*keys); + const auto& string_array = checked_cast(*keys); for (int64_t i = start; i < end; ++i) { encoder->startItem(); diff --git a/src/paimon/format/avro/avro_direct_encoder_decoder_test.cpp b/src/paimon/format/avro/avro_direct_encoder_decoder_test.cpp index bb5bd3c5..f276d946 100644 --- a/src/paimon/format/avro/avro_direct_encoder_decoder_test.cpp +++ b/src/paimon/format/avro/avro_direct_encoder_decoder_test.cpp @@ -28,6 +28,7 @@ #include "avro/ValidSchema.hh" #include "gtest/gtest.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/format/avro/avro_direct_decoder.h" #include "paimon/format/avro/avro_direct_encoder.h" #include "paimon/format/avro/avro_schema_converter.h" @@ -316,9 +317,9 @@ TEST_F(AvroDirectEncoderDecoderTest, TestRecordType) { {std::make_shared(), std::make_shared(), std::make_shared()}); - auto int_builder = static_cast(struct_builder.field_builder(0)); - auto string_builder = static_cast(struct_builder.field_builder(1)); - auto bool_builder = static_cast(struct_builder.field_builder(2)); + auto int_builder = checked_cast(struct_builder.field_builder(0)); + auto string_builder = checked_cast(struct_builder.field_builder(1)); + auto bool_builder = checked_cast(struct_builder.field_builder(2)); // Add first record ASSERT_TRUE(struct_builder.Append().ok()); @@ -416,7 +417,7 @@ TEST_F(AvroDirectEncoderDecoderTest, TestArrayType) { // Create list array arrow::ListBuilder list_builder(arrow::default_memory_pool(), std::make_shared()); - auto int_builder = static_cast(list_builder.value_builder()); + auto int_builder = checked_cast(list_builder.value_builder()); // First list: [1, 2, 3] ASSERT_TRUE(list_builder.Append().ok()); @@ -446,8 +447,8 @@ TEST_F(AvroDirectEncoderDecoderTest, TestMapType) { arrow::MapBuilder map_builder(arrow::default_memory_pool(), std::make_shared(), std::make_shared()); - auto key_builder = static_cast(map_builder.key_builder()); - auto value_builder = static_cast(map_builder.item_builder()); + auto key_builder = checked_cast(map_builder.key_builder()); + auto value_builder = checked_cast(map_builder.item_builder()); // First map: {"key1": "value1", "key2": "value2"} ASSERT_TRUE(map_builder.Append().ok()); @@ -490,8 +491,8 @@ TEST_F(AvroDirectEncoderDecoderTest, TestArrayBasedMapType) { arrow::MapBuilder map_builder(arrow::default_memory_pool(), std::make_shared(), std::make_shared()); - auto key_builder = static_cast(map_builder.key_builder()); - auto value_builder = static_cast(map_builder.item_builder()); + auto key_builder = checked_cast(map_builder.key_builder()); + auto value_builder = checked_cast(map_builder.item_builder()); // First map: {111: "value1", 222: "value2"} ASSERT_TRUE(map_builder.Append().ok()); @@ -619,8 +620,8 @@ TEST_F(AvroDirectEncoderDecoderTest, TestInvalidMapType) { arrow::MapBuilder map_builder(arrow::default_memory_pool(), std::make_shared(), std::make_shared()); - auto key_builder = static_cast(map_builder.key_builder()); - auto value_builder = static_cast(map_builder.item_builder()); + auto key_builder = checked_cast(map_builder.key_builder()); + auto value_builder = checked_cast(map_builder.item_builder()); ASSERT_TRUE(map_builder.Append().ok()); ASSERT_TRUE(key_builder->Append(1).ok()); ASSERT_TRUE(value_builder->Append("value1").ok()); diff --git a/src/paimon/format/avro/avro_format_writer_test.cpp b/src/paimon/format/avro/avro_format_writer_test.cpp index 965c1832..1e6e84e1 100644 --- a/src/paimon/format/avro/avro_format_writer_test.cpp +++ b/src/paimon/format/avro/avro_format_writer_test.cpp @@ -30,6 +30,7 @@ #include "arrow/memory_pool.h" #include "gtest/gtest.h" #include "paimon/common/utils/arrow/mem_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/format/avro/avro_file_batch_reader.h" #include "paimon/format/file_format.h" @@ -86,9 +87,9 @@ class AvroFormatWriterTest : public ::testing::Test { data_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto int_builder = static_cast(struct_builder.field_builder(1)); - auto bool_builder = static_cast(struct_builder.field_builder(2)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(1)); + auto bool_builder = checked_cast(struct_builder.field_builder(2)); for (int32_t i = 0 + offset; i < record_batch_size + offset; ++i) { EXPECT_TRUE(struct_builder.Append().ok()); EXPECT_TRUE(string_builder->Append("str_" + std::to_string(i)).ok()); @@ -126,15 +127,12 @@ class AvroFormatWriterTest : public ::testing::Test { ASSERT_OK_AND_ASSIGN(auto result_array, ::paimon::test::ReadResultCollector::CollectResult(file_reader.get())); - const auto& struct_array = - std::static_pointer_cast(result_array->chunk(0)); - const auto& string_array = - std::static_pointer_cast(struct_array->field(0)); + const auto& struct_array = checked_pointer_cast(result_array->chunk(0)); + const auto& string_array = checked_pointer_cast(struct_array->field(0)); ASSERT_TRUE(string_array); - const auto& int_array = std::static_pointer_cast(struct_array->field(1)); + const auto& int_array = checked_pointer_cast(struct_array->field(1)); ASSERT_TRUE(int_array); - const auto& bool_array = - std::static_pointer_cast(struct_array->field(2)); + const auto& bool_array = checked_pointer_cast(struct_array->field(2)); ASSERT_TRUE(bool_array); ASSERT_EQ(string_array->null_count(), 0); ASSERT_EQ(int_array->null_count(), (row_count - 1) / 3 + 1); diff --git a/src/paimon/format/avro/avro_schema_converter.cpp b/src/paimon/format/avro/avro_schema_converter.cpp index bfdbe5e0..3d6550bf 100644 --- a/src/paimon/format/avro/avro_schema_converter.cpp +++ b/src/paimon/format/avro/avro_schema_converter.cpp @@ -23,7 +23,6 @@ #include #include -#include "arrow/util/checked_cast.h" #include "avro/CustomAttributes.hh" #include "avro/LogicalType.hh" #include "avro/Node.hh" @@ -32,6 +31,7 @@ #include "avro/ValidSchema.hh" #include "fmt/format.h" #include "paimon/common/data/variant/variant_type_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/format/avro/avro_file_format_factory.h" #include "paimon/format/avro/avro_utils.h" @@ -175,8 +175,7 @@ Result> AvroSchemaConverter::GetArrowType( if (logical_map_type->id() != arrow::Type::STRUCT) { return Status::TypeError("invalid avro logical map item type"); } - auto struct_type = - arrow::internal::checked_pointer_cast(logical_map_type); + auto struct_type = checked_pointer_cast(logical_map_type); const auto& fields = struct_type->fields(); if (fields.size() != 2) { return Status::TypeError("invalid avro logical map struct fields size"); @@ -280,7 +279,7 @@ Result<::avro::Schema> AvroSchemaConverter::ArrowTypeToAvroSchema( } case arrow::Type::type::TIMESTAMP: { const auto& arrow_timestamp_type = - arrow::internal::checked_pointer_cast(arrow_type); + checked_pointer_cast(arrow_type); bool has_timezone = !arrow_timestamp_type->timezone().empty(); ::avro::LongSchema timestamp_schema; switch (arrow_timestamp_type->unit()) { @@ -314,7 +313,7 @@ Result<::avro::Schema> AvroSchemaConverter::ArrowTypeToAvroSchema( } case arrow::Type::type::DECIMAL128: { const auto& arrow_decimal_type = - arrow::internal::checked_pointer_cast(arrow_type); + checked_pointer_cast(arrow_type); ::avro::BytesSchema decimal_schema; ::avro::LogicalType decimal_type = ::avro::LogicalType(::avro::LogicalType::DECIMAL); decimal_type.setPrecision(arrow_decimal_type->precision()); @@ -323,8 +322,7 @@ Result<::avro::Schema> AvroSchemaConverter::ArrowTypeToAvroSchema( return nullable ? NullableSchema(decimal_schema) : decimal_schema; } case arrow::Type::LIST: { - const auto& list_type = - arrow::internal::checked_pointer_cast(arrow_type); + const auto& list_type = checked_pointer_cast(arrow_type); const auto& value_field = list_type->value_field(); PAIMON_ASSIGN_OR_RAISE(::avro::Schema value_schema, ArrowTypeToAvroSchema(value_field, row_name)); @@ -332,8 +330,7 @@ Result<::avro::Schema> AvroSchemaConverter::ArrowTypeToAvroSchema( return nullable ? NullableSchema(array_schema) : array_schema; } case arrow::Type::STRUCT: { - const auto& struct_type = - arrow::internal::checked_pointer_cast(arrow_type); + const auto& struct_type = checked_pointer_cast(arrow_type); const auto& fields = struct_type->fields(); ::avro::RecordSchema record_schema(row_name); @@ -345,8 +342,7 @@ Result<::avro::Schema> AvroSchemaConverter::ArrowTypeToAvroSchema( return nullable ? NullableSchema(record_schema) : record_schema; } case arrow::Type::MAP: { - const auto& map_type = - arrow::internal::checked_pointer_cast(arrow_type); + const auto& map_type = checked_pointer_cast(arrow_type); const auto& key_field = map_type->key_field(); const auto& item_field = map_type->item_field(); if (key_field->nullable()) { diff --git a/src/paimon/format/avro/avro_stats_extractor.cpp b/src/paimon/format/avro/avro_stats_extractor.cpp index 3bfbcf95..5dfa82c0 100644 --- a/src/paimon/format/avro/avro_stats_extractor.cpp +++ b/src/paimon/format/avro/avro_stats_extractor.cpp @@ -25,8 +25,8 @@ #include "arrow/api.h" #include "arrow/c/abi.h" #include "arrow/c/bridge.h" -#include "arrow/util/checked_cast.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/core/core_options.h" #include "paimon/defs.h" @@ -102,14 +102,13 @@ Result> AvroStatsExtractor::FetchColumnStatistics( case arrow::Type::type::DATE32: return ColumnStats::CreateDateColumnStats(std::nullopt, std::nullopt, std::nullopt); case arrow::Type::type::TIMESTAMP: { - auto ts_type = arrow::internal::checked_pointer_cast<::arrow::TimestampType>(type); + auto ts_type = checked_pointer_cast<::arrow::TimestampType>(type); int32_t precision = DateTimeUtils::GetPrecisionFromType(ts_type); return ColumnStats::CreateTimestampColumnStats(std::nullopt, std::nullopt, std::nullopt, precision); } case arrow::Type::type::DECIMAL128: { - auto decimal_type = - arrow::internal::checked_pointer_cast<::arrow::Decimal128Type>(type); + auto decimal_type = checked_pointer_cast<::arrow::Decimal128Type>(type); int32_t precision = decimal_type->precision(); int32_t scale = decimal_type->scale(); return ColumnStats::CreateDecimalColumnStats(std::nullopt, std::nullopt, std::nullopt, diff --git a/src/paimon/format/blob/blob_file_batch_reader.cpp b/src/paimon/format/blob/blob_file_batch_reader.cpp index 3cd94ed0..d52ac8ea 100644 --- a/src/paimon/format/blob/blob_file_batch_reader.cpp +++ b/src/paimon/format/blob/blob_file_batch_reader.cpp @@ -33,6 +33,7 @@ #include "paimon/common/metrics/metrics_impl.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/delta_varint_compressor.h" #include "paimon/common/utils/stream_utils.h" #include "paimon/data/blob.h" @@ -261,14 +262,17 @@ Result> BlobFileBatchReader::BuildTargetArray( // For descriptor mode, build using StructBuilder to handle nulls properly PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::unique_ptr array_builder, arrow::MakeBuilder(target_type_, arrow_pool_.get())); - auto builder = dynamic_cast(array_builder.get()); - if (builder == nullptr) { + if (!array_builder || !array_builder->type() || + array_builder->type()->id() != arrow::Type::STRUCT) { return Status::Invalid("cast to struct builder failed"); } - auto field_builder = dynamic_cast(builder->field_builder(0)); - if (field_builder == nullptr) { + auto* builder = checked_cast(array_builder.get()); + auto* field_builder_base = builder->field_builder(0); + if (!field_builder_base || !field_builder_base->type() || + field_builder_base->type()->id() != arrow::Type::LARGE_BINARY) { return Status::Invalid("cast to large binary builder failed"); } + auto* field_builder = checked_cast(field_builder_base); for (int32_t k = 0; k < rows_to_read; ++k) { const size_t i = current_pos_ + k; PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append()); diff --git a/src/paimon/format/blob/blob_file_format_factory_test.cpp b/src/paimon/format/blob/blob_file_format_factory_test.cpp index a5807fd6..95505f1d 100644 --- a/src/paimon/format/blob/blob_file_format_factory_test.cpp +++ b/src/paimon/format/blob/blob_file_format_factory_test.cpp @@ -27,6 +27,7 @@ #include "gtest/gtest.h" #include "paimon/common/data/blob_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/data/blob.h" #include "paimon/defs.h" #include "paimon/format/file_format.h" @@ -69,7 +70,7 @@ TEST(BlobFileFormatFactoryTest, TestWriteNullOptionPropagation) { PAIMON_ASSIGN_OR_RAISE(std::unique_ptr writer_builder, format->CreateWriterBuilder(&c_schema, /*batch_size=*/1024)); // The blob writer builder is a SpecificFSWriterBuilder by construction. - static_cast(writer_builder.get())->WithFileSystem(fs); + checked_cast(writer_builder.get())->WithFileSystem(fs); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr out, fs->Create(dir->Str() + "/" + file_name, /*overwrite=*/true)); PAIMON_ASSIGN_OR_RAISE(std::unique_ptr writer, diff --git a/src/paimon/format/blob/blob_format_writer.cpp b/src/paimon/format/blob/blob_format_writer.cpp index c3666569..e02dfb60 100644 --- a/src/paimon/format/blob/blob_format_writer.cpp +++ b/src/paimon/format/blob/blob_format_writer.cpp @@ -30,6 +30,7 @@ #include "paimon/common/memory/memory_segment_utils.h" #include "paimon/common/metrics/metrics_impl.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/delta_varint_compressor.h" #include "paimon/data/blob.h" #include "paimon/fs/file_system.h" @@ -101,7 +102,7 @@ Status BlobFormatWriter::AddBatch(ArrowArray* batch) { arrow::ImportArray(batch, data_type_)); assert(arrow_array->num_fields() == 1); - auto struct_array = arrow::internal::checked_pointer_cast(arrow_array); + auto struct_array = checked_pointer_cast(arrow_array); auto child_array = struct_array->field(0); // Struct-level null is not supported (caller should not pass null struct rows) @@ -118,8 +119,7 @@ Status BlobFormatWriter::AddBatch(ArrowArray* batch) { return Status::Invalid("BlobFormatWriter only support large binary type."); } - const auto& blob_array = - arrow::internal::checked_cast(*child_array); + const auto& blob_array = checked_cast(*child_array); assert(blob_array.length() == 1); std::string_view blob_data = blob_array.GetView(0); // Only a data-evolution partial-update write interprets the sentinel, which marks a row diff --git a/src/paimon/format/blob/blob_format_writer_test.cpp b/src/paimon/format/blob/blob_format_writer_test.cpp index 16c9e2af..a813d66a 100644 --- a/src/paimon/format/blob/blob_format_writer_test.cpp +++ b/src/paimon/format/blob/blob_format_writer_test.cpp @@ -26,6 +26,7 @@ #include "gtest/gtest.h" #include "paimon/common/data/blob_descriptor.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/stream_utils.h" #include "paimon/data/blob.h" #include "paimon/format/blob/blob_file_batch_reader.h" @@ -160,7 +161,7 @@ class BlobFormatWriterTestBase : public ::testing::Test { arrow::StructBuilder struct_builder(struct_type_, arrow::default_memory_pool(), {std::make_shared()}); auto blob_builder = - static_cast(struct_builder.field_builder(0)); + checked_cast(struct_builder.field_builder(0)); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder.Append()); PAIMON_RETURN_NOT_OK_FROM_ARROW(blob_builder->Append(bytes.data(), bytes.size())); std::shared_ptr array; @@ -185,7 +186,7 @@ class BlobFormatWriterTestBase : public ::testing::Test { paimon::test::ReadResultCollector::CollectResult(reader.get())); PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr concat_array, arrow::Concatenate(chunked_array->chunks())); - return arrow::internal::checked_pointer_cast(concat_array); + return checked_pointer_cast(concat_array); } protected: @@ -212,7 +213,7 @@ class BlobFormatWriterTest : public BlobFormatWriterTestBase, arrow::StructBuilder struct_builder(struct_type_, arrow::default_memory_pool(), {std::make_shared()}); auto blob_builder = - static_cast(struct_builder.field_builder(0)); + checked_cast(struct_builder.field_builder(0)); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder.Append()); PAIMON_ASSIGN_OR_RAISE(PAIMON_UNIQUE_PTR blob_data, blob->ToData(file_system_, pool_)); @@ -278,7 +279,7 @@ TEST_P(BlobFormatWriterTest, TestSimple) { // check result if (blob_as_descriptor_) { auto concat_array = arrow::Concatenate(chunked_array->chunks()).ValueOrDie(); - auto struct_array = arrow::internal::checked_pointer_cast(concat_array); + auto struct_array = checked_pointer_cast(concat_array); ASSERT_TRUE(struct_array); ASSERT_OK_AND_ASSIGN(std::vector> result_blobs, paimon::test::TestHelper::ToBlobs(struct_array)); @@ -364,7 +365,7 @@ TEST_P(BlobFormatWriterTest, TestAddBatchWithInvalidBatchLength) { // Test batch with wrong length (not 1) arrow::StructBuilder struct_builder(struct_type_, arrow::default_memory_pool(), {std::make_shared()}); - auto blob_builder = static_cast(struct_builder.field_builder(0)); + auto blob_builder = checked_cast(struct_builder.field_builder(0)); // Add two rows instead of one ASSERT_OK_AND_ASSIGN(auto blob, Blob::FromPath(paimon::test::GetDataDir() + "/xxhash.data")); @@ -475,7 +476,7 @@ TEST_P(BlobFormatWriterTest, TestLargeBlob) { // check result if (blob_as_descriptor_) { auto concat_array = arrow::Concatenate(chunked_array->chunks()).ValueOrDie(); - auto struct_array = arrow::internal::checked_pointer_cast(concat_array); + auto struct_array = checked_pointer_cast(concat_array); ASSERT_TRUE(struct_array); ASSERT_OK_AND_ASSIGN(std::vector> result_blobs, paimon::test::TestHelper::ToBlobs(struct_array)); @@ -494,7 +495,7 @@ TEST_P(BlobFormatWriterTest, TestAddBatchWithNullValues) { // Write one row with child-level null blob arrow::StructBuilder struct_builder(struct_type_, arrow::default_memory_pool(), {std::make_shared()}); - auto blob_builder = static_cast(struct_builder.field_builder(0)); + auto blob_builder = checked_cast(struct_builder.field_builder(0)); ASSERT_TRUE(struct_builder.Append().ok()); ASSERT_TRUE(blob_builder->AppendNull().ok()); std::shared_ptr null_child_array; @@ -523,7 +524,7 @@ TEST_P(BlobFormatWriterTest, TestAddBatchWithNullValues) { paimon::test::ReadResultCollector::CollectResult(reader.get())); auto concat_array = arrow::Concatenate(chunked_array->chunks()).ValueOrDie(); - auto result_struct = arrow::internal::checked_pointer_cast(concat_array); + auto result_struct = checked_pointer_cast(concat_array); ASSERT_TRUE(result_struct); ASSERT_EQ(result_struct->length(), 1); ASSERT_TRUE(result_struct->field(0)->IsNull(0)); @@ -574,8 +575,7 @@ TEST_F(BlobFormatWriterWriteNullTest, TestWriteNullOnMissingFile) { ASSERT_EQ(result_struct->length(), 2); ASSERT_TRUE(result_struct->field(0)->IsNull(0)); ASSERT_FALSE(result_struct->field(0)->IsNull(1)); - auto binary_array = - arrow::internal::checked_pointer_cast(result_struct->field(0)); + auto binary_array = checked_pointer_cast(result_struct->field(0)); ASSERT_OK_AND_ASSIGN(auto expected_data, blob->ToData(file_system_, pool_)); ASSERT_EQ(binary_array->GetView(1), std::string_view(expected_data->data(), expected_data->size())); @@ -665,8 +665,7 @@ TEST_F(BlobFormatWriterWriteNullTest, TestWriteNullOnBothOptionsEnabled) { ASSERT_TRUE(result_struct->field(0)->IsNull(0)); ASSERT_TRUE(result_struct->field(0)->IsNull(1)); ASSERT_FALSE(result_struct->field(0)->IsNull(2)); - auto binary_array = - arrow::internal::checked_pointer_cast(result_struct->field(0)); + auto binary_array = checked_pointer_cast(result_struct->field(0)); ASSERT_OK_AND_ASSIGN(auto expected_data, blob->ToData(file_system_, pool_)); ASSERT_EQ(binary_array->GetView(2), std::string_view(expected_data->data(), expected_data->size())); @@ -872,8 +871,7 @@ TEST_F(BlobFormatWriterWriteNullTest, TestWriteNullOnExistsCheckFailure) { ASSERT_OK_AND_ASSIGN(std::shared_ptr result_struct, ReadBackAsData()); ASSERT_EQ(result_struct->length(), 1); ASSERT_FALSE(result_struct->field(0)->IsNull(0)); - auto binary_array = - arrow::internal::checked_pointer_cast(result_struct->field(0)); + auto binary_array = checked_pointer_cast(result_struct->field(0)); ASSERT_OK_AND_ASSIGN(auto expected_data, blob->ToData(file_system_, pool_)); ASSERT_EQ(binary_array->GetView(0), std::string_view(expected_data->data(), expected_data->size())); @@ -987,7 +985,7 @@ TEST_F(BlobFormatWriterPlaceholderTest, TestWritePlaceholderGoldenBytes) { arrow::StructBuilder struct_builder(struct_type_, arrow::default_memory_pool(), {std::make_shared()}); - auto blob_builder = static_cast(struct_builder.field_builder(0)); + auto blob_builder = checked_cast(struct_builder.field_builder(0)); ASSERT_TRUE(struct_builder.Append().ok()); ASSERT_TRUE(blob_builder->AppendNull().ok()); std::shared_ptr null_array; @@ -1068,10 +1066,9 @@ TEST_F(BlobFormatWriterPlaceholderTest, TestReadPlaceholderStrictAndAwareModes) ASSERT_OK_AND_ASSIGN(auto chunked_array, paimon::test::ReadResultCollector::CollectResult(reader.get())); auto concat_array = arrow::Concatenate(chunked_array->chunks()).ValueOrDie(); - auto struct_array = arrow::internal::checked_pointer_cast(concat_array); + auto struct_array = checked_pointer_cast(concat_array); ASSERT_EQ(struct_array->length(), 2); - auto binary_array = - arrow::internal::checked_pointer_cast(struct_array->field(0)); + auto binary_array = checked_pointer_cast(struct_array->field(0)); ASSERT_EQ(binary_array->GetString(0), "inline"); ASSERT_FALSE(binary_array->IsNull(1)); ASSERT_EQ(binary_array->GetString(1), PlaceholderSentinelBytes()); @@ -1093,9 +1090,8 @@ TEST_F(BlobFormatWriterPlaceholderTest, TestReadPlaceholderStrictAndAwareModes) ASSERT_OK_AND_ASSIGN(auto chunked_array, paimon::test::ReadResultCollector::CollectResult(reader.get())); auto concat_array = arrow::Concatenate(chunked_array->chunks()).ValueOrDie(); - auto struct_array = arrow::internal::checked_pointer_cast(concat_array); - auto binary_array = - arrow::internal::checked_pointer_cast(struct_array->field(0)); + auto struct_array = checked_pointer_cast(concat_array); + auto binary_array = checked_pointer_cast(struct_array->field(0)); ASSERT_EQ(binary_array->GetString(1), PlaceholderSentinelBytes()); } } @@ -1127,10 +1123,9 @@ TEST_F(BlobFormatWriterPlaceholderTest, TestReadPlaceholderWithSelectionBitmap) ASSERT_OK_AND_ASSIGN(auto chunked_array, paimon::test::ReadResultCollector::CollectResult(reader.get())); auto concat_array = arrow::Concatenate(chunked_array->chunks()).ValueOrDie(); - auto struct_array = arrow::internal::checked_pointer_cast(concat_array); + auto struct_array = checked_pointer_cast(concat_array); ASSERT_EQ(struct_array->length(), 2); - auto binary_array = - arrow::internal::checked_pointer_cast(struct_array->field(0)); + auto binary_array = checked_pointer_cast(struct_array->field(0)); ASSERT_EQ(binary_array->GetString(0), PlaceholderSentinelBytes()); ASSERT_EQ(binary_array->GetString(1), "third"); } @@ -1158,10 +1153,9 @@ TEST_F(BlobFormatWriterPlaceholderTest, TestSentinelBytesVerbatimWithoutPlacehol ASSERT_OK_AND_ASSIGN(auto chunked_array, paimon::test::ReadResultCollector::CollectResult(reader.get())); auto concat_array = arrow::Concatenate(chunked_array->chunks()).ValueOrDie(); - auto struct_array = arrow::internal::checked_pointer_cast(concat_array); + auto struct_array = checked_pointer_cast(concat_array); ASSERT_EQ(struct_array->length(), 1); - auto binary_array = - arrow::internal::checked_pointer_cast(struct_array->field(0)); + auto binary_array = checked_pointer_cast(struct_array->field(0)); ASSERT_FALSE(binary_array->IsNull(0)); ASSERT_EQ(binary_array->GetString(0), PlaceholderSentinelBytes()); } @@ -1194,9 +1188,8 @@ TEST_F(BlobFormatWriterPlaceholderTest, TestSentinelPrefixedValueVerbatimInPlace ASSERT_OK_AND_ASSIGN(auto chunked_array, paimon::test::ReadResultCollector::CollectResult(reader.get())); auto concat_array = arrow::Concatenate(chunked_array->chunks()).ValueOrDie(); - auto struct_array = arrow::internal::checked_pointer_cast(concat_array); - auto binary_array = - arrow::internal::checked_pointer_cast(struct_array->field(0)); + auto struct_array = checked_pointer_cast(concat_array); + auto binary_array = checked_pointer_cast(struct_array->field(0)); ASSERT_EQ(struct_array->length(), 2); ASSERT_EQ(binary_array->GetString(0), sentinel + sentinel); ASSERT_EQ(binary_array->GetString(1), sentinel + "suffix"); diff --git a/src/paimon/format/orc/orc_adapter.cpp b/src/paimon/format/orc/orc_adapter.cpp index 4773f2ed..4a03d7cd 100644 --- a/src/paimon/format/orc/orc_adapter.cpp +++ b/src/paimon/format/orc/orc_adapter.cpp @@ -47,7 +47,6 @@ #include "arrow/type_fwd.h" #include "arrow/type_traits.h" #include "arrow/util/bitmap_ops.h" -#include "arrow/util/checked_cast.h" #include "arrow/util/decimal.h" #include "arrow/util/key_value_metadata.h" #include "arrow/util/range.h" @@ -58,6 +57,7 @@ #include "orc/Type.hh" #include "orc/Vector.hh" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/data/timestamp.h" @@ -414,9 +414,8 @@ class UnPooledMapBuilder : public EmptyBuilder { } std::shared_ptr type() const override { - auto map_type = arrow::internal::checked_cast(type_.get()); - auto list_type = - arrow::internal::checked_pointer_cast(list_builder_->type()); + auto map_type = checked_cast(type_.get()); + auto list_type = checked_pointer_cast(list_builder_->type()); return std::make_shared(arrow::field("entries", list_type->value_type()), map_type->keys_sorted()); } @@ -656,8 +655,7 @@ Result> MakeOrcBackedTimestampBuilder( const bool has_nulls = typed_batch->hasNulls; const auto* not_null = typed_batch->notNull.data(); auto is_null = [has_nulls, not_null](int64_t index) { return has_nulls && !not_null[index]; }; - auto timestamp_type = arrow::internal::checked_pointer_cast(type); - assert(timestamp_type); + auto timestamp_type = checked_pointer_cast(type); int32_t precision = DateTimeUtils::GetPrecisionFromType(timestamp_type); // TODO(lisizhuo.lsz): check nano overflow in arrow if (precision == Timestamp::MIN_PRECISION) { @@ -720,11 +718,9 @@ Result> MakeOrcBackedDecimal128Builder( arrow::MemoryPool* pool) { auto builder = std::make_shared(type, pool); const bool has_nulls = column_vector_batch->hasNulls; - auto decimal_type = arrow::internal::checked_cast(type.get()); - assert(decimal_type); + auto decimal_type = checked_cast(type.get()); if (decimal_type->precision() == 0 || decimal_type->precision() > 18) { - auto typed_batch = - arrow::internal::checked_cast(column_vector_batch); + auto typed_batch = checked_cast(column_vector_batch); for (size_t i = 0; i < typed_batch->numElements; i++) { if (!has_nulls || typed_batch->notNull[i]) { int64_t high_bits = typed_batch->values[i].getHighBits(); @@ -736,8 +732,7 @@ Result> MakeOrcBackedDecimal128Builder( } } } else { - auto typed_batch = - arrow::internal::checked_cast(column_vector_batch); + auto typed_batch = checked_cast(column_vector_batch); for (size_t i = 0; i < typed_batch->numElements; i++) { if (!has_nulls || typed_batch->notNull[i]) { PAIMON_RETURN_NOT_OK_FROM_ARROW( @@ -807,7 +802,7 @@ Result> MakeOrcBackedListBuilder( using OffsetType = arrow::ListType::offset_type; auto typed_batch = dynamic_cast<::orc::ListVectorBatch*>(column_vector_batch); assert(typed_batch); - auto list_type = arrow::internal::checked_cast(type.get()); + auto list_type = checked_cast(type.get()); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr elements_builder, MakeArrowBuilder(list_type->value_type(), typed_batch->elements.get(), pool)); @@ -830,7 +825,7 @@ Result> MakeOrcBackedStructBuilder( arrow::MemoryPool* pool) { auto typed_batch = dynamic_cast<::orc::StructVectorBatch*>(column_vector_batch); assert(typed_batch); - auto struct_type = arrow::internal::checked_cast(type.get()); + auto struct_type = checked_cast(type.get()); std::vector> children_builders; children_builders.reserve(typed_batch->fields.size()); for (size_t i = 0; i < typed_batch->fields.size(); i++) { @@ -851,7 +846,7 @@ Result> MakeOrcBackedMapBuilder( using OffsetType = arrow::ListType::offset_type; auto typed_batch = dynamic_cast<::orc::MapVectorBatch*>(column_vector_batch); assert(typed_batch); - auto map_type = arrow::internal::checked_cast(type.get()); + auto map_type = checked_cast(type.get()); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr key_builder, MakeArrowBuilder(map_type->key_type(), typed_batch->keys.get(), pool)); PAIMON_ASSIGN_OR_RAISE( @@ -959,7 +954,7 @@ arrow::Result> NormalizeArray( arrow::Type::type kind = array->type_id(); switch (kind) { case arrow::Type::type::STRUCT: { - auto struct_array = arrow::internal::checked_cast(array.get()); + auto struct_array = checked_cast(array.get()); const std::shared_ptr bitmap = struct_array->null_bitmap(); std::shared_ptr struct_type = struct_array->type(); std::size_t size = struct_type->fields().size(); @@ -1002,14 +997,14 @@ arrow::Result> NormalizeArray( struct_array->null_count(), struct_array->offset()); } case arrow::Type::type::LIST: { - auto list_array = arrow::internal::checked_cast(array.get()); + auto list_array = checked_cast(array.get()); ARROW_ASSIGN_OR_RAISE(auto value_array, NormalizeArray(list_array->values())); return std::make_shared( list_array->type(), list_array->length(), list_array->value_offsets(), value_array, list_array->null_bitmap(), list_array->null_count(), list_array->offset()); } case arrow::Type::type::MAP: { - auto map_array = arrow::internal::checked_cast(array.get()); + auto map_array = checked_cast(array.get()); ARROW_ASSIGN_OR_RAISE(auto key_array, NormalizeArray(map_array->keys())); ARROW_ASSIGN_OR_RAISE(auto item_array, NormalizeArray(map_array->items())); return std::make_shared( @@ -1168,8 +1163,8 @@ arrow::Status ShallowCopyGenericBatch(const arrow::Array& array, ::orc::ColumnVectorBatch* column_vector_batch) { using ArrayType = typename arrow::TypeTraits::ArrayType; using value_type = typename ArrayType::value_type; - const auto& array_(arrow::internal::checked_cast(array)); - auto batch = arrow::internal::checked_cast(column_vector_batch); + const auto& array_(checked_cast(array)); + auto batch = checked_cast(column_vector_batch); if (array.null_count()) { batch->hasNulls = true; } @@ -1191,8 +1186,8 @@ template arrow::Status WriteGenericBatch(const arrow::Array& array, ::orc::ColumnVectorBatch* column_vector_batch) { using ArrayType = typename arrow::TypeTraits::ArrayType; - const auto& array_(arrow::internal::checked_cast(array)); - auto batch = arrow::internal::checked_cast(column_vector_batch); + const auto& array_(checked_cast(array)); + auto batch = checked_cast(column_vector_batch); if (array.null_count()) { batch->hasNulls = true; } @@ -1206,12 +1201,12 @@ template arrow::Status WriteTimestampBatch(const arrow::Array& array, ::orc::ColumnVectorBatch* column_vector_batch) { using ArrayType = typename arrow::TypeTraits::ArrayType; - const auto& array_(arrow::internal::checked_cast(array)); - auto batch = arrow::internal::checked_cast<::orc::TimestampVectorBatch*>(column_vector_batch); + const auto& array_(checked_cast(array)); + auto batch = checked_cast<::orc::TimestampVectorBatch*>(column_vector_batch); if (array.null_count()) { batch->hasNulls = true; } - auto timestamp_type = arrow::internal::checked_pointer_cast(array.type()); + auto timestamp_type = checked_pointer_cast(array.type()); auto time_type = DateTimeUtils::GetTimeTypeFromArrowType(timestamp_type); TimestampAppender appender{time_type, array_, batch, /*orc_offset=*/0, 0}; @@ -1223,9 +1218,8 @@ arrow::Status WriteTimestampBatch(const arrow::Array& array, arrow::Status WriteStructBatch(const arrow::Array& array, ::orc::ColumnVectorBatch* column_vector_batch) { std::shared_ptr array_ = arrow::MakeArray(array.data()); - auto* struct_array = arrow::internal::checked_cast(array_.get()); - assert(struct_array); - auto batch = arrow::internal::checked_cast<::orc::StructVectorBatch*>(column_vector_batch); + auto* struct_array = checked_cast(array_.get()); + auto batch = checked_cast<::orc::StructVectorBatch*>(column_vector_batch); std::size_t size = array.type()->fields().size(); int64_t arrow_length = array.length(); batch->numElements = arrow_length; @@ -1250,8 +1244,8 @@ arrow::Status WriteStructBatch(const arrow::Array& array, template arrow::Status WriteListBatch(const arrow::Array& array, ::orc::ColumnVectorBatch* column_vector_batch) { - const auto& list_array(arrow::internal::checked_cast(array)); - auto batch = arrow::internal::checked_cast<::orc::ListVectorBatch*>(column_vector_batch); + const auto& list_array(checked_cast(array)); + auto batch = checked_cast<::orc::ListVectorBatch*>(column_vector_batch); ::orc::ColumnVectorBatch* element_batch = (batch->elements).get(); int64_t arrow_length = array.length(); batch->numElements = arrow_length; @@ -1282,8 +1276,8 @@ arrow::Status WriteListBatch(const arrow::Array& array, arrow::Status WriteMapBatch(const arrow::Array& array, ::orc::ColumnVectorBatch* column_vector_batch) { - const auto& map_array(arrow::internal::checked_cast(array)); - auto batch = arrow::internal::checked_cast<::orc::MapVectorBatch*>(column_vector_batch); + const auto& map_array(checked_cast(array)); + auto batch = checked_cast<::orc::MapVectorBatch*>(column_vector_batch); ::orc::ColumnVectorBatch* key_batch = (batch->keys).get(); ::orc::ColumnVectorBatch* element_batch = (batch->elements).get(); std::shared_ptr key_array = map_array.keys(); @@ -1357,8 +1351,7 @@ arrow::Status WriteBatch(const arrow::Array& array, ::orc::ColumnVectorBatch* co return WriteTimestampBatch(array, column_vector_batch); case arrow::Type::type::DECIMAL128: { int32_t precision = - arrow::internal::checked_cast(array.type().get()) - ->precision(); + checked_cast(array.type().get())->precision(); if (precision > 18 || precision == 0) { return WriteGenericBatch( array, column_vector_batch); @@ -1415,31 +1408,28 @@ arrow::Result> GetOrcType(const arrow::DataType& ty case arrow::Type::type::DATE32: return ::orc::createPrimitiveType(::orc::TypeKind::DATE); case arrow::Type::type::TIMESTAMP: { - const auto& timestamp_type = - arrow::internal::checked_cast(type); + const auto& timestamp_type = checked_cast(type); if (timestamp_type.timezone().empty()) { return ::orc::createPrimitiveType(::orc::TypeKind::TIMESTAMP); } return ::orc::createPrimitiveType(::orc::TypeKind::TIMESTAMP_INSTANT); } case arrow::Type::type::DECIMAL128: { - const auto precision = static_cast( - arrow::internal::checked_cast(type).precision()); - const auto scale = static_cast( - arrow::internal::checked_cast(type).scale()); + const auto precision = + static_cast(checked_cast(type).precision()); + const auto scale = + static_cast(checked_cast(type).scale()); return ::orc::createDecimalType(precision, scale); } case arrow::Type::type::LIST: { - const auto& value_field = - arrow::internal::checked_cast(type).value_field(); + const auto& value_field = checked_cast(type).value_field(); ARROW_ASSIGN_OR_RAISE(auto orc_subtype, paimon::orc::GetOrcType(*value_field->type())); SetAttributes(value_field, orc_subtype.get()); return ::orc::createListType(std::move(orc_subtype)); } case arrow::Type::type::STRUCT: { std::unique_ptr<::orc::Type> out_type = ::orc::createStructType(); - arrow::FieldVector arrow_fields = - arrow::internal::checked_cast(type).fields(); + arrow::FieldVector arrow_fields = checked_cast(type).fields(); for (auto& arrow_field : arrow_fields) { std::string field_name = arrow_field->name(); ARROW_ASSIGN_OR_RAISE(auto orc_subtype, GetOrcType(*arrow_field->type())); @@ -1449,10 +1439,8 @@ arrow::Result> GetOrcType(const arrow::DataType& ty return out_type; } case arrow::Type::type::MAP: { - const auto& key_field = - arrow::internal::checked_cast(type).key_field(); - const auto& item_field = - arrow::internal::checked_cast(type).item_field(); + const auto& key_field = checked_cast(type).key_field(); + const auto& item_field = checked_cast(type).item_field(); ARROW_ASSIGN_OR_RAISE(auto key_orc_type, GetOrcType(*key_field->type())); ARROW_ASSIGN_OR_RAISE(auto item_orc_type, GetOrcType(*item_field->type())); SetAttributes(key_field, key_orc_type.get()); diff --git a/src/paimon/format/orc/orc_format_writer_test.cpp b/src/paimon/format/orc/orc_format_writer_test.cpp index 0f531f52..fff6816c 100644 --- a/src/paimon/format/orc/orc_format_writer_test.cpp +++ b/src/paimon/format/orc/orc_format_writer_test.cpp @@ -40,6 +40,7 @@ #include "orc/Vector.hh" #include "orc/Writer.hh" #include "paimon/common/data/variant/variant_type_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/format/orc/orc_format_defs.h" #include "paimon/format/orc/orc_input_stream_impl.h" #include "paimon/format/orc/orc_metrics.h" @@ -77,9 +78,9 @@ class OrcFormatWriterTest : public ::testing::Test { data_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto int_builder = static_cast(struct_builder.field_builder(1)); - auto bool_builder = static_cast(struct_builder.field_builder(2)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(1)); + auto bool_builder = checked_cast(struct_builder.field_builder(2)); for (int32_t i = 0 + offset; i < record_batch_size + offset; ++i) { EXPECT_TRUE(struct_builder.Append().ok()); if (i % 2 == 0) { @@ -135,7 +136,7 @@ class OrcFormatWriterTest : public ::testing::Test { auto struct_batch = dynamic_cast<::orc::StructVectorBatch*>(batch.get()); ASSERT_TRUE(struct_batch); - auto string_batch = static_cast<::orc::StringVectorBatch*>(struct_batch->fields[0]); + auto string_batch = checked_cast<::orc::StringVectorBatch*>(struct_batch->fields[0]); ASSERT_TRUE(string_batch); auto int_batch = dynamic_cast<::orc::IntVectorBatch*>(struct_batch->fields[1]); ASSERT_TRUE(int_batch); diff --git a/src/paimon/format/orc/orc_stats_extractor.cpp b/src/paimon/format/orc/orc_stats_extractor.cpp index 84fa6335..dbdf26a8 100644 --- a/src/paimon/format/orc/orc_stats_extractor.cpp +++ b/src/paimon/format/orc/orc_stats_extractor.cpp @@ -30,6 +30,7 @@ #include "orc/Statistics.hh" #include "orc/Type.hh" #include "orc/Vector.hh" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/core/casting/decimal_to_decimal_cast_executor.h" #include "paimon/data/decimal.h" @@ -226,8 +227,7 @@ Result> OrcStatsExtractor::FetchColumnStatistics( "cannot cast to TimestampColumnStatistics for orc::TIMESTAMP/TIMESTAMP_INSTANT " "type"); } - auto write_ts_type = - arrow::internal::checked_pointer_cast<::arrow::TimestampType>(write_type); + auto write_ts_type = checked_pointer_cast<::arrow::TimestampType>(write_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(write_ts_type); if (all_null || !typed_stats->hasMinimum()) { return ColumnStats::CreateTimestampColumnStats(std::nullopt, std::nullopt, diff --git a/src/paimon/format/parquet/file_reader_wrapper_test.cpp b/src/paimon/format/parquet/file_reader_wrapper_test.cpp index de3b6fdc..aaef711e 100644 --- a/src/paimon/format/parquet/file_reader_wrapper_test.cpp +++ b/src/paimon/format/parquet/file_reader_wrapper_test.cpp @@ -33,6 +33,7 @@ #include "paimon/common/utils/arrow/arrow_input_stream_adapter.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/format/parquet/parquet_field_id_converter.h" #include "paimon/format/parquet/parquet_format_defs.h" @@ -86,9 +87,9 @@ class FileReaderWrapperTest : public ::testing::Test { data_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto int_builder = static_cast(struct_builder.field_builder(1)); - auto bool_builder = static_cast(struct_builder.field_builder(2)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(1)); + auto bool_builder = checked_cast(struct_builder.field_builder(2)); for (int32_t i = 0 + offset; i < record_batch_size + offset; ++i) { EXPECT_TRUE(struct_builder.Append().ok()); EXPECT_TRUE(string_builder->Append("str_" + std::to_string(i)).ok()); diff --git a/src/paimon/format/parquet/parquet_field_id_converter.cpp b/src/paimon/format/parquet/parquet_field_id_converter.cpp index 010df3a0..56d36d36 100644 --- a/src/paimon/format/parquet/parquet_field_id_converter.cpp +++ b/src/paimon/format/parquet/parquet_field_id_converter.cpp @@ -26,6 +26,7 @@ #include "arrow/api.h" #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" namespace paimon::parquet { @@ -90,7 +91,7 @@ arrow::Result> ParquetFieldIdConverter::ProcessField( CopyId(field->metadata(), convert_type)); auto type = field->type(); if (type->id() == arrow::Type::STRUCT) { - auto struct_type = std::static_pointer_cast(type); + auto struct_type = checked_pointer_cast(type); std::vector> new_fields; for (const auto& child : struct_type->fields()) { ARROW_ASSIGN_OR_RAISE(auto new_child, ProcessField(child, convert_type)); @@ -99,13 +100,13 @@ arrow::Result> ParquetFieldIdConverter::ProcessField( auto new_type = arrow::struct_(new_fields); return field->WithType(new_type)->WithMergedMetadata(updated_metadata); } else if (type->id() == arrow::Type::LIST) { - auto list_type = std::static_pointer_cast(type); + auto list_type = checked_pointer_cast(type); ARROW_ASSIGN_OR_RAISE(auto new_value_field, ProcessField(list_type->value_field(), convert_type)); auto new_type = arrow::list(new_value_field); return field->WithType(new_type)->WithMergedMetadata(updated_metadata); } else if (type->id() == arrow::Type::MAP) { - auto map_type = std::static_pointer_cast(type); + auto map_type = checked_pointer_cast(type); ARROW_ASSIGN_OR_RAISE(auto new_key_field, ProcessField(map_type->key_field(), convert_type)); ARROW_ASSIGN_OR_RAISE(auto new_item_field, diff --git a/src/paimon/format/parquet/parquet_field_id_converter_test.cpp b/src/paimon/format/parquet/parquet_field_id_converter_test.cpp index e85cb440..7f7c114e 100644 --- a/src/paimon/format/parquet/parquet_field_id_converter_test.cpp +++ b/src/paimon/format/parquet/parquet_field_id_converter_test.cpp @@ -26,6 +26,7 @@ #include "arrow/api.h" #include "gtest/gtest.h" #include "paimon/common/types/data_field.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/schema/table_schema.h" #include "paimon/status.h" #include "paimon/testing/utils/testharness.h" @@ -91,16 +92,16 @@ class ParquetFieldIdConverterTest : public ::testing::Test { auto type_id = field->type()->id(); if (type_id == arrow::Type::STRUCT) { - auto struct_type = std::static_pointer_cast(field->type()); + auto struct_type = checked_pointer_cast(field->type()); for (const auto& child : struct_type->fields()) { PrintFieldMetadataRecursive(child, indent + 1, convert_type, field_infos); } } else if (type_id == arrow::Type::LIST) { - auto list_type = std::static_pointer_cast(field->type()); + auto list_type = checked_pointer_cast(field->type()); PrintFieldMetadataRecursive(list_type->value_field(), indent + 1, convert_type, field_infos); } else if (type_id == arrow::Type::MAP) { - auto map_type = std::static_pointer_cast(field->type()); + auto map_type = checked_pointer_cast(field->type()); PrintFieldMetadataRecursive(map_type->key_field(), indent + 1, convert_type, field_infos); PrintFieldMetadataRecursive(map_type->item_field(), indent + 1, convert_type, diff --git a/src/paimon/format/parquet/parquet_file_batch_reader_test.cpp b/src/paimon/format/parquet/parquet_file_batch_reader_test.cpp index 59e5a25f..3810af8a 100644 --- a/src/paimon/format/parquet/parquet_file_batch_reader_test.cpp +++ b/src/paimon/format/parquet/parquet_file_batch_reader_test.cpp @@ -41,6 +41,7 @@ #include "paimon/common/utils/arrow/arrow_input_stream_adapter.h" #include "paimon/common/utils/arrow/arrow_utils.h" #include "paimon/common/utils/arrow/mem_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/path_util.h" #include "paimon/defs.h" @@ -995,7 +996,7 @@ TEST_F(ParquetFileBatchReaderTest, TestPredicateAndBitmapRowGroupPushDown) { auto arrow_type = arrow::struct_(fields); arrow::StructBuilder struct_builder(arrow_type, arrow::default_memory_pool(), {std::make_shared()}); - auto int_builder = static_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(0)); int32_t length = 1024; for (int32_t i = 0; i < length; ++i) { ASSERT_TRUE(struct_builder.Append().ok()); @@ -1052,7 +1053,7 @@ TEST_F(ParquetFileBatchReaderTest, TestPredicateAndBitmapPagePushDown) { auto arrow_type = arrow::struct_(fields); arrow::StructBuilder struct_builder(arrow_type, arrow::default_memory_pool(), {std::make_shared()}); - auto int_builder = static_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(0)); int32_t length = 1024; for (int32_t i = 0; i < length; ++i) { ASSERT_TRUE(struct_builder.Append().ok()); diff --git a/src/paimon/format/parquet/parquet_format_writer_test.cpp b/src/paimon/format/parquet/parquet_format_writer_test.cpp index f70c6332..117a1450 100644 --- a/src/paimon/format/parquet/parquet_format_writer_test.cpp +++ b/src/paimon/format/parquet/parquet_format_writer_test.cpp @@ -37,6 +37,7 @@ #include "arrow/memory_pool.h" #include "gtest/gtest.h" #include "paimon/common/utils/arrow/mem_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/path_util.h" #include "paimon/format/file_format.h" @@ -95,9 +96,9 @@ class ParquetFormatWriterTest : public ::testing::Test { data_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto int_builder = static_cast(struct_builder.field_builder(1)); - auto bool_builder = static_cast(struct_builder.field_builder(2)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(1)); + auto bool_builder = checked_cast(struct_builder.field_builder(2)); for (int32_t i = 0 + offset; i < record_batch_size + offset; ++i) { EXPECT_TRUE(struct_builder.Append().ok()); if (all_null_value) { @@ -157,13 +158,11 @@ class ParquetFormatWriterTest : public ::testing::Test { ASSERT_TRUE(reader->ReadColumn(1, &col1_array).ok()); ASSERT_TRUE(reader->ReadColumn(2, &col2_array).ok()); - const auto& string_array = - std::static_pointer_cast(col0_array->chunk(0)); + const auto& string_array = checked_pointer_cast(col0_array->chunk(0)); ASSERT_TRUE(string_array); - const auto& int_array = std::static_pointer_cast(col1_array->chunk(0)); + const auto& int_array = checked_pointer_cast(col1_array->chunk(0)); ASSERT_TRUE(int_array); - const auto& bool_array = - std::static_pointer_cast(col2_array->chunk(0)); + const auto& bool_array = checked_pointer_cast(col2_array->chunk(0)); ASSERT_TRUE(bool_array); ASSERT_EQ(string_array->null_count(), 0); ASSERT_EQ(int_array->null_count(), (row_count - 1) / 3 + 1); diff --git a/src/paimon/format/parquet/parquet_schema_util.cpp b/src/paimon/format/parquet/parquet_schema_util.cpp index fdeb5290..472b81fe 100644 --- a/src/paimon/format/parquet/parquet_schema_util.cpp +++ b/src/paimon/format/parquet/parquet_schema_util.cpp @@ -25,7 +25,7 @@ #include "arrow/result.h" #include "arrow/status.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "parquet/schema.h" #include "parquet/types.h" @@ -38,7 +38,6 @@ namespace paimon::parquet { using ::arrow::Result; using ::arrow::Status; -using ::arrow::internal::checked_cast; Result> MakeArrowDecimal(const ::parquet::LogicalType& logical_type) { const auto& decimal = checked_cast(logical_type); diff --git a/src/paimon/format/parquet/parquet_stats_extractor.cpp b/src/paimon/format/parquet/parquet_stats_extractor.cpp index f1df8b6e..4b8f97f0 100644 --- a/src/paimon/format/parquet/parquet_stats_extractor.cpp +++ b/src/paimon/format/parquet/parquet_stats_extractor.cpp @@ -25,11 +25,11 @@ #include "arrow/memory_pool.h" #include "arrow/type.h" -#include "arrow/util/checked_cast.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/arrow_input_stream_adapter.h" #include "paimon/common/utils/arrow/mem_utils.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/data/decimal.h" #include "paimon/data/timestamp.h" @@ -81,14 +81,12 @@ Result> ConvertStatsToColumnStats( } switch (id) { case arrow::Type::BOOL: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::BoolStatistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::BoolStatistics>(stats); auto [min, max] = CollectMinMaxStats(typed_stats); return ColumnStats::CreateBooleanColumnStats(min, max, null_count); } case arrow::Type::INT8: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::Int32Statistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::Int32Statistics>(stats); std::optional min; std::optional max; if (typed_stats && typed_stats->HasMinMax()) { @@ -98,8 +96,7 @@ Result> ConvertStatsToColumnStats( return ColumnStats::CreateTinyIntColumnStats(min, max, null_count); } case arrow::Type::INT16: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::Int32Statistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::Int32Statistics>(stats); std::optional min; std::optional max; if (typed_stats && typed_stats->HasMinMax()) { @@ -109,32 +106,27 @@ Result> ConvertStatsToColumnStats( return ColumnStats::CreateSmallIntColumnStats(min, max, null_count); } case arrow::Type::INT32: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::Int32Statistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::Int32Statistics>(stats); auto [min, max] = CollectMinMaxStats(typed_stats); return ColumnStats::CreateIntColumnStats(min, max, null_count); } case arrow::Type::INT64: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::Int64Statistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::Int64Statistics>(stats); auto [min, max] = CollectMinMaxStats(typed_stats); return ColumnStats::CreateBigIntColumnStats(min, max, null_count); } case arrow::Type::FLOAT: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::FloatStatistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::FloatStatistics>(stats); auto [min, max] = CollectMinMaxStats(typed_stats); return ColumnStats::CreateFloatColumnStats(min, max, null_count); } case arrow::Type::DOUBLE: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::DoubleStatistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::DoubleStatistics>(stats); auto [min, max] = CollectMinMaxStats(typed_stats); return ColumnStats::CreateDoubleColumnStats(min, max, null_count); } case arrow::Type::STRING: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::ByteArrayStatistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::ByteArrayStatistics>(stats); std::optional min; std::optional max; if (typed_stats && typed_stats->HasMinMax()) { @@ -147,26 +139,22 @@ Result> ConvertStatsToColumnStats( return ColumnStats::CreateStringColumnStats(std::nullopt, std::nullopt, null_count); } case arrow::Type::DATE32: { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::Int32Statistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::Int32Statistics>(stats); auto [min, max] = CollectMinMaxStats<::parquet::Int32Statistics>(typed_stats); return ColumnStats::CreateDateColumnStats(min, max, null_count); } case arrow::Type::TIMESTAMP: { - auto timestamp_type = - arrow::internal::checked_pointer_cast<::arrow::TimestampType>(data_type); + auto timestamp_type = checked_pointer_cast<::arrow::TimestampType>(data_type); if (timestamp_type->unit() == arrow::TimeUnit::type::NANO) { // int96 does not have statistics return ColumnStats::CreateTimestampColumnStats( std::nullopt, std::nullopt, std::nullopt, Timestamp::MAX_PRECISION); } - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::Int64Statistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::Int64Statistics>(stats); auto [min, max] = CollectMinMaxStats(typed_stats); // while write type is ts(second), data type in parquet file will be ts(milli), correct // precision is supposed to be extracted from write type - auto write_ts_type = - arrow::internal::checked_pointer_cast<::arrow::TimestampType>(write_type); + auto write_ts_type = checked_pointer_cast<::arrow::TimestampType>(write_type); int32_t precision = DateTimeUtils::GetPrecisionFromType(write_ts_type); if (!min || !max) { return ColumnStats::CreateTimestampColumnStats(std::nullopt, std::nullopt, @@ -184,22 +172,19 @@ Result> ConvertStatsToColumnStats( null_count, precision); } case arrow::Type::DECIMAL128: { - auto decimal_type = - arrow::internal::checked_pointer_cast<::arrow::Decimal128Type>(data_type); + auto decimal_type = checked_pointer_cast<::arrow::Decimal128Type>(data_type); int32_t precision = decimal_type->precision(); int32_t scale = decimal_type->scale(); std::optional min_value; std::optional max_value; if (primitive_node->physical_type() == ::parquet::Type::INT32) { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::Int32Statistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::Int32Statistics>(stats); if (typed_stats && typed_stats->HasMinMax()) { min_value = Decimal(precision, scale, typed_stats->min()); max_value = Decimal(precision, scale, typed_stats->max()); } } else if (primitive_node->physical_type() == ::parquet::Type::INT64) { - auto typed_stats = - arrow::internal::checked_pointer_cast<::parquet::Int64Statistics>(stats); + auto typed_stats = checked_pointer_cast<::parquet::Int64Statistics>(stats); if (typed_stats && typed_stats->HasMinMax()) { min_value = Decimal(precision, scale, typed_stats->min()); max_value = Decimal(precision, scale, typed_stats->max()); @@ -230,8 +215,7 @@ void MergeTypedStats( if (!entry) { entry = stats; } else { - arrow::internal::checked_pointer_cast(entry)->Merge( - *arrow::internal::checked_pointer_cast(stats)); + checked_pointer_cast(entry)->Merge(*checked_pointer_cast(stats)); } } @@ -321,9 +305,7 @@ ParquetStatsExtractor::ExtractWithFileInfo(const std::shared_ptr& fi } result_stats.push_back(ColumnStats::CreateNestedColumnStats(nested_type, std::nullopt)); } else { - auto primitive_node = - arrow::internal::checked_pointer_cast<::parquet::schema::PrimitiveNode>(node); - assert(primitive_node != nullptr); + auto primitive_node = checked_pointer_cast<::parquet::schema::PrimitiveNode>(node); auto iter = merged_stats.find(node->name()); const std::shared_ptr<::parquet::Statistics>& parquet_stats = iter == merged_stats.end() ? nullptr : iter->second; diff --git a/src/paimon/format/parquet/parquet_timestamp_converter.cpp b/src/paimon/format/parquet/parquet_timestamp_converter.cpp index c9c9e75c..fc628e60 100644 --- a/src/paimon/format/parquet/parquet_timestamp_converter.cpp +++ b/src/paimon/format/parquet/parquet_timestamp_converter.cpp @@ -25,6 +25,7 @@ #include "arrow/type.h" #include "fmt/format.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/core/casting/timestamp_to_timestamp_cast_executor.h" @@ -34,8 +35,7 @@ Result> ParquetTimestampConverter::AdjustTimezo arrow::Type::type type = src_data_type->id(); switch (type) { case arrow::Type::type::STRUCT: { - auto* src_struct_type = - arrow::internal::checked_cast(src_data_type.get()); + auto* src_struct_type = checked_cast(src_data_type.get()); arrow::FieldVector new_fields; new_fields.reserve(src_struct_type->num_fields()); for (int32_t i = 0; i < src_struct_type->num_fields(); ++i) { @@ -46,8 +46,7 @@ Result> ParquetTimestampConverter::AdjustTimezo return arrow::struct_(new_fields); } case arrow::Type::type::MAP: { - auto* src_map_type = - arrow::internal::checked_cast(src_data_type.get()); + auto* src_map_type = checked_cast(src_data_type.get()); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr key_type, AdjustTimezone(src_map_type->key_type())); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr item_type, @@ -57,15 +56,13 @@ Result> ParquetTimestampConverter::AdjustTimezo src_map_type->item_field()->WithType(item_type)); } case arrow::Type::type::LIST: { - auto* src_list_type = - arrow::internal::checked_cast(src_data_type.get()); + auto* src_list_type = checked_cast(src_data_type.get()); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr value_type, AdjustTimezone(src_list_type->value_type())); return arrow::list(src_list_type->value_field()->WithType(value_type)); } case arrow::Type::type::TIMESTAMP: { - auto* src_ts_type = - arrow::internal::checked_cast(src_data_type.get()); + auto* src_ts_type = checked_cast(src_data_type.get()); if (!src_ts_type->timezone().empty()) { return arrow::timestamp(src_ts_type->unit(), DateTimeUtils::GetLocalTimezoneName()); } @@ -86,10 +83,8 @@ Result ParquetTimestampConverter::NeedCastArrayForTimestamp( } switch (type) { case arrow::Type::type::STRUCT: { - auto* src_struct_type = - arrow::internal::checked_cast(src_data_type.get()); - auto* target_struct_type = - arrow::internal::checked_cast(target_data_type.get()); + auto* src_struct_type = checked_cast(src_data_type.get()); + auto* target_struct_type = checked_cast(target_data_type.get()); if (src_struct_type->num_fields() != target_struct_type->num_fields()) { return Status::Invalid( fmt::format("src type {} and target type {} number of fields mismatch", @@ -106,10 +101,8 @@ Result ParquetTimestampConverter::NeedCastArrayForTimestamp( return false; } case arrow::Type::type::MAP: { - auto* src_map_type = - arrow::internal::checked_cast(src_data_type.get()); - auto* target_map_type = - arrow::internal::checked_cast(target_data_type.get()); + auto* src_map_type = checked_cast(src_data_type.get()); + auto* target_map_type = checked_cast(target_data_type.get()); PAIMON_ASSIGN_OR_RAISE( bool need_cast, NeedCastArrayForTimestamp(src_map_type->key_type(), target_map_type->key_type())); @@ -122,20 +115,16 @@ Result ParquetTimestampConverter::NeedCastArrayForTimestamp( return need_cast; } case arrow::Type::type::LIST: { - auto* src_list_type = - arrow::internal::checked_cast(src_data_type.get()); - auto* target_list_type = - arrow::internal::checked_cast(target_data_type.get()); + auto* src_list_type = checked_cast(src_data_type.get()); + auto* target_list_type = checked_cast(target_data_type.get()); PAIMON_ASSIGN_OR_RAISE(bool need_cast, NeedCastArrayForTimestamp(src_list_type->value_type(), target_list_type->value_type())); return need_cast; } case arrow::Type::type::TIMESTAMP: { - auto* src_ts_type = - arrow::internal::checked_cast(src_data_type.get()); - auto* target_ts_type = - arrow::internal::checked_cast(target_data_type.get()); + auto* src_ts_type = checked_cast(src_data_type.get()); + auto* target_ts_type = checked_cast(target_data_type.get()); if (src_ts_type->unit() != target_ts_type->unit() || src_ts_type->timezone() != target_ts_type->timezone()) { return true; @@ -154,7 +143,7 @@ Result> ParquetTimestampConverter::CastArrayForTim arrow::Type::type type = array->type()->id(); switch (type) { case arrow::Type::type::STRUCT: { - auto* struct_array = arrow::internal::checked_cast(array.get()); + auto* struct_array = checked_cast(array.get()); arrow::ArrayVector target_sub_arrays; std::vector target_names; target_sub_arrays.reserve(struct_array->num_fields()); @@ -175,8 +164,8 @@ Result> ParquetTimestampConverter::CastArrayForTim return new_array; } case arrow::Type::type::MAP: { - auto* map_array = arrow::internal::checked_cast(array.get()); - auto* map_type = arrow::internal::checked_cast(target_data_type.get()); + auto* map_array = checked_cast(array.get()); + auto* map_type = checked_cast(target_data_type.get()); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr key_array, CastArrayForTimestamp(map_array->keys(), map_type->key_type(), arrow_pool)); @@ -189,9 +178,8 @@ Result> ParquetTimestampConverter::CastArrayForTim map_array->null_count(), map_array->offset()); } case arrow::Type::type::LIST: { - auto* list_array = arrow::internal::checked_cast(array.get()); - auto* list_type = - arrow::internal::checked_cast(target_data_type.get()); + auto* list_array = checked_cast(array.get()); + auto* list_type = checked_cast(target_data_type.get()); PAIMON_ASSIGN_OR_RAISE( std::shared_ptr value_array, CastArrayForTimestamp(list_array->values(), list_type->value_type(), arrow_pool)); @@ -201,11 +189,9 @@ Result> ParquetTimestampConverter::CastArrayForTim list_array->offset()); } case arrow::Type::type::TIMESTAMP: { - auto* ts_array = arrow::internal::checked_cast(array.get()); - auto* src_type = - arrow::internal::checked_cast(ts_array->type().get()); - auto* ts_target_type = - arrow::internal::checked_cast(target_data_type.get()); + auto* ts_array = checked_cast(array.get()); + auto* src_type = checked_cast(ts_array->type().get()); + auto* ts_target_type = checked_cast(target_data_type.get()); if (src_type->unit() == arrow::TimeUnit::type::MILLI && ts_target_type->unit() == arrow::TimeUnit::type::SECOND) { // parquet writer do not support second, and it cast second to milli. diff --git a/src/paimon/format/parquet/variant_parquet_test.cpp b/src/paimon/format/parquet/variant_parquet_test.cpp index b2235b2a..c17b7275 100644 --- a/src/paimon/format/parquet/variant_parquet_test.cpp +++ b/src/paimon/format/parquet/variant_parquet_test.cpp @@ -39,6 +39,7 @@ #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/arrow_input_stream_adapter.h" #include "paimon/common/utils/arrow/mem_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/core/core_options.h" #include "paimon/data/variant.h" @@ -432,7 +433,7 @@ class VariantParquetTest : public ::testing::Test { auto& [read_batch, bitmap] = batch_with_bitmap; auto imported = arrow::ImportArray(read_batch.first.get(), read_batch.second.get()); ASSERT_TRUE(imported.ok()) << imported.status().ToString(); - auto result_struct = std::static_pointer_cast(imported.ValueOrDie()); + auto result_struct = checked_pointer_cast(imported.ValueOrDie()); *column = result_struct->field(1); shredding_reader->Close(); // The assembled arrays borrow the reader's memory pool; keep the reader alive until the @@ -446,7 +447,7 @@ class VariantParquetTest : public ::testing::Test { std::shared_ptr column; ReadColumn(read_schema, &column); ASSERT_EQ(column->type_id(), arrow::Type::STRUCT); - *v_column = std::static_pointer_cast(column); + *v_column = checked_pointer_cast(column); } protected: @@ -511,7 +512,7 @@ TEST_F(VariantParquetTest, PhysicalLayoutMatchesJava) { ASSERT_EQ(variant_group_node->field_id(), 2); ASSERT_EQ(variant_group_node->logical_type()->type(), ::parquet::LogicalType::Type::NONE); const auto* variant_group = - static_cast(variant_group_node.get()); + checked_cast(variant_group_node.get()); ASSERT_EQ(variant_group->field_count(), 2); const auto& value_node = variant_group->field(0); ASSERT_EQ(value_node->name(), "value"); @@ -519,7 +520,7 @@ TEST_F(VariantParquetTest, PhysicalLayoutMatchesJava) { ASSERT_TRUE(value_node->is_required()); ASSERT_EQ(value_node->field_id(), 0); ASSERT_EQ( - static_cast(value_node.get())->physical_type(), + checked_cast(value_node.get())->physical_type(), ::parquet::Type::BYTE_ARRAY); const auto& metadata_node = variant_group->field(1); ASSERT_EQ(metadata_node->name(), "metadata"); @@ -550,8 +551,8 @@ TEST_F(VariantParquetTest, WriteAndReadRoundTrip) { ::parquet::arrow::OpenFile(file.ValueOrDie(), arrow_pool_.get(), &raw_reader).ok()); std::shared_ptr table; ASSERT_TRUE(raw_reader->ReadTable(&table).ok()); - auto raw_variant = std::static_pointer_cast(table->column(1)->chunk(0)); - auto raw_value = std::static_pointer_cast(raw_variant->field(0)); + auto raw_variant = checked_pointer_cast(table->column(1)->chunk(0)); + auto raw_value = checked_pointer_cast(raw_variant->field(0)); for (size_t i = 0; i < jsons.size(); ++i) { SCOPED_TRACE("raw row " + std::to_string(i)); if (jsons[i] != nullptr) { @@ -582,13 +583,13 @@ TEST_F(VariantParquetTest, WriteAndReadRoundTrip) { batch_reader->Close(); ASSERT_EQ(result_chunked->length(), static_cast(jsons.size())); ASSERT_EQ(result_chunked->num_chunks(), 1); - auto result_struct = std::static_pointer_cast(result_chunked->chunk(0)); + auto result_struct = checked_pointer_cast(result_chunked->chunk(0)); - auto variant_column = std::static_pointer_cast(result_struct->field(1)); + auto variant_column = checked_pointer_cast(result_struct->field(1)); ASSERT_EQ(variant_column->length(), static_cast(jsons.size())); ASSERT_EQ(variant_column->field(0)->length(), variant_column->length()); - auto value_column = std::static_pointer_cast(variant_column->field(0)); - auto metadata_column = std::static_pointer_cast(variant_column->field(1)); + auto value_column = checked_pointer_cast(variant_column->field(0)); + auto metadata_column = checked_pointer_cast(variant_column->field(1)); for (size_t i = 0; i < jsons.size(); ++i) { SCOPED_TRACE("row " + std::to_string(i)); if (jsons[i] == nullptr) { @@ -635,8 +636,8 @@ TEST_F(VariantParquetTest, ShreddedWriteAndReadRoundTrip) { std::shared_ptr variant_column; ReadVariantColumn(paimon_schema_, &variant_column); ASSERT_EQ(variant_column->length(), static_cast(jsons.size())); - auto value_column = std::static_pointer_cast(variant_column->field(0)); - auto metadata_column = std::static_pointer_cast(variant_column->field(1)); + auto value_column = checked_pointer_cast(variant_column->field(0)); + auto metadata_column = checked_pointer_cast(variant_column->field(1)); for (size_t i = 0; i < jsons.size(); ++i) { SCOPED_TRACE("row " + std::to_string(i)); if (jsons[i] == nullptr) { @@ -683,8 +684,8 @@ TEST_F(VariantParquetTest, UntypedPhysicalVariantWriteAndReadRoundTrip) { std::shared_ptr variant_column; ReadVariantColumn(paimon_schema_, &variant_column); ASSERT_EQ(variant_column->length(), static_cast(jsons.size())); - auto value_column = std::static_pointer_cast(variant_column->field(0)); - auto metadata_column = std::static_pointer_cast(variant_column->field(1)); + auto value_column = checked_pointer_cast(variant_column->field(0)); + auto metadata_column = checked_pointer_cast(variant_column->field(1)); for (size_t i = 0; i < jsons.size(); ++i) { SCOPED_TRACE("row " + std::to_string(i)); if (jsons[i] == nullptr) { @@ -735,8 +736,8 @@ TEST_F(VariantParquetTest, AdaptiveInferenceUntypedPhysicalWriteAndReadRoundTrip std::shared_ptr variant_column; ReadVariantColumn(paimon_schema_, &variant_column); ASSERT_EQ(variant_column->length(), static_cast(jsons.size())); - auto value_column = std::static_pointer_cast(variant_column->field(0)); - auto metadata_column = std::static_pointer_cast(variant_column->field(1)); + auto value_column = checked_pointer_cast(variant_column->field(0)); + auto metadata_column = checked_pointer_cast(variant_column->field(1)); for (size_t i = 0; i < jsons.size(); ++i) { SCOPED_TRACE("row " + std::to_string(i)); if (jsons[i] == nullptr) { diff --git a/src/paimon/global_index/lumina/lumina_global_index.cpp b/src/paimon/global_index/lumina/lumina_global_index.cpp index b27cdc7a..98585f21 100644 --- a/src/paimon/global_index/lumina/lumina_global_index.cpp +++ b/src/paimon/global_index/lumina/lumina_global_index.cpp @@ -35,6 +35,7 @@ #include "lumina/core/Types.h" #include "lumina/extensions/experimental/BuildCombinedExtensionV0.h" #include "paimon/common/global_index/global_index_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/options_utils.h" #include "paimon/common/utils/rapidjson_util.h" #include "paimon/common/utils/string_utils.h" @@ -165,7 +166,7 @@ template void AppendPrimitiveTagValue(const std::shared_ptr& array, int64_t index, std::vector* values) { values->push_back( - static_cast(static_cast(array.get())->Value(index))); + static_cast(checked_cast(array.get())->Value(index))); } template @@ -211,7 +212,7 @@ Status AppendTagValue(const std::shared_ptr& array, int64_t index, AppendPrimitiveTagValue(array, index, values); } else if constexpr (std::is_same_v) { PAIMON_RETURN_NOT_OK(validate_array_type(arrow::Type::STRING, "string")); - auto string_array = static_cast(array.get()); + auto string_array = checked_cast(array.get()); auto view = string_array->GetView(index); values->emplace_back(view.data(), view.size()); } else { diff --git a/src/paimon/rest/rest_catalog.cpp b/src/paimon/rest/rest_catalog.cpp index 6706bb50..5d2bb823 100644 --- a/src/paimon/rest/rest_catalog.cpp +++ b/src/paimon/rest/rest_catalog.cpp @@ -24,6 +24,7 @@ #include "paimon/catalog/table.h" #include "paimon/catalog_options.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/rapidjson_util.h" #include "paimon/common/utils/string_utils.h" #include "paimon/core/catalog/catalog_utils.h" @@ -400,7 +401,7 @@ Result> RestCatalog::LoadTableSchema(const Identifier& i } PAIMON_ASSIGN_OR_RAISE(std::shared_ptr schema, LoadDataTableSchema(load_identifier, branch, nullptr)); - return std::static_pointer_cast(schema); + return checked_pointer_cast(schema); } Result> RestCatalog::GetTable(const Identifier& identifier) const { diff --git a/src/paimon/rest/rest_catalog_test.cpp b/src/paimon/rest/rest_catalog_test.cpp index 242104fb..fda03cc4 100644 --- a/src/paimon/rest/rest_catalog_test.cpp +++ b/src/paimon/rest/rest_catalog_test.cpp @@ -34,6 +34,7 @@ #include "paimon/catalog/catalog.h" #include "paimon/catalog/table.h" #include "paimon/catalog_options.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/string_utils.h" #include "paimon/core/schema/table_schema.h" #include "paimon/defs.h" @@ -976,11 +977,11 @@ TEST(RestApiErrorTest, ErrorToStatus) { ASSERT_NOK_WITH_MSG(not_authorized, "not authorized"); ASSERT_NE(nullptr, not_authorized.detail()); ASSERT_EQ(std::string(RestErrorDetail::kTypeId), not_authorized.detail()->type_id()); - ASSERT_EQ(401, std::static_pointer_cast(not_authorized.detail())->GetCode()); + ASSERT_EQ(401, checked_pointer_cast(not_authorized.detail())->GetCode()); response.code = 403; Status forbidden = RestApi::ErrorToStatus(response); ASSERT_NOK_WITH_MSG(forbidden, "forbidden"); - ASSERT_EQ(403, std::static_pointer_cast(forbidden.detail())->GetCode()); + ASSERT_EQ(403, checked_pointer_cast(forbidden.detail())->GetCode()); // 503 and the codes without an own mapping (e.g. 429) become IOError with a // message naming the code diff --git a/src/paimon/testing/utils/data_generator.cpp b/src/paimon/testing/utils/data_generator.cpp index 2ef5c9d1..ec1aa5c8 100644 --- a/src/paimon/testing/utils/data_generator.cpp +++ b/src/paimon/testing/utils/data_generator.cpp @@ -36,6 +36,7 @@ #include "paimon/common/data/binary_string.h" #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/core/schema/table_schema.h" #include "paimon/core/utils/file_store_path_factory.h" @@ -119,49 +120,49 @@ Status DataGenerator::AppendValue(const BinaryRow& row, int32_t field_id, switch (type_id) { case arrow::Type::type::BOOL: { auto builder = - static_cast(struct_builder->field_builder(field_id)); + checked_cast(struct_builder->field_builder(field_id)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.GetBoolean(field_id))); break; } case arrow::Type::type::INT8: { auto builder = - static_cast(struct_builder->field_builder(field_id)); + checked_cast(struct_builder->field_builder(field_id)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.GetByte(field_id))); break; } case arrow::Type::type::INT16: { auto builder = - static_cast(struct_builder->field_builder(field_id)); + checked_cast(struct_builder->field_builder(field_id)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.GetShort(field_id))); break; } case arrow::Type::type::INT32: { auto builder = - static_cast(struct_builder->field_builder(field_id)); + checked_cast(struct_builder->field_builder(field_id)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.GetInt(field_id))); break; } case arrow::Type::type::INT64: { auto builder = - static_cast(struct_builder->field_builder(field_id)); + checked_cast(struct_builder->field_builder(field_id)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.GetLong(field_id))); break; } case arrow::Type::type::FLOAT: { auto builder = - static_cast(struct_builder->field_builder(field_id)); + checked_cast(struct_builder->field_builder(field_id)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.GetFloat(field_id))); break; } case arrow::Type::type::DOUBLE: { auto builder = - static_cast(struct_builder->field_builder(field_id)); + checked_cast(struct_builder->field_builder(field_id)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.GetDouble(field_id))); break; } case arrow::Type::type::STRING: { auto builder = - static_cast(struct_builder->field_builder(field_id)); + checked_cast(struct_builder->field_builder(field_id)); PAIMON_RETURN_NOT_OK_FROM_ARROW(builder->Append(row.GetString(field_id).ToString())); break; } diff --git a/src/paimon/testing/utils/dict_array_converter.h b/src/paimon/testing/utils/dict_array_converter.h index 14ee83be..b2267923 100644 --- a/src/paimon/testing/utils/dict_array_converter.h +++ b/src/paimon/testing/utils/dict_array_converter.h @@ -22,6 +22,7 @@ #include "arrow/api.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/result.h" namespace paimon::test { @@ -38,8 +39,7 @@ class DictArrayConverter { switch (kind) { case arrow::Type::type::STRUCT: { // convert array - auto struct_array = - arrow::internal::checked_pointer_cast(array); + auto struct_array = checked_pointer_cast(array); arrow::ArrayVector new_children; std::size_t size = struct_array->fields().size(); for (size_t i = 0; i < size; i++) { @@ -65,7 +65,7 @@ class DictArrayConverter { struct_array->null_bitmap()); } case arrow::Type::type::LIST: { - auto list_array = arrow::internal::checked_pointer_cast(array); + auto list_array = checked_pointer_cast(array); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr value_array, ConvertDictArray(list_array->values(), pool)); return std::make_shared( @@ -74,13 +74,12 @@ class DictArrayConverter { list_array->null_count(), list_array->offset()); } case arrow::Type::type::MAP: { - auto map_array = arrow::internal::checked_pointer_cast(array); + auto map_array = checked_pointer_cast(array); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr key_array, ConvertDictArray(map_array->keys(), pool)); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr item_array, ConvertDictArray(map_array->items(), pool)); - auto map_type = - arrow::internal::checked_pointer_cast(map_array->type()); + auto map_type = checked_pointer_cast(map_array->type()); auto new_map_type = std::make_shared( key_array->type(), item_array->type(), map_type->keys_sorted()); return std::make_shared( @@ -89,10 +88,8 @@ class DictArrayConverter { map_array->offset()); } case arrow::Type::type::DICTIONARY: { - auto dict_array = - arrow::internal::checked_pointer_cast(array); - auto dict_type = arrow::internal::checked_pointer_cast( - dict_array->type()); + auto dict_array = checked_pointer_cast(array); + auto dict_type = checked_pointer_cast(dict_array->type()); auto value_type_id = dict_type->value_type()->id(); if (value_type_id == arrow::Type::type::STRING) { return ConvertDictionaryArrayToStringArray(dict_array, diff --git a/src/paimon/testing/utils/test_helper.h b/src/paimon/testing/utils/test_helper.h index f5a1edd2..dfca5f49 100644 --- a/src/paimon/testing/utils/test_helper.h +++ b/src/paimon/testing/utils/test_helper.h @@ -37,6 +37,7 @@ #include "paimon/common/data/blob_utils.h" #include "paimon/common/types/data_field.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/core/operation/append_only_file_store_write.h" #include "paimon/core/operation/file_store_commit_impl.h" @@ -187,7 +188,7 @@ class TestHelper { arrow::StructBuilder struct_builder(struct_type, arrow::default_memory_pool(), {std::make_shared()}); auto blob_builder = - static_cast(struct_builder.field_builder(0)); + checked_cast(struct_builder.field_builder(0)); PAIMON_RETURN_NOT_OK_FROM_ARROW(struct_builder.Append()); PAIMON_UNIQUE_PTR descriptor = blob->ToDescriptor(pool); PAIMON_RETURN_NOT_OK_FROM_ARROW( @@ -253,8 +254,7 @@ class TestHelper { assert(child_array->null_count() == 0); assert(child_array->type_id() == arrow::Type::type::LARGE_BINARY); - const auto& blob_array = - arrow::internal::checked_cast(*child_array); + const auto& blob_array = checked_cast(*child_array); for (int64_t i = 0; i < blob_array.length(); ++i) { std::string_view descriptor = blob_array.GetView(i); PAIMON_ASSIGN_OR_RAISE(std::shared_ptr blob, diff --git a/test/inte/blob_table_inte_test.cpp b/test/inte/blob_table_inte_test.cpp index 5c1c0f77..ea951a31 100644 --- a/test/inte/blob_table_inte_test.cpp +++ b/test/inte/blob_table_inte_test.cpp @@ -51,6 +51,7 @@ #include "paimon/common/factories/io_hook.h" #include "paimon/common/reader/reader_utils.h" #include "paimon/common/table/special_fields.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/core/global_index/indexed_split_impl.h" @@ -394,8 +395,7 @@ class BlobTableInteTest : public testing::Test, public ::testing::WithParamInter child_arrays.push_back(col); continue; } - const auto& binary_array = - arrow::internal::checked_cast(*col); + const auto& binary_array = checked_cast(*col); arrow::LargeBinaryBuilder builder; for (int64_t i = 0; i < binary_array.length(); ++i) { if (binary_array.IsNull(i)) { @@ -444,8 +444,8 @@ class BlobTableInteTest : public testing::Test, public ::testing::WithParamInter /// `field_name`, so that a subsequent table write observes a missing file. Status DeleteDescriptorTarget(const std::shared_ptr& desc_array, const std::string& field_name, int64_t row) const { - const auto& blob_col = arrow::internal::checked_cast( - *desc_array->GetFieldByName(field_name)); + const auto& blob_col = + checked_cast(*desc_array->GetFieldByName(field_name)); std::string_view descriptor_bytes = blob_col.GetView(row); PAIMON_ASSIGN_OR_RAISE( std::unique_ptr descriptor, @@ -1178,7 +1178,7 @@ std::shared_ptr MakeBlobUpdateArray( auto struct_type = arrow::struct_({blob_field}); arrow::StructBuilder struct_builder(struct_type, arrow::default_memory_pool(), {std::make_shared()}); - auto blob_builder = static_cast(struct_builder.field_builder(0)); + auto blob_builder = checked_cast(struct_builder.field_builder(0)); for (const auto& row : rows) { EXPECT_TRUE(struct_builder.Append().ok()); if (!row) { @@ -1724,9 +1724,9 @@ TEST_P(BlobTableInteTest, TestBlobValueEqualToPlaceholderSentinelBytes) { struct_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared()}); - auto f0_builder = static_cast(struct_builder.field_builder(0)); - auto f1_builder = static_cast(struct_builder.field_builder(1)); - auto b0_builder = static_cast(struct_builder.field_builder(2)); + auto f0_builder = checked_cast(struct_builder.field_builder(0)); + auto f1_builder = checked_cast(struct_builder.field_builder(1)); + auto b0_builder = checked_cast(struct_builder.field_builder(2)); ASSERT_TRUE(struct_builder.Append().ok()); ASSERT_TRUE(f0_builder->Append(1).ok()); ASSERT_TRUE(f1_builder->Append("a").ok()); diff --git a/test/inte/clean_inte_test.cpp b/test/inte/clean_inte_test.cpp index 536bdc74..89cadd4f 100644 --- a/test/inte/clean_inte_test.cpp +++ b/test/inte/clean_inte_test.cpp @@ -45,6 +45,7 @@ #include "paimon/commit_context.h" #include "paimon/common/factories/io_hook.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/path_util.h" #include "paimon/core/manifest/manifest_file_meta.h" @@ -135,10 +136,10 @@ class CleanInteTest : public testing::Test { struct_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto int_builder = static_cast(struct_builder.field_builder(1)); - auto int_builder1 = static_cast(struct_builder.field_builder(2)); - auto double_builder = static_cast(struct_builder.field_builder(3)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(1)); + auto int_builder1 = checked_cast(struct_builder.field_builder(2)); + auto double_builder = checked_cast(struct_builder.field_builder(3)); for (const auto& d : raw_data) { EXPECT_TRUE(struct_builder.Append().ok()); diff --git a/test/inte/pk_compaction_inte_test.cpp b/test/inte/pk_compaction_inte_test.cpp index 9103fbcc..a7441aca 100644 --- a/test/inte/pk_compaction_inte_test.cpp +++ b/test/inte/pk_compaction_inte_test.cpp @@ -33,6 +33,7 @@ #include "paimon/commit_context.h" #include "paimon/common/factories/io_hook.h" #include "paimon/common/table/special_fields.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/core/deletionvectors/deletion_vectors_index_file.h" #include "paimon/core/io/data_file_meta.h" @@ -3542,7 +3543,7 @@ TEST_F(PkCompactionInteTest, AggHllAndThetaSketches) { } children[column + 1] = builder.Finish().ValueOrDie(); } - return std::static_pointer_cast( + return checked_pointer_cast( arrow::StructArray::Make(children, fields).ValueOrDie()); }; @@ -3567,10 +3568,10 @@ TEST_F(PkCompactionInteTest, AggHllAndThetaSketches) { std::map> estimates; ScanAllRows(table_path, [&estimates](const std::shared_ptr& result) { for (const std::shared_ptr& chunk : result->chunks()) { - auto rows = std::static_pointer_cast(chunk); - auto keys = std::static_pointer_cast(rows->field(1)); - auto hll_column = std::static_pointer_cast(rows->field(2)); - auto theta_column = std::static_pointer_cast(rows->field(3)); + auto rows = checked_pointer_cast(chunk); + auto keys = checked_pointer_cast(rows->field(1)); + auto hll_column = checked_pointer_cast(rows->field(2)); + auto theta_column = checked_pointer_cast(rows->field(3)); for (int64_t i = 0; i < rows->length(); ++i) { ASSERT_FALSE(hll_column->IsNull(i)); ASSERT_FALSE(theta_column->IsNull(i)); diff --git a/test/inte/variant_table_inte_test.cpp b/test/inte/variant_table_inte_test.cpp index 3cedac21..ba41c59c 100644 --- a/test/inte/variant_table_inte_test.cpp +++ b/test/inte/variant_table_inte_test.cpp @@ -33,6 +33,7 @@ #include "paimon/common/data/variant/variant_shredding_utils.h" #include "paimon/common/data/variant/variant_type_utils.h" #include "paimon/common/factories/io_hook.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/path_util.h" #include "paimon/common/utils/scope_guard.h" #include "paimon/core/io/data_file_meta.h" @@ -93,20 +94,18 @@ class VariantTableInteTest : public ::testing::Test { const std::vector& expected_jsons) { ASSERT_OK_AND_ASSIGN(auto result, helper->ReadResult(splits)); ASSERT_EQ(result->num_chunks(), 1); - auto result_struct = std::static_pointer_cast(result->chunk(0)); + auto result_struct = checked_pointer_cast(result->chunk(0)); ASSERT_EQ(result_struct->length(), static_cast(expected_jsons.size())); - auto struct_type = std::static_pointer_cast(result_struct->type()); + auto struct_type = checked_pointer_cast(result_struct->type()); int32_t id_index = struct_type->GetFieldIndex("id"); int32_t variant_index = struct_type->GetFieldIndex("v"); ASSERT_GE(id_index, 0); ASSERT_GE(variant_index, 0); - auto id_column = - std::static_pointer_cast(result_struct->field(id_index)); + auto id_column = checked_pointer_cast(result_struct->field(id_index)); auto variant_column = - std::static_pointer_cast(result_struct->field(variant_index)); - auto value_column = std::static_pointer_cast(variant_column->field(0)); - auto metadata_column = - std::static_pointer_cast(variant_column->field(1)); + checked_pointer_cast(result_struct->field(variant_index)); + auto value_column = checked_pointer_cast(variant_column->field(0)); + auto metadata_column = checked_pointer_cast(variant_column->field(1)); for (size_t i = 0; i < expected_jsons.size(); ++i) { SCOPED_TRACE("row " + std::to_string(i)); ASSERT_EQ(id_column->Value(i), expected_ids[i]); @@ -151,7 +150,7 @@ class VariantTableInteTest : public ::testing::Test { ASSERT_TRUE(arrow::ExportSchema(*read_schema, c_read_schema.get()).ok()); ASSERT_OK_AND_ASSIGN(auto result, helper->ReadResult(splits, std::move(c_read_schema))); ASSERT_EQ(result->num_chunks(), 1); - *result_struct = std::static_pointer_cast(result->chunk(0)); + *result_struct = checked_pointer_cast(result->chunk(0)); } Result> ReadDataFileSchema( @@ -441,18 +440,18 @@ TEST_F(VariantTableInteTest, TestAdaptiveInferenceWithMultipleVariantFields) { ASSERT_OK_AND_ASSIGN(std::shared_ptr result, helper->ReadResult(splits)); std::map actual; for (const std::shared_ptr& chunk : result->chunks()) { - auto rows = std::static_pointer_cast(chunk); - auto row_type = std::static_pointer_cast(rows->type()); + auto rows = checked_pointer_cast(chunk); + auto row_type = checked_pointer_cast(rows->type()); auto ids = - std::static_pointer_cast(rows->field(row_type->GetFieldIndex("id"))); - auto left = std::static_pointer_cast( + checked_pointer_cast(rows->field(row_type->GetFieldIndex("id"))); + auto left = checked_pointer_cast( rows->field(row_type->GetFieldIndex("left_payload"))); - auto right = std::static_pointer_cast( + auto right = checked_pointer_cast( rows->field(row_type->GetFieldIndex("right_payload"))); - auto left_values = std::static_pointer_cast(left->field(0)); - auto left_metadata = std::static_pointer_cast(left->field(1)); - auto right_values = std::static_pointer_cast(right->field(0)); - auto right_metadata = std::static_pointer_cast(right->field(1)); + auto left_values = checked_pointer_cast(left->field(0)); + auto left_metadata = checked_pointer_cast(left->field(1)); + auto right_values = checked_pointer_cast(right->field(0)); + auto right_metadata = checked_pointer_cast(right->field(1)); for (int64_t i = 0; i < rows->length(); ++i) { ASSERT_OK_AND_ASSIGN( std::shared_ptr left_variant, @@ -555,7 +554,7 @@ TEST_F(VariantTableInteTest, TestAdaptiveInferenceWithNestedVariant) { ReadDataFileSchema(data_split->BucketPath(), files[i], options)); std::shared_ptr file_nested = file_schema->GetFieldByName("nested"); ASSERT_NE(file_nested, nullptr); - auto file_nested_type = std::static_pointer_cast(file_nested->type()); + auto file_nested_type = checked_pointer_cast(file_nested->type()); std::shared_ptr file_variant = file_nested_type->GetFieldByName("payload"); ASSERT_NE(file_variant, nullptr); ASSERT_TRUE(file_variant->type()->Equals(*expected_types[i])) @@ -566,19 +565,19 @@ TEST_F(VariantTableInteTest, TestAdaptiveInferenceWithNestedVariant) { ASSERT_OK_AND_ASSIGN(std::shared_ptr result, helper->ReadResult(splits)); std::map actual; for (const std::shared_ptr& chunk : result->chunks()) { - auto rows = std::static_pointer_cast(chunk); - auto row_type = std::static_pointer_cast(rows->type()); + auto rows = checked_pointer_cast(chunk); + auto row_type = checked_pointer_cast(rows->type()); auto ids = - std::static_pointer_cast(rows->field(row_type->GetFieldIndex("id"))); - auto nested = std::static_pointer_cast( + checked_pointer_cast(rows->field(row_type->GetFieldIndex("id"))); + auto nested = checked_pointer_cast( rows->field(row_type->GetFieldIndex("nested"))); - auto nested_type = std::static_pointer_cast(nested->type()); - auto label_column = std::static_pointer_cast( + auto nested_type = checked_pointer_cast(nested->type()); + auto label_column = checked_pointer_cast( nested->field(nested_type->GetFieldIndex("label"))); - auto variant = std::static_pointer_cast( + auto variant = checked_pointer_cast( nested->field(nested_type->GetFieldIndex("payload"))); - auto value_column = std::static_pointer_cast(variant->field(0)); - auto metadata_column = std::static_pointer_cast(variant->field(1)); + auto value_column = checked_pointer_cast(variant->field(0)); + auto metadata_column = checked_pointer_cast(variant->field(1)); for (int64_t i = 0; i < rows->length(); ++i) { ASSERT_OK_AND_ASSIGN(std::shared_ptr value, GenericVariant::Create(value_column->GetView(i), @@ -647,8 +646,8 @@ TEST_F(VariantTableInteTest, TestVariantAccessRead) { std::shared_ptr result_struct; ReadWithSchema(helper.get(), splits, read_schema, &result_struct); ASSERT_EQ(result_struct->length(), 3); - auto struct_type = std::static_pointer_cast(result_struct->type()); - auto v_column = std::static_pointer_cast( + auto struct_type = checked_pointer_cast(result_struct->type()); + auto v_column = checked_pointer_cast( result_struct->field(struct_type->GetFieldIndex("v"))); const auto& age = static_cast(*v_column->field(0)); const auto& other = static_cast(*v_column->field(1)); @@ -709,8 +708,8 @@ TEST_F(VariantTableInteTest, TestNestedRowVariantAccessRead) { std::shared_ptr result_struct; ReadWithSchema(helper.get(), splits, read_schema, &result_struct); - auto struct_type = std::static_pointer_cast(result_struct->type()); - auto s_column = std::static_pointer_cast( + auto struct_type = checked_pointer_cast(result_struct->type()); + auto s_column = checked_pointer_cast( result_struct->field(struct_type->GetFieldIndex("s"))); const auto& nv = static_cast(*s_column->field(0)); const auto& age = static_cast(*nv.field(0)); @@ -771,7 +770,7 @@ TEST_F(VariantTableInteTest, TestArrayVariantAccessRead) { std::shared_ptr result_struct; ReadWithSchema(helper.get(), splits, read_schema, &result_struct); - auto struct_type = std::static_pointer_cast(result_struct->type()); + auto struct_type = checked_pointer_cast(result_struct->type()); const auto& list = static_cast( *result_struct->field(struct_type->GetFieldIndex("arr"))); ASSERT_EQ(list.length(), 3); diff --git a/test/inte/write_and_read_inte_test.cpp b/test/inte/write_and_read_inte_test.cpp index bdb0e2db..a14461b8 100644 --- a/test/inte/write_and_read_inte_test.cpp +++ b/test/inte/write_and_read_inte_test.cpp @@ -34,6 +34,7 @@ #include "paimon/commit_context.h" #include "paimon/common/data/shredding/map_shared_shredding_utils.h" #include "paimon/common/reader/reader_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/path_util.h" #include "paimon/common/utils/string_utils.h" @@ -472,18 +473,16 @@ TEST_P(WriteAndReadInteTest, TestSchemaEvolutionAddFieldInsideListAndMap) { int32_t next_id = schema_v0->HighestFieldId(); auto items_field = fields_v0[1].ArrowField(); - auto items_list = arrow::internal::checked_pointer_cast(items_field->type()); - auto items_struct = - arrow::internal::checked_pointer_cast(items_list->value_type()); + auto items_list = checked_pointer_cast(items_field->type()); + auto items_struct = checked_pointer_cast(items_list->value_type()); auto c_field = DataField::ConvertDataFieldToArrowField( DataField(++next_id, arrow::field("c", arrow::int32()))); auto new_items_type = arrow::list(items_list->value_field()->WithType( arrow::struct_({items_struct->field(0), items_struct->field(1), c_field}))); auto props_field = fields_v0[2].ArrowField(); - auto props_map = arrow::internal::checked_pointer_cast(props_field->type()); - auto props_value = - arrow::internal::checked_pointer_cast(props_map->item_type()); + auto props_map = checked_pointer_cast(props_field->type()); + auto props_value = checked_pointer_cast(props_map->item_type()); auto m2_field = DataField::ConvertDataFieldToArrowField( DataField(++next_id, arrow::field("m2", arrow::int32()))); auto new_props_type = arrow::map( @@ -3132,9 +3131,8 @@ TEST_P(WriteAndReadInteTest, TestMapSharedShreddingStructValueSchemaEvolutionRea }; auto tag_field = fields_v0[1].ArrowField(); - auto tag_map = arrow::internal::checked_pointer_cast(tag_field->type()); - auto tag_value_struct = - arrow::internal::checked_pointer_cast(tag_map->item_type()); + auto tag_map = checked_pointer_cast(tag_field->type()); + auto tag_value_struct = checked_pointer_cast(tag_map->item_type()); // Simulate alter table changing the shared-shredding MAP value struct field type. auto changed_tag_value_type = @@ -3151,8 +3149,7 @@ TEST_P(WriteAndReadInteTest, TestMapSharedShreddingStructValueSchemaEvolutionRea "PruneDataType nested item type mismatch inside map: read string vs data int64"); auto profile_field = fields_v0[2].ArrowField(); - auto profile_struct = - arrow::internal::checked_pointer_cast(profile_field->type()); + auto profile_struct = checked_pointer_cast(profile_field->type()); // Simulate alter table renaming a nested field inside a STRUCT column. std::vector fields_with_renamed_profile_child = fields_v0; diff --git a/test/inte/write_inte_test.cpp b/test/inte/write_inte_test.cpp index 11564b93..ffa02140 100644 --- a/test/inte/write_inte_test.cpp +++ b/test/inte/write_inte_test.cpp @@ -51,6 +51,7 @@ #include "paimon/common/types/data_field.h" #include "paimon/common/types/row_kind.h" #include "paimon/common/utils/arrow/status_utils.h" +#include "paimon/common/utils/checked_cast.h" #include "paimon/common/utils/date_time_utils.h" #include "paimon/common/utils/decimal_utils.h" #include "paimon/common/utils/path_util.h" @@ -173,10 +174,10 @@ class WriteInteTest : public testing::Test, public ::testing::WithParamInterface struct_type, arrow::default_memory_pool(), {std::make_shared(), std::make_shared(), std::make_shared(), std::make_shared()}); - auto string_builder = static_cast(struct_builder.field_builder(0)); - auto int_builder = static_cast(struct_builder.field_builder(1)); - auto int_builder1 = static_cast(struct_builder.field_builder(2)); - auto double_builder = static_cast(struct_builder.field_builder(3)); + auto string_builder = checked_cast(struct_builder.field_builder(0)); + auto int_builder = checked_cast(struct_builder.field_builder(1)); + auto int_builder1 = checked_cast(struct_builder.field_builder(2)); + auto double_builder = checked_cast(struct_builder.field_builder(3)); for (const auto& d : raw_data) { EXPECT_TRUE(struct_builder.Append().ok()); @@ -317,7 +318,7 @@ class WriteInteTest : public testing::Test, public ::testing::WithParamInterface {BlobUtils::ToArrowField(blob_field, false)})); PAIMON_ASSIGN_OR_RAISE( auto actual_blobs, - TestHelper::ToBlobs(std::static_pointer_cast(blob_struct_array))); + TestHelper::ToBlobs(checked_pointer_cast(blob_struct_array))); PAIMON_ASSIGN_OR_RAISE(bool blobs_equal, TestHelper::CheckBlobsEqual( actual_blobs, expected_blobs, file_system_)); if (!blobs_equal) {