Skip to content

[C++] Cast function bind failed after add a alias name through AddAlias #40183

@ZhangHuiGui

Description

@ZhangHuiGui

Describe the bug, including details regarding any error messages, version, and platform.

How to reproduce

auto fm = arrow::compute::GetFunctionRegistry();
ASSERT_OK(fm->AddAlias("alias_cast", "cast"));
auto s1 = arrow::schema({arrow::field("f1", arrow::decimal128(30, 3))});
auto b = arrow::RecordBatchFromJSON(s1, R"([
    ["1.000"],
    ["-4567.890"]
])");
auto expr = arrow::compute::call("alias_cast", {arrow::compute::field_ref("f1")}, 
        arrow::compute::CastOptions::Unsafe(arrow::int32()));
ASSERT_OK_AND_ASSIGN(expr, expr.Bind(*s1)); // Bind failed

ASSERT_OK_AND_ASSIGN(auto input, arrow::compute::MakeExecBatch(*s1, b));
ASSERT_OK_AND_ASSIGN(auto res_dat,
                     arrow::compute::ExecuteScalarExpression(expr, input));

Bind failed with NotImplemented: Dispatch for a MetaFunction's Kernels.

Reason

BindNonRecursive will call arrow::compute::GetFunction, the function handle the cast with specific name and
return an original function object rather than CastFunction which override the DispatchExact.

inline Result<std::shared_ptr<compute::Function>> GetFunction(
    const Expression::Call& call, compute::ExecContext* exec_context) {
  if (call.function_name != "cast") {
    return exec_context->func_registry()->GetFunction(call.function_name);
  }
  // XXX this special case is strange; why not make "cast" a ScalarFunction?
  const TypeHolder& to_type =
      ::arrow::internal::checked_cast<const compute::CastOptions&>(*call.options).to_type;
  return GetCastFunction(*to_type);
}

It's a huge project for us to unify the CastFunction schedule path to standard ScalarFunction, so i think maybe we should ban AddAlias for cast?

Component(s)

C++

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions