| 157 | : PrimitiveConverter(pool, type) {} |
| 158 | |
| 159 | Status Convert(const std::shared_ptr<Array>& in, std::shared_ptr<Array>* out) override { |
| 160 | if (in->type_id() == Type::NA) { |
| 161 | return MakeArrayOfNull(out_type_, in->length(), pool_).Value(out); |
| 162 | } |
| 163 | const auto& dict_array = GetDictionaryArray(in); |
| 164 | |
| 165 | using Builder = typename TypeTraits<T>::BuilderType; |
| 166 | Builder builder(out_type_, pool_); |
| 167 | RETURN_NOT_OK(builder.Resize(dict_array.indices()->length())); |
| 168 | const auto& decimal_type(checked_cast<const DecimalType&>(*out_type_)); |
| 169 | int32_t out_precision = decimal_type.precision(); |
| 170 | int32_t out_scale = decimal_type.scale(); |
| 171 | |
| 172 | auto visit_valid = [&](string_view repr) { |
| 173 | value_type value; |
| 174 | int32_t precision, scale; |
| 175 | RETURN_NOT_OK(TypeTraits<T>::BuilderType::ValueType::FromString( |
| 176 | repr, &value, &precision, &scale)); |
| 177 | if (precision > out_precision) { |
| 178 | return GenericConversionError(*out_type_, ": ", repr, " requires precision ", |
| 179 | precision); |
| 180 | } |
| 181 | if (scale != out_scale) { |
| 182 | auto result = value.Rescale(scale, out_scale); |
| 183 | if (ARROW_PREDICT_FALSE(!result.ok())) { |
| 184 | return GenericConversionError(*out_type_, ": ", repr, " requires scale ", |
| 185 | scale); |
| 186 | } else { |
| 187 | value = result.MoveValueUnsafe(); |
| 188 | } |
| 189 | } |
| 190 | builder.UnsafeAppend(value); |
| 191 | return Status::OK(); |
| 192 | }; |
| 193 | |
| 194 | auto visit_null = [&builder]() { |
| 195 | builder.UnsafeAppendNull(); |
| 196 | return Status::OK(); |
| 197 | }; |
| 198 | |
| 199 | RETURN_NOT_OK(VisitDictionaryEntries(dict_array, visit_valid, visit_null)); |
| 200 | return builder.Finish(out); |
| 201 | } |
| 202 | }; |
| 203 | |
| 204 | template <typename DateTimeType> |
nothing calls this directly
no test coverage detected