aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvvvv <vvvv@yandex-team.com>2025-02-21 18:08:26 +0300
committervvvv <vvvv@yandex-team.com>2025-02-21 19:12:56 +0300
commit807412ee4958d5903d6bb22cfb95ea126919c6f9 (patch)
tree94e95014f93ccb0e440dd0d16cb4fe4d52a8d269
parent253d0dcf6c3fbbbf0594538d398123fc4eb9ae68 (diff)
downloadydb-807412ee4958d5903d6bb22cfb95ea126919c6f9.tar.gz
YQL-19593 better error handling for Udf
commit_hash:216229b0558e1004453dedddbec8b767b2dab9c6
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_udf.cpp76
-rw-r--r--yql/essentials/minikql/computation/mkql_computation_node_graph.cpp5
2 files changed, 65 insertions, 16 deletions
diff --git a/yql/essentials/minikql/comp_nodes/mkql_udf.cpp b/yql/essentials/minikql/comp_nodes/mkql_udf.cpp
index 9240dad141..0834256743 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_udf.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_udf.cpp
@@ -15,6 +15,16 @@ namespace NMiniKQL {
namespace {
+constexpr size_t TypeDiffLimit = 1000;
+
+TString TruncateTypeDiff(const TString& s) {
+ if (s.size() < TypeDiffLimit) {
+ return s;
+ }
+
+ return s.substr(0,TypeDiffLimit) + "...";
+}
+
template<class TValidatePolicy, class TValidateMode>
class TSimpleUdfWrapper: public TMutableComputationNode<TSimpleUdfWrapper<TValidatePolicy,TValidateMode>> {
using TBaseComputation = TMutableComputationNode<TSimpleUdfWrapper<TValidatePolicy,TValidateMode>>;
@@ -43,8 +53,15 @@ public:
ctx.TypeEnv, ctx.TypeInfoHelper, ctx.CountersProvider, FunctionName, UserType->IsVoid() ? nullptr : UserType,
TypeConfig, flags, Pos, ctx.SecureParamsProvider, &funcInfo);
- MKQL_ENSURE(status.IsOk(), status.GetError());
- MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set for function " << FunctionName);
+ if (!status.IsOk()) {
+ UdfTerminate((TStringBuilder() << Pos << " Failed to find UDF function " << FunctionName << ", reason: "
+ << status.GetError()).c_str());
+ }
+
+ if (!funcInfo.Implementation) {
+ UdfTerminate((TStringBuilder() << Pos << " UDF implementation is not set for function " << FunctionName).c_str());
+ }
+
NUdf::TUnboxedValue udf(NUdf::TUnboxedValuePod(funcInfo.Implementation.Release()));
TValidate<TValidatePolicy,TValidateMode>::WrapCallable(CallableType, udf, TStringBuilder() << "FunctionWithConfig<" << FunctionName << ">");
return udf.Release();
@@ -190,13 +207,19 @@ private:
ctx.TypeEnv, ctx.TypeInfoHelper, ctx.CountersProvider, FunctionName, UserType->IsVoid() ? nullptr : UserType,
TypeConfig, flags, Pos, ctx.SecureParamsProvider, &funcInfo);
- MKQL_ENSURE(status.IsOk(), status.GetError());
- MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set for function " << FunctionName);
+ if (!status.IsOk()) {
+ UdfTerminate((TStringBuilder() << Pos << " Failed to find UDF function " << FunctionName << ", reason: "
+ << status.GetError()).c_str());
+ }
+
+ if (!funcInfo.Implementation) {
+ UdfTerminate((TStringBuilder() << Pos << " UDF implementation is not set for function " << FunctionName).c_str());
+ }
+
udf = NUdf::TUnboxedValuePod(funcInfo.Implementation.Release());
}
void Wrap(NUdf::TUnboxedValue& callable) const {
- MKQL_ENSURE(bool(callable), "Returned empty value in function: " << FunctionName);
TValidate<TValidatePolicy,TValidateMode>::WrapCallable(CallableType, callable, TStringBuilder() << "FunctionWithConfig<" << FunctionName << ">");
}
@@ -270,16 +293,27 @@ IComputationNode* WrapUdf(TCallable& callable, const TComputationNodeFactoryCont
ctx.Env, ctx.TypeInfoHelper, ctx.CountersProvider, funcName, userType->IsVoid() ? nullptr : userType,
typeConfig, flags, pos, ctx.SecureParamsProvider, &funcInfo);
- MKQL_ENSURE(status.IsOk(), status.GetError());
- MKQL_ENSURE(funcInfo.FunctionType->IsConvertableTo(*callable.GetType()->GetReturnType(), true),
- "Function '" << funcName << "' type mismatch, expected return type: " << PrintNode(callable.GetType()->GetReturnType(), true) <<
- ", actual:" << PrintNode(funcInfo.FunctionType, true));
- MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set for function " << funcName);
+ if (!status.IsOk()) {
+ UdfTerminate((TStringBuilder() << pos << " Failed to find UDF function " << funcName << ", reason: "
+ << status.GetError()).c_str());
+ }
+
+ if (!funcInfo.FunctionType->IsConvertableTo(*callable.GetType()->GetReturnType(), true)) {
+ TString diff = TStringBuilder() << "type mismatch, expected return type: " << PrintNode(callable.GetType()->GetReturnType(), true) <<
+ ", actual:" << PrintNode(funcInfo.FunctionType, true);
+ UdfTerminate((TStringBuilder() << pos << " UDF Function '" << funcName << "' " << TruncateTypeDiff(diff)).c_str());
+ }
+
+ if (!funcInfo.Implementation) {
+ UdfTerminate((TStringBuilder() << pos << " UDF implementation is not set for function " << funcName).c_str());
+ }
const auto runConfigType = funcInfo.RunConfigType;
- const bool typesMatch = runConfigType->IsSameType(*runCfgNode.GetStaticType());
- MKQL_ENSURE(typesMatch, "RunConfig '" << funcName << "' type mismatch, expected: " << PrintNode(runCfgNode.GetStaticType(), true) <<
- ", actual: " << PrintNode(runConfigType, true));
+ if (!runConfigType->IsSameType(*runCfgNode.GetStaticType())) {
+ TString diff = TStringBuilder() << "run config type mismatch, expected: " << PrintNode(runCfgNode.GetStaticType(), true) <<
+ ", actual:" << PrintNode(runConfigType, true);
+ UdfTerminate((TStringBuilder() << pos << " UDF Function '" << funcName << "' " << TruncateTypeDiff(diff)).c_str());
+ }
if (runConfigType->IsVoid()) {
if (ctx.ValidateMode == NUdf::EValidateMode::None && funcInfo.ModuleIR && funcInfo.IRFunctionName) {
@@ -320,10 +354,20 @@ IComputationNode* WrapScriptUdf(TCallable& callable, const TComputationNodeFacto
const auto status = ctx.FunctionRegistry.FindFunctionTypeInfo(
ctx.Env, ctx.TypeInfoHelper, ctx.CountersProvider, funcName, userType,
typeConfig, flags, pos, ctx.SecureParamsProvider, &funcInfo);
- MKQL_ENSURE(status.IsOk(), status.GetError());
- MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set");
- MKQL_ENSURE(!funcInfo.FunctionType, "Function type info is exist for same kind script, it's better use it");
+ if (!status.IsOk()) {
+ UdfTerminate((TStringBuilder() << pos << " Failed to find UDF function " << funcName << ", reason: "
+ << status.GetError()).c_str());
+ }
+
+ if (!funcInfo.Implementation) {
+ UdfTerminate((TStringBuilder() << pos << " UDF implementation is not set for function " << funcName).c_str());
+ }
+
+ if (funcInfo.FunctionType) {
+ UdfTerminate((TStringBuilder() << pos << " UDF function type exists for function " << funcName).c_str());
+ }
+
const auto callableType = callable.GetType();
MKQL_ENSURE(callableType->GetKind() == TType::EKind::Callable, "Expected callable type in callable type info");
const auto callableResultType = callableType->GetReturnType();
diff --git a/yql/essentials/minikql/computation/mkql_computation_node_graph.cpp b/yql/essentials/minikql/computation/mkql_computation_node_graph.cpp
index e1a79dff5b..75bcc4ce5c 100644
--- a/yql/essentials/minikql/computation/mkql_computation_node_graph.cpp
+++ b/yql/essentials/minikql/computation/mkql_computation_node_graph.cpp
@@ -164,6 +164,10 @@ public:
}
}
+ ITerminator& GetTerminator() {
+ return *ValueBuilder;
+ }
+
const TComputationMutables& GetMutables() const {
return Mutables;
}
@@ -994,6 +998,7 @@ TIntrusivePtr<TComputationPatternImpl> MakeComputationPatternImpl(TExploringNode
depScanner.Walk(root.GetNode(), opts.Env);
auto builder = MakeHolder<TComputationGraphBuildingVisitor>(opts);
+ const TBindTerminator bind(&builder->GetPatternNodes()->GetTerminator());
for (const auto& node : explorer.GetNodes()) {
Y_ABORT_UNLESS(node->GetCookie() <= IS_NODE_REACHABLE, "TNode graph should not be reused");
if (node->GetCookie() == IS_NODE_REACHABLE) {