@@ -132,6 +132,99 @@ int64_t ArrayData::GetNullCount() const {
132132
133133int64_t Array::null_count () const { return data_->GetNullCount (); }
134134
135+ namespace internal {
136+
137+ struct ScalarFromArraySlotImpl {
138+ template <typename T>
139+ using ScalarType = typename TypeTraits<T>::ScalarType;
140+
141+ Status Visit (const NullArray& a) {
142+ out_ = std::make_shared<NullScalar>();
143+ return Status::OK ();
144+ }
145+
146+ Status Visit (const BooleanArray& a) { return Finish (a.Value (index_)); }
147+
148+ template <typename T>
149+ Status Visit (const NumericArray<T>& a) {
150+ return Finish (a.Value (index_));
151+ }
152+
153+ template <typename T>
154+ Status Visit (const BaseBinaryArray<T>& a) {
155+ return Finish (a.GetString (index_));
156+ }
157+
158+ Status Visit (const FixedSizeBinaryArray& a) { return Finish (a.GetString (index_)); }
159+
160+ Status Visit (const DayTimeIntervalArray& a) { return Finish (a.Value (index_)); }
161+
162+ template <typename T>
163+ Status Visit (const BaseListArray<T>& a) {
164+ return Finish (a.value_slice (index_));
165+ }
166+
167+ Status Visit (const FixedSizeListArray& a) { return Finish (a.value_slice (index_)); }
168+
169+ Status Visit (const StructArray& a) {
170+ ScalarVector children;
171+ for (const auto & child : a.fields ()) {
172+ children.emplace_back ();
173+ ARROW_ASSIGN_OR_RAISE (children.back (), child->GetScalar (index_));
174+ }
175+ return Finish (std::move (children));
176+ }
177+
178+ Status Visit (const UnionArray& a) {
179+ return Status::NotImplemented (" Non-null UnionScalar" );
180+ }
181+
182+ Status Visit (const DictionaryArray& a) {
183+ ARROW_ASSIGN_OR_RAISE (auto value, a.dictionary ()->GetScalar (a.GetValueIndex (index_)));
184+ return Finish (std::move (value));
185+ }
186+
187+ Status Visit (const ExtensionArray& a) {
188+ return Status::NotImplemented (" Non-null ExtensionScalar" );
189+ }
190+
191+ template <typename Arg>
192+ Status Finish (Arg&& arg) {
193+ return MakeScalar (array_.type (), std::forward<Arg>(arg)).Value (&out_);
194+ }
195+
196+ Status Finish (std::string arg) {
197+ return MakeScalar (array_.type (), Buffer::FromString (std::move (arg))).Value (&out_);
198+ }
199+
200+ Result<std::shared_ptr<Scalar>> Finish () && {
201+ if (index_ >= array_.length ()) {
202+ return Status::IndexError (" tried to refer to element " , index_,
203+ " but array is only " , array_.length (), " long" );
204+ }
205+
206+ if (array_.IsNull (index_)) {
207+ return MakeNullScalar (array_.type ());
208+ }
209+
210+ RETURN_NOT_OK (VisitArrayInline (array_, this ));
211+ return std::move (out_);
212+ }
213+
214+ ScalarFromArraySlotImpl (const Array& array, int64_t index)
215+ : array_(array), index_(index) {}
216+
217+ const Array& array_;
218+ int64_t index_;
219+ std::shared_ptr<Scalar> out_;
220+ };
221+
222+ } // namespace internal
223+
224+ Result<std::shared_ptr<Scalar>> Array::GetScalar (int64_t i) const {
225+ return internal::ScalarFromArraySlotImpl{*this , i}.Finish ();
226+ }
227+
135228std::string Array::Diff (const Array& other) const {
136229 std::stringstream diff;
137230 ARROW_IGNORE_EXPR (Equals (other, EqualOptions ().diff_sink (&diff)));
@@ -363,20 +456,20 @@ Result<std::shared_ptr<Array>> FlattenListArray(const ListArrayT& list_array,
363456
364457} // namespace
365458
366- ListArray::ListArray (const std::shared_ptr<ArrayData>& data) { SetData (data); }
459+ ListArray::ListArray (std::shared_ptr<ArrayData> data) { SetData (std::move ( data) ); }
367460
368461LargeListArray::LargeListArray (const std::shared_ptr<ArrayData>& data) { SetData (data); }
369462
370- ListArray::ListArray (const std::shared_ptr<DataType>& type, int64_t length,
371- const std::shared_ptr<Buffer>& value_offsets,
372- const std::shared_ptr<Array>& values,
373- const std::shared_ptr<Buffer>& null_bitmap, int64_t null_count,
463+ ListArray::ListArray (std::shared_ptr<DataType> type, int64_t length,
464+ std::shared_ptr<Buffer> value_offsets, std::shared_ptr<Array> values,
465+ std::shared_ptr<Buffer> null_bitmap, int64_t null_count,
374466 int64_t offset) {
375467 ARROW_CHECK_EQ (type->id (), Type::LIST );
376- auto internal_data =
377- ArrayData::Make (type, length, {null_bitmap, value_offsets}, null_count, offset);
468+ auto internal_data = ArrayData::Make (
469+ std::move (type), length,
470+ BufferVector{std::move (null_bitmap), std::move (value_offsets)}, null_count, offset);
378471 internal_data->child_data .emplace_back (values->data ());
379- SetData (internal_data);
472+ SetData (std::move ( internal_data) );
380473}
381474
382475LargeListArray::LargeListArray (const std::shared_ptr<DataType>& type, int64_t length,
@@ -788,6 +881,13 @@ const StructType* StructArray::struct_type() const {
788881 return checked_cast<const StructType*>(data_->type .get ());
789882}
790883
884+ const ArrayVector& StructArray::fields () const {
885+ for (int i = 0 ; i < num_fields (); ++i) {
886+ (void )field (i);
887+ }
888+ return boxed_fields_;
889+ }
890+
791891std::shared_ptr<Array> StructArray::field (int i) const {
792892 std::shared_ptr<Array> result = internal::atomic_load (&boxed_fields_[i]);
793893 if (!result) {
@@ -1034,6 +1134,23 @@ Status ValidateDictionaryIndices(const std::shared_ptr<Array>& indices,
10341134
10351135std::shared_ptr<Array> DictionaryArray::indices () const { return indices_; }
10361136
1137+ int64_t DictionaryArray::GetValueIndex (int64_t i) const {
1138+ switch (indices_->type_id ()) {
1139+ case Type::INT8 :
1140+ return checked_cast<const Int8Array&>(*indices_).Value (i);
1141+ case Type::INT16 :
1142+ return checked_cast<const Int16Array&>(*indices_).Value (i);
1143+ case Type::INT32 :
1144+ return checked_cast<const Int32Array&>(*indices_).Value (i);
1145+ case Type::INT64 :
1146+ return checked_cast<const Int64Array&>(*indices_).Value (i);
1147+ default :
1148+ break ;
1149+ }
1150+ ARROW_CHECK (false ) << " unreachable" ;
1151+ return -1 ;
1152+ }
1153+
10371154DictionaryArray::DictionaryArray (const std::shared_ptr<ArrayData>& data)
10381155 : dict_type_(checked_cast<const DictionaryType*>(data->type.get())) {
10391156 ARROW_CHECK_EQ (data->type ->id (), Type::DICTIONARY );
0 commit comments