Skip to content

Commit 0490569

Browse files
committed
YQL-19967: Relax closure type comparison
commit_hash:6425e8ea846ad5be20c46282f4fde40f5e83f81d (cherry picked from commit fcc18ad)
1 parent 56233d0 commit 0490569

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

yql/essentials/minikql/comp_nodes/mkql_udf.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ IComputationNode* WrapUdf(TCallable& callable, const TComputationNodeFactoryCont
405405
const auto closureNodeType = runConfigNodeType->IsVoid()
406406
? AS_TYPE(TCallableType, callableNodeType)->GetReturnType()
407407
: callableNodeType;
408-
if (!closureNodeType->IsSameType(*closureFuncType)) {
408+
if (!closureNodeType->IsConvertableTo(*closureFuncType)) {
409409
TString diff = TStringBuilder()
410410
<< "type mismatch, expected return type: "
411411
<< PrintNode(closureNodeType, true)

yql/essentials/minikql/comp_nodes/ut/mkql_udf_ut.cpp

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,55 @@
11
#include "mkql_computation_node_ut.h"
22
#include <yql/essentials/public/udf/udf_helpers.h>
33
#include <yql/essentials/minikql/mkql_node_serialization.h>
4+
#include <yql/essentials/minikql/mkql_node_cast.h>
45

56
namespace NKikimr {
67
namespace NMiniKQL {
78

9+
// XXX: Emulate type transformations similar to the one made by
10+
// type annotation and compilation phases. As a result, the name
11+
// (i.e. "UDF") of callable type is lost. Hence, the type resolved
12+
// at the type annotation phase (and, ergo, used for bytecode
13+
// compilation) differs from the type, resolved for the underline
14+
// function at runtime.
15+
template<typename TUdf>
16+
static TType* TweakUdfType(const NYql::NUdf::TStringRef& name, TType* userType,
17+
const TTypeEnvironment& env)
18+
{
19+
TFunctionTypeInfoBuilder typeInfoBuilder(NYql::UnknownLangVersion, env,
20+
new TTypeInfoHelper(),
21+
"", nullptr, {});
22+
23+
// Obtain the callable type of the particular UDF.
24+
TFunctionTypeInfo funcInfo;
25+
UNIT_ASSERT(TUdf::DeclareSignature(name, userType, typeInfoBuilder, true));
26+
typeInfoBuilder.Build(&funcInfo);
27+
28+
// Create the new MiniKQL type to emulate two conversions:
29+
// * Convert the given MiniKQL type to the expression type.
30+
// See <NYql::NCommon::ConvertMiniKQLType>.
31+
// * Convert the expression type back to the MiniKQL one.
32+
// See <NYql::NCommon::TMkqlBuildContext::BuildType>.
33+
// The aforementioned conversions are made by the pipeline in
34+
// scope of type annotation and compilation phases.
35+
// As a result of the first conversion, the name of the
36+
// callable type is lost, so the new MiniKQL type has to be
37+
// the same as the resolved one, but the name is omitted.
38+
const auto funcType = AS_TYPE(TCallableType, funcInfo.FunctionType);
39+
TVector<TType*> argsTypes;
40+
for (size_t i = 0; i < funcType->GetArgumentsCount(); i++) {
41+
argsTypes.push_back(funcType->GetArgumentType(i));
42+
}
43+
const auto nodeType = TCallableType::Create("", /* Name has to be empty. */
44+
funcType->GetReturnType(),
45+
funcType->GetArgumentsCount(),
46+
argsTypes.data(),
47+
funcType->GetPayload(),
48+
env);
49+
nodeType->SetOptionalArgumentsCount(funcType->GetOptionalArgumentsCount());
50+
return nodeType;
51+
};
52+
853
class TImpl : public NYql::NUdf::TBoxedValue {
954
public:
1055
explicit TImpl(NYql::NUdf::TSourcePosition pos,
@@ -219,7 +264,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLUdfTest) {
219264
pb.NewTupleType({strType}),
220265
pb.NewEmptyStructType(),
221266
pb.NewEmptyTupleType()});
222-
const auto udf = pb.Udf("TestModule.Test", upvalue, userType);
267+
268+
const auto udfType = TweakUdfType<TRunConfig>("Test", userType, *compileSetup.Env);
269+
const auto udf = pb.TypedUdf("TestModule.Test", udfType, upvalue, userType);
223270

224271
const auto list = pb.NewList(strType, {value});
225272
const auto pgmReturn = pb.Map(list, [&pb, udf](const TRuntimeNode item) {
@@ -268,7 +315,9 @@ Y_UNIT_TEST_SUITE(TMiniKQLUdfTest) {
268315
pb.NewTupleType({strType}),
269316
pb.NewEmptyStructType(),
270317
pb.NewEmptyTupleType()});
271-
const auto udf = pb.Udf("TestModule.Test", pb.NewVoid(), userType);
318+
319+
const auto udfType = TweakUdfType<TCurrying>("Test", userType, *compileSetup.Env);
320+
const auto udf = pb.TypedUdf("TestModule.Test", udfType, pb.NewVoid(), userType);
272321
const auto closure = pb.Apply(udf, {upvalue, optional});
273322

274323
const auto list = pb.NewList(strType, {value});

0 commit comments

Comments
 (0)