Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion cpp/src/arrow/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,12 @@ class ARROW_EXPORT DataType : public std::enable_shared_from_this<DataType>,
bool Equals(const std::shared_ptr<DataType>& other, bool check_metadata = false) const;

/// \brief Return the child field at index i.
const std::shared_ptr<Field>& field(int i) const { return children_[i]; }
///
/// Returns a null shared_ptr if index is out of bounds [0, num_fields()).
const std::shared_ptr<Field>& field(int i) const {
static const std::shared_ptr<Field> kNullField;
return (i < 0 || i >= num_fields()) ? kNullField : children_[i];
}

/// \brief Return the children fields associated with this type.
const FieldVector& fields() const { return children_; }
Expand Down
21 changes: 20 additions & 1 deletion cpp/src/arrow/type_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2029,8 +2029,27 @@ TEST(TestStructType, Basics) {
auto t3 = struct_({field("c", int8()), field("b", utf8())});
ASSERT_TRUE(t1->Equals(t2));
ASSERT_TRUE(!t1->Equals(t3));
}

// Test that out-of-bounds field access returns null
TEST(TestStructType, FieldAccessOutOfBounds) {
auto f0 = field("f0", int32());
auto f1 = field("f1", utf8());
auto f2 = field("f2", uint8());
StructType struct_type({f0, f1, f2});

ASSERT_EQ(struct_type.num_fields(), 3);

// Out-of-bounds indices return nullptr
ASSERT_EQ(struct_type.field(3), nullptr);
ASSERT_EQ(struct_type.field(4), nullptr);
ASSERT_EQ(struct_type.field(100), nullptr);
ASSERT_EQ(struct_type.field(-1), nullptr);

// TODO(wesm): out of bounds for field(...)
// All out-of-bounds accesses return the same static null
const auto& null1 = struct_type.field(3);
const auto& null2 = struct_type.field(100);
EXPECT_EQ(&null1, &null2);
}

TEST(TestStructType, GetFieldByName) {
Expand Down
Loading