| 143 | |
| 144 | template <typename TYPE> |
| 145 | Result<std::shared_ptr<typename TypeTraits<TYPE>::ArrayType>> ListViewArrayFromArrays( |
| 146 | std::shared_ptr<DataType> type, const Array& offsets, const Array& sizes, |
| 147 | const Array& values, MemoryPool* pool, std::shared_ptr<Buffer> null_bitmap = NULLPTR, |
| 148 | int64_t null_count = kUnknownNullCount) { |
| 149 | using offset_type = typename TYPE::offset_type; |
| 150 | using ArrayType = typename TypeTraits<TYPE>::ArrayType; |
| 151 | using OffsetArrowType = typename CTypeTraits<offset_type>::ArrowType; |
| 152 | |
| 153 | if (offsets.type_id() != OffsetArrowType::type_id) { |
| 154 | return Status::TypeError("List offsets must be ", OffsetArrowType::type_name()); |
| 155 | } |
| 156 | |
| 157 | if (sizes.length() != offsets.length() && sizes.length() != offsets.length() - 1) { |
| 158 | return Status::Invalid( |
| 159 | "List sizes must have the same length as offsets or one less than offsets"); |
| 160 | } |
| 161 | if (sizes.type_id() != OffsetArrowType::type_id) { |
| 162 | return Status::TypeError("List sizes must be ", OffsetArrowType::type_name()); |
| 163 | } |
| 164 | |
| 165 | if (offsets.offset() != sizes.offset()) { |
| 166 | return Status::Invalid("List offsets and sizes must have the same offset"); |
| 167 | } |
| 168 | const int64_t array_offset = sizes.offset(); |
| 169 | |
| 170 | if (null_bitmap) { |
| 171 | if (offsets.null_count() > 0 || sizes.null_count() > 0) { |
| 172 | return Status::Invalid( |
| 173 | "Ambiguous to specify both validity map and offsets or sizes with nulls"); |
| 174 | } |
| 175 | if (array_offset != 0) { |
| 176 | return Status::Invalid( |
| 177 | "List offsets and sizes must not be slices if a validity map is specified"); |
| 178 | } |
| 179 | } else { |
| 180 | if (offsets.null_count() > 0 && sizes.null_count() > 0) { |
| 181 | return Status::Invalid("Ambiguous to specify both offsets and sizes with nulls"); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | DCHECK(offsets.length() == sizes.length() || offsets.length() - 1 == sizes.length()); |
| 186 | |
| 187 | using OffsetArrayType = typename TypeTraits<OffsetArrowType>::ArrayType; |
| 188 | const auto& typed_offsets = checked_cast<const OffsetArrayType&>(offsets); |
| 189 | const auto& typed_sizes = checked_cast<const OffsetArrayType&>(sizes); |
| 190 | |
| 191 | auto derived_validity_buffer = std::move(null_bitmap); |
| 192 | if (offsets.null_count() > 0) { |
| 193 | derived_validity_buffer = offsets.null_bitmap(); |
| 194 | null_count = offsets.null_count(); |
| 195 | // We allow construction from an offsets array containing one extra value. |
| 196 | // If that is the case, we might need to discount one null from out_null_count. |
| 197 | if (offsets.length() - 1 == sizes.length() && !offsets.IsValid(sizes.length())) { |
| 198 | null_count -= 1; |
| 199 | } |
| 200 | } else if (sizes.null_count() > 0) { |
| 201 | derived_validity_buffer = sizes.null_bitmap(); |
| 202 | null_count = sizes.null_count(); |
nothing calls this directly
no test coverage detected