3232#include " arrow/util/logging.h"
3333
3434namespace arrow {
35+
36+ using internal::ToTypeName;
37+
3538namespace compute {
3639namespace internal {
3740
@@ -54,6 +57,29 @@ void InitCastTable() {
5457
5558void EnsureInitCastTable () { std::call_once (cast_table_initialized, InitCastTable); }
5659
60+ namespace {
61+
62+ // Private version of GetCastFunction with better error reporting
63+ // if the input type is known.
64+ Result<std::shared_ptr<CastFunction>> GetCastFunctionInternal (
65+ const std::shared_ptr<DataType>& to_type, const DataType* from_type = nullptr ) {
66+ internal::EnsureInitCastTable ();
67+ auto it = internal::g_cast_table.find (static_cast <int >(to_type->id ()));
68+ if (it == internal::g_cast_table.end ()) {
69+ if (from_type != nullptr ) {
70+ return Status::NotImplemented (" Unsupported cast from " , *from_type, " to " ,
71+ *to_type,
72+ " (no available cast function for target type)" );
73+ } else {
74+ return Status::NotImplemented (" Unsupported cast to " , *to_type,
75+ " (no available cast function for target type)" );
76+ }
77+ }
78+ return it->second ;
79+ }
80+
81+ } // namespace
82+
5783// Metafunction for dispatching to appropraite CastFunction. This corresponds
5884// to the standard SQL CAST(expr AS target_type)
5985class CastMetaFunction : public MetaFunction {
@@ -79,8 +105,9 @@ class CastMetaFunction : public MetaFunction {
79105 if (args[0 ].type ()->Equals (*cast_options->to_type )) {
80106 return args[0 ];
81107 }
82- ARROW_ASSIGN_OR_RAISE (std::shared_ptr<CastFunction> cast_func,
83- GetCastFunction (cast_options->to_type ));
108+ ARROW_ASSIGN_OR_RAISE (
109+ std::shared_ptr<CastFunction> cast_func,
110+ GetCastFunctionInternal (cast_options->to_type , args[0 ].type ().get ()));
84111 return cast_func->Execute (args, options, ctx);
85112 }
86113};
@@ -147,9 +174,9 @@ Result<const ScalarKernel*> CastFunction::DispatchExact(
147174 }
148175
149176 if (candidate_kernels.size () == 0 ) {
150- return Status::NotImplemented (" Function " , this -> name (),
151- " has no kernel matching input type " ,
152- values[ 0 ]. ToString ());
177+ return Status::NotImplemented (" Unsupported cast from " , values[ 0 ]. type -> ToString (),
178+ " to " , ToTypeName (impl_-> out_type ), " using function " ,
179+ this -> name ());
153180 } else if (candidate_kernels.size () == 1 ) {
154181 // One match, return it
155182 return candidate_kernels[0 ];
@@ -188,13 +215,7 @@ Result<std::shared_ptr<Array>> Cast(const Array& value, std::shared_ptr<DataType
188215
189216Result<std::shared_ptr<CastFunction>> GetCastFunction (
190217 const std::shared_ptr<DataType>& to_type) {
191- internal::EnsureInitCastTable ();
192- auto it = internal::g_cast_table.find (static_cast <int >(to_type->id ()));
193- if (it == internal::g_cast_table.end ()) {
194- return Status::NotImplemented (" No cast function available to cast to " ,
195- to_type->ToString ());
196- }
197- return it->second ;
218+ return internal::GetCastFunctionInternal (to_type);
198219}
199220
200221bool CanCast (const DataType& from_type, const DataType& to_type) {
0 commit comments