Skip to content
This repository was archived by the owner on Nov 1, 2024. It is now read-only.

Commit 31e8b83

Browse files
bearzxfacebook-github-bot
authored andcommitted
better error message with unsupported velox udfs (#400)
Summary: As noted in issue #230 we want to improve the error messages when missing velox UDFs to specify is it: 1. UDF doesn't exist at all 2. UDF exists, but doesn't accept the input types that user provided This is implemented using similar code in https://github.com/facebookincubator/velox/blob/041f3759d6e4c070c2ecd2e01eae6a7be9d93957/velox/parse/TypeResolver.cpp#L112-L124 Pull Request resolved: #400 Reviewed By: wenleix Differential Revision: D37399459 Pulled By: bearzx fbshipit-source-id: 75ca2cd818be30879a1e9b8e23d8a4ead02acedd
1 parent 2573109 commit 31e8b83

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

csrc/velox/column.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include "column.h"
10+
#include <boost/algorithm/string.hpp>
1011
#include <memory>
1112
#include "VariantToVector.h"
1213
#include "bindings.h"
@@ -435,6 +436,30 @@ std::unique_ptr<OperatorHandle> OperatorHandle::fromCall(
435436
std::move(callTypedExprs), &TorchArrowGlobalStatic::execContext()));
436437
}
437438

439+
std::string udfSignaturesToString(
440+
const std::vector<const velox::exec::FunctionSignature*>& signatures) {
441+
std::stringstream out;
442+
for (auto i = 0; i < signatures.size(); ++i) {
443+
if (i > 0) {
444+
out << ", ";
445+
}
446+
out << signatures[i]->toString();
447+
}
448+
return out.str();
449+
}
450+
451+
std::string udfSignaturesToString(velox::RowTypePtr inputRowType) {
452+
auto children = inputRowType->children();
453+
std::stringstream out;
454+
for (auto i = 0; i < children.size(); ++i) {
455+
if (i > 0) {
456+
out << ",";
457+
}
458+
out << children[i]->toString();
459+
}
460+
return "(" + boost::algorithm::to_lower_copy(out.str()) + ")";
461+
}
462+
438463
std::unique_ptr<OperatorHandle> OperatorHandle::fromUDF(
439464
velox::RowTypePtr inputRowType,
440465
const std::string& udfName) {
@@ -445,8 +470,22 @@ std::unique_ptr<OperatorHandle> OperatorHandle::fromUDF(
445470

446471
velox::TypePtr outputType =
447472
velox::resolveFunction(udfName, inputRowType->children());
473+
448474
if (outputType == nullptr) {
449-
throw std::runtime_error("Request for unknown Velox UDF: " + udfName);
475+
std::string signature = udfSignaturesToString(inputRowType);
476+
477+
auto allSignatures = velox::getFunctionSignatures();
478+
auto it = allSignatures.find(udfName);
479+
if (it == allSignatures.end()) {
480+
throw std::runtime_error(
481+
"Request for unknown Velox UDF: " + udfName + signature);
482+
} else {
483+
const auto& functionSignatures = it->second;
484+
throw std::runtime_error(
485+
"Velox UDF signature is not supported: " + signature +
486+
". Supported signatures: " +
487+
udfSignaturesToString(functionSignatures));
488+
}
450489
}
451490
return OperatorHandle::fromCall(inputRowType, outputType, udfName);
452491
}

torcharrow/test/test_functional_cpu.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,24 @@ def test_functional_dispatch(self):
5151
# Validate that invoking unknown UDFs errors nicely.
5252
with self.assertRaises(RuntimeError) as ex:
5353
assert functional.idontexist(str_col)
54-
self.assertEqual(str(ex.exception), "Request for unknown Velox UDF: idontexist")
54+
self.assertTrue(
55+
str(ex.exception).startswith("Request for unknown Velox UDF: idontexist")
56+
)
57+
58+
# Validate that invoking unknown UDFs with unsupported signatures errors nicely too.
59+
with self.assertRaises(RuntimeError) as ex:
60+
assert functional.firstx(str_col, 1)
61+
msg = str(ex.exception)
62+
print(msg)
63+
self.assertTrue(
64+
msg.startswith("Velox UDF signature is not supported: (varchar,bigint)")
65+
)
66+
67+
supported_sig = msg[msg.find("Supported signatures:") : :]
68+
self.assertTrue(
69+
"(array(bigint),bigint) -> array(bigint), (array(integer),bigint) -> array(integer), (array(bigint),integer) -> array(bigint), (array(integer),integer) -> array(integer)"
70+
in supported_sig
71+
)
5572

5673
def test_factory_dispatch(self):
5774
rand_col = functional.rand(size=42)

0 commit comments

Comments
 (0)