bkietz commented on code in PR #40687:
URL: https://github.com/apache/arrow/pull/40687#discussion_r1532504328


##########
cpp/src/arrow/compute/kernels/scalar_compare.cc:
##########
@@ -705,6 +705,14 @@ struct BinaryScalarMinMax {
 template <typename Op>
 struct FixedSizeBinaryScalarMinMax {
   static Status Exec(KernelContext* ctx, const ExecSpan& batch, ExecResult* 
out) {
+    if (batch.IsNull()) {
+      std::shared_ptr<Scalar> result = 
MakeNullScalar(out->type()->GetSharedPtr());
+      ARROW_ASSIGN_OR_RAISE(std::shared_ptr<Array> arr_result,
+                            MakeArrayFromScalar(*result, 1));
+      out->value = std::move(arr_result->data());

Review Comment:
   This factory allocates and so should use the pool provided by the kernel 
context. Also this can be written more concisely with MakeArrayOfNull
   ```suggestion
         ARROW_ASSIGN_OR_RAISE(out->value,
                               MakeArrayOfNull(out->type()->GetSharedPtr(), 1
                                               ctx->memory_pool()));
   ```



##########
cpp/src/arrow/compute/kernels/scalar_random.cc:
##########
@@ -57,6 +57,14 @@ random::pcg64_oneseq MakeSeedGenerator() {
 }
 
 Status ExecRandom(KernelContext* ctx, const ExecSpan& batch, ExecResult* out) {
+  if (batch.IsNull()) {

Review Comment:
   Since random is not a pure function, it should not return scalar like this.



##########
cpp/src/arrow/compute/exec_test.cc:
##########
@@ -1425,6 +1426,33 @@ TEST(Ordering, IsSuborderOf) {
   CheckOrdering(unordered, {true, true, true, true, true, true});
 }
 
+static Status RegisterMyScalarPureFunction() {
+  const std::string name = "my_scalar_function";
+  auto func = std::make_shared<ScalarFunction>(name, Arity::Nullary(),
+                                               FunctionDoc::Empty(), nullptr);
+  auto func_exec = [](KernelContext* /*ctx*/, const ExecSpan& /*batch*/,
+                      ExecResult* out) -> Status {
+    auto scalar = MakeScalar("I am a scalar");
+    ARROW_ASSIGN_OR_RAISE(auto arr_res, MakeArrayFromScalar(*scalar, 1));
+    out->value = std::move(arr_res->data());
+    return Status::OK();
+  };
+
+  ScalarKernel kernel({}, utf8(), func_exec);
+  ARROW_RETURN_NOT_OK(func->AddKernel(kernel));
+
+  auto registry = GetFunctionRegistry();
+  ARROW_RETURN_NOT_OK(registry->AddFunction(std::move(func)));
+  return Status::OK();
+}
+
+TEST(CallFunction, ScalarPureFunction) {
+  ASSERT_OK(RegisterMyScalarPureFunction());
+
+  EXPECT_THAT(CallFunction("my_scalar_function", ExecBatch({})),
+              ResultWith(MakeScalar("I am a scalar")));
+}

Review Comment:
   
   I don't think this test is relevant to the PR. "my_scalar_function" returns 
only scalar in any case



##########
cpp/src/arrow/compute/exec.h:
##########
@@ -257,6 +257,10 @@ struct ARROW_EXPORT ExecBatch {
     return result;
   }
 
+  /// \brief A check for the empty ExecBatch with no output length
+  /// and function's arguments.
+  bool IsNull() const { return length == 0 && num_values() == 0; }

Review Comment:
   Under what circumstances would we have `num_values() == 0` but `length != 
0`? It seems accessing the length of an ExecBatch with no values would be ill 
formed and we could forgo `IsValid()` in favor of just checking `num_values() 
== 0`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to