@@ -545,67 +545,61 @@ Result<Expression> BindNonRecursive(Expression::Call call, bool insert_implicit_
545545 std::vector<TypeHolder> types = GetTypes (call.arguments );
546546 ARROW_ASSIGN_OR_RAISE (call.function , GetFunction (call, exec_context));
547547
548- auto FinishBind = [&] {
549- compute::KernelContext kernel_context (exec_context, call.kernel );
550- if (call.kernel ->init ) {
551- const FunctionOptions* options =
552- call.options ? call.options .get () : call.function ->default_options ();
553- ARROW_ASSIGN_OR_RAISE (
554- call.kernel_state ,
555- call.kernel ->init (&kernel_context, {call.kernel , types, options}));
556-
557- kernel_context.SetState (call.kernel_state .get ());
558- }
559-
560- ARROW_ASSIGN_OR_RAISE (
561- call.type , call.kernel ->signature ->out_type ().Resolve (&kernel_context, types));
562- return Status::OK ();
563- };
564-
565548 // First try and bind exactly
566549 Result<const Kernel*> maybe_exact_match = call.function ->DispatchExact (types);
567550 if (maybe_exact_match.ok ()) {
568551 call.kernel = *maybe_exact_match;
569- if (FinishBind ().ok ()) {
570- return Expression (std::move (call));
552+ } else {
553+ if (!insert_implicit_casts) {
554+ return maybe_exact_match.status ();
571555 }
572- }
573556
574- if (!insert_implicit_casts) {
575- return maybe_exact_match.status ();
576- }
557+ // If exact binding fails, and we are allowed to cast, then prefer casting literals
558+ // first. Since DispatchBest generally prefers up-casting the best way to do this is
559+ // first down-cast the literals as much as possible
560+ types = GetTypesWithSmallestLiteralRepresentation (call.arguments );
561+ ARROW_ASSIGN_OR_RAISE (call.kernel , call.function ->DispatchBest (&types));
577562
578- // If exact binding fails, and we are allowed to cast, then prefer casting literals
579- // first. Since DispatchBest generally prefers up-casting the best way to do this is
580- // first down-cast the literals as much as possible
581- types = GetTypesWithSmallestLiteralRepresentation (call.arguments );
582- ARROW_ASSIGN_OR_RAISE (call.kernel , call.function ->DispatchBest (&types));
563+ for (size_t i = 0 ; i < types.size (); ++i) {
564+ if (types[i] == call.arguments [i].type ()) continue ;
583565
584- for (size_t i = 0 ; i < types.size (); ++i) {
585- if (types[i] == call.arguments [i].type ()) continue ;
566+ if (const Datum* lit = call.arguments [i].literal ()) {
567+ ARROW_ASSIGN_OR_RAISE (Datum new_lit,
568+ compute::Cast (*lit, types[i].GetSharedPtr ()));
569+ call.arguments [i] = literal (std::move (new_lit));
570+ continue ;
571+ }
586572
587- if (const Datum* lit = call.arguments [i].literal ()) {
588- ARROW_ASSIGN_OR_RAISE (Datum new_lit, compute::Cast (*lit, types[i].GetSharedPtr ()));
589- call.arguments [i] = literal (std::move (new_lit));
590- continue ;
591- }
573+ // construct an implicit cast Expression with which to replace this argument
574+ Expression::Call implicit_cast;
575+ implicit_cast.function_name = " cast" ;
576+ implicit_cast.arguments = {std::move (call.arguments [i])};
592577
593- // construct an implicit cast Expression with which to replace this argument
594- Expression::Call implicit_cast;
595- implicit_cast.function_name = " cast" ;
596- implicit_cast.arguments = {std::move (call.arguments [i])};
578+ // TODO(wesm): Use TypeHolder in options
579+ implicit_cast.options = std::make_shared<compute::CastOptions>(
580+ compute::CastOptions::Safe (types[i].GetSharedPtr ()));
597581
598- // TODO(wesm): Use TypeHolder in options
599- implicit_cast.options = std::make_shared<compute::CastOptions>(
600- compute::CastOptions::Safe (types[i].GetSharedPtr ()));
582+ ARROW_ASSIGN_OR_RAISE (
583+ call.arguments [i],
584+ BindNonRecursive (std::move (implicit_cast),
585+ /* insert_implicit_casts=*/ false , exec_context));
586+ }
587+ }
601588
589+ compute::KernelContext kernel_context (exec_context, call.kernel );
590+ if (call.kernel ->init ) {
591+ const FunctionOptions* options =
592+ call.options ? call.options .get () : call.function ->default_options ();
602593 ARROW_ASSIGN_OR_RAISE (
603- call.arguments [i],
604- BindNonRecursive (std::move (implicit_cast),
605- /* insert_implicit_casts=*/ false , exec_context));
594+ call.kernel_state ,
595+ call.kernel ->init (&kernel_context, {call.kernel , types, options}));
596+
597+ kernel_context.SetState (call.kernel_state .get ());
606598 }
607599
608- RETURN_NOT_OK (FinishBind ());
600+ ARROW_ASSIGN_OR_RAISE (
601+ call.type , call.kernel ->signature ->out_type ().Resolve (&kernel_context, types));
602+
609603 return Expression (std::move (call));
610604}
611605
0 commit comments