Skip to content

Commit

Permalink
Fix comment
Browse files Browse the repository at this point in the history
  • Loading branch information
PHILO-HE committed Jun 25, 2024
1 parent 165a838 commit 299ac91
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 37 deletions.
44 changes: 16 additions & 28 deletions velox/core/SimpleFunctionMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,15 +666,16 @@ class UDFHolder {
DECLARE_METHOD_RESOLVER(callAscii_method_resolver, callAscii);
DECLARE_METHOD_RESOLVER(initialize_method_resolver, initialize);

// Check which flavor of the call() method is provided by the UDF object. UDFs
// are required to provide at least one of the following methods:
// Check which flavor of the call()/callNullable()/callNullFree() method is
// provided by the UDF object. UDFs are required to provide at least one of
// the following methods:
//
// - bool|void|Status call(...)
// - bool|void|Status callNullable(...)
// - bool|void|Status callNullFree(...)
//
// Each of these methods can return either bool or void or Status. Returning
// void means that the UDF is assumed never to return null values. Returning
// Each of these methods can return bool, void or Status. Returning void
// means that the UDF is assumed never to return null values. Returning
// Status to hold success or error outcome of the function call.
//
// Optionally, UDFs can also provide the following methods:
Expand Down Expand Up @@ -708,14 +709,9 @@ class UDFHolder {
udf_has_call_return_void | udf_has_call_return_status;

static_assert(
!(udf_has_call_return_bool && udf_has_call_return_void),
"Provided call() methods need to return either void OR bool OR Status.");
static_assert(
!(udf_has_call_return_bool && udf_has_call_return_status),
"Provided call() methods need to return either void OR bool OR Status.");
static_assert(
!(udf_has_call_return_void && udf_has_call_return_status),
"Provided call() methods need to return either void OR bool OR Status.");
udf_has_call_return_void ^ udf_has_call_return_bool ^
udf_has_call_return_status,
"Provided call() methods need to only return void, bool OR Status.");

// callNullable():
static constexpr bool udf_has_callNullable_return_bool = util::has_method<
Expand All @@ -739,15 +735,11 @@ class UDFHolder {
static constexpr bool udf_has_callNullable =
udf_has_callNullable_return_bool | udf_has_callNullable_return_void |
udf_has_callNullable_return_status;

static_assert(
!(udf_has_callNullable_return_bool && udf_has_callNullable_return_void),
"Provided callNullable() methods need to return either void OR bool OR Status.");
static_assert(
!(udf_has_callNullable_return_bool && udf_has_callNullable_return_status),
"Provided callNullable() methods need to return either void OR bool OR Status.");
static_assert(
!(udf_has_callNullable_return_void && udf_has_callNullable_return_status),
"Provided callNullable() methods need to return either void OR bool OR Status.");
udf_has_callNullable_return_void ^ udf_has_callNullable_return_bool ^
udf_has_callNullable_return_status,
"Provided callNullable() methods need to only return void, bool OR Status.");

// callNullFree():
static constexpr bool udf_has_callNullFree_return_bool = util::has_method<
Expand All @@ -771,15 +763,11 @@ class UDFHolder {
static constexpr bool udf_has_callNullFree =
udf_has_callNullFree_return_bool | udf_has_callNullFree_return_void |
udf_has_callNullFree_return_status;

static_assert(
!(udf_has_callNullFree_return_bool && udf_has_callNullFree_return_void),
"Provided callNullFree() methods need to return either void OR bool OR Status.");
static_assert(
!(udf_has_callNullFree_return_bool && udf_has_callNullFree_return_status),
"Provided callNullFree() methods need to return either void OR bool OR Status.");
static_assert(
!(udf_has_callNullFree_return_void && udf_has_callNullFree_return_status),
"Provided callNullFree() methods need to return either void OR bool OR Status.");
udf_has_callNullFree_return_void ^ udf_has_callNullFree_return_bool ^
udf_has_callNullFree_return_status,
"Provided callNullFree() methods need to only return void, bool OR Status.");

// callAscii():
static constexpr bool udf_has_callAscii_return_bool = util::has_method<
Expand Down
65 changes: 56 additions & 9 deletions velox/expression/tests/SimpleFunctionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1508,13 +1508,6 @@ struct NoThrowFunction {
out = in / 6;
return Status::OK();
}

Status callNullable(out_type<int64_t>& out, const arg_type<int64_t>* in) {
if (!in) {
return Status::UserError("Input cannot be NULL");
}
return Status::OK();
}
};

TEST_F(SimpleFunctionTest, noThrow) {
Expand Down Expand Up @@ -1547,12 +1540,66 @@ TEST_F(SimpleFunctionTest, noThrow) {
VELOX_ASSERT_THROW(
(evaluateOnce<int64_t, int64_t>("try(no_throw(c0))", 6)),
"Input must not be 6");
}

template <typename TExec>
struct CallNullableNoThrowFunction {
VELOX_DEFINE_FUNCTION_TYPES(TExec);

Status callNullable(out_type<int64_t>& out, const arg_type<int64_t>* in) {
if (!in) {
return Status::UserError("Input cannot be NULL");
}
out = *in + 1;
return Status::OK();
}
};

TEST_F(SimpleFunctionTest, callNullableNoThrow) {
registerFunction<CallNullableNoThrowFunction, int64_t, int64_t>(
{"nullable_no_throw"});
// Error reported via Status by callNullable.
VELOX_ASSERT_THROW(
(evaluateOnce<int64_t, int64_t>("no_throw(c0)", std::nullopt)),
(evaluateOnce<int64_t, int64_t>("nullable_no_throw(c0)", std::nullopt)),
"Input cannot be NULL");
result = evaluateOnce<int64_t, int64_t>("try(no_throw(c0))", std::nullopt);

result = evaluateOnce<int64_t, int64_t>(
"try(nullable_no_throw(c0))", std::nullopt);
EXPECT_EQ(std::nullopt, result);
}

template <typename TExec>
struct CallNullFreeNoThrowFunction {
VELOX_DEFINE_FUNCTION_TYPES(TExec);

Status callNullFree(out_type<int64_t>& out, const arg_type<int64_t>& in) {
if (in == 0) {
return Status::UserError("Input cannot be 0");
}
if (in % 2 == 0) {
return Status::UserError("Input cannot be even");
}
out = *in + 1;
return Status::OK();
}
};

TEST_F(SimpleFunctionTest, callNullFreeNoThrow) {
registerFunction<CallNullFreeNoThrowFunction, int64_t, int64_t>(
{"null_free_no_throw"});
// Error reported via Status by callNullable.
VELOX_ASSERT_THROW(
(evaluateOnce<int64_t, int64_t>("null_free_no_throw(c0)", 0)),
"Input cannot be 0");

result = evaluateOnce<int64_t, int64_t>("try(null_free_no_throw(c0))", 0);
EXPECT_EQ(std::nullopt, result);

VELOX_ASSERT_THROW(
(evaluateOnce<int64_t, int64_t>("null_free_no_throw(c0)", 4)),
"Input cannot be even");

result = evaluateOnce<int64_t, int64_t>("try(null_free_no_throw(c0))", 4);
EXPECT_EQ(std::nullopt, result);
}

Expand Down

0 comments on commit 299ac91

Please sign in to comment.