| 27 | |
| 28 | namespace { |
| 29 | Status CastToExtension(KernelContext* ctx, const ExecSpan& batch, ExecResult* out) { |
| 30 | const CastOptions& options = checked_cast<const CastState*>(ctx->state())->options; |
| 31 | const auto& ext_ty = static_cast<const ExtensionType&>(*options.to_type.type); |
| 32 | auto out_ty = ext_ty.storage_type(); |
| 33 | |
| 34 | DCHECK(batch[0].is_array()); |
| 35 | std::shared_ptr<Array> array = batch[0].array.ToArray(); |
| 36 | |
| 37 | // Try to prevent user errors by preventing casting between extensions w/ |
| 38 | // different storage types. Provide a tip on how to accomplish same outcome. |
| 39 | std::shared_ptr<Array> result; |
| 40 | if (array->type()->id() == Type::EXTENSION) { |
| 41 | if (!array->type()->Equals(out_ty)) { |
| 42 | return Status::TypeError("Casting from '" + array->type()->ToString() + |
| 43 | "' to different extension type '" + ext_ty.ToString() + |
| 44 | "' not permitted. One can first cast to the storage " |
| 45 | "type, then to the extension type."); |
| 46 | } |
| 47 | result = array; |
| 48 | } else { |
| 49 | ARROW_ASSIGN_OR_RAISE(result, Cast(*array, out_ty, options, ctx->exec_context())); |
| 50 | } |
| 51 | |
| 52 | ExtensionArray extension(options.to_type.GetSharedPtr(), result); |
| 53 | out->value = std::move(extension.data()); |
| 54 | return Status::OK(); |
| 55 | } |
| 56 | |
| 57 | std::shared_ptr<CastFunction> GetCastToExtension(std::string name) { |
| 58 | auto func = std::make_shared<CastFunction>(std::move(name), Type::EXTENSION); |
nothing calls this directly
no test coverage detected